]> code.ossystems Code Review - openembedded-core.git/blob
f796ce834654289c06be1b0c08cd4fbd4be91b38
[openembedded-core.git] /
1 From 3041daa54b49bcb6ab444c7b9e14bc6a1ade6236 Mon Sep 17 00:00:00 2001
2 From: Vaibhav Hiremath <hvaibhav@ti.com>
3 Date: Fri, 13 Feb 2009 14:44:20 +0530
4 Subject: [PATCH 1/2] Resizer and Previewer driver added to commit
5
6 The Resizer and Previewer driver added to the commit
7 from the patch submitted by Sergio on 12 Dec 2008.
8
9 The new WTBU code base and Nokia fixes package doesn't contain
10 standalone resizer driver support.
11
12 Following major changes done -
13
14         - Added stand-alone resizer driver support
15           in isp.c file.
16         - Seperate Kconfig file created
17         - hardware access of resizer module fixed as per new
18           isp.c
19
20 Signed-off-by: Vaibhav Hiremath <hvaibhav@ti.com>
21 ---
22  drivers/media/video/Kconfig              |    5 +-
23  drivers/media/video/isp/Kconfig          |   16 +
24  drivers/media/video/isp/Makefile         |    7 +
25  drivers/media/video/isp/isp.c            |   12 +
26  drivers/media/video/isp/ispmmu.c         |    1 +
27  drivers/media/video/isp/omap_previewer.c |  825 +++++++++++++++
28  drivers/media/video/isp/omap_previewer.h |  162 +++
29  drivers/media/video/isp/omap_resizer.c   | 1634 ++++++++++++++++++++++++++++++
30  include/linux/omap_resizer.h             |  136 +++
31  9 files changed, 2794 insertions(+), 4 deletions(-)
32  create mode 100644 drivers/media/video/isp/Kconfig
33  create mode 100644 drivers/media/video/isp/omap_previewer.c
34  create mode 100644 drivers/media/video/isp/omap_previewer.h
35  create mode 100644 drivers/media/video/isp/omap_resizer.c
36  create mode 100644 include/linux/omap_resizer.h
37
38 diff --git a/drivers/media/video/isp/Kconfig b/drivers/media/video/isp/Kconfig
39 new file mode 100644
40 index 0000000..acda63b
41 --- /dev/null
42 +++ b/drivers/media/video/isp/Kconfig
43 @@ -0,0 +1,16 @@
44 +# Kconfig for OMAP3 ISP driver
45 +
46 +config VIDEO_OMAP3_ISP
47 +       tristate
48 +       select VIDEOBUF_GEN
49 +       select VIDEOBUF_DMA_SG
50 +
51 +config VIDEO_OMAP34XX_ISP_PREVIEWER
52 +       tristate "OMAP ISP Previewer"
53 +       depends on !ARCH_OMAP3410
54 +       select VIDEO_OMAP3_ISP
55 +
56 +config VIDEO_OMAP34XX_ISP_RESIZER
57 +       tristate "OMAP ISP Resizer"
58 +       depends on !ARCH_OMAP3410
59 +       select VIDEO_OMAP3_ISP
60 diff --git a/drivers/media/video/isp/Makefile b/drivers/media/video/isp/Makefile
61 index 0f9301c..ed10a51 100644
62 --- a/drivers/media/video/isp/Makefile
63 +++ b/drivers/media/video/isp/Makefile
64 @@ -7,6 +7,13 @@ else
65  isp-mod-objs += \
66         isp.o ispccdc.o ispmmu.o \
67         isppreview.o ispresizer.o isph3a.o isphist.o isp_af.o ispcsi2.o
68 +
69 +obj-$(CONFIG_VIDEO_OMAP34XX_ISP_PREVIEWER) += \
70 +       omap_previewer.o
71 +
72 +obj-$(CONFIG_VIDEO_OMAP34XX_ISP_RESIZER) += \
73 +       omap_resizer.o
74 +
75  endif
76  
77  obj-$(CONFIG_VIDEO_OMAP3_ISP) += isp-mod.o
78 diff --git a/drivers/media/video/isp/isp.c b/drivers/media/video/isp/isp.c
79 index 6034a56..09a1792 100644
80 --- a/drivers/media/video/isp/isp.c
81 +++ b/drivers/media/video/isp/isp.c
82 @@ -521,6 +521,13 @@ int isp_set_callback(enum isp_callback_type type, isp_callback_t callback,
83                                         OMAP3_ISP_IOMEM_MAIN,
84                                         ISP_IRQ0ENABLE);
85                 break;
86 +       case CBK_RESZ_DONE:
87 +               isp_reg_writel(IRQ0ENABLE_RSZ_DONE_IRQ, OMAP3_ISP_IOMEM_MAIN,
88 +                               ISP_IRQ0STATUS);
89 +               isp_reg_writel(isp_reg_readl(OMAP3_ISP_IOMEM_MAIN, ISP_IRQ0ENABLE) |
90 +                               IRQ0ENABLE_RSZ_DONE_IRQ, OMAP3_ISP_IOMEM_MAIN,
91 +                               ISP_IRQ0ENABLE);
92 +               break;
93         default:
94                 break;
95         }
96 @@ -996,6 +1003,11 @@ static irqreturn_t omap34xx_isp_isr(int irq, void *_isp)
97                         if (!ispresizer_busy())
98                                 ispresizer_config_shadow_registers();
99                         isp_buf_process(bufs);
100 +               } else {
101 +                       if (irqdis->isp_callbk[CBK_RESZ_DONE])
102 +                               irqdis->isp_callbk[CBK_RESZ_DONE](RESZ_DONE,
103 +                                               irqdis->isp_callbk_arg1[CBK_RESZ_DONE],
104 +                                               irqdis->isp_callbk_arg2[CBK_RESZ_DONE]);
105                 }
106         }
107  
108 diff --git a/drivers/media/video/isp/ispmmu.c b/drivers/media/video/isp/ispmmu.c
109 index 076aea1..b943d5b 100644
110 --- a/drivers/media/video/isp/ispmmu.c
111 +++ b/drivers/media/video/isp/ispmmu.c
112 @@ -289,6 +289,7 @@ int ispmmu_get_mapeable_space(void)
113         return (L2P_TABLE_NR - no_of_l2p_alloted) * ISPMMU_TTB_ENTRIES_NR *
114                                                         ISPMMU_L2D_ENTRIES_NR;
115  }
116 +EXPORT_SYMBOL_GPL(ispmmu_get_mapeable_space);
117  
118  /**
119   * ispmmu_map - Map a physically contiguous buffer to ISP space.
120 diff --git a/drivers/media/video/isp/omap_previewer.c b/drivers/media/video/isp/omap_previewer.c
121 new file mode 100644
122 index 0000000..634a056
123 --- /dev/null
124 +++ b/drivers/media/video/isp/omap_previewer.c
125 @@ -0,0 +1,825 @@
126 +/*
127 + * drivers/media/video/isp/omap_previewer.c
128 + *
129 + * Wrapper for Preview module in TI's OMAP3430 ISP
130 + *
131 + * Copyright (C) 2008 Texas Instruments, Inc.
132 + *
133 + * Contributors:
134 + *     Leonides Martinez <leonides.martinez@ti.com>
135 + *     Sergio Aguirre <saaguirre@ti.com>
136 + *
137 + * This package is free software; you can redistribute it and/or modify
138 + * it under the terms of the GNU General Public License version 2 as
139 + * published by the Free Software Foundation.
140 + *
141 + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
142 + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
143 + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
144 + */
145 +
146 +#include <linux/mutex.h>
147 +#include <linux/cdev.h>
148 +#include <linux/device.h>
149 +#include <linux/delay.h>
150 +#include <linux/fs.h>
151 +#include <linux/mm.h>
152 +#include <linux/module.h>
153 +#include <linux/platform_device.h>
154 +#include <linux/uaccess.h>
155 +#include <linux/io.h>
156 +#include <media/v4l2-dev.h>
157 +#include <asm/cacheflush.h>
158 +
159 +#include "isp.h"
160 +#include "ispmmu.h"
161 +#include "ispreg.h"
162 +#include "omap_previewer.h"
163 +
164 +#define OMAP_PREV_NAME         "omap-previewer"
165 +
166 +static int prev_major = -1;
167 +static struct device *prev_dev;
168 +static struct class *prev_class;
169 +static struct prev_device *prevdevice;
170 +static struct platform_driver omap_previewer_driver;
171 +
172 +static u32 prev_bufsize;
173 +
174 +/**
175 + * prev_calculate_crop - Calculate crop size according to device parameters
176 + * @device: Structure containing ISP preview wrapper global information
177 + * @crop: Structure containing crop size
178 + *
179 + * This function is used to calculate frame size reduction depending on
180 + * the features enabled by the application.
181 + **/
182 +static void prev_calculate_crop(struct prev_device *device,
183 +                                               struct prev_cropsize *crop)
184 +{
185 +       dev_dbg(prev_dev, "prev_calculate_crop E\n");
186 +
187 +       if (!device || !crop) {
188 +               dev_err(prev_dev, "\nErron in argument");
189 +               return;
190 +       }
191 +
192 +       isppreview_try_size(device->params->size_params.hsize,
193 +                                       device->params->size_params.vsize,
194 +                                       &crop->hcrop, &crop->vcrop);
195 +       crop->hcrop &= PREV_16PIX_ALIGN_MASK;
196 +       dev_dbg(prev_dev, "prev_calculate_crop L\n");
197 +}
198 +
199 +/**
200 + * prev_get_status - Get status of ISP preview module
201 + * @status: Structure containing the busy state.
202 + *
203 + * Checks if the ISP preview module is busy.
204 + *
205 + * Returns 0 if successful, or -EINVAL if the status parameter is invalid.
206 + **/
207 +static int prev_get_status(struct prev_status *status)
208 +{
209 +       if (!status) {
210 +               dev_err(prev_dev, "get_status: invalid parameter\n");
211 +               return -EINVAL;
212 +       }
213 +       status->hw_busy = (char)isppreview_busy();
214 +       return 0;
215 +}
216 +
217 +/**
218 + * prev_hw_setup - Stores the desired configuration in the proper HW registers
219 + * @config: Structure containing the desired configuration for ISP preview
220 + *          module.
221 + *
222 + * Reads the structure sent, and modifies the desired registers.
223 + *
224 + * Always returns 0.
225 + **/
226 +static int prev_hw_setup(struct prev_params *config)
227 +{
228 +       dev_dbg(prev_dev, "prev_hw_setup E\n");
229 +
230 +       if (config->features & PREV_AVERAGER)
231 +               isppreview_config_averager(config->average);
232 +       else
233 +               isppreview_config_averager(0);
234 +
235 +       if (config->features & PREV_INVERSE_ALAW)
236 +               isppreview_enable_invalaw(1);
237 +       else
238 +               isppreview_enable_invalaw(0);
239 +
240 +       if (config->features & PREV_HORZ_MEDIAN_FILTER) {
241 +               isppreview_config_hmed(config->hmf_params);
242 +               isppreview_enable_hmed(1);
243 +       } else
244 +               isppreview_enable_hmed(0);
245 +
246 +       if (config->features & PREV_DARK_FRAME_SUBTRACT) {
247 +               isppreview_set_darkaddr(config->drkf_params.addr);
248 +               isppreview_config_darklineoffset(config->drkf_params.offset);
249 +               isppreview_enable_drkframe(1);
250 +       } else
251 +               isppreview_enable_drkframe(0);
252 +
253 +       if (config->features & PREV_LENS_SHADING) {
254 +               isppreview_config_drkf_shadcomp(config->lens_shading_shift);
255 +               isppreview_enable_shadcomp(1);
256 +       } else
257 +               isppreview_enable_shadcomp(0);
258 +
259 +       dev_dbg(prev_dev, "prev_hw_setup L\n");
260 +       return 0;
261 +}
262 +
263 +/**
264 + * prev_validate_params - Validate configuration parameters for Preview Wrapper
265 + * @params: Structure containing configuration parameters
266 + *
267 + * Validate configuration parameters for Preview Wrapper
268 + *
269 + * Returns 0 if successful, or -EINVAL if a parameter value is invalid.
270 + **/
271 +static int prev_validate_params(struct prev_params *params)
272 +{
273 +       if (!params) {
274 +               dev_err(prev_dev, "validate_params: error in argument");
275 +               goto err_einval;
276 +       }
277 +
278 +       if ((params->features & PREV_AVERAGER) == PREV_AVERAGER) {
279 +               if ((params->average != NO_AVE)
280 +                                       && (params->average != AVE_2_PIX)
281 +                                       && (params->average != AVE_4_PIX)
282 +                                       && (params->average != AVE_8_PIX)) {
283 +                       dev_err(prev_dev, "validate_params: wrong pix "
284 +                                                               "average\n");
285 +                       goto err_einval;
286 +               } else if (((params->average == AVE_2_PIX)
287 +                                       && (params->size_params.hsize % 2))
288 +                                       || ((params->average == AVE_4_PIX)
289 +                                       && (params->size_params.hsize % 4))
290 +                                       || ((params->average == AVE_8_PIX)
291 +                                       && (params->size_params.hsize % 8))) {
292 +                       dev_err(prev_dev, "validate_params: "
293 +                                       "wrong pix average for input size\n");
294 +                       goto err_einval;
295 +               }
296 +       }
297 +
298 +       if ((params->size_params.pixsize != PREV_INWIDTH_8BIT)
299 +                                       && (params->size_params.pixsize
300 +                                       != PREV_INWIDTH_10BIT)) {
301 +               dev_err(prev_dev, "validate_params: wrong pixsize\n");
302 +               goto err_einval;
303 +       }
304 +
305 +       if (params->size_params.hsize > MAX_IMAGE_WIDTH
306 +                                       || params->size_params.hsize < 0) {
307 +               dev_err(prev_dev, "validate_params: wrong hsize\n");
308 +               goto err_einval;
309 +       }
310 +
311 +       if ((params->pix_fmt != YCPOS_YCrYCb)
312 +                                       && (YCPOS_YCbYCr != params->pix_fmt)
313 +                                       && (YCPOS_CbYCrY != params->pix_fmt)
314 +                                       && (YCPOS_CrYCbY != params->pix_fmt)) {
315 +               dev_err(prev_dev, "validate_params: wrong pix_fmt");
316 +               goto err_einval;
317 +       }
318 +
319 +       if ((params->features & PREV_DARK_FRAME_SUBTRACT)
320 +                                               && (params->features
321 +                                               & PREV_DARK_FRAME_CAPTURE)) {
322 +               dev_err(prev_dev, "validate_params: DARK FRAME CAPTURE and "
323 +                                               "SUBSTRACT cannot be enabled "
324 +                                               "at same time\n");
325 +               goto err_einval;
326 +       }
327 +
328 +       if (params->features & PREV_DARK_FRAME_SUBTRACT)
329 +               if (!params->drkf_params.addr
330 +                                       || (params->drkf_params.offset % 32)) {
331 +                       dev_err(prev_dev, "validate_params: dark frame "
332 +                                                               "address\n");
333 +                       goto err_einval;
334 +               }
335 +
336 +       if (params->features & PREV_LENS_SHADING)
337 +               if ((params->lens_shading_shift > 7)
338 +                                       || !params->drkf_params.addr
339 +                                       || (params->drkf_params.offset % 32)) {
340 +                       dev_err(prev_dev, "validate_params: lens shading "
341 +                                                               "shift\n");
342 +                       goto err_einval;
343 +               }
344 +
345 +       if ((params->size_params.in_pitch <= 0)
346 +                               || (params->size_params.in_pitch % 32)) {
347 +               params->size_params.in_pitch =
348 +                               (params->size_params.hsize * 2) & 0xFFE0;
349 +               dev_err(prev_dev, "\nError in in_pitch; new value = %d",
350 +                                               params->size_params.in_pitch);
351 +       }
352 +
353 +       return 0;
354 +err_einval:
355 +       return -EINVAL;
356 +}
357 +
358 +/**
359 + * preview_isr - Callback from ISP driver for ISP Preview Interrupt
360 + * @status: ISP IRQ0STATUS register value
361 + * @arg1: Structure containing ISP preview wrapper global information
362 + * @arg2: Currently not used
363 + **/
364 +static void preview_isr(unsigned long status, isp_vbq_callback_ptr arg1,
365 +                                                               void *arg2)
366 +{
367 +       struct prev_device *device = (struct prev_device *)arg1;
368 +
369 +       if ((status & PREV_DONE) != PREV_DONE)
370 +               return;
371 +
372 +       if (device)
373 +               complete(&device->wfc);
374 +}
375 +
376 +/**
377 + * prev_do_preview - Performs the Preview process
378 + * @device: Structure containing ISP preview wrapper global information
379 + * @arg: Currently not used
380 + *
381 + * Returns 0 if successful, or -EINVAL if the sent parameters are invalid.
382 + **/
383 +static int prev_do_preview(struct prev_device *device, int *arg)
384 +{
385 +       int bpp, size;
386 +       int ret = 0;
387 +       u32 out_hsize, out_vsize, out_line_offset;
388 +
389 +       dev_dbg(prev_dev, "prev_do_preview E\n");
390 +
391 +       if (!device) {
392 +               dev_err(prev_dev, "preview: invalid parameters\n");
393 +               return -EINVAL;
394 +       }
395 +
396 +       if (device->params->size_params.pixsize == PREV_INWIDTH_8BIT)
397 +               bpp = 1;
398 +       else
399 +               bpp = 2;
400 +
401 +       size = device->params->size_params.hsize *
402 +               device->params->size_params.vsize * bpp;
403 +
404 +       ret = isppreview_set_inaddr(device->isp_addr_read);
405 +       if (ret)
406 +               goto out;
407 +
408 +       ret = isppreview_set_outaddr(device->isp_addr_read);
409 +       if (ret)
410 +               goto out;
411 +
412 +       isppreview_try_size(device->params->size_params.hsize,
413 +                                       device->params->size_params.vsize,
414 +                                       &out_hsize, &out_vsize);
415 +
416 +       ret = isppreview_config_inlineoffset(device->params->size_params.hsize
417 +                                               * bpp);
418 +       if (ret)
419 +               goto out;
420 +
421 +       out_line_offset = (out_hsize * bpp) & PREV_32BYTES_ALIGN_MASK;
422 +
423 +       ret = isppreview_config_outlineoffset(out_line_offset);
424 +       if (ret)
425 +               goto out;
426 +
427 +       ret = isppreview_config_size(device->params->size_params.hsize,
428 +                                       device->params->size_params.vsize,
429 +                                       out_hsize, out_vsize);
430 +       if (ret)
431 +               goto out;
432 +
433 +       isppreview_config_datapath(PRV_RAW_MEM, PREVIEW_MEM);
434 +
435 +       ret = isp_set_callback(CBK_PREV_DONE, preview_isr, (void *)device,
436 +                                                               (void *)NULL);
437 +       if (ret) {
438 +               dev_err(prev_dev, "ERROR while setting Previewer callback!\n");
439 +               goto out;
440 +       }
441 +       isppreview_enable(1);
442 +
443 +       wait_for_completion_interruptible(&device->wfc);
444 +
445 +       if (device->isp_addr_read) {
446 +               ispmmu_vunmap(device->isp_addr_read);
447 +               device->isp_addr_read = 0;
448 +       }
449 +
450 +       ret = isp_unset_callback(CBK_PREV_DONE);
451 +
452 +       dev_dbg(prev_dev, "prev_do_preview L\n");
453 +out:
454 +       return ret;
455 +}
456 +
457 +/**
458 + * previewer_vbq_release - Videobuffer queue release
459 + * @q: Structure containing the videobuffer queue.
460 + * @vb: Structure containing the videobuffer used for previewer processing.
461 + **/
462 +static void previewer_vbq_release(struct videobuf_queue *q,
463 +                                               struct videobuf_buffer *vb)
464 +{
465 +       struct prev_fh *fh = q->priv_data;
466 +       struct prev_device *device = fh->device;
467 +
468 +       ispmmu_vunmap(device->isp_addr_read);
469 +       device->isp_addr_read = 0;
470 +       spin_lock(&device->vbq_lock);
471 +       vb->state = VIDEOBUF_NEEDS_INIT;
472 +       spin_unlock(&device->vbq_lock);
473 +       dev_dbg(prev_dev, "previewer_vbq_release\n");
474 +}
475 +
476 +/**
477 + * previewer_vbq_setup - Sets up the videobuffer size and validates count.
478 + * @q: Structure containing the videobuffer queue.
479 + * @cnt: Number of buffers requested
480 + * @size: Size in bytes of the buffer used for previewing
481 + *
482 + * Always returns 0.
483 + **/
484 +static int previewer_vbq_setup(struct videobuf_queue *q,
485 +                                                       unsigned int *cnt,
486 +                                                       unsigned int *size)
487 +{
488 +       struct prev_fh *fh = q->priv_data;
489 +       struct prev_device *device = fh->device;
490 +       u32 bpp = 1;
491 +
492 +       spin_lock(&device->vbq_lock);
493 +       if (*cnt <= 0)
494 +               *cnt = VIDEO_MAX_FRAME;
495 +
496 +       if (*cnt > VIDEO_MAX_FRAME)
497 +               *cnt = VIDEO_MAX_FRAME;
498 +
499 +       if (!device->params->size_params.hsize ||
500 +               !device->params->size_params.vsize) {
501 +               dev_err(prev_dev, "Can't setup buffer size\n");
502 +               spin_unlock(&device->vbq_lock);
503 +               return -EINVAL;
504 +       }
505 +
506 +       if (device->params->size_params.pixsize == PREV_INWIDTH_10BIT)
507 +               bpp = 2;
508 +       *size = prev_bufsize = bpp * device->params->size_params.hsize
509 +                                       * device->params->size_params.vsize;
510 +       spin_unlock(&device->vbq_lock);
511 +       dev_dbg(prev_dev, "previewer_vbq_setup\n");
512 +       return 0;
513 +}
514 +
515 +/**
516 + * previewer_vbq_prepare - Videobuffer is prepared and mmapped.
517 + * @q: Structure containing the videobuffer queue.
518 + * @vb: Structure containing the videobuffer used for previewer processing.
519 + * @field: Type of field to set in videobuffer device.
520 + *
521 + * Returns 0 if successful, or -EINVAL if buffer couldn't get allocated, or
522 + * -EIO if the ISP MMU mapping fails
523 + **/
524 +static int previewer_vbq_prepare(struct videobuf_queue *q,
525 +                                               struct videobuf_buffer *vb,
526 +                                               enum v4l2_field field)
527 +{
528 +       struct prev_fh *fh = q->priv_data;
529 +       struct prev_device *device = fh->device;
530 +       int err = -EINVAL;
531 +       unsigned int isp_addr;
532 +       struct videobuf_dmabuf *dma = videobuf_to_dma(vb);
533 +
534 +       dev_dbg(prev_dev, "previewer_vbq_prepare E\n");
535 +       spin_lock(&device->vbq_lock);
536 +       if (vb->baddr) {
537 +               vb->size = prev_bufsize;
538 +               vb->bsize = prev_bufsize;
539 +       } else {
540 +               spin_unlock(&device->vbq_lock);
541 +               dev_err(prev_dev, "No user buffer allocated\n");
542 +               goto out;
543 +       }
544 +
545 +       vb->width = device->params->size_params.hsize;
546 +       vb->height = device->params->size_params.vsize;
547 +       vb->field = field;
548 +       spin_unlock(&device->vbq_lock);
549 +
550 +       if (vb->state == VIDEOBUF_NEEDS_INIT) {
551 +               err = videobuf_iolock(q, vb, NULL);
552 +               if (!err) {
553 +                       isp_addr = ispmmu_vmap(dma->sglist, dma->sglen);
554 +                       if (!isp_addr)
555 +                               err = -EIO;
556 +                       else
557 +                               device->isp_addr_read = isp_addr;
558 +               }
559 +       }
560 +
561 +       if (!err) {
562 +               vb->state = VIDEOBUF_PREPARED;
563 +               flush_cache_user_range(NULL, vb->baddr,
564 +                                       (vb->baddr + vb->bsize));
565 +       } else
566 +               previewer_vbq_release(q, vb);
567 +
568 +       dev_dbg(prev_dev, "previewer_vbq_prepare L\n");
569 +out:
570 +       return err;
571 +}
572 +
573 +static void previewer_vbq_queue(struct videobuf_queue *q,
574 +                                               struct videobuf_buffer *vb)
575 +{
576 +       return;
577 +}
578 +
579 +/**
580 + * previewer_open - Initializes and opens the Preview Wrapper
581 + * @inode: Inode structure associated with the Preview Wrapper
582 + * @filp: File structure associated with the Preview Wrapper
583 + *
584 + * Returns 0 if successful, -EACCES if its unable to initialize default config,
585 + * -EBUSY if its already opened or the ISP module is not available, or -ENOMEM
586 + * if its unable to allocate the device in kernel space memory.
587 + **/
588 +static int previewer_open(struct inode *inode, struct file *filp)
589 +{
590 +       int ret = 0;
591 +       struct prev_device *device = prevdevice;
592 +       struct prev_params *config = isppreview_get_config();
593 +       struct prev_fh *fh;
594 +
595 +       if (config == NULL) {
596 +               dev_err(prev_dev, "Unable to initialize default config "
597 +                       "from isppreviewer\n\n");
598 +               return -EACCES;
599 +       }
600 +
601 +       if (device->opened || (filp->f_flags & O_NONBLOCK)) {
602 +               dev_err(prev_dev, "previewer_open: device is already "
603 +                                                               "opened\n");
604 +               return -EBUSY;
605 +       }
606 +
607 +       fh = kzalloc(sizeof(struct prev_fh), GFP_KERNEL);
608 +       if (NULL == fh)
609 +               return -ENOMEM;
610 +
611 +       isp_get();
612 +       ret = isppreview_request();
613 +       if (ret) {
614 +               isp_put();
615 +               dev_err(prev_dev, "Can't acquire isppreview\n");
616 +               return ret;
617 +       }
618 +
619 +       device->params = config;
620 +       device->opened = 1;
621 +
622 +       filp->private_data = fh;
623 +       fh->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
624 +       fh->device = device;
625 +
626 +       videobuf_queue_sg_init(&fh->vbq, &device->vbq_ops, NULL,
627 +                                       &device->vbq_lock, fh->type,
628 +                                       V4L2_FIELD_NONE,
629 +                                       sizeof(struct videobuf_buffer), fh);
630 +
631 +       init_completion(&device->wfc);
632 +       device->wfc.done = 0;
633 +       mutex_init(&device->prevwrap_mutex);
634 +
635 +       return 0;
636 +}
637 +
638 +/**
639 + * previewer_release - Releases Preview Wrapper and frees up allocated memory
640 + * @inode: Inode structure associated with the Preview Wrapper
641 + * @filp: File structure associated with the Preview Wrapper
642 + *
643 + * Always returns 0.
644 + **/
645 +static int previewer_release(struct inode *inode, struct file *filp)
646 +{
647 +       struct prev_fh *fh = filp->private_data;
648 +       struct prev_device *device = fh->device;
649 +       struct videobuf_queue *q = &fh->vbq;
650 +
651 +       device->opened = 0;
652 +       device->params = NULL;
653 +       isppreview_free();
654 +       videobuf_mmap_free(q);
655 +       isp_put();
656 +       prev_bufsize = 0;
657 +       filp->private_data = NULL;
658 +       kfree(fh);
659 +
660 +       dev_dbg(prev_dev, "previewer_release\n");
661 +       return 0;
662 +}
663 +
664 +/**
665 + * previewer_mmap - Memory maps the Preview Wrapper module.
666 + * @file: File structure associated with the Preview Wrapper
667 + * @vma: Virtual memory area structure.
668 + *
669 + * Returns 0 if successful, or returned value by the videobuf_mmap_mapper()
670 + * function.
671 + **/
672 +static int previewer_mmap(struct file *file, struct vm_area_struct *vma)
673 +{
674 +       struct prev_fh *fh = file->private_data;
675 +       dev_dbg(prev_dev, "previewer_mmap\n");
676 +
677 +       return videobuf_mmap_mapper(&fh->vbq, vma);
678 +}
679 +
680 +/**
681 + * previewer_ioctl - I/O control function for Preview Wrapper
682 + * @inode: Inode structure associated with the Preview Wrapper.
683 + * @file: File structure associated with the Preview Wrapper.
684 + * @cmd: Type of command to execute.
685 + * @arg: Argument to send to requested command.
686 + *
687 + * Returns 0 if successful, -1 if bad command passed or access is denied,
688 + * -EFAULT if copy_from_user() or copy_to_user() fails, -EINVAL if parameter
689 + * validation fails or parameter structure is not present
690 + **/
691 +static int previewer_ioctl(struct inode *inode, struct file *file,
692 +                                       unsigned int cmd, unsigned long arg)
693 +{
694 +       int ret = 0;
695 +       struct prev_params params;
696 +       struct prev_fh *fh = file->private_data;
697 +       struct prev_device *device = fh->device;
698 +
699 +       dev_dbg(prev_dev, "Entering previewer_ioctl()\n");
700 +
701 +       if ((_IOC_TYPE(cmd) != PREV_IOC_BASE)
702 +                                       || (_IOC_NR(cmd) > PREV_IOC_MAXNR)) {
703 +               dev_err(prev_dev, "Bad command Value \n");
704 +               goto err_minusone;
705 +       }
706 +
707 +       if (_IOC_DIR(cmd) & _IOC_READ)
708 +               ret = !access_ok(VERIFY_WRITE, (void *)arg, _IOC_SIZE(cmd));
709 +       else if (_IOC_DIR(cmd) & _IOC_WRITE)
710 +               ret = !access_ok(VERIFY_READ, (void *)arg, _IOC_SIZE(cmd));
711 +       if (ret) {
712 +               dev_err(prev_dev, "access denied\n");
713 +               goto err_minusone;
714 +       }
715 +
716 +       switch (cmd) {
717 +       case PREV_REQBUF:
718 +               if (mutex_lock_interruptible(&device->prevwrap_mutex))
719 +                       goto err_eintr;
720 +               ret = videobuf_reqbufs(&fh->vbq, (void *)arg);
721 +               mutex_unlock(&device->prevwrap_mutex);
722 +               break;
723 +
724 +       case PREV_QUERYBUF:
725 +               if (mutex_lock_interruptible(&device->prevwrap_mutex))
726 +                       goto err_eintr;
727 +               ret = videobuf_querybuf(&fh->vbq, (void *)arg);
728 +               mutex_unlock(&device->prevwrap_mutex);
729 +               break;
730 +
731 +       case PREV_QUEUEBUF:
732 +               if (mutex_lock_interruptible(&device->prevwrap_mutex))
733 +                       goto err_eintr;
734 +               ret = videobuf_qbuf(&fh->vbq, (void *)arg);
735 +               mutex_unlock(&device->prevwrap_mutex);
736 +               break;
737 +
738 +       case PREV_SET_PARAM:
739 +               if (mutex_lock_interruptible(&device->prevwrap_mutex))
740 +                       goto err_eintr;
741 +               if (copy_from_user(&params, (struct prev_params *)arg,
742 +                                               sizeof(struct prev_params))) {
743 +                       mutex_unlock(&device->prevwrap_mutex);
744 +                       return -EFAULT;
745 +               }
746 +               ret = prev_validate_params(&params);
747 +               if (ret < 0) {
748 +                       dev_err(prev_dev, "Error validating parameters!\n");
749 +                       mutex_unlock(&device->prevwrap_mutex);
750 +                       goto out;
751 +               }
752 +               if (device->params)
753 +                       memcpy(device->params, &params,
754 +                                               sizeof(struct prev_params));
755 +               else {
756 +                       mutex_unlock(&device->prevwrap_mutex);
757 +                       return -EINVAL;
758 +               }
759 +
760 +               ret = prev_hw_setup(device->params);
761 +               mutex_unlock(&device->prevwrap_mutex);
762 +               break;
763 +
764 +       case PREV_GET_PARAM:
765 +               if (copy_to_user((struct prev_params *)arg, device->params,
766 +                                               sizeof(struct prev_params)))
767 +                       ret = -EFAULT;
768 +               break;
769 +
770 +       case PREV_GET_STATUS:
771 +               ret = prev_get_status((struct prev_status *)arg);
772 +               break;
773 +
774 +       case PREV_PREVIEW:
775 +               if (mutex_lock_interruptible(&device->prevwrap_mutex))
776 +                       goto err_eintr;
777 +               ret = prev_do_preview(device, (int *)arg);
778 +               mutex_unlock(&device->prevwrap_mutex);
779 +               break;
780 +
781 +       case PREV_GET_CROPSIZE:
782 +               {
783 +               struct prev_cropsize outputsize;
784 +               prev_calculate_crop(device, &outputsize);
785 +               if (copy_to_user((struct prev_cropsize *)arg, &outputsize,
786 +                                               sizeof(struct prev_cropsize)))
787 +                       ret = -EFAULT;
788 +               }
789 +               break;
790 +
791 +       default:
792 +               dev_err(prev_dev, "previewer_ioctl: Invalid Command Value\n");
793 +               ret = -EINVAL;
794 +       }
795 +out:
796 +       return ret;
797 +err_minusone:
798 +       return -1;
799 +err_eintr:
800 +       return -EINTR;
801 +}
802 +
803 +/**
804 + * previewer_platform_release - Acts when Reference count is zero
805 + * @device: Structure containing ISP preview wrapper global information
806 + *
807 + * This is called when the reference count goes to zero
808 + **/
809 +static void previewer_platform_release(struct device *device)
810 +{
811 +       dev_dbg(prev_dev, "previewer_platform_release()\n");
812 +}
813 +
814 +static struct file_operations prev_fops = {
815 +       .owner = THIS_MODULE,
816 +       .open = previewer_open,
817 +       .release = previewer_release,
818 +       .mmap = previewer_mmap,
819 +       .ioctl = previewer_ioctl,
820 +};
821 +
822 +static struct platform_device omap_previewer_device = {
823 +       .name = OMAP_PREV_NAME,
824 +       .id = -1,
825 +       .dev = {
826 +               .release = previewer_platform_release,
827 +       }
828 +};
829 +
830 +/**
831 + * previewer_probe - Checks for device presence
832 + * @pdev: Structure containing details of the current device.
833 + *
834 + * Always returns 0
835 + **/
836 +static int __init previewer_probe(struct platform_device *pdev)
837 +{
838 +       return 0;
839 +}
840 +
841 +/**
842 + * previewer_remove - Handles the removal of the driver
843 + * @pdev: Structure containing details of the current device.
844 + *
845 + * Always returns 0.
846 + **/
847 +static int previewer_remove(struct platform_device *pdev)
848 +{
849 +       dev_dbg(prev_dev, "previewer_remove()\n");
850 +
851 +       platform_device_unregister(&omap_previewer_device);
852 +       platform_driver_unregister(&omap_previewer_driver);
853 +       unregister_chrdev(prev_major, OMAP_PREV_NAME);
854 +       return 0;
855 +}
856 +
857 +static struct platform_driver omap_previewer_driver = {
858 +       .probe = previewer_probe,
859 +       .remove = previewer_remove,
860 +       .driver = {
861 +               .owner = THIS_MODULE,
862 +               .name = OMAP_PREV_NAME,
863 +       },
864 +};
865 +
866 +/**
867 + * omap_previewer_init - Initialization of Preview Wrapper
868 + *
869 + * Returns 0 if successful, -ENOMEM if could not allocate memory, -ENODEV if
870 + * could not register the wrapper as a character device, or other errors if the
871 + * device or driver can't register.
872 + **/
873 +static int __init omap_previewer_init(void)
874 +{
875 +       int ret;
876 +       struct prev_device *device;
877 +
878 +       device = kzalloc(sizeof(struct prev_device), GFP_KERNEL);
879 +       if (!device) {
880 +               dev_err(prev_dev, OMAP_PREV_NAME ": could not allocate"
881 +                                                               " memory\n");
882 +               return -ENOMEM;
883 +       }
884 +       prev_major = register_chrdev(0, OMAP_PREV_NAME, &prev_fops);
885 +
886 +       if (prev_major < 0) {
887 +               dev_err(prev_dev, OMAP_PREV_NAME ": initialization "
888 +                               "failed. could not register character "
889 +                               "device\n");
890 +               return -ENODEV;
891 +       }
892 +
893 +       ret = platform_driver_register(&omap_previewer_driver);
894 +       if (ret) {
895 +               dev_err(prev_dev, OMAP_PREV_NAME
896 +                       ": failed to register platform driver!\n");
897 +               goto fail2;
898 +       }
899 +       ret = platform_device_register(&omap_previewer_device);
900 +       if (ret) {
901 +               dev_err(prev_dev, OMAP_PREV_NAME
902 +                       ": failed to register platform device!\n");
903 +               goto fail3;
904 +       }
905 +
906 +       prev_class = class_create(THIS_MODULE, OMAP_PREV_NAME);
907 +       if (!prev_class)
908 +               goto fail4;
909 +
910 +       prev_dev = device_create(prev_class, prev_dev,
911 +                                               (MKDEV(prev_major, 0)), NULL,
912 +                                               OMAP_PREV_NAME);
913 +       dev_dbg(prev_dev, OMAP_PREV_NAME ": Registered Previewer Wrapper\n");
914 +       device->opened = 0;
915 +
916 +       device->vbq_ops.buf_setup = previewer_vbq_setup;
917 +       device->vbq_ops.buf_prepare = previewer_vbq_prepare;
918 +       device->vbq_ops.buf_release = previewer_vbq_release;
919 +       device->vbq_ops.buf_queue = previewer_vbq_queue;
920 +       spin_lock_init(&device->vbq_lock);
921 +
922 +       prevdevice = device;
923 +       return 0;
924 +
925 +fail4:
926 +       platform_device_unregister(&omap_previewer_device);
927 +fail3:
928 +       platform_driver_unregister(&omap_previewer_driver);
929 +fail2:
930 +       unregister_chrdev(prev_major, OMAP_PREV_NAME);
931 +
932 +       return ret;
933 +}
934 +
935 +/**
936 + * omap_previewer_exit - Close of Preview Wrapper
937 + **/
938 +static void __exit omap_previewer_exit(void)
939 +{
940 +       previewer_remove(&omap_previewer_device);
941 +       kfree(prevdevice);
942 +       prev_major = -1;
943 +}
944 +
945 +module_init(omap_previewer_init);
946 +module_exit(omap_previewer_exit);
947 +
948 +MODULE_AUTHOR("Texas Instruments");
949 +MODULE_DESCRIPTION("OMAP ISP Previewer");
950 +MODULE_LICENSE("GPL");
951 diff --git a/drivers/media/video/isp/omap_previewer.h b/drivers/media/video/isp/omap_previewer.h
952 new file mode 100644
953 index 0000000..0bb31cd
954 --- /dev/null
955 +++ b/drivers/media/video/isp/omap_previewer.h
956 @@ -0,0 +1,162 @@
957 +/*
958 + * drivers/media/video/isp/omap_previewer.h
959 + *
960 + * Header file for Preview module wrapper in TI's OMAP3430 ISP
961 + *
962 + * Copyright (C) 2008 Texas Instruments, Inc.
963 + *
964 + * Contributors:
965 + *     Leonides Martinez <leonides.martinez@ti.com>
966 + *     Sergio Aguirre <saaguirre@ti.com>
967 + *
968 + * This package is free software; you can redistribute it and/or modify
969 + * it under the terms of the GNU General Public License version 2 as
970 + * published by the Free Software Foundation.
971 + *
972 + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
973 + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
974 + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
975 + */
976 +
977 +#include "isppreview.h"
978 +
979 +#ifndef OMAP_ISP_PREVIEW_WRAP_H
980 +#define OMAP_ISP_PREVIEW_WRAP_H
981 +
982 +#define PREV_IOC_BASE                  'P'
983 +#define PREV_REQBUF                    _IOWR(PREV_IOC_BASE, 1,\
984 +                                               struct v4l2_requestbuffers)
985 +#define PREV_QUERYBUF                  _IOWR(PREV_IOC_BASE, 2,\
986 +                                                       struct v4l2_buffer)
987 +#define PREV_SET_PARAM                 _IOW(PREV_IOC_BASE, 3,\
988 +                                                       struct prev_params)
989 +#define PREV_GET_PARAM                 _IOWR(PREV_IOC_BASE, 4,\
990 +                                                       struct prev_params)
991 +#define PREV_PREVIEW                   _IOR(PREV_IOC_BASE, 5, int)
992 +#define PREV_GET_STATUS                        _IOR(PREV_IOC_BASE, 6, char)
993 +#define PREV_GET_CROPSIZE              _IOR(PREV_IOC_BASE, 7,\
994 +                                                       struct prev_cropsize)
995 +#define PREV_QUEUEBUF                  _IOWR(PREV_IOC_BASE, 8,\
996 +                                                       struct v4l2_buffer)
997 +#define PREV_IOC_MAXNR                 8
998 +
999 +#define LUMA_TABLE_SIZE                        128
1000 +#define GAMMA_TABLE_SIZE               1024
1001 +#define CFA_COEFF_TABLE_SIZE           576
1002 +#define NOISE_FILTER_TABLE_SIZE                256
1003 +
1004 +#define MAX_IMAGE_WIDTH                        3300
1005 +
1006 +#define PREV_INWIDTH_8BIT              0       /* pixel width of 8 bits */
1007 +#define PREV_INWIDTH_10BIT             1       /* pixel width of 10 bits */
1008 +
1009 +#define PREV_32BYTES_ALIGN_MASK                0xFFFFFFE0
1010 +#define PREV_16PIX_ALIGN_MASK          0xFFFFFFF0
1011 +
1012 +/**
1013 + * struct prev_rgbblending - Structure for RGB2RGB blending parameters
1014 + * @blending: Color correlation 3x3 matrix.
1015 + * @offset: Color correlation offsets.
1016 + */
1017 +struct prev_rgbblending {
1018 +       short blending[RGB_MAX][RGB_MAX];       /* color correlation 3x3
1019 +                                                * matrix.
1020 +                                                */
1021 +       short offset[RGB_MAX];                  /* color correlation offsets */
1022 +};
1023 +
1024 +/**
1025 + * struct prev_cfa_coeffs - Structure for CFA coefficients
1026 + * @hthreshold: Horizontal threshold.
1027 + * @vthreshold: Vertical threshold.
1028 + * @coeffs: CFA coefficients
1029 + */
1030 +struct prev_cfa_coeffs {
1031 +       char hthreshold, vthreshold;
1032 +       int coeffs[CFA_COEFF_TABLE_SIZE];
1033 +};
1034 +
1035 +/**
1036 + * struct prev_gamma_coeffs - Structure for Gamma Coefficients
1037 + * @red: Table of gamma correction values for red color.
1038 + * @green: Table of gamma correction values for green color.
1039 + * @blue: Table of gamma correction values for blue color.
1040 + */
1041 +struct prev_gamma_coeffs {
1042 +       unsigned char red[GAMMA_TABLE_SIZE];
1043 +       unsigned char green[GAMMA_TABLE_SIZE];
1044 +       unsigned char blue[GAMMA_TABLE_SIZE];
1045 +};
1046 +
1047 +/**
1048 + * struct prev_noiseflt_coeffs - Structure for Noise Filter Coefficients.
1049 + * @noise: Noise filter table.
1050 + * @strength: Used to find out weighted average.
1051 + */
1052 +struct prev_noiseflt_coeffs {
1053 +       unsigned char noise[NOISE_FILTER_TABLE_SIZE];
1054 +       unsigned char strength;
1055 +};
1056 +
1057 +/**
1058 + * struct prev_chroma_spr - Structure for Chroma Suppression.
1059 + * @hpfy: High passed version of Y or normal Y.
1060 + * @threshold: Threshold for chroma suppress.
1061 + * @gain: Chroma suppression gain
1062 + */
1063 +struct prev_chroma_spr {
1064 +       unsigned char hpfy;
1065 +       char threshold;
1066 +       unsigned char gain;
1067 +};
1068 +
1069 +/**
1070 + * struct prev_status - Structure to know status of the hardware
1071 + * @hw_busy: Flag to indicate if Hardware is Busy.
1072 + */
1073 +struct prev_status {
1074 +       char hw_busy;
1075 +};
1076 +
1077 +/**
1078 + * struct prev_cropsize - Structure to know crop size.
1079 + * @hcrop: Horizontal size of crop window.
1080 + * @vcrop: Vertical size of crop window.
1081 + */
1082 +struct prev_cropsize {
1083 +       int hcrop;
1084 +       int vcrop;
1085 +};
1086 +
1087 +/**
1088 + * struct prev_device - Global device information structure.
1089 + * @params: Pointer to structure containing preview parameters.
1090 + * @opened: State of the device.
1091 + * @wfc: Wait for completion. Used for locking operations.
1092 + * @prevwrap_mutex: Mutex for preview wrapper use.
1093 + * @vbq_lock: Spinlock for videobuf queues.
1094 + * @vbq_ops: Videobuf queue operations
1095 + * @isp_addr_read: Input/Output address
1096 + */
1097 +struct prev_device {
1098 +       struct prev_params *params;
1099 +       unsigned char opened;
1100 +       struct completion wfc;
1101 +       struct mutex prevwrap_mutex; /* For generic internal use */
1102 +       spinlock_t vbq_lock;    /* For videobuffer queue handling */
1103 +       struct videobuf_queue_ops vbq_ops;
1104 +       dma_addr_t isp_addr_read;
1105 +};
1106 +
1107 +/**
1108 + * struct prev_fh - Per-filehandle data structure
1109 + * @type: Used buffer type.
1110 + * @vbq: Videobuffer queue.
1111 + * @device: Pointer to device information structure.
1112 + */
1113 +struct prev_fh {
1114 +       enum v4l2_buf_type type;
1115 +       struct videobuf_queue vbq;
1116 +       struct prev_device *device;
1117 +};
1118 +#endif
1119 diff --git a/drivers/media/video/isp/omap_resizer.c b/drivers/media/video/isp/omap_resizer.c
1120 new file mode 100644
1121 index 0000000..54bc425
1122 --- /dev/null
1123 +++ b/drivers/media/video/isp/omap_resizer.c
1124 @@ -0,0 +1,1634 @@
1125 +/*
1126 + * drivers/media/video/isp/omap_resizer.c
1127 + *
1128 + * Wrapper for Resizer module in TI's OMAP3430 ISP
1129 + *
1130 + * Copyright (C) 2008 Texas Instruments, Inc.
1131 + *
1132 + * Contributors:
1133 + *     Sergio Aguirre <saaguirre@ti.com>
1134 + *     Troy Laramy <t-laramy@ti.com>
1135 + *
1136 + * This package is free software; you can redistribute it and/or modify
1137 + * it under the terms of the GNU General Public License version 2 as
1138 + * published by the Free Software Foundation.
1139 + *
1140 + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
1141 + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
1142 + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
1143 + */
1144 +
1145 +#include <linux/mutex.h>
1146 +#include <linux/cdev.h>
1147 +#include <linux/delay.h>
1148 +#include <linux/device.h>
1149 +#include <linux/fs.h>
1150 +#include <linux/mm.h>
1151 +#include <linux/module.h>
1152 +#include <linux/platform_device.h>
1153 +#include <linux/io.h>
1154 +#include <linux/uaccess.h>
1155 +#include <media/v4l2-dev.h>
1156 +#include <asm/cacheflush.h>
1157 +
1158 +#include "isp.h"
1159 +#include "ispmmu.h"
1160 +#include "ispreg.h"
1161 +#include "ispresizer.h"
1162 +#include <linux/omap_resizer.h>
1163 +
1164 +#define OMAP_REZR_NAME         "omap-resizer"
1165 +
1166 +/* Defines and Constants*/
1167 +#define MAX_CHANNELS           16
1168 +#define MAX_IMAGE_WIDTH                2047
1169 +#define MAX_IMAGE_WIDTH_HIGH   2047
1170 +#define ALIGNMENT              16
1171 +#define CHANNEL_BUSY           1
1172 +#define CHANNEL_FREE           0
1173 +#define PIXEL_EVEN             2
1174 +#define RATIO_MULTIPLIER       256
1175 +/* Bit position Macro */
1176 +/* macro for bit set and clear */
1177 +#define BITSET(variable, bit)  ((variable) | (1 << bit))
1178 +#define BITRESET(variable, bit)        ((variable) & ~(0x00000001 << (bit)))
1179 +#define SET_BIT_INPUTRAM       28
1180 +#define SET_BIT_CBLIN          29
1181 +#define SET_BIT_INPTYP         27
1182 +#define SET_BIT_YCPOS          26
1183 +#define INPUT_RAM              1
1184 +#define UP_RSZ_RATIO           64
1185 +#define DOWN_RSZ_RATIO         512
1186 +#define UP_RSZ_RATIO1          513
1187 +#define DOWN_RSZ_RATIO1                1024
1188 +#define RSZ_IN_SIZE_VERT_SHIFT 16
1189 +#define MAX_HORZ_PIXEL_8BIT    31
1190 +#define MAX_HORZ_PIXEL_16BIT   15
1191 +#define NUM_PHASES             8
1192 +#define NUM_TAPS               4
1193 +#define NUM_D2PH               4       /* for downsampling * 2+x ~ 4x,
1194 +                                        * number of phases
1195 +                                        */
1196 +#define NUM_D2TAPS             7       /* for downsampling * 2+x ~ 4x,
1197 +                                        * number of taps
1198 +                                        */
1199 +#define ALIGN32                        32
1200 +#define MAX_COEF_COUNTER       16
1201 +#define COEFF_ADDRESS_OFFSET   0x04
1202 +
1203 +/* Global structure which contains information about number of channels
1204 +   and protection variables */
1205 +struct device_params {
1206 +
1207 +       unsigned char opened;                   /* state of the device */
1208 +       struct completion compl_isr;            /* Completion for interrupt */
1209 +       struct mutex reszwrap_mutex;            /* Semaphore for array */
1210 +
1211 +       struct videobuf_queue_ops vbq_ops;      /* videobuf queue operations */
1212 +};
1213 +
1214 +/* Register mapped structure which contains the every register
1215 +   information */
1216 +struct resizer_config {
1217 +       u32 rsz_pcr;                            /* pcr register mapping
1218 +                                                * variable.
1219 +                                                */
1220 +       u32 rsz_in_start;                       /* in_start register mapping
1221 +                                                * variable.
1222 +                                                */
1223 +       u32 rsz_in_size;                        /* in_size register mapping
1224 +                                                * variable.
1225 +                                                */
1226 +       u32 rsz_out_size;                       /* out_size register mapping
1227 +                                                * variable.
1228 +                                                */
1229 +       u32 rsz_cnt;                            /* rsz_cnt register mapping
1230 +                                                * variable.
1231 +                                                */
1232 +       u32 rsz_sdr_inadd;                      /* sdr_inadd register mapping
1233 +                                                * variable.
1234 +                                                */
1235 +       u32 rsz_sdr_inoff;                      /* sdr_inoff register mapping
1236 +                                                * variable.
1237 +                                                */
1238 +       u32 rsz_sdr_outadd;                     /* sdr_outadd register mapping
1239 +                                                * variable.
1240 +                                                */
1241 +       u32 rsz_sdr_outoff;                     /* sdr_outbuff register
1242 +                                                * mapping variable.
1243 +                                                */
1244 +       u32 rsz_coeff_horz[16];                 /* horizontal coefficients
1245 +                                                * mapping array.
1246 +                                                */
1247 +       u32 rsz_coeff_vert[16];                 /* vertical coefficients
1248 +                                                * mapping array.
1249 +                                                */
1250 +       u32 rsz_yehn;                           /* yehn(luma)register mapping
1251 +                                                * variable.
1252 +                                                */
1253 +};
1254 +
1255 +struct rsz_mult {
1256 +       int in_hsize;                           /* input frame horizontal
1257 +                                                * size.
1258 +                                                */
1259 +       int in_vsize;                           /* input frame vertical size.
1260 +                                                */
1261 +       int out_hsize;                          /* output frame horizontal
1262 +                                                * size.
1263 +                                                */
1264 +       int out_vsize;                          /* output frame vertical
1265 +                                                * size.
1266 +                                                */
1267 +       int in_pitch;                           /* offset between two rows of
1268 +                                                * input frame.
1269 +                                                */
1270 +       int out_pitch;                          /* offset between two rows of
1271 +                                                * output frame.
1272 +                                                */
1273 +       int end_hsize;
1274 +       int end_vsize;
1275 +       int num_htap;                           /* 0 = 7tap; 1 = 4tap */
1276 +       int num_vtap;                           /* 0 = 7tap; 1 = 4tap */
1277 +       int active;
1278 +       int inptyp;
1279 +       int vrsz;
1280 +       int hrsz;
1281 +       int hstph;                              /* for specifying horizontal
1282 +                                                * starting phase.
1283 +                                                */
1284 +       int vstph;
1285 +       int pix_fmt;                            /* # defined, UYVY or YUYV. */
1286 +       int cbilin;                             /* # defined, filter with luma
1287 +                                                * or bi-linear.
1288 +                                                */
1289 +       u16 tap4filt_coeffs[32];                /* horizontal filter
1290 +                                                * coefficients.
1291 +                                                */
1292 +       u16 tap7filt_coeffs[32];                /* vertical filter
1293 +                                                * coefficients.
1294 +                                                */
1295 +};
1296 +/* Channel specific structure contains information regarding
1297 +   the every channel */
1298 +struct channel_config {
1299 +       struct resizer_config register_config;  /* Instance of register set
1300 +                                                * mapping structure
1301 +                                                */
1302 +       int status;                             /* Specifies whether the
1303 +                                                * channel is busy or not
1304 +                                                */
1305 +       struct mutex chanprotection_mutex;
1306 +       enum config_done config_state;
1307 +       u8 input_buf_index;
1308 +       u8 output_buf_index;
1309 +
1310 +};
1311 +
1312 +/* per-filehandle data structure */
1313 +struct rsz_fh {
1314 +       struct rsz_params *params;
1315 +       struct channel_config *config;
1316 +       struct rsz_mult *multipass;             /* Multipass to support
1317 +                                                * resizing ration outside
1318 +                                                * of 0.25x to 4x
1319 +                                                */
1320 +       spinlock_t vbq_lock;                    /* spinlock for videobuf
1321 +                                                * queues.
1322 +                                                */
1323 +       enum v4l2_buf_type type;
1324 +       struct videobuf_queue vbq;
1325 +       struct device_params *device;
1326 +
1327 +       dma_addr_t isp_addr_read;               /* Input/Output address */
1328 +       dma_addr_t isp_addr_write;              /* Input/Output address */
1329 +       u32 rsz_bufsize;                        /* channel specific buffersize
1330 +                                                */
1331 +};
1332 +
1333 +static struct device_params *device_config;
1334 +static struct device *rsz_device;
1335 +static int rsz_major = -1;
1336 +/* functions declaration */
1337 +static void rsz_hardware_setup(struct channel_config *rsz_conf_chan);
1338 +static int rsz_set_params(struct rsz_mult *multipass, struct rsz_params *,
1339 +                                               struct channel_config *);
1340 +static int rsz_get_params(struct rsz_params *, struct channel_config *);
1341 +static void rsz_copy_data(struct rsz_mult *multipass,
1342 +                                               struct rsz_params *params);
1343 +static void rsz_isr(unsigned long status, isp_vbq_callback_ptr arg1,
1344 +                                               void *arg2);
1345 +static void rsz_calculate_crop(struct channel_config *rsz_conf_chan,
1346 +                                       struct rsz_cropsize *cropsize);
1347 +static int rsz_set_multipass(struct rsz_mult *multipass,
1348 +                                       struct channel_config *rsz_conf_chan);
1349 +static int rsz_set_ratio(struct rsz_mult *multipass,
1350 +                                       struct channel_config *rsz_conf_chan);
1351 +static void rsz_config_ratio(struct rsz_mult *multipass,
1352 +                                       struct channel_config *rsz_conf_chan);
1353 +
1354 +/**
1355 + * rsz_hardware_setup - Sets hardware configuration registers
1356 + * @rsz_conf_chan: Structure containing channel configuration
1357 + *
1358 + * Set hardware configuration registers
1359 + **/
1360 +static void rsz_hardware_setup(struct channel_config *rsz_conf_chan)
1361 +{
1362 +       int coeffcounter;
1363 +       int coeffoffset = 0;
1364 +
1365 +       omap_writel(rsz_conf_chan->register_config.rsz_cnt,
1366 +                                       OMAP3ISP_RESZ_REG(ISPRSZ_CNT));
1367 +
1368 +       omap_writel(rsz_conf_chan->register_config.rsz_in_start,
1369 +                                       OMAP3ISP_RESZ_REG(ISPRSZ_IN_START));
1370 +       omap_writel(rsz_conf_chan->register_config.rsz_in_size,
1371 +                                       OMAP3ISP_RESZ_REG(ISPRSZ_IN_SIZE));
1372 +
1373 +       omap_writel(rsz_conf_chan->register_config.rsz_out_size,
1374 +                                       OMAP3ISP_RESZ_REG(ISPRSZ_OUT_SIZE));
1375 +       omap_writel(rsz_conf_chan->register_config.rsz_sdr_inadd,
1376 +                                       OMAP3ISP_RESZ_REG(ISPRSZ_SDR_INADD));
1377 +       omap_writel(rsz_conf_chan->register_config.rsz_sdr_inoff,
1378 +                                       OMAP3ISP_RESZ_REG(ISPRSZ_SDR_INOFF));
1379 +       omap_writel(rsz_conf_chan->register_config.rsz_sdr_outadd,
1380 +                                       OMAP3ISP_RESZ_REG(ISPRSZ_SDR_OUTADD));
1381 +       omap_writel(rsz_conf_chan->register_config.rsz_sdr_outoff,
1382 +                                       OMAP3ISP_RESZ_REG(ISPRSZ_SDR_OUTOFF));
1383 +       omap_writel(rsz_conf_chan->register_config.rsz_yehn, OMAP3ISP_RESZ_REG(ISPRSZ_YENH));
1384 +
1385 +       for (coeffcounter = 0; coeffcounter < MAX_COEF_COUNTER;
1386 +                                                       coeffcounter++) {
1387 +               omap_writel(rsz_conf_chan->register_config.
1388 +                                       rsz_coeff_horz[coeffcounter],
1389 +                                       OMAP3ISP_RESZ_REG(ISPRSZ_HFILT10
1390 +                                               + coeffoffset));
1391 +
1392 +               omap_writel(rsz_conf_chan->register_config.
1393 +                                       rsz_coeff_vert[coeffcounter],
1394 +                                       OMAP3ISP_RESZ_REG(ISPRSZ_VFILT10
1395 +                                               + coeffoffset));
1396 +               coeffoffset = coeffoffset + COEFF_ADDRESS_OFFSET;
1397 +       }
1398 +}
1399 +
1400 +/**
1401 + * rsz_start - Enables Resizer Wrapper
1402 + * @arg: Currently not used.
1403 + * @device: Structure containing ISP resizer wrapper global information
1404 + *
1405 + * Submits a resizing task specified by the rsz_resize structure. The call can
1406 + * either be blocked until the task is completed or returned immediately based
1407 + * on the value of the blocking argument in the rsz_resize structure. If it is
1408 + * blocking, the status of the task can be checked by calling ioctl
1409 + * RSZ_G_STATUS. Only one task can be outstanding for each logical channel.
1410 + *
1411 + * Returns 0 if successful, or -EINVAL if could not set callback for RSZR IRQ
1412 + * event or the state of the channel is not configured.
1413 + **/
1414 +int rsz_start(int *arg, struct rsz_fh *fh)
1415 +{
1416 +       struct channel_config *rsz_conf_chan = fh->config;
1417 +       struct rsz_mult *multipass = fh->multipass;
1418 +       struct videobuf_queue *q = &fh->vbq;
1419 +       int ret;
1420 +
1421 +       if (rsz_conf_chan->config_state) {
1422 +               dev_err(rsz_device, "State not configured \n");
1423 +               goto err_einval;
1424 +       }
1425 +
1426 +       rsz_conf_chan->status = CHANNEL_BUSY;
1427 +
1428 +       rsz_hardware_setup(rsz_conf_chan);
1429 +
1430 +       if (isp_set_callback(CBK_RESZ_DONE, rsz_isr, (void *) NULL,
1431 +                                                       (void *)NULL)) {
1432 +               dev_err(rsz_device, "No callback for RSZR\n");
1433 +               goto err_einval;
1434 +       }
1435 +mult:
1436 +       device_config->compl_isr.done = 0;
1437 +
1438 +       ispresizer_enable(1);
1439 +
1440 +       ret = wait_for_completion_interruptible(&device_config->compl_isr);
1441 +       if (ret != 0) {
1442 +               dev_dbg(rsz_device, "Unexpected exit from "
1443 +                               "wait_for_completion_interruptible\n");
1444 +               wait_for_completion(&device_config->compl_isr);
1445 +       }
1446 +
1447 +       if (multipass->active) {
1448 +               rsz_set_multipass(multipass, rsz_conf_chan);
1449 +               goto mult;
1450 +       }
1451 +
1452 +       if (fh->isp_addr_read) {
1453 +               ispmmu_vunmap(fh->isp_addr_read);
1454 +               fh->isp_addr_read = 0;
1455 +       }
1456 +       if (fh->isp_addr_write) {
1457 +               ispmmu_vunmap(fh->isp_addr_write);
1458 +               fh->isp_addr_write = 0;
1459 +       }
1460 +
1461 +       rsz_conf_chan->status = CHANNEL_FREE;
1462 +       q->bufs[rsz_conf_chan->input_buf_index]->state = VIDEOBUF_NEEDS_INIT;
1463 +       q->bufs[rsz_conf_chan->output_buf_index]->state = VIDEOBUF_NEEDS_INIT;
1464 +       rsz_conf_chan->register_config.rsz_sdr_outadd = 0;
1465 +       rsz_conf_chan->register_config.rsz_sdr_inadd = 0;
1466 +
1467 +       /* Unmap and free the DMA memory allocated for buffers */
1468 +       videobuf_dma_unmap(q, videobuf_to_dma(
1469 +                               q->bufs[rsz_conf_chan->input_buf_index]));
1470 +       videobuf_dma_unmap(q, videobuf_to_dma(
1471 +                               q->bufs[rsz_conf_chan->output_buf_index]));
1472 +       videobuf_dma_free(videobuf_to_dma(
1473 +                               q->bufs[rsz_conf_chan->input_buf_index]));
1474 +       videobuf_dma_free(videobuf_to_dma(
1475 +                               q->bufs[rsz_conf_chan->output_buf_index]));
1476 +
1477 +       isp_unset_callback(CBK_RESZ_DONE);
1478 +
1479 +       return 0;
1480 +err_einval:
1481 +       return -EINVAL;
1482 +}
1483 +
1484 +/**
1485 + * rsz_set_multipass - Set resizer multipass
1486 + * @rsz_conf_chan: Structure containing channel configuration
1487 + *
1488 + * Returns always 0
1489 + **/
1490 +static int rsz_set_multipass(struct rsz_mult *multipass,
1491 +                       struct channel_config *rsz_conf_chan)
1492 +{
1493 +       multipass->in_hsize = multipass->out_hsize;
1494 +       multipass->in_vsize = multipass->out_vsize;
1495 +       multipass->out_hsize = multipass->end_hsize;
1496 +       multipass->out_vsize = multipass->end_vsize;
1497 +
1498 +       multipass->out_pitch = (multipass->inptyp ? multipass->out_hsize
1499 +                                               : (multipass->out_hsize * 2));
1500 +       multipass->in_pitch = (multipass->inptyp ? multipass->in_hsize
1501 +                                               : (multipass->in_hsize * 2));
1502 +
1503 +       rsz_set_ratio(multipass, rsz_conf_chan);
1504 +       rsz_config_ratio(multipass, rsz_conf_chan);
1505 +       rsz_hardware_setup(rsz_conf_chan);
1506 +       return 0;
1507 +}
1508 +
1509 +/**
1510 + * rsz_copy_data - Copy data
1511 + * @params: Structure containing the Resizer Wrapper parameters
1512 + *
1513 + * Copy data
1514 + **/
1515 +static void rsz_copy_data(struct rsz_mult *multipass, struct rsz_params *params)
1516 +{
1517 +       int i;
1518 +       multipass->in_hsize = params->in_hsize;
1519 +       multipass->in_vsize = params->in_vsize;
1520 +       multipass->out_hsize = params->out_hsize;
1521 +       multipass->out_vsize = params->out_vsize;
1522 +       multipass->end_hsize = params->out_hsize;
1523 +       multipass->end_vsize = params->out_vsize;
1524 +       multipass->in_pitch = params->in_pitch;
1525 +       multipass->out_pitch = params->out_pitch;
1526 +       multipass->hstph = params->hstph;
1527 +       multipass->vstph = params->vstph;
1528 +       multipass->inptyp = params->inptyp;
1529 +       multipass->pix_fmt = params->pix_fmt;
1530 +       multipass->cbilin = params->cbilin;
1531 +
1532 +       for (i = 0; i < 32; i++) {
1533 +               multipass->tap4filt_coeffs[i] = params->tap4filt_coeffs[i];
1534 +               multipass->tap7filt_coeffs[i] = params->tap7filt_coeffs[i];
1535 +       }
1536 +}
1537 +
1538 +/**
1539 + * rsz_set_params - Set parameters for resizer wrapper
1540 + * @params: Structure containing the Resizer Wrapper parameters
1541 + * @rsz_conf_chan: Structure containing channel configuration
1542 + *
1543 + * Used to set the parameters of the Resizer hardware, including input and
1544 + * output image size, horizontal and vertical poly-phase filter coefficients,
1545 + * luma enchancement filter coefficients, etc.
1546 + **/
1547 +static int rsz_set_params(struct rsz_mult *multipass, struct rsz_params *params,
1548 +                                       struct channel_config *rsz_conf_chan)
1549 +{
1550 +       int mul = 1;
1551 +       if ((params->yenh_params.type < 0) || (params->yenh_params.type > 2)) {
1552 +               dev_err(rsz_device, "rsz_set_params: Wrong yenh type\n");
1553 +               return -EINVAL;
1554 +       }
1555 +       if ((params->in_vsize <= 0) || (params->in_hsize <= 0) ||
1556 +                       (params->out_vsize <= 0) || (params->out_hsize <= 0) ||
1557 +                       (params->in_pitch <= 0) || (params->out_pitch <= 0)) {
1558 +               dev_err(rsz_device, "rsz_set_params: Invalid size params\n");
1559 +               return -EINVAL;
1560 +       }
1561 +       if ((params->inptyp != RSZ_INTYPE_YCBCR422_16BIT) &&
1562 +                       (params->inptyp != RSZ_INTYPE_PLANAR_8BIT)) {
1563 +               dev_err(rsz_device, "rsz_set_params: Invalid input type\n");
1564 +               return -EINVAL;
1565 +       }
1566 +       if ((params->pix_fmt != RSZ_PIX_FMT_UYVY) &&
1567 +                       (params->pix_fmt != RSZ_PIX_FMT_YUYV)) {
1568 +               dev_err(rsz_device, "rsz_set_params: Invalid pixel format\n");
1569 +               return -EINVAL;
1570 +       }
1571 +       if (params->inptyp == RSZ_INTYPE_YCBCR422_16BIT)
1572 +               mul = 2;
1573 +       else
1574 +               mul = 1;
1575 +       if (params->in_pitch < (params->in_hsize * mul)) {
1576 +               dev_err(rsz_device, "rsz_set_params: Pitch is incorrect\n");
1577 +               return -EINVAL;
1578 +       }
1579 +       if (params->out_pitch < (params->out_hsize * mul)) {
1580 +               dev_err(rsz_device, "rsz_set_params: Out pitch cannot be less"
1581 +                                       " than out hsize\n");
1582 +               return -EINVAL;
1583 +       }
1584 +       /* Output H size should be even */
1585 +       if ((params->out_hsize % PIXEL_EVEN) != 0) {
1586 +               dev_err(rsz_device, "rsz_set_params: Output H size should"
1587 +                                       " be even\n");
1588 +               return -EINVAL;
1589 +       }
1590 +       if (params->horz_starting_pixel < 0) {
1591 +               dev_err(rsz_device, "rsz_set_params: Horz start pixel cannot"
1592 +                                       " be less than zero\n");
1593 +               return -EINVAL;
1594 +       }
1595 +
1596 +       rsz_copy_data(multipass, params);
1597 +       if (0 != rsz_set_ratio(multipass, rsz_conf_chan))
1598 +               goto err_einval;
1599 +
1600 +       if (params->yenh_params.type) {
1601 +               if ((multipass->num_htap && multipass->out_hsize >
1602 +                               1280) ||
1603 +                               (!multipass->num_htap && multipass->out_hsize >
1604 +                               640))
1605 +                       goto err_einval;
1606 +       }
1607 +
1608 +       if (INPUT_RAM)
1609 +               params->vert_starting_pixel = 0;
1610 +
1611 +       rsz_conf_chan->register_config.rsz_in_start =
1612 +                                               (params->vert_starting_pixel
1613 +                                               << ISPRSZ_IN_SIZE_VERT_SHIFT)
1614 +                                               & ISPRSZ_IN_SIZE_VERT_MASK;
1615 +
1616 +       if (params->inptyp == RSZ_INTYPE_PLANAR_8BIT) {
1617 +               if (params->horz_starting_pixel > MAX_HORZ_PIXEL_8BIT)
1618 +                       goto err_einval;
1619 +       }
1620 +       if (params->inptyp == RSZ_INTYPE_YCBCR422_16BIT) {
1621 +               if (params->horz_starting_pixel > MAX_HORZ_PIXEL_16BIT)
1622 +                       goto err_einval;
1623 +       }
1624 +
1625 +       rsz_conf_chan->register_config.rsz_in_start |=
1626 +                                               params->horz_starting_pixel
1627 +                                               & ISPRSZ_IN_START_HORZ_ST_MASK;
1628 +
1629 +       rsz_conf_chan->register_config.rsz_yehn =
1630 +                                               (params->yenh_params.type
1631 +                                               << ISPRSZ_YENH_ALGO_SHIFT)
1632 +                                               & ISPRSZ_YENH_ALGO_MASK;
1633 +
1634 +       if (params->yenh_params.type) {
1635 +               rsz_conf_chan->register_config.rsz_yehn |=
1636 +                                               params->yenh_params.core
1637 +                                               & ISPRSZ_YENH_CORE_MASK;
1638 +
1639 +               rsz_conf_chan->register_config.rsz_yehn |=
1640 +                                               (params->yenh_params.gain
1641 +                                               << ISPRSZ_YENH_GAIN_SHIFT)
1642 +                                               & ISPRSZ_YENH_GAIN_MASK;
1643 +
1644 +               rsz_conf_chan->register_config.rsz_yehn |=
1645 +                                               (params->yenh_params.slop
1646 +                                               << ISPRSZ_YENH_SLOP_SHIFT)
1647 +                                               & ISPRSZ_YENH_SLOP_MASK;
1648 +       }
1649 +
1650 +       rsz_config_ratio(multipass, rsz_conf_chan);
1651 +
1652 +       rsz_conf_chan->config_state = STATE_CONFIGURED;
1653 +
1654 +       return 0;
1655 +err_einval:
1656 +       return -EINVAL;
1657 +}
1658 +
1659 +/**
1660 + * rsz_set_ratio - Set ratio
1661 + * @rsz_conf_chan: Structure containing channel configuration
1662 + *
1663 + * Returns 0 if successful, -EINVAL if invalid output size, upscaling ratio is
1664 + * being requested, or other ratio configuration value is out of bounds
1665 + **/
1666 +static int rsz_set_ratio(struct rsz_mult *multipass,
1667 +                               struct channel_config *rsz_conf_chan)
1668 +{
1669 +       int alignment = 0;
1670 +
1671 +       rsz_conf_chan->register_config.rsz_cnt = 0;
1672 +
1673 +       if ((multipass->out_hsize > MAX_IMAGE_WIDTH) ||
1674 +                       (multipass->out_vsize > MAX_IMAGE_WIDTH)) {
1675 +               dev_err(rsz_device, "Invalid output size!");
1676 +               goto err_einval;
1677 +       }
1678 +       if (multipass->cbilin) {
1679 +               rsz_conf_chan->register_config.rsz_cnt =
1680 +                               BITSET(rsz_conf_chan->register_config.rsz_cnt,
1681 +                               SET_BIT_CBLIN);
1682 +       }
1683 +       if (INPUT_RAM) {
1684 +               rsz_conf_chan->register_config.rsz_cnt =
1685 +                               BITSET(rsz_conf_chan->register_config.rsz_cnt,
1686 +                               SET_BIT_INPUTRAM);
1687 +       }
1688 +       if (multipass->inptyp == RSZ_INTYPE_PLANAR_8BIT) {
1689 +               rsz_conf_chan->register_config.rsz_cnt =
1690 +                               BITSET(rsz_conf_chan->register_config.rsz_cnt,
1691 +                               SET_BIT_INPTYP);
1692 +       } else {
1693 +               rsz_conf_chan->register_config.rsz_cnt =
1694 +                               BITRESET(rsz_conf_chan->register_config.
1695 +                               rsz_cnt, SET_BIT_INPTYP);
1696 +
1697 +               if (multipass->pix_fmt == RSZ_PIX_FMT_UYVY) {
1698 +                       rsz_conf_chan->register_config.rsz_cnt =
1699 +                               BITRESET(rsz_conf_chan->register_config.
1700 +                               rsz_cnt, SET_BIT_YCPOS);
1701 +               } else if (multipass->pix_fmt == RSZ_PIX_FMT_YUYV) {
1702 +                       rsz_conf_chan->register_config.rsz_cnt =
1703 +                                       BITSET(rsz_conf_chan->register_config.
1704 +                                       rsz_cnt, SET_BIT_YCPOS);
1705 +               }
1706 +
1707 +       }
1708 +       multipass->vrsz =
1709 +               (multipass->in_vsize * RATIO_MULTIPLIER) / multipass->out_vsize;
1710 +       multipass->hrsz =
1711 +               (multipass->in_hsize * RATIO_MULTIPLIER) / multipass->out_hsize;
1712 +       if (UP_RSZ_RATIO > multipass->vrsz || UP_RSZ_RATIO > multipass->hrsz) {
1713 +               dev_err(rsz_device, "Upscaling ratio not supported!");
1714 +               goto err_einval;
1715 +       }
1716 +       multipass->vrsz = (multipass->in_vsize - NUM_D2TAPS) * RATIO_MULTIPLIER
1717 +                                               / (multipass->out_vsize - 1);
1718 +       multipass->hrsz = ((multipass->in_hsize - NUM_D2TAPS)
1719 +                                               * RATIO_MULTIPLIER) /
1720 +                                               (multipass->out_hsize - 1);
1721 +
1722 +       if (multipass->hrsz <= 512) {
1723 +               multipass->hrsz = (multipass->in_hsize - NUM_TAPS)
1724 +                                               * RATIO_MULTIPLIER
1725 +                                               / (multipass->out_hsize - 1);
1726 +               if (multipass->hrsz < 64)
1727 +                       multipass->hrsz = 64;
1728 +               if (multipass->hrsz > 512)
1729 +                       multipass->hrsz = 512;
1730 +               if (multipass->hstph > NUM_PHASES)
1731 +                       goto err_einval;
1732 +               multipass->num_htap = 1;
1733 +       } else if (multipass->hrsz >= 513 && multipass->hrsz <= 1024) {
1734 +               if (multipass->hstph > NUM_D2PH)
1735 +                       goto err_einval;
1736 +               multipass->num_htap = 0;
1737 +       }
1738 +
1739 +       if (multipass->vrsz <= 512) {
1740 +               multipass->vrsz = (multipass->in_vsize - NUM_TAPS)
1741 +                                               * RATIO_MULTIPLIER
1742 +                                               / (multipass->out_vsize - 1);
1743 +               if (multipass->vrsz < 64)
1744 +                       multipass->vrsz = 64;
1745 +               if (multipass->vrsz > 512)
1746 +                       multipass->vrsz = 512;
1747 +               if (multipass->vstph > NUM_PHASES)
1748 +                       goto err_einval;
1749 +               multipass->num_vtap = 1;
1750 +       } else if (multipass->vrsz >= 513 && multipass->vrsz <= 1024) {
1751 +               if (multipass->vstph > NUM_D2PH)
1752 +                       goto err_einval;
1753 +               multipass->num_vtap = 0;
1754 +       }
1755 +
1756 +       if ((multipass->in_pitch) % ALIGN32) {
1757 +               dev_err(rsz_device, "Invalid input pitch: %d \n",
1758 +                                                       multipass->in_pitch);
1759 +               goto err_einval;
1760 +       }
1761 +       if ((multipass->out_pitch) % ALIGN32) {
1762 +               dev_err(rsz_device, "Invalid output pitch %d \n",
1763 +                                                       multipass->out_pitch);
1764 +               goto err_einval;
1765 +       }
1766 +
1767 +       if (multipass->vrsz < 256 &&
1768 +                       (multipass->in_vsize < multipass->out_vsize)) {
1769 +               if (multipass->inptyp == RSZ_INTYPE_PLANAR_8BIT)
1770 +                       alignment = ALIGNMENT;
1771 +               else if (multipass->inptyp == RSZ_INTYPE_YCBCR422_16BIT)
1772 +                       alignment = (ALIGNMENT / 2);
1773 +               else
1774 +                       dev_err(rsz_device, "Invalid input type\n");
1775 +
1776 +               if (!(((multipass->out_hsize % PIXEL_EVEN) == 0)
1777 +                               && (multipass->out_hsize % alignment) == 0)) {
1778 +                       dev_err(rsz_device, "wrong hsize\n");
1779 +                       goto err_einval;
1780 +               }
1781 +       }
1782 +       if (multipass->hrsz >= 64 && multipass->hrsz <= 1024) {
1783 +               if (multipass->out_hsize > MAX_IMAGE_WIDTH) {
1784 +                       dev_err(rsz_device, "wrong width\n");
1785 +                       goto err_einval;
1786 +               }
1787 +               multipass->active = 0;
1788 +
1789 +       } else if (multipass->hrsz > 1024) {
1790 +               if (multipass->out_hsize > MAX_IMAGE_WIDTH) {
1791 +                       dev_err(rsz_device, "wrong width\n");
1792 +                       goto err_einval;
1793 +               }
1794 +               if (multipass->hstph > NUM_D2PH)
1795 +                       goto err_einval;
1796 +               multipass->num_htap = 0;
1797 +               multipass->out_hsize = multipass->in_hsize * 256 / 1024;
1798 +               if (multipass->out_hsize % ALIGN32) {
1799 +                       multipass->out_hsize +=
1800 +                               abs((multipass->out_hsize % ALIGN32) - ALIGN32);
1801 +               }
1802 +               multipass->out_pitch = ((multipass->inptyp) ?
1803 +                                               multipass->out_hsize :
1804 +                                               (multipass->out_hsize * 2));
1805 +               multipass->hrsz = ((multipass->in_hsize - NUM_D2TAPS)
1806 +                                               * RATIO_MULTIPLIER)
1807 +                                               / (multipass->out_hsize - 1);
1808 +               multipass->active = 1;
1809 +
1810 +       }
1811 +
1812 +       if (multipass->vrsz > 1024) {
1813 +               if (multipass->out_vsize > MAX_IMAGE_WIDTH_HIGH) {
1814 +                       dev_err(rsz_device, "wrong width\n");
1815 +                       goto err_einval;
1816 +               }
1817 +
1818 +               multipass->out_vsize = multipass->in_vsize * 256 / 1024;
1819 +               multipass->vrsz = ((multipass->in_vsize - NUM_D2TAPS)
1820 +                                               * RATIO_MULTIPLIER)
1821 +                                               / (multipass->out_vsize - 1);
1822 +               multipass->active = 1;
1823 +               multipass->num_vtap = 0;
1824 +
1825 +       }
1826 +       rsz_conf_chan->register_config.rsz_out_size =
1827 +                                               multipass->out_hsize
1828 +                                               & ISPRSZ_OUT_SIZE_HORZ_MASK;
1829 +
1830 +       rsz_conf_chan->register_config.rsz_out_size |=
1831 +                                               (multipass->out_vsize
1832 +                                               << ISPRSZ_OUT_SIZE_VERT_SHIFT)
1833 +                                               & ISPRSZ_OUT_SIZE_VERT_MASK;
1834 +
1835 +       rsz_conf_chan->register_config.rsz_sdr_inoff =
1836 +                                               multipass->in_pitch
1837 +                                               & ISPRSZ_SDR_INOFF_OFFSET_MASK;
1838 +
1839 +       rsz_conf_chan->register_config.rsz_sdr_outoff =
1840 +                                       multipass->out_pitch
1841 +                                       & ISPRSZ_SDR_OUTOFF_OFFSET_MASK;
1842 +
1843 +       if (multipass->hrsz >= 64 && multipass->hrsz <= 512) {
1844 +               if (multipass->hstph > NUM_PHASES)
1845 +                       goto err_einval;
1846 +       } else if (multipass->hrsz >= 64 && multipass->hrsz <= 512) {
1847 +               if (multipass->hstph > NUM_D2PH)
1848 +                       goto err_einval;
1849 +       }
1850 +
1851 +       rsz_conf_chan->register_config.rsz_cnt |=
1852 +                                               (multipass->hstph
1853 +                                               << ISPRSZ_CNT_HSTPH_SHIFT)
1854 +                                               & ISPRSZ_CNT_HSTPH_MASK;
1855 +
1856 +       if (multipass->vrsz >= 64 && multipass->hrsz <= 512) {
1857 +               if (multipass->vstph > NUM_PHASES)
1858 +                       goto err_einval;
1859 +       } else if (multipass->vrsz >= 64 && multipass->vrsz <= 512) {
1860 +               if (multipass->vstph > NUM_D2PH)
1861 +                       goto err_einval;
1862 +       }
1863 +
1864 +       rsz_conf_chan->register_config.rsz_cnt |=
1865 +                                               (multipass->vstph
1866 +                                               << ISPRSZ_CNT_VSTPH_SHIFT)
1867 +                                               & ISPRSZ_CNT_VSTPH_MASK;
1868 +
1869 +       rsz_conf_chan->register_config.rsz_cnt |=
1870 +                                               (multipass->hrsz - 1)
1871 +                                               & ISPRSZ_CNT_HRSZ_MASK;
1872 +
1873 +       rsz_conf_chan->register_config.rsz_cnt |=
1874 +                                               ((multipass->vrsz - 1)
1875 +                                               << ISPRSZ_CNT_VRSZ_SHIFT)
1876 +                                               & ISPRSZ_CNT_VRSZ_MASK;
1877 +
1878 +       return 0;
1879 +err_einval:
1880 +       return -EINVAL;
1881 +}
1882 +
1883 +/**
1884 + * rsz_config_ratio - Configure ratio
1885 + * @rsz_conf_chan: Structure containing channel configuration
1886 + *
1887 + * Configure ratio
1888 + **/
1889 +static void rsz_config_ratio(struct rsz_mult *multipass,
1890 +                               struct channel_config *rsz_conf_chan)
1891 +{
1892 +       int hsize;
1893 +       int vsize;
1894 +       int coeffcounter;
1895 +
1896 +       if (multipass->hrsz <= 512) {
1897 +               hsize = ((32 * multipass->hstph + (multipass->out_hsize - 1)
1898 +                                       * multipass->hrsz + 16) >> 8) + 7;
1899 +       } else {
1900 +               hsize = ((64 * multipass->hstph + (multipass->out_hsize - 1)
1901 +                                       * multipass->hrsz + 32) >> 8) + 7;
1902 +       }
1903 +       if (multipass->vrsz <= 512) {
1904 +               vsize = ((32 * multipass->vstph + (multipass->out_vsize - 1)
1905 +                                       * multipass->vrsz + 16) >> 8) + 4;
1906 +       } else {
1907 +               vsize = ((64 * multipass->vstph + (multipass->out_vsize - 1)
1908 +                                       * multipass->vrsz + 32) >> 8) + 7;
1909 +       }
1910 +       rsz_conf_chan->register_config.rsz_in_size = hsize;
1911 +
1912 +       rsz_conf_chan->register_config.rsz_in_size |=
1913 +                                       ((vsize << ISPRSZ_IN_SIZE_VERT_SHIFT)
1914 +                                       & ISPRSZ_IN_SIZE_VERT_MASK);
1915 +
1916 +       for (coeffcounter = 0; coeffcounter < MAX_COEF_COUNTER;
1917 +                                                       coeffcounter++) {
1918 +               if (multipass->num_htap) {
1919 +                       rsz_conf_chan->register_config.
1920 +                                       rsz_coeff_horz[coeffcounter] =
1921 +                                       (multipass->tap4filt_coeffs[2
1922 +                                       * coeffcounter]
1923 +                                       & ISPRSZ_HFILT10_COEF0_MASK);
1924 +                       rsz_conf_chan->register_config.
1925 +                                       rsz_coeff_horz[coeffcounter] |=
1926 +                                       ((multipass->tap4filt_coeffs[2
1927 +                                       * coeffcounter + 1]
1928 +                                       << ISPRSZ_HFILT10_COEF1_SHIFT)
1929 +                                       & ISPRSZ_HFILT10_COEF1_MASK);
1930 +               } else {
1931 +                       rsz_conf_chan->register_config.
1932 +                                       rsz_coeff_horz[coeffcounter] =
1933 +                                       (multipass->tap7filt_coeffs[2
1934 +                                       * coeffcounter]
1935 +                                       & ISPRSZ_HFILT10_COEF0_MASK);
1936 +
1937 +                       rsz_conf_chan->register_config.
1938 +                                       rsz_coeff_horz[coeffcounter] |=
1939 +                                       ((multipass->tap7filt_coeffs[2
1940 +                                       * coeffcounter + 1]
1941 +                                       << ISPRSZ_HFILT10_COEF1_SHIFT)
1942 +                                       & ISPRSZ_HFILT10_COEF1_MASK);
1943 +               }
1944 +
1945 +               if (multipass->num_vtap) {
1946 +                       rsz_conf_chan->register_config.
1947 +                                       rsz_coeff_vert[coeffcounter] =
1948 +                                       (multipass->tap4filt_coeffs[2
1949 +                                       * coeffcounter]
1950 +                                       & ISPRSZ_VFILT10_COEF0_MASK);
1951 +
1952 +                       rsz_conf_chan->register_config.
1953 +                                       rsz_coeff_vert[coeffcounter] |=
1954 +                                       ((multipass->tap4filt_coeffs[2
1955 +                                       * coeffcounter + 1]
1956 +                                       << ISPRSZ_VFILT10_COEF1_SHIFT) &
1957 +                                       ISPRSZ_VFILT10_COEF1_MASK);
1958 +               } else {
1959 +                       rsz_conf_chan->register_config.
1960 +                                       rsz_coeff_vert[coeffcounter] =
1961 +                                       (multipass->tap7filt_coeffs[2
1962 +                                       * coeffcounter]
1963 +                                       & ISPRSZ_VFILT10_COEF0_MASK);
1964 +                       rsz_conf_chan->register_config.
1965 +                                       rsz_coeff_vert[coeffcounter] |=
1966 +                                       ((multipass->tap7filt_coeffs[2
1967 +                                       * coeffcounter + 1]
1968 +                                       << ISPRSZ_VFILT10_COEF1_SHIFT)
1969 +                                       & ISPRSZ_VFILT10_COEF1_MASK);
1970 +               }
1971 +       }
1972 +}
1973 +
1974 +/**
1975 + * rsz_get_params - Gets the parameter values
1976 + * @params: Structure containing the Resizer Wrapper parameters
1977 + * @rsz_conf_chan: Structure containing channel configuration
1978 + *
1979 + * Used to get the Resizer hardware settings associated with the
1980 + * current logical channel represented by fd.
1981 + **/
1982 +static int rsz_get_params(struct rsz_params *params,
1983 +                                       struct channel_config *rsz_conf_chan)
1984 +{
1985 +       int coeffcounter;
1986 +
1987 +       if (rsz_conf_chan->config_state) {
1988 +               dev_err(rsz_device, "state not configured\n");
1989 +               return -EINVAL;
1990 +       }
1991 +
1992 +       params->in_hsize = rsz_conf_chan->register_config.rsz_in_size
1993 +                                       & ISPRSZ_IN_SIZE_HORZ_MASK;
1994 +       params->in_vsize = (rsz_conf_chan->register_config.rsz_in_size
1995 +                                       & ISPRSZ_IN_SIZE_VERT_MASK)
1996 +                                       >> ISPRSZ_IN_SIZE_VERT_SHIFT;
1997 +
1998 +       params->in_pitch = rsz_conf_chan->register_config.rsz_sdr_inoff
1999 +                                       & ISPRSZ_SDR_INOFF_OFFSET_MASK;
2000 +
2001 +       params->out_hsize = rsz_conf_chan->register_config.rsz_out_size
2002 +                                       & ISPRSZ_OUT_SIZE_HORZ_MASK;
2003 +
2004 +       params->out_vsize = (rsz_conf_chan->register_config.rsz_out_size
2005 +                                       & ISPRSZ_OUT_SIZE_VERT_MASK)
2006 +                                       >> ISPRSZ_OUT_SIZE_VERT_SHIFT;
2007 +
2008 +       params->out_pitch = rsz_conf_chan->register_config.rsz_sdr_outoff
2009 +                                       & ISPRSZ_SDR_OUTOFF_OFFSET_MASK;
2010 +
2011 +       params->cbilin = (rsz_conf_chan->register_config.rsz_cnt
2012 +                                       & SET_BIT_CBLIN) >> SET_BIT_CBLIN;
2013 +
2014 +       params->inptyp = (rsz_conf_chan->register_config.rsz_cnt
2015 +                                       & ISPRSZ_CNT_INPTYP_MASK)
2016 +                                       >> SET_BIT_INPTYP;
2017 +       params->horz_starting_pixel = ((rsz_conf_chan->register_config.
2018 +                                       rsz_in_start
2019 +                                       & ISPRSZ_IN_START_HORZ_ST_MASK));
2020 +       params->vert_starting_pixel = ((rsz_conf_chan->register_config.
2021 +                                       rsz_in_start
2022 +                                       & ISPRSZ_IN_START_VERT_ST_MASK)
2023 +                                       >> ISPRSZ_IN_START_VERT_ST_SHIFT);
2024 +
2025 +       params->hstph = ((rsz_conf_chan->register_config.rsz_cnt
2026 +                                       & ISPRSZ_CNT_HSTPH_MASK
2027 +                                       >> ISPRSZ_CNT_HSTPH_SHIFT));
2028 +       params->vstph = ((rsz_conf_chan->register_config.rsz_cnt
2029 +                                       & ISPRSZ_CNT_VSTPH_MASK
2030 +                                       >> ISPRSZ_CNT_VSTPH_SHIFT));
2031 +
2032 +       for (coeffcounter = 0; coeffcounter < MAX_COEF_COUNTER;
2033 +                                                       coeffcounter++) {
2034 +               params->tap4filt_coeffs[2 * coeffcounter] =
2035 +                                       rsz_conf_chan->register_config.
2036 +                                       rsz_coeff_horz[coeffcounter]
2037 +                                       & ISPRSZ_HFILT10_COEF0_MASK;
2038 +
2039 +               params->tap4filt_coeffs[2 * coeffcounter + 1] =
2040 +                                       (rsz_conf_chan->register_config.
2041 +                                       rsz_coeff_horz[coeffcounter]
2042 +                                       & ISPRSZ_HFILT10_COEF1_MASK)
2043 +                                       >> ISPRSZ_HFILT10_COEF1_SHIFT;
2044 +
2045 +               params->tap7filt_coeffs[2 * coeffcounter] =
2046 +                                       rsz_conf_chan->register_config.
2047 +                                       rsz_coeff_vert[coeffcounter]
2048 +                                       & ISPRSZ_VFILT10_COEF0_MASK;
2049 +
2050 +               params->tap7filt_coeffs[2 * coeffcounter + 1] =
2051 +                                       (rsz_conf_chan->register_config.
2052 +                                       rsz_coeff_vert[coeffcounter]
2053 +                                       & ISPRSZ_VFILT10_COEF1_MASK)
2054 +                                       >> ISPRSZ_VFILT10_COEF1_SHIFT;
2055 +
2056 +       }
2057 +
2058 +       params->yenh_params.type = (rsz_conf_chan->register_config.rsz_yehn
2059 +                                       & ISPRSZ_YENH_ALGO_MASK)
2060 +                                       >> ISPRSZ_YENH_ALGO_SHIFT;
2061 +
2062 +       params->yenh_params.core = rsz_conf_chan->register_config.rsz_yehn
2063 +                                       & ISPRSZ_YENH_CORE_MASK;
2064 +
2065 +       params->yenh_params.gain = (rsz_conf_chan->register_config.rsz_yehn
2066 +                                       & ISPRSZ_YENH_GAIN_MASK)
2067 +                                       >> ISPRSZ_YENH_GAIN_SHIFT;
2068 +
2069 +       params->yenh_params.slop = (rsz_conf_chan->register_config.rsz_yehn
2070 +                                       & ISPRSZ_YENH_SLOP_MASK)
2071 +                                       >> ISPRSZ_YENH_SLOP_SHIFT;
2072 +
2073 +       params->pix_fmt = ((rsz_conf_chan->register_config.rsz_cnt
2074 +                                       & ISPRSZ_CNT_PIXFMT_MASK)
2075 +                                       >> SET_BIT_YCPOS);
2076 +
2077 +       if (params->pix_fmt)
2078 +               params->pix_fmt = RSZ_PIX_FMT_UYVY;
2079 +       else
2080 +               params->pix_fmt = RSZ_PIX_FMT_YUYV;
2081 +
2082 +       return 0;
2083 +}
2084 +
2085 +/**
2086 + * rsz_calculate_crop - Calculate Crop values
2087 + * @rsz_conf_chan: Structure containing channel configuration
2088 + * @cropsize: Structure containing crop parameters
2089 + *
2090 + * Calculate Crop values
2091 + **/
2092 +static void rsz_calculate_crop(struct channel_config *rsz_conf_chan,
2093 +                                               struct rsz_cropsize *cropsize)
2094 +{
2095 +       int luma_enable;
2096 +
2097 +       cropsize->hcrop = 0;
2098 +       cropsize->vcrop = 0;
2099 +
2100 +       luma_enable = (rsz_conf_chan->register_config.rsz_yehn
2101 +                                               & ISPRSZ_YENH_ALGO_MASK)
2102 +                                               >> ISPRSZ_YENH_ALGO_SHIFT;
2103 +
2104 +       if (luma_enable)
2105 +               cropsize->hcrop += 2;
2106 +}
2107 +
2108 +/**
2109 + * rsz_vbq_release - Videobuffer queue release
2110 + * @q: Structure containing the videobuffer queue file handle, and device
2111 + *     structure which contains the actual configuration.
2112 + * @vb: Structure containing the videobuffer used for resizer processing.
2113 + **/
2114 +static void rsz_vbq_release(struct videobuf_queue *q,
2115 +                                               struct videobuf_buffer *vb)
2116 +{
2117 +       int i;
2118 +       struct rsz_fh *fh = q->priv_data;
2119 +
2120 +       for (i = 0; i < VIDEO_MAX_FRAME; i++) {
2121 +               struct videobuf_dmabuf *dma = NULL;
2122 +               if (!q->bufs[i])
2123 +                       continue;
2124 +               if (q->bufs[i]->memory != V4L2_MEMORY_MMAP)
2125 +                       continue;
2126 +               dma = videobuf_to_dma(q->bufs[i]);
2127 +               videobuf_dma_unmap(q, dma);
2128 +               videobuf_dma_free(dma);
2129 +       }
2130 +
2131 +       ispmmu_vunmap(fh->isp_addr_read);
2132 +       ispmmu_vunmap(fh->isp_addr_write);
2133 +       fh->isp_addr_read = 0;
2134 +       fh->isp_addr_write = 0;
2135 +       spin_lock(&fh->vbq_lock);
2136 +       vb->state = VIDEOBUF_NEEDS_INIT;
2137 +       spin_unlock(&fh->vbq_lock);
2138 +
2139 +}
2140 +
2141 +/**
2142 + * rsz_vbq_setup - Sets up the videobuffer size and validates count.
2143 + * @q: Structure containing the videobuffer queue file handle, and device
2144 + *     structure which contains the actual configuration.
2145 + * @cnt: Number of buffers requested
2146 + * @size: Size in bytes of the buffer used for previewing
2147 + *
2148 + * Always returns 0.
2149 + **/
2150 +static int rsz_vbq_setup(struct videobuf_queue *q, unsigned int *cnt,
2151 +                                                       unsigned int *size)
2152 +{
2153 +       struct rsz_fh *fh = q->priv_data;
2154 +       struct rsz_mult *multipass = fh->multipass;
2155 +       u32 insize, outsize;
2156 +
2157 +       spin_lock(&fh->vbq_lock);
2158 +       if (*cnt <= 0)
2159 +               *cnt = VIDEO_MAX_FRAME;
2160 +
2161 +       if (*cnt > VIDEO_MAX_FRAME)
2162 +               *cnt = VIDEO_MAX_FRAME;
2163 +
2164 +       outsize = multipass->out_pitch * multipass->out_vsize;
2165 +       insize = multipass->in_pitch * multipass->in_vsize;
2166 +       if (*cnt == 1 && (outsize > insize)) {
2167 +               dev_err(rsz_device, "2 buffers are required for Upscaling "
2168 +                                                               "mode\n");
2169 +               goto err_einval;
2170 +       }
2171 +       if (!fh->params->in_hsize || !fh->params->in_vsize) {
2172 +               dev_err(rsz_device, "Can't setup buffer size\n");
2173 +               goto err_einval;
2174 +       } else {
2175 +               if (outsize > insize)
2176 +                       *size = outsize;
2177 +               else
2178 +                       *size = insize;
2179 +
2180 +               fh->rsz_bufsize = *size;
2181 +       }
2182 +       spin_unlock(&fh->vbq_lock);
2183 +
2184 +       return 0;
2185 +err_einval:
2186 +       spin_unlock(&fh->vbq_lock);
2187 +       return -EINVAL;
2188 +}
2189 +
2190 +/**
2191 + * rsz_vbq_prepare - Videobuffer is prepared and mmapped.
2192 + * @q: Structure containing the videobuffer queue file handle, and device
2193 + *     structure which contains the actual configuration.
2194 + * @vb: Structure containing the videobuffer used for resizer processing.
2195 + * @field: Type of field to set in videobuffer device.
2196 + *
2197 + * Returns 0 if successful, or -EINVAL if buffer couldn't get allocated, or
2198 + * -EIO if the ISP MMU mapping fails
2199 + **/
2200 +static int rsz_vbq_prepare(struct videobuf_queue *q,
2201 +                                               struct videobuf_buffer *vb,
2202 +                                               enum v4l2_field field)
2203 +{
2204 +       struct rsz_fh *fh = q->priv_data;
2205 +       struct channel_config *rsz_conf_chan = fh->config;
2206 +       struct rsz_mult *multipass = fh->multipass;
2207 +       int err = 0;
2208 +       unsigned int isp_addr, insize, outsize;
2209 +       struct videobuf_dmabuf *dma = videobuf_to_dma(vb);
2210 +
2211 +       spin_lock(&fh->vbq_lock);
2212 +       if (vb->baddr) {
2213 +               vb->size = fh->rsz_bufsize;
2214 +               vb->bsize = fh->rsz_bufsize;
2215 +       } else {
2216 +               spin_unlock(&fh->vbq_lock);
2217 +               dev_err(rsz_device, "No user buffer allocated\n");
2218 +               goto out;
2219 +       }
2220 +       if (vb->i) {
2221 +               vb->width = fh->params->out_hsize;
2222 +               vb->height = fh->params->out_vsize;
2223 +       } else {
2224 +               vb->width = fh->params->in_hsize;
2225 +               vb->height = fh->params->in_vsize;
2226 +       }
2227 +
2228 +       vb->field = field;
2229 +       spin_unlock(&fh->vbq_lock);
2230 +
2231 +       if (vb->state == VIDEOBUF_NEEDS_INIT) {
2232 +               err = videobuf_iolock(q, vb, NULL);
2233 +               if (!err) {
2234 +                       isp_addr = ispmmu_vmap(dma->sglist, dma->sglen);
2235 +                       if (!isp_addr)
2236 +                               err = -EIO;
2237 +                       else {
2238 +                               if (vb->i) {
2239 +                                       rsz_conf_chan->register_config.
2240 +                                                       rsz_sdr_outadd
2241 +                                                       = isp_addr;
2242 +                                       fh->isp_addr_write = isp_addr;
2243 +                                       rsz_conf_chan->output_buf_index = vb->i;
2244 +                               } else {
2245 +                                       rsz_conf_chan->register_config.
2246 +                                                       rsz_sdr_inadd
2247 +                                                       = isp_addr;
2248 +                                       rsz_conf_chan->input_buf_index = vb->i;
2249 +                                       outsize = multipass->out_pitch *
2250 +                                                       multipass->out_vsize;
2251 +                                       insize = multipass->in_pitch *
2252 +                                                       multipass->in_vsize;
2253 +                                       if (outsize < insize) {
2254 +                                               rsz_conf_chan->register_config.
2255 +                                                               rsz_sdr_outadd
2256 +                                                               = isp_addr;
2257 +                                               rsz_conf_chan->
2258 +                                                       output_buf_index =
2259 +                                                       vb->i;
2260 +                                       }
2261 +
2262 +                                       fh->isp_addr_read = isp_addr;
2263 +                               }
2264 +                       }
2265 +               }
2266 +
2267 +       }
2268 +
2269 +       if (!err) {
2270 +               spin_lock(&fh->vbq_lock);
2271 +               vb->state = VIDEOBUF_PREPARED;
2272 +               spin_unlock(&fh->vbq_lock);
2273 +               flush_cache_user_range(NULL, vb->baddr, (vb->baddr
2274 +                                                               + vb->bsize));
2275 +       } else
2276 +               rsz_vbq_release(q, vb);
2277 +
2278 +out:
2279 +       return err;
2280 +}
2281 +
2282 +static void rsz_vbq_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
2283 +{
2284 +       return;
2285 +}
2286 +
2287 +/**
2288 + * rsz_open - Initializes and opens the Resizer Wrapper
2289 + * @inode: Inode structure associated with the Resizer Wrapper
2290 + * @filp: File structure associated with the Resizer Wrapper
2291 + *
2292 + * Returns 0 if successful, -EBUSY if its already opened or the ISP module is
2293 + * not available, or -ENOMEM if its unable to allocate the device in kernel
2294 + * space memory.
2295 + **/
2296 +static int rsz_open(struct inode *inode, struct file *filp)
2297 +{
2298 +       int ret = 0;
2299 +       struct channel_config *rsz_conf_chan;
2300 +       struct rsz_fh *fh;
2301 +       struct device_params *device = device_config;
2302 +       struct rsz_params *params;
2303 +       struct rsz_mult *multipass;
2304 +
2305 +       if ((filp->f_flags & O_NONBLOCK) == O_NONBLOCK) {
2306 +               printk(KERN_DEBUG "omap-resizer: Device is opened in "
2307 +                                       "non blocking mode\n");
2308 +       } else {
2309 +               printk(KERN_DEBUG "omap-resizer: Device is opened in blocking "
2310 +                                       "mode\n");
2311 +       }
2312 +       fh = kzalloc(sizeof(struct rsz_fh), GFP_KERNEL);
2313 +       if (NULL == fh)
2314 +               return -ENOMEM;
2315 +
2316 +       isp_get();
2317 +
2318 +       rsz_conf_chan = kzalloc(sizeof(struct channel_config), GFP_KERNEL);
2319 +       if (rsz_conf_chan == NULL) {
2320 +               dev_err(rsz_device, "\n cannot allocate memory to config");
2321 +               ret = -ENOMEM;
2322 +               goto err_enomem0;
2323 +       }
2324 +       params = kzalloc(sizeof(struct rsz_params), GFP_KERNEL);
2325 +       if (params == NULL) {
2326 +               dev_err(rsz_device, "\n cannot allocate memory to params");
2327 +               ret = -ENOMEM;
2328 +               goto err_enomem1;
2329 +       }
2330 +       multipass = kzalloc(sizeof(struct rsz_mult), GFP_KERNEL);
2331 +       if (multipass == NULL) {
2332 +               dev_err(rsz_device, "\n cannot allocate memory to multipass");
2333 +               ret = -ENOMEM;
2334 +               goto err_enomem2;
2335 +       }
2336 +
2337 +       fh->multipass = multipass;
2338 +       fh->params = params;
2339 +       fh->config = rsz_conf_chan;
2340 +
2341 +       if (mutex_lock_interruptible(&device->reszwrap_mutex)) {
2342 +               ret = -EINTR;
2343 +               goto err_enomem2;
2344 +       }
2345 +       device->opened++;
2346 +       mutex_unlock(&device->reszwrap_mutex);
2347 +
2348 +       rsz_conf_chan->config_state = STATE_NOT_CONFIGURED;
2349 +       rsz_conf_chan->status = CHANNEL_FREE;
2350 +
2351 +       filp->private_data = fh;
2352 +       fh->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2353 +       fh->device = device;
2354 +
2355 +       videobuf_queue_sg_init(&fh->vbq, &device->vbq_ops, NULL,
2356 +                                       &fh->vbq_lock, fh->type,
2357 +                                       V4L2_FIELD_NONE,
2358 +                                       sizeof(struct videobuf_buffer), fh);
2359 +
2360 +       spin_lock_init(&fh->vbq_lock);
2361 +       mutex_init(&rsz_conf_chan->chanprotection_mutex);
2362 +
2363 +       return 0;
2364 +err_enomem2:
2365 +       kfree(params);
2366 +err_enomem1:
2367 +       kfree(rsz_conf_chan);
2368 +err_enomem0:
2369 +       kfree(fh);
2370 +       return ret;
2371 +}
2372 +
2373 +/**
2374 + * rsz_release - Releases Resizer Wrapper and frees up allocated memory
2375 + * @inode: Inode structure associated with the Resizer Wrapper
2376 + * @filp: File structure associated with the Resizer Wrapper
2377 + *
2378 + * Returns 0 if successful, or -EBUSY if channel is being used.
2379 + **/
2380 +static int rsz_release(struct inode *inode, struct file *filp)
2381 +{
2382 +       u32 timeout = 0;
2383 +       struct rsz_fh *fh = filp->private_data;
2384 +       struct channel_config *rsz_conf_chan = fh->config;
2385 +       struct rsz_params *params = fh->params;
2386 +       struct rsz_mult *multipass = fh->multipass;
2387 +       struct videobuf_queue *q = &fh->vbq;
2388 +
2389 +       while ((rsz_conf_chan->status != CHANNEL_FREE) && (timeout < 20)) {
2390 +               timeout++;
2391 +               schedule();
2392 +       }
2393 +       if (mutex_lock_interruptible(&device_config->reszwrap_mutex))
2394 +               return -EINTR;
2395 +       device_config->opened--;
2396 +       mutex_unlock(&device_config->reszwrap_mutex);
2397 +       /* This will Free memory allocated to the buffers,
2398 +        * and flushes the queue
2399 +        */
2400 +       videobuf_queue_cancel(q);
2401 +       fh->params = NULL;
2402 +       fh->config = NULL;
2403 +
2404 +       fh->rsz_bufsize = 0;
2405 +       filp->private_data = NULL;
2406 +
2407 +       kfree(rsz_conf_chan);
2408 +       kfree(params);
2409 +       kfree(multipass);
2410 +       kfree(fh);
2411 +
2412 +       isp_put();
2413 +
2414 +       return 0;
2415 +}
2416 +
2417 +/**
2418 + * rsz_mmap - Memory maps the Resizer Wrapper module.
2419 + * @file: File structure associated with the Resizer Wrapper
2420 + * @vma: Virtual memory area structure.
2421 + *
2422 + * Returns 0 if successful, or returned value by the videobuf_mmap_mapper()
2423 + * function.
2424 + **/
2425 +static int rsz_mmap(struct file *file, struct vm_area_struct *vma)
2426 +{
2427 +       struct rsz_fh *fh = file->private_data;
2428 +
2429 +       return videobuf_mmap_mapper(&fh->vbq, vma);
2430 +}
2431 +
2432 +/**
2433 + * rsz_ioctl - I/O control function for Resizer Wrapper
2434 + * @inode: Inode structure associated with the Resizer Wrapper.
2435 + * @file: File structure associated with the Resizer Wrapper.
2436 + * @cmd: Type of command to execute.
2437 + * @arg: Argument to send to requested command.
2438 + *
2439 + * Returns 0 if successful, -EBUSY if channel is being used, -1 if bad command
2440 + * passed or access is denied, -EFAULT if copy_from_user() or copy_to_user()
2441 + * fails, -EINVAL if parameter validation fails or parameter structure is not
2442 + * present.
2443 + **/
2444 +static long rsz_unlocked_ioctl(struct file *file, unsigned int cmd,
2445 +                                                       unsigned long arg)
2446 +{
2447 +       int ret = 0;
2448 +       struct rsz_fh *fh = file->private_data;
2449 +       struct device_params *device = fh->device;
2450 +       struct channel_config *rsz_conf_chan = fh->config;
2451 +
2452 +       if ((_IOC_TYPE(cmd) != RSZ_IOC_BASE)
2453 +                                       || (_IOC_NR(cmd) > RSZ_IOC_MAXNR)) {
2454 +               dev_err(rsz_device, "Bad command value \n");
2455 +               return -1;
2456 +       }
2457 +
2458 +       if (_IOC_DIR(cmd) & _IOC_READ)
2459 +               ret = !access_ok(VERIFY_WRITE, (void *)arg, _IOC_SIZE(cmd));
2460 +       else if (_IOC_DIR(cmd) & _IOC_WRITE)
2461 +               ret = !access_ok(VERIFY_READ, (void *)arg, _IOC_SIZE(cmd));
2462 +
2463 +       if (ret) {
2464 +               dev_err(rsz_device, "Access denied\n");
2465 +               return -1;
2466 +       }
2467 +
2468 +       switch (cmd) {
2469 +       case RSZ_REQBUF:
2470 +       {
2471 +               struct v4l2_requestbuffers req_buf;
2472 +               if (copy_from_user(&req_buf, (struct v4l2_requestbuffers *)arg,
2473 +                                       sizeof(struct v4l2_requestbuffers))) {
2474 +                       return -EFAULT;
2475 +               }
2476 +               if (mutex_lock_interruptible(&rsz_conf_chan->
2477 +                                                       chanprotection_mutex))
2478 +                       return -EINTR;
2479 +               ret = videobuf_reqbufs(&fh->vbq, (void *)&req_buf);
2480 +               mutex_unlock(&rsz_conf_chan->chanprotection_mutex);
2481 +               break;
2482 +       }
2483 +       case RSZ_QUERYBUF:
2484 +       {
2485 +               struct v4l2_buffer buf;
2486 +               if (copy_from_user(&buf, (struct v4l2_buffer *)arg,
2487 +                                               sizeof(struct v4l2_buffer))) {
2488 +                       return -EFAULT;
2489 +               }
2490 +               if (mutex_lock_interruptible(&rsz_conf_chan->
2491 +                                                       chanprotection_mutex))
2492 +                       return -EINTR;
2493 +               ret = videobuf_querybuf(&fh->vbq, (void *)&buf);
2494 +               mutex_unlock(&rsz_conf_chan->chanprotection_mutex);
2495 +               if (copy_to_user((struct v4l2_buffer *)arg, &buf,
2496 +                                               sizeof(struct v4l2_buffer)))
2497 +                       return -EFAULT;
2498 +               break;
2499 +       }
2500 +       case RSZ_QUEUEBUF:
2501 +       {
2502 +               struct v4l2_buffer buf;
2503 +               if (copy_from_user(&buf, (struct v4l2_buffer *)arg,
2504 +                                               sizeof(struct v4l2_buffer))) {
2505 +                       return -EFAULT;
2506 +               }
2507 +               if (mutex_lock_interruptible(&rsz_conf_chan->
2508 +                                                       chanprotection_mutex))
2509 +                       return -EINTR;
2510 +               ret = videobuf_qbuf(&fh->vbq, (void *)&buf);
2511 +               mutex_unlock(&rsz_conf_chan->chanprotection_mutex);
2512 +               break;
2513 +       }
2514 +       case RSZ_S_PARAM:
2515 +       {
2516 +               struct rsz_params *params = fh->params;
2517 +               if (copy_from_user(params, (struct rsz_params *)arg,
2518 +                                               sizeof(struct rsz_params))) {
2519 +                       return -EFAULT;
2520 +               }
2521 +               if (mutex_lock_interruptible(&rsz_conf_chan->
2522 +                                                       chanprotection_mutex))
2523 +                       return -EINTR;
2524 +               ret = rsz_set_params(fh->multipass, params, rsz_conf_chan);
2525 +               mutex_unlock(&rsz_conf_chan->chanprotection_mutex);
2526 +               break;
2527 +       }
2528 +       case RSZ_G_PARAM:
2529 +               ret = rsz_get_params((struct rsz_params *)arg, rsz_conf_chan);
2530 +               break;
2531 +
2532 +       case RSZ_G_STATUS:
2533 +       {
2534 +               struct rsz_status *status;
2535 +               status = (struct rsz_status *)arg;
2536 +               status->chan_busy = rsz_conf_chan->status;
2537 +               status->hw_busy = ispresizer_busy();
2538 +               status->src = INPUT_RAM;
2539 +               break;
2540 +       }
2541 +       case RSZ_RESIZE:
2542 +               if (file->f_flags & O_NONBLOCK) {
2543 +                       if (ispresizer_busy())
2544 +                               return -EBUSY;
2545 +                       else {
2546 +                               if (!mutex_trylock(&device->reszwrap_mutex))
2547 +                                       return -EBUSY;
2548 +                       }
2549 +               } else {
2550 +                       if (mutex_lock_interruptible(&device->reszwrap_mutex))
2551 +                               return -EINTR;
2552 +               }
2553 +               ret = rsz_start((int *)arg, fh);
2554 +               mutex_unlock(&device->reszwrap_mutex);
2555 +               break;
2556 +       case RSZ_GET_CROPSIZE:
2557 +               rsz_calculate_crop(rsz_conf_chan, (struct rsz_cropsize *)arg);
2558 +               break;
2559 +
2560 +       default:
2561 +               dev_err(rsz_device, "resizer_ioctl: Invalid Command Value");
2562 +               return -EINVAL;
2563 +       }
2564 +
2565 +       return (long)ret;
2566 +}
2567 +
2568 +static struct file_operations rsz_fops = {
2569 +       .owner = THIS_MODULE,
2570 +       .open = rsz_open,
2571 +       .release = rsz_release,
2572 +       .mmap = rsz_mmap,
2573 +       .unlocked_ioctl = rsz_unlocked_ioctl,
2574 +};
2575 +
2576 +/**
2577 + * rsz_isr - Interrupt Service Routine for Resizer wrapper
2578 + * @status: ISP IRQ0STATUS register value
2579 + * @arg1: Currently not used
2580 + * @arg2: Currently not used
2581 + *
2582 + * Interrupt Service Routine for Resizer wrapper
2583 + **/
2584 +static void rsz_isr(unsigned long status, isp_vbq_callback_ptr arg1, void *arg2)
2585 +{
2586 +
2587 +       if ((status & RESZ_DONE) != RESZ_DONE)
2588 +               return;
2589 +
2590 +       complete(&(device_config->compl_isr));
2591 +
2592 +}
2593 +
2594 +/**
2595 + * resizer_platform_release - Acts when Reference count is zero
2596 + * @device: Structure containing ISP resizer wrapper global information
2597 + *
2598 + * This is called when the reference count goes to zero.
2599 + **/
2600 +static void resizer_platform_release(struct device *device)
2601 +{
2602 +}
2603 +
2604 +/**
2605 + * resizer_probe - Checks for device presence
2606 + * @device: Structure containing details of the current device.
2607 + *
2608 + * Always returns 0.
2609 + **/
2610 +static int __init resizer_probe(struct platform_device *device)
2611 +{
2612 +       return 0;
2613 +}
2614 +
2615 +/**
2616 + * resizer_remove - Handles the removal of the driver
2617 + * @omap_resizer_device: Structure containing details of the current device.
2618 + *
2619 + * Always returns 0.
2620 + **/
2621 +static int resizer_remove(struct platform_device *omap_resizer_device)
2622 +{
2623 +       return 0;
2624 +}
2625 +
2626 +static struct class *rsz_class;
2627 +static struct cdev c_dev;
2628 +static dev_t dev;
2629 +static struct platform_device omap_resizer_device = {
2630 +       .name = OMAP_REZR_NAME,
2631 +       .id = 2,
2632 +       .dev = {
2633 +               .release = resizer_platform_release,}
2634 +};
2635 +
2636 +static struct platform_driver omap_resizer_driver = {
2637 +       .probe = resizer_probe,
2638 +       .remove = resizer_remove,
2639 +       .driver = {
2640 +                       .bus = &platform_bus_type,
2641 +                       .name = OMAP_REZR_NAME,
2642 +       },
2643 +};
2644 +
2645 +/**
2646 + * omap_rsz_init - Initialization of Resizer Wrapper
2647 + *
2648 + * Returns 0 if successful, -ENOMEM if could not allocate memory, -ENODEV if
2649 + * could not register the wrapper as a character device, or other errors if the
2650 + * device or driver can't register.
2651 + **/
2652 +static int __init omap_rsz_init(void)
2653 +{
2654 +       int ret = 0;
2655 +       struct device_params *device;
2656 +       device = kzalloc(sizeof(struct device_params), GFP_KERNEL);
2657 +       if (!device) {
2658 +               dev_err(rsz_device, OMAP_REZR_NAME ": could not allocate "
2659 +                                                               "memory\n");
2660 +               return -ENOMEM;
2661 +       }
2662 +
2663 +       ret = alloc_chrdev_region(&dev, 0, 1, OMAP_REZR_NAME);
2664 +       if (ret < 0) {
2665 +               dev_err(rsz_device, OMAP_REZR_NAME ": intialization failed. "
2666 +                       "Could not allocate region "
2667 +                       "for character device\n");
2668 +               kfree(device);
2669 +               return -ENODEV;
2670 +       }
2671 +
2672 +       /* Register the driver in the kernel */
2673 +       /* Initialize of character device */
2674 +       cdev_init(&c_dev, &rsz_fops);
2675 +       c_dev.owner = THIS_MODULE;
2676 +       c_dev.ops = &rsz_fops;
2677 +
2678 +       /* Addding character device */
2679 +       ret = cdev_add(&c_dev, dev, 1);
2680 +       if (ret) {
2681 +               dev_err(rsz_device, OMAP_REZR_NAME ": Error adding "
2682 +                       "device - %d\n", ret);
2683 +               goto fail2;
2684 +       }
2685 +       rsz_major = MAJOR(dev);
2686 +
2687 +       /* register driver as a platform driver */
2688 +       ret = platform_driver_register(&omap_resizer_driver);
2689 +       if (ret) {
2690 +               dev_err(rsz_device, OMAP_REZR_NAME
2691 +                               ": Failed to register platform driver!\n");
2692 +               goto fail3;
2693 +       }
2694 +
2695 +       /* Register the drive as a platform device */
2696 +       ret = platform_device_register(&omap_resizer_device);
2697 +       if (ret) {
2698 +               dev_err(rsz_device, OMAP_REZR_NAME
2699 +                               ": Failed to register platform device!\n");
2700 +               goto fail4;
2701 +       }
2702 +
2703 +       rsz_class = class_create(THIS_MODULE, OMAP_REZR_NAME);
2704 +       if (!rsz_class) {
2705 +               dev_err(rsz_device, OMAP_REZR_NAME
2706 +                       ": Failed to create class!\n");
2707 +               goto fail5;
2708 +       }
2709 +
2710 +       /* make entry in the devfs */
2711 +       rsz_device = device_create(rsz_class, rsz_device,
2712 +                                               MKDEV(rsz_major, 0), NULL,
2713 +                                               OMAP_REZR_NAME);
2714 +       dev_dbg(rsz_device, OMAP_REZR_NAME ": Registered Resizer Wrapper\n");
2715 +       device->opened = 0;
2716 +
2717 +       device->vbq_ops.buf_setup = rsz_vbq_setup;
2718 +       device->vbq_ops.buf_prepare = rsz_vbq_prepare;
2719 +       device->vbq_ops.buf_release = rsz_vbq_release;
2720 +       device->vbq_ops.buf_queue = rsz_vbq_queue;
2721 +       init_completion(&device->compl_isr);
2722 +       mutex_init(&device->reszwrap_mutex);
2723 +
2724 +       device_config = device;
2725 +       return 0;
2726 +
2727 +fail5:
2728 +       platform_device_unregister(&omap_resizer_device);
2729 +fail4:
2730 +       platform_driver_unregister(&omap_resizer_driver);
2731 +fail3:
2732 +       cdev_del(&c_dev);
2733 +fail2:
2734 +       unregister_chrdev_region(dev, 1);
2735 +       kfree(device);
2736 +       return ret;
2737 +}
2738 +
2739 +/**
2740 + * omap_rsz_exit - Close of Resizer Wrapper
2741 + **/
2742 +void __exit omap_rsz_exit(void)
2743 +{
2744 +       device_destroy(rsz_class, dev);
2745 +       class_destroy(rsz_class);
2746 +       platform_device_unregister(&omap_resizer_device);
2747 +       platform_driver_unregister(&omap_resizer_driver);
2748 +       cdev_del(&c_dev);
2749 +       unregister_chrdev_region(dev, 1);
2750 +       kfree(device_config);
2751 +}
2752 +
2753 +module_init(omap_rsz_init)
2754 +module_exit(omap_rsz_exit)
2755 +
2756 +MODULE_AUTHOR("Texas Instruments");
2757 +MODULE_DESCRIPTION("OMAP ISP Resizer");
2758 +MODULE_LICENSE("GPL");
2759 diff --git a/include/linux/omap_resizer.h b/include/linux/omap_resizer.h
2760 new file mode 100644
2761 index 0000000..5ac0c88
2762 --- /dev/null
2763 +++ b/include/linux/omap_resizer.h
2764 @@ -0,0 +1,136 @@
2765 +/*
2766 + * drivers/media/video/isp/omap_resizer.h
2767 + *
2768 + * Include file for Resizer module wrapper in TI's OMAP3430 ISP
2769 + *
2770 + * Copyright (C) 2008 Texas Instruments, Inc.
2771 + *
2772 + * This package is free software; you can redistribute it and/or modify
2773 + * it under the terms of the GNU General Public License version 2 as
2774 + * published by the Free Software Foundation.
2775 + *
2776 + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
2777 + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
2778 + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
2779 + */
2780 +
2781 +#ifndef OMAP_RESIZER_H
2782 +#define OMAP_RESIZER_H
2783 +
2784 +#include <linux/types.h>
2785 +
2786 +/* ioctls definition */
2787 +#define RSZ_IOC_BASE           'R'
2788 +#define RSZ_IOC_MAXNR          8
2789 +
2790 +/*Ioctl options which are to be passed while calling the ioctl*/
2791 +#define RSZ_REQBUF             _IOWR(RSZ_IOC_BASE, 1,\
2792 +                                       struct v4l2_requestbuffers)
2793 +#define RSZ_QUERYBUF           _IOWR(RSZ_IOC_BASE, 2, struct v4l2_buffer)
2794 +#define RSZ_S_PARAM            _IOWR(RSZ_IOC_BASE, 3, struct rsz_params)
2795 +#define RSZ_G_PARAM            _IOWR(RSZ_IOC_BASE, 4, struct rsz_params)
2796 +#define RSZ_RESIZE             _IOWR(RSZ_IOC_BASE, 5, __s32)
2797 +#define RSZ_G_STATUS           _IOWR(RSZ_IOC_BASE, 6, struct rsz_status)
2798 +#define RSZ_QUEUEBUF           _IOWR(RSZ_IOC_BASE, 7, struct v4l2_buffer)
2799 +#define RSZ_GET_CROPSIZE       _IOWR(RSZ_IOC_BASE, 8, struct rsz_cropsize)
2800 +
2801 +#define RSZ_INTYPE_YCBCR422_16BIT      0
2802 +#define RSZ_INTYPE_PLANAR_8BIT         1
2803 +#define RSZ_PIX_FMT_UYVY               1       /* cb:y:cr:y */
2804 +#define RSZ_PIX_FMT_YUYV               0       /* y:cb:y:cr */
2805 +
2806 +enum config_done {
2807 +       STATE_CONFIGURED,                       /* Resizer driver configured
2808 +                                                * by application.
2809 +                                                */
2810 +       STATE_NOT_CONFIGURED                    /* Resizer driver not
2811 +                                                * configured by application.
2812 +                                                */
2813 +};
2814 +
2815 +/* Structure Definitions */
2816 +
2817 +/* used to luma enhancement options */
2818 +
2819 +struct rsz_yenh {
2820 +       __s32 type;                             /* represents luma enable or
2821 +                                                * disable.
2822 +                                                */
2823 +       __u8 gain;                      /* represents gain. */
2824 +       __u8 slop;                      /* represents slop. */
2825 +       __u8 core;                      /* Represents core value. */
2826 +};
2827 +
2828 +/* Conatins all the parameters for resizing. This structure
2829 + * is used to configure resiser parameters
2830 + */
2831 +struct rsz_params {
2832 +       __s32 in_hsize;                         /* input frame horizontal
2833 +                                                * size.
2834 +                                                */
2835 +       __s32 in_vsize;                         /* input frame vertical size */
2836 +       __s32 in_pitch;                         /* offset between two rows of
2837 +                                                * input frame.
2838 +                                                */
2839 +       __s32 inptyp;                           /* for determining 16 bit or
2840 +                                                * 8 bit data.
2841 +                                                */
2842 +       __s32 vert_starting_pixel;              /* for specifying vertical
2843 +                                                * starting pixel in input.
2844 +                                                */
2845 +       __s32 horz_starting_pixel;              /* for specyfing horizontal
2846 +                                                * starting pixel in input.
2847 +                                                */
2848 +       __s32 cbilin;                           /* # defined, filter with luma
2849 +                                                * or bi-linear interpolation.
2850 +                                                */
2851 +       __s32 pix_fmt;                          /* # defined, UYVY or YUYV */
2852 +       __s32 out_hsize;                        /* output frame horizontal
2853 +                                                * size.
2854 +                                                */
2855 +       __s32 out_vsize;                                /* output frame vertical
2856 +                                                * size.
2857 +                                                */
2858 +       __s32 out_pitch;                        /* offset between two rows of
2859 +                                                * output frame.
2860 +                                                */
2861 +       __s32 hstph;                            /* for specifying horizontal
2862 +                                                * starting phase.
2863 +                                                */
2864 +       __s32 vstph;                            /* for specifying vertical
2865 +                                                * starting phase.
2866 +                                                */
2867 +       __u16 tap4filt_coeffs[32];              /* horizontal filter
2868 +                                                * coefficients.
2869 +                                                */
2870 +       __u16 tap7filt_coeffs[32];              /* vertical filter
2871 +                                                * coefficients.
2872 +                                                */
2873 +       struct rsz_yenh yenh_params;
2874 +};
2875 +
2876 +/* Contains the status of hardware and channel */
2877 +struct rsz_status {
2878 +       __s32 chan_busy;                                /* 1: channel is busy,
2879 +                                                * 0: channel is not busy
2880 +                                                */
2881 +       __s32 hw_busy;                          /* 1: hardware is busy,
2882 +                                                * 0: hardware is not busy
2883 +                                                */
2884 +       __s32 src;                              /* # defined, can be either
2885 +                                                * SD-RAM or CCDC/PREVIEWER
2886 +                                                */
2887 +};
2888 +
2889 +/* Passed by application for getting crop size */
2890 +struct rsz_cropsize {
2891 +       __u32 hcrop;                    /* Number of pixels per line
2892 +                                                * cropped in output image.
2893 +                                                */
2894 +
2895 +       __u32 vcrop;                    /* Number of lines cropped
2896 +                                                * in output image.
2897 +                                                */
2898 +};
2899 +
2900 +#endif
2901 -- 
2902 1.6.0.3
2903
2904 --- /tmp/Kconfig        2009-04-06 10:56:27.000000000 +0200
2905 +++ git/drivers/media/video/Kconfig     2009-04-06 10:57:25.000000000 +0200
2906 @@ -711,6 +711,9 @@
2907           CMOS camera controller.  This is the controller found on first-
2908           generation OLPC systems.
2909  
2910 +
2911 +source "drivers/media/video/isp/Kconfig"
2912 +
2913  config VIDEO_OMAP3
2914          tristate "OMAP 3 Camera support"
2915         select VIDEOBUF_GEN