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
6 The Resizer and Previewer driver added to the commit
7 from the patch submitted by Sergio on 12 Dec 2008.
9 The new WTBU code base and Nokia fixes package doesn't contain
10 standalone resizer driver support.
12 Following major changes done -
14 - Added stand-alone resizer driver support
16 - Seperate Kconfig file created
17 - hardware access of resizer module fixed as per new
20 Signed-off-by: Vaibhav Hiremath <hvaibhav@ti.com>
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
38 diff --git a/drivers/media/video/isp/Kconfig b/drivers/media/video/isp/Kconfig
40 index 0000000..acda63b
42 +++ b/drivers/media/video/isp/Kconfig
44 +# Kconfig for OMAP3 ISP driver
46 +config VIDEO_OMAP3_ISP
49 + select VIDEOBUF_DMA_SG
51 +config VIDEO_OMAP34XX_ISP_PREVIEWER
52 + tristate "OMAP ISP Previewer"
53 + depends on !ARCH_OMAP3410
54 + select VIDEO_OMAP3_ISP
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
66 isp.o ispccdc.o ispmmu.o \
67 isppreview.o ispresizer.o isph3a.o isphist.o isp_af.o ispcsi2.o
69 +obj-$(CONFIG_VIDEO_OMAP34XX_ISP_PREVIEWER) += \
72 +obj-$(CONFIG_VIDEO_OMAP34XX_ISP_RESIZER) += \
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,
87 + isp_reg_writel(IRQ0ENABLE_RSZ_DONE_IRQ, OMAP3_ISP_IOMEM_MAIN,
89 + isp_reg_writel(isp_reg_readl(OMAP3_ISP_IOMEM_MAIN, ISP_IRQ0ENABLE) |
90 + IRQ0ENABLE_RSZ_DONE_IRQ, OMAP3_ISP_IOMEM_MAIN,
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);
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]);
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;
116 +EXPORT_SYMBOL_GPL(ispmmu_get_mapeable_space);
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
122 index 0000000..634a056
124 +++ b/drivers/media/video/isp/omap_previewer.c
127 + * drivers/media/video/isp/omap_previewer.c
129 + * Wrapper for Preview module in TI's OMAP3430 ISP
131 + * Copyright (C) 2008 Texas Instruments, Inc.
134 + * Leonides Martinez <leonides.martinez@ti.com>
135 + * Sergio Aguirre <saaguirre@ti.com>
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.
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.
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>
162 +#include "omap_previewer.h"
164 +#define OMAP_PREV_NAME "omap-previewer"
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;
172 +static u32 prev_bufsize;
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
179 + * This function is used to calculate frame size reduction depending on
180 + * the features enabled by the application.
182 +static void prev_calculate_crop(struct prev_device *device,
183 + struct prev_cropsize *crop)
185 + dev_dbg(prev_dev, "prev_calculate_crop E\n");
187 + if (!device || !crop) {
188 + dev_err(prev_dev, "\nErron in argument");
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");
200 + * prev_get_status - Get status of ISP preview module
201 + * @status: Structure containing the busy state.
203 + * Checks if the ISP preview module is busy.
205 + * Returns 0 if successful, or -EINVAL if the status parameter is invalid.
207 +static int prev_get_status(struct prev_status *status)
210 + dev_err(prev_dev, "get_status: invalid parameter\n");
213 + status->hw_busy = (char)isppreview_busy();
218 + * prev_hw_setup - Stores the desired configuration in the proper HW registers
219 + * @config: Structure containing the desired configuration for ISP preview
222 + * Reads the structure sent, and modifies the desired registers.
224 + * Always returns 0.
226 +static int prev_hw_setup(struct prev_params *config)
228 + dev_dbg(prev_dev, "prev_hw_setup E\n");
230 + if (config->features & PREV_AVERAGER)
231 + isppreview_config_averager(config->average);
233 + isppreview_config_averager(0);
235 + if (config->features & PREV_INVERSE_ALAW)
236 + isppreview_enable_invalaw(1);
238 + isppreview_enable_invalaw(0);
240 + if (config->features & PREV_HORZ_MEDIAN_FILTER) {
241 + isppreview_config_hmed(config->hmf_params);
242 + isppreview_enable_hmed(1);
244 + isppreview_enable_hmed(0);
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);
251 + isppreview_enable_drkframe(0);
253 + if (config->features & PREV_LENS_SHADING) {
254 + isppreview_config_drkf_shadcomp(config->lens_shading_shift);
255 + isppreview_enable_shadcomp(1);
257 + isppreview_enable_shadcomp(0);
259 + dev_dbg(prev_dev, "prev_hw_setup L\n");
264 + * prev_validate_params - Validate configuration parameters for Preview Wrapper
265 + * @params: Structure containing configuration parameters
267 + * Validate configuration parameters for Preview Wrapper
269 + * Returns 0 if successful, or -EINVAL if a parameter value is invalid.
271 +static int prev_validate_params(struct prev_params *params)
274 + dev_err(prev_dev, "validate_params: error in argument");
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 "
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");
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");
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");
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");
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 "
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 "
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 "
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);
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
364 +static void preview_isr(unsigned long status, isp_vbq_callback_ptr arg1,
367 + struct prev_device *device = (struct prev_device *)arg1;
369 + if ((status & PREV_DONE) != PREV_DONE)
373 + complete(&device->wfc);
377 + * prev_do_preview - Performs the Preview process
378 + * @device: Structure containing ISP preview wrapper global information
379 + * @arg: Currently not used
381 + * Returns 0 if successful, or -EINVAL if the sent parameters are invalid.
383 +static int prev_do_preview(struct prev_device *device, int *arg)
387 + u32 out_hsize, out_vsize, out_line_offset;
389 + dev_dbg(prev_dev, "prev_do_preview E\n");
392 + dev_err(prev_dev, "preview: invalid parameters\n");
396 + if (device->params->size_params.pixsize == PREV_INWIDTH_8BIT)
401 + size = device->params->size_params.hsize *
402 + device->params->size_params.vsize * bpp;
404 + ret = isppreview_set_inaddr(device->isp_addr_read);
408 + ret = isppreview_set_outaddr(device->isp_addr_read);
412 + isppreview_try_size(device->params->size_params.hsize,
413 + device->params->size_params.vsize,
414 + &out_hsize, &out_vsize);
416 + ret = isppreview_config_inlineoffset(device->params->size_params.hsize
421 + out_line_offset = (out_hsize * bpp) & PREV_32BYTES_ALIGN_MASK;
423 + ret = isppreview_config_outlineoffset(out_line_offset);
427 + ret = isppreview_config_size(device->params->size_params.hsize,
428 + device->params->size_params.vsize,
429 + out_hsize, out_vsize);
433 + isppreview_config_datapath(PRV_RAW_MEM, PREVIEW_MEM);
435 + ret = isp_set_callback(CBK_PREV_DONE, preview_isr, (void *)device,
438 + dev_err(prev_dev, "ERROR while setting Previewer callback!\n");
441 + isppreview_enable(1);
443 + wait_for_completion_interruptible(&device->wfc);
445 + if (device->isp_addr_read) {
446 + ispmmu_vunmap(device->isp_addr_read);
447 + device->isp_addr_read = 0;
450 + ret = isp_unset_callback(CBK_PREV_DONE);
452 + dev_dbg(prev_dev, "prev_do_preview L\n");
458 + * previewer_vbq_release - Videobuffer queue release
459 + * @q: Structure containing the videobuffer queue.
460 + * @vb: Structure containing the videobuffer used for previewer processing.
462 +static void previewer_vbq_release(struct videobuf_queue *q,
463 + struct videobuf_buffer *vb)
465 + struct prev_fh *fh = q->priv_data;
466 + struct prev_device *device = fh->device;
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");
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
482 + * Always returns 0.
484 +static int previewer_vbq_setup(struct videobuf_queue *q,
486 + unsigned int *size)
488 + struct prev_fh *fh = q->priv_data;
489 + struct prev_device *device = fh->device;
492 + spin_lock(&device->vbq_lock);
494 + *cnt = VIDEO_MAX_FRAME;
496 + if (*cnt > VIDEO_MAX_FRAME)
497 + *cnt = VIDEO_MAX_FRAME;
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);
506 + if (device->params->size_params.pixsize == PREV_INWIDTH_10BIT)
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");
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.
521 + * Returns 0 if successful, or -EINVAL if buffer couldn't get allocated, or
522 + * -EIO if the ISP MMU mapping fails
524 +static int previewer_vbq_prepare(struct videobuf_queue *q,
525 + struct videobuf_buffer *vb,
526 + enum v4l2_field field)
528 + struct prev_fh *fh = q->priv_data;
529 + struct prev_device *device = fh->device;
531 + unsigned int isp_addr;
532 + struct videobuf_dmabuf *dma = videobuf_to_dma(vb);
534 + dev_dbg(prev_dev, "previewer_vbq_prepare E\n");
535 + spin_lock(&device->vbq_lock);
537 + vb->size = prev_bufsize;
538 + vb->bsize = prev_bufsize;
540 + spin_unlock(&device->vbq_lock);
541 + dev_err(prev_dev, "No user buffer allocated\n");
545 + vb->width = device->params->size_params.hsize;
546 + vb->height = device->params->size_params.vsize;
548 + spin_unlock(&device->vbq_lock);
550 + if (vb->state == VIDEOBUF_NEEDS_INIT) {
551 + err = videobuf_iolock(q, vb, NULL);
553 + isp_addr = ispmmu_vmap(dma->sglist, dma->sglen);
557 + device->isp_addr_read = isp_addr;
562 + vb->state = VIDEOBUF_PREPARED;
563 + flush_cache_user_range(NULL, vb->baddr,
564 + (vb->baddr + vb->bsize));
566 + previewer_vbq_release(q, vb);
568 + dev_dbg(prev_dev, "previewer_vbq_prepare L\n");
573 +static void previewer_vbq_queue(struct videobuf_queue *q,
574 + struct videobuf_buffer *vb)
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
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.
588 +static int previewer_open(struct inode *inode, struct file *filp)
591 + struct prev_device *device = prevdevice;
592 + struct prev_params *config = isppreview_get_config();
593 + struct prev_fh *fh;
595 + if (config == NULL) {
596 + dev_err(prev_dev, "Unable to initialize default config "
597 + "from isppreviewer\n\n");
601 + if (device->opened || (filp->f_flags & O_NONBLOCK)) {
602 + dev_err(prev_dev, "previewer_open: device is already "
607 + fh = kzalloc(sizeof(struct prev_fh), GFP_KERNEL);
612 + ret = isppreview_request();
615 + dev_err(prev_dev, "Can't acquire isppreview\n");
619 + device->params = config;
620 + device->opened = 1;
622 + filp->private_data = fh;
623 + fh->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
624 + fh->device = device;
626 + videobuf_queue_sg_init(&fh->vbq, &device->vbq_ops, NULL,
627 + &device->vbq_lock, fh->type,
629 + sizeof(struct videobuf_buffer), fh);
631 + init_completion(&device->wfc);
632 + device->wfc.done = 0;
633 + mutex_init(&device->prevwrap_mutex);
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
643 + * Always returns 0.
645 +static int previewer_release(struct inode *inode, struct file *filp)
647 + struct prev_fh *fh = filp->private_data;
648 + struct prev_device *device = fh->device;
649 + struct videobuf_queue *q = &fh->vbq;
651 + device->opened = 0;
652 + device->params = NULL;
654 + videobuf_mmap_free(q);
657 + filp->private_data = NULL;
660 + dev_dbg(prev_dev, "previewer_release\n");
665 + * previewer_mmap - Memory maps the Preview Wrapper module.
666 + * @file: File structure associated with the Preview Wrapper
667 + * @vma: Virtual memory area structure.
669 + * Returns 0 if successful, or returned value by the videobuf_mmap_mapper()
672 +static int previewer_mmap(struct file *file, struct vm_area_struct *vma)
674 + struct prev_fh *fh = file->private_data;
675 + dev_dbg(prev_dev, "previewer_mmap\n");
677 + return videobuf_mmap_mapper(&fh->vbq, vma);
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.
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
691 +static int previewer_ioctl(struct inode *inode, struct file *file,
692 + unsigned int cmd, unsigned long arg)
695 + struct prev_params params;
696 + struct prev_fh *fh = file->private_data;
697 + struct prev_device *device = fh->device;
699 + dev_dbg(prev_dev, "Entering previewer_ioctl()\n");
701 + if ((_IOC_TYPE(cmd) != PREV_IOC_BASE)
702 + || (_IOC_NR(cmd) > PREV_IOC_MAXNR)) {
703 + dev_err(prev_dev, "Bad command Value \n");
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));
712 + dev_err(prev_dev, "access denied\n");
718 + if (mutex_lock_interruptible(&device->prevwrap_mutex))
720 + ret = videobuf_reqbufs(&fh->vbq, (void *)arg);
721 + mutex_unlock(&device->prevwrap_mutex);
724 + case PREV_QUERYBUF:
725 + if (mutex_lock_interruptible(&device->prevwrap_mutex))
727 + ret = videobuf_querybuf(&fh->vbq, (void *)arg);
728 + mutex_unlock(&device->prevwrap_mutex);
731 + case PREV_QUEUEBUF:
732 + if (mutex_lock_interruptible(&device->prevwrap_mutex))
734 + ret = videobuf_qbuf(&fh->vbq, (void *)arg);
735 + mutex_unlock(&device->prevwrap_mutex);
738 + case PREV_SET_PARAM:
739 + if (mutex_lock_interruptible(&device->prevwrap_mutex))
741 + if (copy_from_user(¶ms, (struct prev_params *)arg,
742 + sizeof(struct prev_params))) {
743 + mutex_unlock(&device->prevwrap_mutex);
746 + ret = prev_validate_params(¶ms);
748 + dev_err(prev_dev, "Error validating parameters!\n");
749 + mutex_unlock(&device->prevwrap_mutex);
752 + if (device->params)
753 + memcpy(device->params, ¶ms,
754 + sizeof(struct prev_params));
756 + mutex_unlock(&device->prevwrap_mutex);
760 + ret = prev_hw_setup(device->params);
761 + mutex_unlock(&device->prevwrap_mutex);
764 + case PREV_GET_PARAM:
765 + if (copy_to_user((struct prev_params *)arg, device->params,
766 + sizeof(struct prev_params)))
770 + case PREV_GET_STATUS:
771 + ret = prev_get_status((struct prev_status *)arg);
775 + if (mutex_lock_interruptible(&device->prevwrap_mutex))
777 + ret = prev_do_preview(device, (int *)arg);
778 + mutex_unlock(&device->prevwrap_mutex);
781 + case PREV_GET_CROPSIZE:
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)))
792 + dev_err(prev_dev, "previewer_ioctl: Invalid Command Value\n");
804 + * previewer_platform_release - Acts when Reference count is zero
805 + * @device: Structure containing ISP preview wrapper global information
807 + * This is called when the reference count goes to zero
809 +static void previewer_platform_release(struct device *device)
811 + dev_dbg(prev_dev, "previewer_platform_release()\n");
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,
822 +static struct platform_device omap_previewer_device = {
823 + .name = OMAP_PREV_NAME,
826 + .release = previewer_platform_release,
831 + * previewer_probe - Checks for device presence
832 + * @pdev: Structure containing details of the current device.
836 +static int __init previewer_probe(struct platform_device *pdev)
842 + * previewer_remove - Handles the removal of the driver
843 + * @pdev: Structure containing details of the current device.
845 + * Always returns 0.
847 +static int previewer_remove(struct platform_device *pdev)
849 + dev_dbg(prev_dev, "previewer_remove()\n");
851 + platform_device_unregister(&omap_previewer_device);
852 + platform_driver_unregister(&omap_previewer_driver);
853 + unregister_chrdev(prev_major, OMAP_PREV_NAME);
857 +static struct platform_driver omap_previewer_driver = {
858 + .probe = previewer_probe,
859 + .remove = previewer_remove,
861 + .owner = THIS_MODULE,
862 + .name = OMAP_PREV_NAME,
867 + * omap_previewer_init - Initialization of Preview Wrapper
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.
873 +static int __init omap_previewer_init(void)
876 + struct prev_device *device;
878 + device = kzalloc(sizeof(struct prev_device), GFP_KERNEL);
880 + dev_err(prev_dev, OMAP_PREV_NAME ": could not allocate"
884 + prev_major = register_chrdev(0, OMAP_PREV_NAME, &prev_fops);
886 + if (prev_major < 0) {
887 + dev_err(prev_dev, OMAP_PREV_NAME ": initialization "
888 + "failed. could not register character "
893 + ret = platform_driver_register(&omap_previewer_driver);
895 + dev_err(prev_dev, OMAP_PREV_NAME
896 + ": failed to register platform driver!\n");
899 + ret = platform_device_register(&omap_previewer_device);
901 + dev_err(prev_dev, OMAP_PREV_NAME
902 + ": failed to register platform device!\n");
906 + prev_class = class_create(THIS_MODULE, OMAP_PREV_NAME);
910 + prev_dev = device_create(prev_class, prev_dev,
911 + (MKDEV(prev_major, 0)), NULL,
913 + dev_dbg(prev_dev, OMAP_PREV_NAME ": Registered Previewer Wrapper\n");
914 + device->opened = 0;
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);
922 + prevdevice = device;
926 + platform_device_unregister(&omap_previewer_device);
928 + platform_driver_unregister(&omap_previewer_driver);
930 + unregister_chrdev(prev_major, OMAP_PREV_NAME);
936 + * omap_previewer_exit - Close of Preview Wrapper
938 +static void __exit omap_previewer_exit(void)
940 + previewer_remove(&omap_previewer_device);
945 +module_init(omap_previewer_init);
946 +module_exit(omap_previewer_exit);
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
953 index 0000000..0bb31cd
955 +++ b/drivers/media/video/isp/omap_previewer.h
958 + * drivers/media/video/isp/omap_previewer.h
960 + * Header file for Preview module wrapper in TI's OMAP3430 ISP
962 + * Copyright (C) 2008 Texas Instruments, Inc.
965 + * Leonides Martinez <leonides.martinez@ti.com>
966 + * Sergio Aguirre <saaguirre@ti.com>
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.
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.
977 +#include "isppreview.h"
979 +#ifndef OMAP_ISP_PREVIEW_WRAP_H
980 +#define OMAP_ISP_PREVIEW_WRAP_H
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
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
1004 +#define MAX_IMAGE_WIDTH 3300
1006 +#define PREV_INWIDTH_8BIT 0 /* pixel width of 8 bits */
1007 +#define PREV_INWIDTH_10BIT 1 /* pixel width of 10 bits */
1009 +#define PREV_32BYTES_ALIGN_MASK 0xFFFFFFE0
1010 +#define PREV_16PIX_ALIGN_MASK 0xFFFFFFF0
1013 + * struct prev_rgbblending - Structure for RGB2RGB blending parameters
1014 + * @blending: Color correlation 3x3 matrix.
1015 + * @offset: Color correlation offsets.
1017 +struct prev_rgbblending {
1018 + short blending[RGB_MAX][RGB_MAX]; /* color correlation 3x3
1021 + short offset[RGB_MAX]; /* color correlation offsets */
1025 + * struct prev_cfa_coeffs - Structure for CFA coefficients
1026 + * @hthreshold: Horizontal threshold.
1027 + * @vthreshold: Vertical threshold.
1028 + * @coeffs: CFA coefficients
1030 +struct prev_cfa_coeffs {
1031 + char hthreshold, vthreshold;
1032 + int coeffs[CFA_COEFF_TABLE_SIZE];
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.
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];
1048 + * struct prev_noiseflt_coeffs - Structure for Noise Filter Coefficients.
1049 + * @noise: Noise filter table.
1050 + * @strength: Used to find out weighted average.
1052 +struct prev_noiseflt_coeffs {
1053 + unsigned char noise[NOISE_FILTER_TABLE_SIZE];
1054 + unsigned char strength;
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
1063 +struct prev_chroma_spr {
1064 + unsigned char hpfy;
1066 + unsigned char gain;
1070 + * struct prev_status - Structure to know status of the hardware
1071 + * @hw_busy: Flag to indicate if Hardware is Busy.
1073 +struct prev_status {
1078 + * struct prev_cropsize - Structure to know crop size.
1079 + * @hcrop: Horizontal size of crop window.
1080 + * @vcrop: Vertical size of crop window.
1082 +struct prev_cropsize {
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
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;
1108 + * struct prev_fh - Per-filehandle data structure
1109 + * @type: Used buffer type.
1110 + * @vbq: Videobuffer queue.
1111 + * @device: Pointer to device information structure.
1114 + enum v4l2_buf_type type;
1115 + struct videobuf_queue vbq;
1116 + struct prev_device *device;
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
1123 +++ b/drivers/media/video/isp/omap_resizer.c
1126 + * drivers/media/video/isp/omap_resizer.c
1128 + * Wrapper for Resizer module in TI's OMAP3430 ISP
1130 + * Copyright (C) 2008 Texas Instruments, Inc.
1133 + * Sergio Aguirre <saaguirre@ti.com>
1134 + * Troy Laramy <t-laramy@ti.com>
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.
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.
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>
1159 +#include "ispmmu.h"
1160 +#include "ispreg.h"
1161 +#include "ispresizer.h"
1162 +#include <linux/omap_resizer.h>
1164 +#define OMAP_REZR_NAME "omap-resizer"
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
1193 +#define NUM_D2PH 4 /* for downsampling * 2+x ~ 4x,
1194 + * number of phases
1196 +#define NUM_D2TAPS 7 /* for downsampling * 2+x ~ 4x,
1200 +#define MAX_COEF_COUNTER 16
1201 +#define COEFF_ADDRESS_OFFSET 0x04
1203 +/* Global structure which contains information about number of channels
1204 + and protection variables */
1205 +struct device_params {
1207 + unsigned char opened; /* state of the device */
1208 + struct completion compl_isr; /* Completion for interrupt */
1209 + struct mutex reszwrap_mutex; /* Semaphore for array */
1211 + struct videobuf_queue_ops vbq_ops; /* videobuf queue operations */
1214 +/* Register mapped structure which contains the every register
1216 +struct resizer_config {
1217 + u32 rsz_pcr; /* pcr register mapping
1220 + u32 rsz_in_start; /* in_start register mapping
1223 + u32 rsz_in_size; /* in_size register mapping
1226 + u32 rsz_out_size; /* out_size register mapping
1229 + u32 rsz_cnt; /* rsz_cnt register mapping
1232 + u32 rsz_sdr_inadd; /* sdr_inadd register mapping
1235 + u32 rsz_sdr_inoff; /* sdr_inoff register mapping
1238 + u32 rsz_sdr_outadd; /* sdr_outadd register mapping
1241 + u32 rsz_sdr_outoff; /* sdr_outbuff register
1242 + * mapping variable.
1244 + u32 rsz_coeff_horz[16]; /* horizontal coefficients
1247 + u32 rsz_coeff_vert[16]; /* vertical coefficients
1250 + u32 rsz_yehn; /* yehn(luma)register mapping
1256 + int in_hsize; /* input frame horizontal
1259 + int in_vsize; /* input frame vertical size.
1261 + int out_hsize; /* output frame horizontal
1264 + int out_vsize; /* output frame vertical
1267 + int in_pitch; /* offset between two rows of
1270 + int out_pitch; /* offset between two rows of
1275 + int num_htap; /* 0 = 7tap; 1 = 4tap */
1276 + int num_vtap; /* 0 = 7tap; 1 = 4tap */
1281 + int hstph; /* for specifying horizontal
1285 + int pix_fmt; /* # defined, UYVY or YUYV. */
1286 + int cbilin; /* # defined, filter with luma
1289 + u16 tap4filt_coeffs[32]; /* horizontal filter
1292 + u16 tap7filt_coeffs[32]; /* vertical filter
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
1302 + int status; /* Specifies whether the
1303 + * channel is busy or not
1305 + struct mutex chanprotection_mutex;
1306 + enum config_done config_state;
1307 + u8 input_buf_index;
1308 + u8 output_buf_index;
1312 +/* per-filehandle data structure */
1314 + struct rsz_params *params;
1315 + struct channel_config *config;
1316 + struct rsz_mult *multipass; /* Multipass to support
1317 + * resizing ration outside
1320 + spinlock_t vbq_lock; /* spinlock for videobuf
1323 + enum v4l2_buf_type type;
1324 + struct videobuf_queue vbq;
1325 + struct device_params *device;
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
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,
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);
1355 + * rsz_hardware_setup - Sets hardware configuration registers
1356 + * @rsz_conf_chan: Structure containing channel configuration
1358 + * Set hardware configuration registers
1360 +static void rsz_hardware_setup(struct channel_config *rsz_conf_chan)
1363 + int coeffoffset = 0;
1365 + omap_writel(rsz_conf_chan->register_config.rsz_cnt,
1366 + OMAP3ISP_RESZ_REG(ISPRSZ_CNT));
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));
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));
1385 + for (coeffcounter = 0; coeffcounter < MAX_COEF_COUNTER;
1387 + omap_writel(rsz_conf_chan->register_config.
1388 + rsz_coeff_horz[coeffcounter],
1389 + OMAP3ISP_RESZ_REG(ISPRSZ_HFILT10
1392 + omap_writel(rsz_conf_chan->register_config.
1393 + rsz_coeff_vert[coeffcounter],
1394 + OMAP3ISP_RESZ_REG(ISPRSZ_VFILT10
1396 + coeffoffset = coeffoffset + COEFF_ADDRESS_OFFSET;
1401 + * rsz_start - Enables Resizer Wrapper
1402 + * @arg: Currently not used.
1403 + * @device: Structure containing ISP resizer wrapper global information
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.
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.
1414 +int rsz_start(int *arg, struct rsz_fh *fh)
1416 + struct channel_config *rsz_conf_chan = fh->config;
1417 + struct rsz_mult *multipass = fh->multipass;
1418 + struct videobuf_queue *q = &fh->vbq;
1421 + if (rsz_conf_chan->config_state) {
1422 + dev_err(rsz_device, "State not configured \n");
1426 + rsz_conf_chan->status = CHANNEL_BUSY;
1428 + rsz_hardware_setup(rsz_conf_chan);
1430 + if (isp_set_callback(CBK_RESZ_DONE, rsz_isr, (void *) NULL,
1432 + dev_err(rsz_device, "No callback for RSZR\n");
1436 + device_config->compl_isr.done = 0;
1438 + ispresizer_enable(1);
1440 + ret = wait_for_completion_interruptible(&device_config->compl_isr);
1442 + dev_dbg(rsz_device, "Unexpected exit from "
1443 + "wait_for_completion_interruptible\n");
1444 + wait_for_completion(&device_config->compl_isr);
1447 + if (multipass->active) {
1448 + rsz_set_multipass(multipass, rsz_conf_chan);
1452 + if (fh->isp_addr_read) {
1453 + ispmmu_vunmap(fh->isp_addr_read);
1454 + fh->isp_addr_read = 0;
1456 + if (fh->isp_addr_write) {
1457 + ispmmu_vunmap(fh->isp_addr_write);
1458 + fh->isp_addr_write = 0;
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;
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]));
1477 + isp_unset_callback(CBK_RESZ_DONE);
1485 + * rsz_set_multipass - Set resizer multipass
1486 + * @rsz_conf_chan: Structure containing channel configuration
1488 + * Returns always 0
1490 +static int rsz_set_multipass(struct rsz_mult *multipass,
1491 + struct channel_config *rsz_conf_chan)
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;
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));
1503 + rsz_set_ratio(multipass, rsz_conf_chan);
1504 + rsz_config_ratio(multipass, rsz_conf_chan);
1505 + rsz_hardware_setup(rsz_conf_chan);
1510 + * rsz_copy_data - Copy data
1511 + * @params: Structure containing the Resizer Wrapper parameters
1515 +static void rsz_copy_data(struct rsz_mult *multipass, struct rsz_params *params)
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;
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];
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
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.
1547 +static int rsz_set_params(struct rsz_mult *multipass, struct rsz_params *params,
1548 + struct channel_config *rsz_conf_chan)
1551 + if ((params->yenh_params.type < 0) || (params->yenh_params.type > 2)) {
1552 + dev_err(rsz_device, "rsz_set_params: Wrong yenh type\n");
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");
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");
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");
1571 + if (params->inptyp == RSZ_INTYPE_YCBCR422_16BIT)
1575 + if (params->in_pitch < (params->in_hsize * mul)) {
1576 + dev_err(rsz_device, "rsz_set_params: Pitch is incorrect\n");
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");
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"
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");
1596 + rsz_copy_data(multipass, params);
1597 + if (0 != rsz_set_ratio(multipass, rsz_conf_chan))
1600 + if (params->yenh_params.type) {
1601 + if ((multipass->num_htap && multipass->out_hsize >
1603 + (!multipass->num_htap && multipass->out_hsize >
1609 + params->vert_starting_pixel = 0;
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;
1616 + if (params->inptyp == RSZ_INTYPE_PLANAR_8BIT) {
1617 + if (params->horz_starting_pixel > MAX_HORZ_PIXEL_8BIT)
1620 + if (params->inptyp == RSZ_INTYPE_YCBCR422_16BIT) {
1621 + if (params->horz_starting_pixel > MAX_HORZ_PIXEL_16BIT)
1625 + rsz_conf_chan->register_config.rsz_in_start |=
1626 + params->horz_starting_pixel
1627 + & ISPRSZ_IN_START_HORZ_ST_MASK;
1629 + rsz_conf_chan->register_config.rsz_yehn =
1630 + (params->yenh_params.type
1631 + << ISPRSZ_YENH_ALGO_SHIFT)
1632 + & ISPRSZ_YENH_ALGO_MASK;
1634 + if (params->yenh_params.type) {
1635 + rsz_conf_chan->register_config.rsz_yehn |=
1636 + params->yenh_params.core
1637 + & ISPRSZ_YENH_CORE_MASK;
1639 + rsz_conf_chan->register_config.rsz_yehn |=
1640 + (params->yenh_params.gain
1641 + << ISPRSZ_YENH_GAIN_SHIFT)
1642 + & ISPRSZ_YENH_GAIN_MASK;
1644 + rsz_conf_chan->register_config.rsz_yehn |=
1645 + (params->yenh_params.slop
1646 + << ISPRSZ_YENH_SLOP_SHIFT)
1647 + & ISPRSZ_YENH_SLOP_MASK;
1650 + rsz_config_ratio(multipass, rsz_conf_chan);
1652 + rsz_conf_chan->config_state = STATE_CONFIGURED;
1660 + * rsz_set_ratio - Set ratio
1661 + * @rsz_conf_chan: Structure containing channel configuration
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
1666 +static int rsz_set_ratio(struct rsz_mult *multipass,
1667 + struct channel_config *rsz_conf_chan)
1669 + int alignment = 0;
1671 + rsz_conf_chan->register_config.rsz_cnt = 0;
1673 + if ((multipass->out_hsize > MAX_IMAGE_WIDTH) ||
1674 + (multipass->out_vsize > MAX_IMAGE_WIDTH)) {
1675 + dev_err(rsz_device, "Invalid output size!");
1678 + if (multipass->cbilin) {
1679 + rsz_conf_chan->register_config.rsz_cnt =
1680 + BITSET(rsz_conf_chan->register_config.rsz_cnt,
1684 + rsz_conf_chan->register_config.rsz_cnt =
1685 + BITSET(rsz_conf_chan->register_config.rsz_cnt,
1686 + SET_BIT_INPUTRAM);
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,
1693 + rsz_conf_chan->register_config.rsz_cnt =
1694 + BITRESET(rsz_conf_chan->register_config.
1695 + rsz_cnt, SET_BIT_INPTYP);
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);
1709 + (multipass->in_vsize * RATIO_MULTIPLIER) / multipass->out_vsize;
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!");
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);
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)
1732 + multipass->num_htap = 1;
1733 + } else if (multipass->hrsz >= 513 && multipass->hrsz <= 1024) {
1734 + if (multipass->hstph > NUM_D2PH)
1736 + multipass->num_htap = 0;
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)
1749 + multipass->num_vtap = 1;
1750 + } else if (multipass->vrsz >= 513 && multipass->vrsz <= 1024) {
1751 + if (multipass->vstph > NUM_D2PH)
1753 + multipass->num_vtap = 0;
1756 + if ((multipass->in_pitch) % ALIGN32) {
1757 + dev_err(rsz_device, "Invalid input pitch: %d \n",
1758 + multipass->in_pitch);
1761 + if ((multipass->out_pitch) % ALIGN32) {
1762 + dev_err(rsz_device, "Invalid output pitch %d \n",
1763 + multipass->out_pitch);
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);
1774 + dev_err(rsz_device, "Invalid input type\n");
1776 + if (!(((multipass->out_hsize % PIXEL_EVEN) == 0)
1777 + && (multipass->out_hsize % alignment) == 0)) {
1778 + dev_err(rsz_device, "wrong hsize\n");
1782 + if (multipass->hrsz >= 64 && multipass->hrsz <= 1024) {
1783 + if (multipass->out_hsize > MAX_IMAGE_WIDTH) {
1784 + dev_err(rsz_device, "wrong width\n");
1787 + multipass->active = 0;
1789 + } else if (multipass->hrsz > 1024) {
1790 + if (multipass->out_hsize > MAX_IMAGE_WIDTH) {
1791 + dev_err(rsz_device, "wrong width\n");
1794 + if (multipass->hstph > NUM_D2PH)
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);
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;
1812 + if (multipass->vrsz > 1024) {
1813 + if (multipass->out_vsize > MAX_IMAGE_WIDTH_HIGH) {
1814 + dev_err(rsz_device, "wrong width\n");
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;
1826 + rsz_conf_chan->register_config.rsz_out_size =
1827 + multipass->out_hsize
1828 + & ISPRSZ_OUT_SIZE_HORZ_MASK;
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;
1835 + rsz_conf_chan->register_config.rsz_sdr_inoff =
1836 + multipass->in_pitch
1837 + & ISPRSZ_SDR_INOFF_OFFSET_MASK;
1839 + rsz_conf_chan->register_config.rsz_sdr_outoff =
1840 + multipass->out_pitch
1841 + & ISPRSZ_SDR_OUTOFF_OFFSET_MASK;
1843 + if (multipass->hrsz >= 64 && multipass->hrsz <= 512) {
1844 + if (multipass->hstph > NUM_PHASES)
1846 + } else if (multipass->hrsz >= 64 && multipass->hrsz <= 512) {
1847 + if (multipass->hstph > NUM_D2PH)
1851 + rsz_conf_chan->register_config.rsz_cnt |=
1853 + << ISPRSZ_CNT_HSTPH_SHIFT)
1854 + & ISPRSZ_CNT_HSTPH_MASK;
1856 + if (multipass->vrsz >= 64 && multipass->hrsz <= 512) {
1857 + if (multipass->vstph > NUM_PHASES)
1859 + } else if (multipass->vrsz >= 64 && multipass->vrsz <= 512) {
1860 + if (multipass->vstph > NUM_D2PH)
1864 + rsz_conf_chan->register_config.rsz_cnt |=
1866 + << ISPRSZ_CNT_VSTPH_SHIFT)
1867 + & ISPRSZ_CNT_VSTPH_MASK;
1869 + rsz_conf_chan->register_config.rsz_cnt |=
1870 + (multipass->hrsz - 1)
1871 + & ISPRSZ_CNT_HRSZ_MASK;
1873 + rsz_conf_chan->register_config.rsz_cnt |=
1874 + ((multipass->vrsz - 1)
1875 + << ISPRSZ_CNT_VRSZ_SHIFT)
1876 + & ISPRSZ_CNT_VRSZ_MASK;
1884 + * rsz_config_ratio - Configure ratio
1885 + * @rsz_conf_chan: Structure containing channel configuration
1889 +static void rsz_config_ratio(struct rsz_mult *multipass,
1890 + struct channel_config *rsz_conf_chan)
1896 + if (multipass->hrsz <= 512) {
1897 + hsize = ((32 * multipass->hstph + (multipass->out_hsize - 1)
1898 + * multipass->hrsz + 16) >> 8) + 7;
1900 + hsize = ((64 * multipass->hstph + (multipass->out_hsize - 1)
1901 + * multipass->hrsz + 32) >> 8) + 7;
1903 + if (multipass->vrsz <= 512) {
1904 + vsize = ((32 * multipass->vstph + (multipass->out_vsize - 1)
1905 + * multipass->vrsz + 16) >> 8) + 4;
1907 + vsize = ((64 * multipass->vstph + (multipass->out_vsize - 1)
1908 + * multipass->vrsz + 32) >> 8) + 7;
1910 + rsz_conf_chan->register_config.rsz_in_size = hsize;
1912 + rsz_conf_chan->register_config.rsz_in_size |=
1913 + ((vsize << ISPRSZ_IN_SIZE_VERT_SHIFT)
1914 + & ISPRSZ_IN_SIZE_VERT_MASK);
1916 + for (coeffcounter = 0; coeffcounter < MAX_COEF_COUNTER;
1918 + if (multipass->num_htap) {
1919 + rsz_conf_chan->register_config.
1920 + rsz_coeff_horz[coeffcounter] =
1921 + (multipass->tap4filt_coeffs[2
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);
1931 + rsz_conf_chan->register_config.
1932 + rsz_coeff_horz[coeffcounter] =
1933 + (multipass->tap7filt_coeffs[2
1935 + & ISPRSZ_HFILT10_COEF0_MASK);
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);
1945 + if (multipass->num_vtap) {
1946 + rsz_conf_chan->register_config.
1947 + rsz_coeff_vert[coeffcounter] =
1948 + (multipass->tap4filt_coeffs[2
1950 + & ISPRSZ_VFILT10_COEF0_MASK);
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);
1959 + rsz_conf_chan->register_config.
1960 + rsz_coeff_vert[coeffcounter] =
1961 + (multipass->tap7filt_coeffs[2
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);
1975 + * rsz_get_params - Gets the parameter values
1976 + * @params: Structure containing the Resizer Wrapper parameters
1977 + * @rsz_conf_chan: Structure containing channel configuration
1979 + * Used to get the Resizer hardware settings associated with the
1980 + * current logical channel represented by fd.
1982 +static int rsz_get_params(struct rsz_params *params,
1983 + struct channel_config *rsz_conf_chan)
1987 + if (rsz_conf_chan->config_state) {
1988 + dev_err(rsz_device, "state not configured\n");
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;
1998 + params->in_pitch = rsz_conf_chan->register_config.rsz_sdr_inoff
1999 + & ISPRSZ_SDR_INOFF_OFFSET_MASK;
2001 + params->out_hsize = rsz_conf_chan->register_config.rsz_out_size
2002 + & ISPRSZ_OUT_SIZE_HORZ_MASK;
2004 + params->out_vsize = (rsz_conf_chan->register_config.rsz_out_size
2005 + & ISPRSZ_OUT_SIZE_VERT_MASK)
2006 + >> ISPRSZ_OUT_SIZE_VERT_SHIFT;
2008 + params->out_pitch = rsz_conf_chan->register_config.rsz_sdr_outoff
2009 + & ISPRSZ_SDR_OUTOFF_OFFSET_MASK;
2011 + params->cbilin = (rsz_conf_chan->register_config.rsz_cnt
2012 + & SET_BIT_CBLIN) >> SET_BIT_CBLIN;
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.
2019 + & ISPRSZ_IN_START_HORZ_ST_MASK));
2020 + params->vert_starting_pixel = ((rsz_conf_chan->register_config.
2022 + & ISPRSZ_IN_START_VERT_ST_MASK)
2023 + >> ISPRSZ_IN_START_VERT_ST_SHIFT);
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));
2032 + for (coeffcounter = 0; coeffcounter < MAX_COEF_COUNTER;
2034 + params->tap4filt_coeffs[2 * coeffcounter] =
2035 + rsz_conf_chan->register_config.
2036 + rsz_coeff_horz[coeffcounter]
2037 + & ISPRSZ_HFILT10_COEF0_MASK;
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;
2045 + params->tap7filt_coeffs[2 * coeffcounter] =
2046 + rsz_conf_chan->register_config.
2047 + rsz_coeff_vert[coeffcounter]
2048 + & ISPRSZ_VFILT10_COEF0_MASK;
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;
2058 + params->yenh_params.type = (rsz_conf_chan->register_config.rsz_yehn
2059 + & ISPRSZ_YENH_ALGO_MASK)
2060 + >> ISPRSZ_YENH_ALGO_SHIFT;
2062 + params->yenh_params.core = rsz_conf_chan->register_config.rsz_yehn
2063 + & ISPRSZ_YENH_CORE_MASK;
2065 + params->yenh_params.gain = (rsz_conf_chan->register_config.rsz_yehn
2066 + & ISPRSZ_YENH_GAIN_MASK)
2067 + >> ISPRSZ_YENH_GAIN_SHIFT;
2069 + params->yenh_params.slop = (rsz_conf_chan->register_config.rsz_yehn
2070 + & ISPRSZ_YENH_SLOP_MASK)
2071 + >> ISPRSZ_YENH_SLOP_SHIFT;
2073 + params->pix_fmt = ((rsz_conf_chan->register_config.rsz_cnt
2074 + & ISPRSZ_CNT_PIXFMT_MASK)
2075 + >> SET_BIT_YCPOS);
2077 + if (params->pix_fmt)
2078 + params->pix_fmt = RSZ_PIX_FMT_UYVY;
2080 + params->pix_fmt = RSZ_PIX_FMT_YUYV;
2086 + * rsz_calculate_crop - Calculate Crop values
2087 + * @rsz_conf_chan: Structure containing channel configuration
2088 + * @cropsize: Structure containing crop parameters
2090 + * Calculate Crop values
2092 +static void rsz_calculate_crop(struct channel_config *rsz_conf_chan,
2093 + struct rsz_cropsize *cropsize)
2097 + cropsize->hcrop = 0;
2098 + cropsize->vcrop = 0;
2100 + luma_enable = (rsz_conf_chan->register_config.rsz_yehn
2101 + & ISPRSZ_YENH_ALGO_MASK)
2102 + >> ISPRSZ_YENH_ALGO_SHIFT;
2105 + cropsize->hcrop += 2;
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.
2114 +static void rsz_vbq_release(struct videobuf_queue *q,
2115 + struct videobuf_buffer *vb)
2118 + struct rsz_fh *fh = q->priv_data;
2120 + for (i = 0; i < VIDEO_MAX_FRAME; i++) {
2121 + struct videobuf_dmabuf *dma = NULL;
2124 + if (q->bufs[i]->memory != V4L2_MEMORY_MMAP)
2126 + dma = videobuf_to_dma(q->bufs[i]);
2127 + videobuf_dma_unmap(q, dma);
2128 + videobuf_dma_free(dma);
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);
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
2148 + * Always returns 0.
2150 +static int rsz_vbq_setup(struct videobuf_queue *q, unsigned int *cnt,
2151 + unsigned int *size)
2153 + struct rsz_fh *fh = q->priv_data;
2154 + struct rsz_mult *multipass = fh->multipass;
2155 + u32 insize, outsize;
2157 + spin_lock(&fh->vbq_lock);
2159 + *cnt = VIDEO_MAX_FRAME;
2161 + if (*cnt > VIDEO_MAX_FRAME)
2162 + *cnt = VIDEO_MAX_FRAME;
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 "
2171 + if (!fh->params->in_hsize || !fh->params->in_vsize) {
2172 + dev_err(rsz_device, "Can't setup buffer size\n");
2175 + if (outsize > insize)
2180 + fh->rsz_bufsize = *size;
2182 + spin_unlock(&fh->vbq_lock);
2186 + spin_unlock(&fh->vbq_lock);
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.
2197 + * Returns 0 if successful, or -EINVAL if buffer couldn't get allocated, or
2198 + * -EIO if the ISP MMU mapping fails
2200 +static int rsz_vbq_prepare(struct videobuf_queue *q,
2201 + struct videobuf_buffer *vb,
2202 + enum v4l2_field field)
2204 + struct rsz_fh *fh = q->priv_data;
2205 + struct channel_config *rsz_conf_chan = fh->config;
2206 + struct rsz_mult *multipass = fh->multipass;
2208 + unsigned int isp_addr, insize, outsize;
2209 + struct videobuf_dmabuf *dma = videobuf_to_dma(vb);
2211 + spin_lock(&fh->vbq_lock);
2213 + vb->size = fh->rsz_bufsize;
2214 + vb->bsize = fh->rsz_bufsize;
2216 + spin_unlock(&fh->vbq_lock);
2217 + dev_err(rsz_device, "No user buffer allocated\n");
2221 + vb->width = fh->params->out_hsize;
2222 + vb->height = fh->params->out_vsize;
2224 + vb->width = fh->params->in_hsize;
2225 + vb->height = fh->params->in_vsize;
2228 + vb->field = field;
2229 + spin_unlock(&fh->vbq_lock);
2231 + if (vb->state == VIDEOBUF_NEEDS_INIT) {
2232 + err = videobuf_iolock(q, vb, NULL);
2234 + isp_addr = ispmmu_vmap(dma->sglist, dma->sglen);
2239 + rsz_conf_chan->register_config.
2242 + fh->isp_addr_write = isp_addr;
2243 + rsz_conf_chan->output_buf_index = vb->i;
2245 + rsz_conf_chan->register_config.
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.
2258 + output_buf_index =
2262 + fh->isp_addr_read = isp_addr;
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
2276 + rsz_vbq_release(q, vb);
2282 +static void rsz_vbq_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
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
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
2296 +static int rsz_open(struct inode *inode, struct file *filp)
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;
2305 + if ((filp->f_flags & O_NONBLOCK) == O_NONBLOCK) {
2306 + printk(KERN_DEBUG "omap-resizer: Device is opened in "
2307 + "non blocking mode\n");
2309 + printk(KERN_DEBUG "omap-resizer: Device is opened in blocking "
2312 + fh = kzalloc(sizeof(struct rsz_fh), GFP_KERNEL);
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");
2324 + params = kzalloc(sizeof(struct rsz_params), GFP_KERNEL);
2325 + if (params == NULL) {
2326 + dev_err(rsz_device, "\n cannot allocate memory to params");
2330 + multipass = kzalloc(sizeof(struct rsz_mult), GFP_KERNEL);
2331 + if (multipass == NULL) {
2332 + dev_err(rsz_device, "\n cannot allocate memory to multipass");
2337 + fh->multipass = multipass;
2338 + fh->params = params;
2339 + fh->config = rsz_conf_chan;
2341 + if (mutex_lock_interruptible(&device->reszwrap_mutex)) {
2346 + mutex_unlock(&device->reszwrap_mutex);
2348 + rsz_conf_chan->config_state = STATE_NOT_CONFIGURED;
2349 + rsz_conf_chan->status = CHANNEL_FREE;
2351 + filp->private_data = fh;
2352 + fh->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2353 + fh->device = device;
2355 + videobuf_queue_sg_init(&fh->vbq, &device->vbq_ops, NULL,
2356 + &fh->vbq_lock, fh->type,
2358 + sizeof(struct videobuf_buffer), fh);
2360 + spin_lock_init(&fh->vbq_lock);
2361 + mutex_init(&rsz_conf_chan->chanprotection_mutex);
2367 + kfree(rsz_conf_chan);
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
2378 + * Returns 0 if successful, or -EBUSY if channel is being used.
2380 +static int rsz_release(struct inode *inode, struct file *filp)
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;
2389 + while ((rsz_conf_chan->status != CHANNEL_FREE) && (timeout < 20)) {
2393 + if (mutex_lock_interruptible(&device_config->reszwrap_mutex))
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
2400 + videobuf_queue_cancel(q);
2401 + fh->params = NULL;
2402 + fh->config = NULL;
2404 + fh->rsz_bufsize = 0;
2405 + filp->private_data = NULL;
2407 + kfree(rsz_conf_chan);
2418 + * rsz_mmap - Memory maps the Resizer Wrapper module.
2419 + * @file: File structure associated with the Resizer Wrapper
2420 + * @vma: Virtual memory area structure.
2422 + * Returns 0 if successful, or returned value by the videobuf_mmap_mapper()
2425 +static int rsz_mmap(struct file *file, struct vm_area_struct *vma)
2427 + struct rsz_fh *fh = file->private_data;
2429 + return videobuf_mmap_mapper(&fh->vbq, vma);
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.
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
2444 +static long rsz_unlocked_ioctl(struct file *file, unsigned int cmd,
2445 + unsigned long arg)
2448 + struct rsz_fh *fh = file->private_data;
2449 + struct device_params *device = fh->device;
2450 + struct channel_config *rsz_conf_chan = fh->config;
2452 + if ((_IOC_TYPE(cmd) != RSZ_IOC_BASE)
2453 + || (_IOC_NR(cmd) > RSZ_IOC_MAXNR)) {
2454 + dev_err(rsz_device, "Bad command value \n");
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));
2464 + dev_err(rsz_device, "Access denied\n");
2471 + struct v4l2_requestbuffers req_buf;
2472 + if (copy_from_user(&req_buf, (struct v4l2_requestbuffers *)arg,
2473 + sizeof(struct v4l2_requestbuffers))) {
2476 + if (mutex_lock_interruptible(&rsz_conf_chan->
2477 + chanprotection_mutex))
2479 + ret = videobuf_reqbufs(&fh->vbq, (void *)&req_buf);
2480 + mutex_unlock(&rsz_conf_chan->chanprotection_mutex);
2483 + case RSZ_QUERYBUF:
2485 + struct v4l2_buffer buf;
2486 + if (copy_from_user(&buf, (struct v4l2_buffer *)arg,
2487 + sizeof(struct v4l2_buffer))) {
2490 + if (mutex_lock_interruptible(&rsz_conf_chan->
2491 + chanprotection_mutex))
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)))
2500 + case RSZ_QUEUEBUF:
2502 + struct v4l2_buffer buf;
2503 + if (copy_from_user(&buf, (struct v4l2_buffer *)arg,
2504 + sizeof(struct v4l2_buffer))) {
2507 + if (mutex_lock_interruptible(&rsz_conf_chan->
2508 + chanprotection_mutex))
2510 + ret = videobuf_qbuf(&fh->vbq, (void *)&buf);
2511 + mutex_unlock(&rsz_conf_chan->chanprotection_mutex);
2516 + struct rsz_params *params = fh->params;
2517 + if (copy_from_user(params, (struct rsz_params *)arg,
2518 + sizeof(struct rsz_params))) {
2521 + if (mutex_lock_interruptible(&rsz_conf_chan->
2522 + chanprotection_mutex))
2524 + ret = rsz_set_params(fh->multipass, params, rsz_conf_chan);
2525 + mutex_unlock(&rsz_conf_chan->chanprotection_mutex);
2529 + ret = rsz_get_params((struct rsz_params *)arg, rsz_conf_chan);
2532 + case RSZ_G_STATUS:
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;
2542 + if (file->f_flags & O_NONBLOCK) {
2543 + if (ispresizer_busy())
2546 + if (!mutex_trylock(&device->reszwrap_mutex))
2550 + if (mutex_lock_interruptible(&device->reszwrap_mutex))
2553 + ret = rsz_start((int *)arg, fh);
2554 + mutex_unlock(&device->reszwrap_mutex);
2556 + case RSZ_GET_CROPSIZE:
2557 + rsz_calculate_crop(rsz_conf_chan, (struct rsz_cropsize *)arg);
2561 + dev_err(rsz_device, "resizer_ioctl: Invalid Command Value");
2568 +static struct file_operations rsz_fops = {
2569 + .owner = THIS_MODULE,
2571 + .release = rsz_release,
2573 + .unlocked_ioctl = rsz_unlocked_ioctl,
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
2582 + * Interrupt Service Routine for Resizer wrapper
2584 +static void rsz_isr(unsigned long status, isp_vbq_callback_ptr arg1, void *arg2)
2587 + if ((status & RESZ_DONE) != RESZ_DONE)
2590 + complete(&(device_config->compl_isr));
2595 + * resizer_platform_release - Acts when Reference count is zero
2596 + * @device: Structure containing ISP resizer wrapper global information
2598 + * This is called when the reference count goes to zero.
2600 +static void resizer_platform_release(struct device *device)
2605 + * resizer_probe - Checks for device presence
2606 + * @device: Structure containing details of the current device.
2608 + * Always returns 0.
2610 +static int __init resizer_probe(struct platform_device *device)
2616 + * resizer_remove - Handles the removal of the driver
2617 + * @omap_resizer_device: Structure containing details of the current device.
2619 + * Always returns 0.
2621 +static int resizer_remove(struct platform_device *omap_resizer_device)
2626 +static struct class *rsz_class;
2627 +static struct cdev c_dev;
2629 +static struct platform_device omap_resizer_device = {
2630 + .name = OMAP_REZR_NAME,
2633 + .release = resizer_platform_release,}
2636 +static struct platform_driver omap_resizer_driver = {
2637 + .probe = resizer_probe,
2638 + .remove = resizer_remove,
2640 + .bus = &platform_bus_type,
2641 + .name = OMAP_REZR_NAME,
2646 + * omap_rsz_init - Initialization of Resizer Wrapper
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.
2652 +static int __init omap_rsz_init(void)
2655 + struct device_params *device;
2656 + device = kzalloc(sizeof(struct device_params), GFP_KERNEL);
2658 + dev_err(rsz_device, OMAP_REZR_NAME ": could not allocate "
2663 + ret = alloc_chrdev_region(&dev, 0, 1, OMAP_REZR_NAME);
2665 + dev_err(rsz_device, OMAP_REZR_NAME ": intialization failed. "
2666 + "Could not allocate region "
2667 + "for character device\n");
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;
2678 + /* Addding character device */
2679 + ret = cdev_add(&c_dev, dev, 1);
2681 + dev_err(rsz_device, OMAP_REZR_NAME ": Error adding "
2682 + "device - %d\n", ret);
2685 + rsz_major = MAJOR(dev);
2687 + /* register driver as a platform driver */
2688 + ret = platform_driver_register(&omap_resizer_driver);
2690 + dev_err(rsz_device, OMAP_REZR_NAME
2691 + ": Failed to register platform driver!\n");
2695 + /* Register the drive as a platform device */
2696 + ret = platform_device_register(&omap_resizer_device);
2698 + dev_err(rsz_device, OMAP_REZR_NAME
2699 + ": Failed to register platform device!\n");
2703 + rsz_class = class_create(THIS_MODULE, OMAP_REZR_NAME);
2705 + dev_err(rsz_device, OMAP_REZR_NAME
2706 + ": Failed to create class!\n");
2710 + /* make entry in the devfs */
2711 + rsz_device = device_create(rsz_class, rsz_device,
2712 + MKDEV(rsz_major, 0), NULL,
2714 + dev_dbg(rsz_device, OMAP_REZR_NAME ": Registered Resizer Wrapper\n");
2715 + device->opened = 0;
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);
2724 + device_config = device;
2728 + platform_device_unregister(&omap_resizer_device);
2730 + platform_driver_unregister(&omap_resizer_driver);
2734 + unregister_chrdev_region(dev, 1);
2740 + * omap_rsz_exit - Close of Resizer Wrapper
2742 +void __exit omap_rsz_exit(void)
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);
2749 + unregister_chrdev_region(dev, 1);
2750 + kfree(device_config);
2753 +module_init(omap_rsz_init)
2754 +module_exit(omap_rsz_exit)
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
2763 +++ b/include/linux/omap_resizer.h
2766 + * drivers/media/video/isp/omap_resizer.h
2768 + * Include file for Resizer module wrapper in TI's OMAP3430 ISP
2770 + * Copyright (C) 2008 Texas Instruments, Inc.
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.
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.
2781 +#ifndef OMAP_RESIZER_H
2782 +#define OMAP_RESIZER_H
2784 +#include <linux/types.h>
2786 +/* ioctls definition */
2787 +#define RSZ_IOC_BASE 'R'
2788 +#define RSZ_IOC_MAXNR 8
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)
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 */
2807 + STATE_CONFIGURED, /* Resizer driver configured
2810 + STATE_NOT_CONFIGURED /* Resizer driver not
2811 + * configured by application.
2815 +/* Structure Definitions */
2817 +/* used to luma enhancement options */
2820 + __s32 type; /* represents luma enable or
2823 + __u8 gain; /* represents gain. */
2824 + __u8 slop; /* represents slop. */
2825 + __u8 core; /* Represents core value. */
2828 +/* Conatins all the parameters for resizing. This structure
2829 + * is used to configure resiser parameters
2831 +struct rsz_params {
2832 + __s32 in_hsize; /* input frame horizontal
2835 + __s32 in_vsize; /* input frame vertical size */
2836 + __s32 in_pitch; /* offset between two rows of
2839 + __s32 inptyp; /* for determining 16 bit or
2842 + __s32 vert_starting_pixel; /* for specifying vertical
2843 + * starting pixel in input.
2845 + __s32 horz_starting_pixel; /* for specyfing horizontal
2846 + * starting pixel in input.
2848 + __s32 cbilin; /* # defined, filter with luma
2849 + * or bi-linear interpolation.
2851 + __s32 pix_fmt; /* # defined, UYVY or YUYV */
2852 + __s32 out_hsize; /* output frame horizontal
2855 + __s32 out_vsize; /* output frame vertical
2858 + __s32 out_pitch; /* offset between two rows of
2861 + __s32 hstph; /* for specifying horizontal
2864 + __s32 vstph; /* for specifying vertical
2867 + __u16 tap4filt_coeffs[32]; /* horizontal filter
2870 + __u16 tap7filt_coeffs[32]; /* vertical filter
2873 + struct rsz_yenh yenh_params;
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
2881 + __s32 hw_busy; /* 1: hardware is busy,
2882 + * 0: hardware is not busy
2884 + __s32 src; /* # defined, can be either
2885 + * SD-RAM or CCDC/PREVIEWER
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.
2895 + __u32 vcrop; /* Number of lines cropped
2896 + * in output image.
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
2907 CMOS camera controller. This is the controller found on first-
2908 generation OLPC systems.
2911 +source "drivers/media/video/isp/Kconfig"
2914 tristate "OMAP 3 Camera support"