Merge changes If9b57167,Id088ae9d into msm-3.0
* changes:
Revert "Merge "Revert "ASoC: msm8960: Add module MBHC..."" into msm-3.0"
Revert "Merge "Revert "ASoC: wcd9310: Fix headset detect..."" into msm-3.0"
diff --git a/arch/arm/boot/dts/msmcopper.dtsi b/arch/arm/boot/dts/msmcopper.dtsi
index ca67181..284426a 100644
--- a/arch/arm/boot/dts/msmcopper.dtsi
+++ b/arch/arm/boot/dts/msmcopper.dtsi
@@ -72,7 +72,7 @@
reg = <0xf980b000 0x1000>;
interrupts = <0 123 0>;
- qcom,sdcc-clk-rates = <400000 24000000 48000000 96000000 192000000>;
+ qcom,sdcc-clk-rates = <400000 25000000 50000000 96000000 192000000>;
qcom,sdcc-sup-voltages = <3300 3300>;
qcom,sdcc-bus-width = <8>;
qcom,sdcc-hs200;
@@ -86,7 +86,7 @@
reg = <0xf984b000 0x1000>;
interrupts = <0 127 0>;
- qcom,sdcc-clk-rates = <400000 24000000 48000000>;
+ qcom,sdcc-clk-rates = <400000 25000000 50000000>;
qcom,sdcc-sup-voltages = <3300 3300>;
qcom,sdcc-bus-width = <4>;
qcom,sdcc-disable_cmd23;
diff --git a/arch/arm/configs/msm8660-perf_defconfig b/arch/arm/configs/msm8660-perf_defconfig
index 23b4668..a6bbaf4 100644
--- a/arch/arm/configs/msm8660-perf_defconfig
+++ b/arch/arm/configs/msm8660-perf_defconfig
@@ -346,8 +346,10 @@
CONFIG_FB_MSM_MDP40=y
CONFIG_FB_MSM_OVERLAY=y
CONFIG_FB_MSM_OVERLAY0_WRITEBACK=y
+CONFIG_FB_MSM_OVERLAY1_WRITEBACK=y
CONFIG_FB_MSM_LCDC_MIPI_PANEL_AUTO_DETECT=y
CONFIG_FB_MSM_HDMI_MSM_PANEL=y
+CONFIG_FB_MSM_WRITEBACK_MSM_PANEL=y
CONFIG_BACKLIGHT_LCD_SUPPORT=y
CONFIG_BACKLIGHT_CLASS_DEVICE=y
CONFIG_SOUND=y
diff --git a/arch/arm/configs/msm8660_defconfig b/arch/arm/configs/msm8660_defconfig
index fddd385..df49bdc 100644
--- a/arch/arm/configs/msm8660_defconfig
+++ b/arch/arm/configs/msm8660_defconfig
@@ -347,8 +347,10 @@
CONFIG_FB_MSM_MDP40=y
CONFIG_FB_MSM_OVERLAY=y
CONFIG_FB_MSM_OVERLAY0_WRITEBACK=y
+CONFIG_FB_MSM_OVERLAY1_WRITEBACK=y
CONFIG_FB_MSM_LCDC_MIPI_PANEL_AUTO_DETECT=y
CONFIG_FB_MSM_HDMI_MSM_PANEL=y
+CONFIG_FB_MSM_WRITEBACK_MSM_PANEL=y
CONFIG_BACKLIGHT_LCD_SUPPORT=y
CONFIG_BACKLIGHT_CLASS_DEVICE=y
CONFIG_SOUND=y
diff --git a/arch/arm/mach-msm/include/mach/board.h b/arch/arm/mach-msm/include/mach/board.h
index f39336d..36cdd86 100644
--- a/arch/arm/mach-msm/include/mach/board.h
+++ b/arch/arm/mach-msm/include/mach/board.h
@@ -504,6 +504,12 @@
#endif
};
+struct vcap_platform_data {
+ unsigned *gpios;
+ int num_gpios;
+ struct msm_bus_scale_pdata *bus_client_pdata;
+};
+
#if defined(CONFIG_USB_PEHCI_HCD) || defined(CONFIG_USB_PEHCI_HCD_MODULE)
struct isp1763_platform_data {
unsigned reset_gpio;
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index b3b2b52..2e422c4 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -358,8 +358,6 @@
membank0_size = meminfo.bank[0].size;
membank1_start = meminfo.bank[1].start;
-
- pr_info("m0 size %lx m1 start %lx\n", membank0_size, membank1_start);
}
#endif
diff --git a/drivers/gpu/msm/adreno_snapshot.c b/drivers/gpu/msm/adreno_snapshot.c
index e8cb734..2dc6f6c 100644
--- a/drivers/gpu/msm/adreno_snapshot.c
+++ b/drivers/gpu/msm/adreno_snapshot.c
@@ -454,33 +454,36 @@
static void ib_add_gpu_object(struct kgsl_device *device, unsigned int ptbase,
unsigned int gpuaddr, unsigned int dwords)
{
- int i = 0, ret;
+ int i, ret, rem = dwords;
unsigned int *src = (unsigned int *) adreno_convertaddr(device, ptbase,
gpuaddr, dwords << 2);
if (src == NULL)
return;
- while (i < dwords) {
+ for (i = 0; rem != 0; rem--, i++) {
+ int pktsize;
+
+ if (!pkt_is_type0(src[i]) && !pkt_is_type3(src[i]))
+ continue;
+
+ pktsize = type3_pkt_size(src[i]);
+
+ if ((pktsize + 1) > rem)
+ break;
if (pkt_is_type3(src[i])) {
- if ((dwords - i) < type3_pkt_size(src[i]) + 1)
- goto skip;
-
if (adreno_cmd_is_ib(src[i]))
ib_add_gpu_object(device, ptbase,
src[i + 1], src[i + 2]);
else
ib_parse_type3(device, &src[i], ptbase);
-
- i += type3_pkt_size(src[i]);
} else if (pkt_is_type0(src[i])) {
ib_parse_type0(device, &src[i], ptbase);
- i += type0_pkt_size(src[i]);
}
-skip:
- i++;
+ i += pktsize;
+ rem -= pktsize;
}
ret = kgsl_snapshot_get_object(device, ptbase, gpuaddr, dwords << 2,
@@ -571,7 +574,7 @@
while (index != rb->wptr) {
index--;
- if (index < 0) {
+ if (index < 0) {
index = rb->sizedwords - 2;
/*
@@ -587,7 +590,8 @@
}
/* Break if the current packet is a context switch identifier */
- if (adreno_rb_ctxtswitch(&rbptr[index]))
+ if ((rbptr[index] == cp_nop_packet(1)) &&
+ (rbptr[index + 1] == KGSL_CONTEXT_TO_MEM_IDENTIFIER))
break;
}
diff --git a/drivers/gpu/msm/kgsl.h b/drivers/gpu/msm/kgsl.h
index 5f3d2d0..5212d0f 100644
--- a/drivers/gpu/msm/kgsl.h
+++ b/drivers/gpu/msm/kgsl.h
@@ -208,17 +208,25 @@
}
return 0;
}
+
+static inline void *kgsl_memdesc_map(struct kgsl_memdesc *memdesc)
+{
+ if (memdesc->hostptr == NULL && memdesc->ops->map_kernel_mem)
+ memdesc->ops->map_kernel_mem(memdesc);
+
+ return memdesc->hostptr;
+}
+
static inline uint8_t *kgsl_gpuaddr_to_vaddr(struct kgsl_memdesc *memdesc,
unsigned int gpuaddr)
{
- if (memdesc->gpuaddr == 0 ||
- gpuaddr < memdesc->gpuaddr ||
- gpuaddr >= (memdesc->gpuaddr + memdesc->size) ||
- (NULL == memdesc->hostptr && memdesc->ops->map_kernel_mem &&
- memdesc->ops->map_kernel_mem(memdesc)))
- return NULL;
+ void *hostptr = NULL;
- return memdesc->hostptr + (gpuaddr - memdesc->gpuaddr);
+ if ((gpuaddr >= memdesc->gpuaddr) &&
+ (gpuaddr < (memdesc->gpuaddr + memdesc->size)))
+ hostptr = kgsl_memdesc_map(memdesc);
+
+ return hostptr != NULL ? hostptr + (gpuaddr - memdesc->gpuaddr) : NULL;
}
static inline int timestamp_cmp(unsigned int new, unsigned int old)
diff --git a/drivers/gpu/msm/kgsl_snapshot.c b/drivers/gpu/msm/kgsl_snapshot.c
index 553dc60..3efafee 100644
--- a/drivers/gpu/msm/kgsl_snapshot.c
+++ b/drivers/gpu/msm/kgsl_snapshot.c
@@ -334,6 +334,12 @@
}
}
+ if (kgsl_memdesc_map(&entry->memdesc) == NULL) {
+ KGSL_DRV_ERR(device, "Unable to map GPU buffer %X\n",
+ gpuaddr);
+ return 0;
+ }
+
obj = kzalloc(sizeof(*obj), GFP_KERNEL);
if (obj == NULL) {
diff --git a/drivers/media/radio/radio-tavarua.c b/drivers/media/radio/radio-tavarua.c
index 212e5d5..741c3a1 100644
--- a/drivers/media/radio/radio-tavarua.c
+++ b/drivers/media/radio/radio-tavarua.c
@@ -1465,6 +1465,7 @@
xfr_buf[1] = GET_ABS_VAL(band_low);
xfr_buf[2] = RSH_DATA(band_high, 8);
xfr_buf[3] = GET_ABS_VAL(band_high);
+ xfr_buf[4] = 0; /* Active LOW */
retval = sync_write_xfr(radio, RADIO_CONFIG, xfr_buf);
if (retval < 0) {
FMDERR("Could not set regional settings\n");
@@ -3037,8 +3038,8 @@
} else if (ctrl->value == FM_ANALOG_PATH) {
FMDBG("Analog audio path enabled ...\n");
retval = tavarua_set_audio_path(
- TAVARUA_AUDIO_OUT_ANALOG_ON,
- TAVARUA_AUDIO_OUT_DIGITAL_OFF);
+ TAVARUA_AUDIO_OUT_DIGITAL_OFF,
+ TAVARUA_AUDIO_OUT_ANALOG_ON);
if (retval < 0) {
FMDERR("Error in tavarua_set_audio_path"
" %d\n", retval);
@@ -3891,10 +3892,27 @@
{
struct tavarua_device *radio = private_data;
int rx_on = radio->registers[RDCTRL] & FM_RECV;
+ int retval = 0;
if (!radio)
return -ENOMEM;
/* RX */
FMDBG("%s: digital: %d analog: %d\n", __func__, digital_on, analog_on);
+ if ((radio->pdata != NULL) && (radio->pdata->config_i2s_gpio != NULL)) {
+ if (digital_on) {
+ retval = radio->pdata->config_i2s_gpio(FM_I2S_ON);
+ if (retval) {
+ pr_err("%s: config_i2s_gpio failed\n",
+ __func__);
+ }
+ } else {
+ retval = radio->pdata->config_i2s_gpio(FM_I2S_OFF);
+ if (retval) {
+ pr_err("%s: config_i2s_gpio failed\n",
+ __func__);
+ }
+ }
+ }
+
SET_REG_FIELD(radio->registers[AUDIOCTRL],
((rx_on && analog_on) ? 1 : 0),
AUDIORX_ANALOG_OFFSET,
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index 95255fe..07a31a3 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -569,6 +569,14 @@
Say Y here if you want to test video apps or debug V4L devices.
In doubt, say N.
+config MSM_VCAP
+ tristate "Qualcomm MSM VCAP"
+ depends on VIDEO_DEV && VIDEO_V4L2
+ default n
+ ---help---
+ Enables VCAP driver. This device allows for video capture and
+ video processing using the v4l2 api
+
source "drivers/media/video/davinci/Kconfig"
source "drivers/media/video/omap/Kconfig"
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
index c4b240f..65a2348 100644
--- a/drivers/media/video/Makefile
+++ b/drivers/media/video/Makefile
@@ -156,6 +156,8 @@
obj-$(CONFIG_VIDEO_MEM2MEM_TESTDEV) += mem2mem_testdev.o
obj-$(CONFIG_VIDEO_CX23885) += cx23885/
+obj-$(CONFIG_MSM_VCAP) += vcap_v4l2.o
+obj-$(CONFIG_MSM_VCAP) += vcap_vc.o
obj-$(CONFIG_VIDEO_AK881X) += ak881x.o
obj-$(CONFIG_VIDEO_OMAP2) += omap2cam.o
diff --git a/drivers/media/video/vcap_v4l2.c b/drivers/media/video/vcap_v4l2.c
new file mode 100644
index 0000000..6443250
--- /dev/null
+++ b/drivers/media/video/vcap_v4l2.c
@@ -0,0 +1,908 @@
+/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/mutex.h>
+#include <linux/videodev2.h>
+#include <linux/platform_device.h>
+#include <linux/memory_alloc.h>
+
+#include <mach/msm_subsystem_map.h>
+#include <mach/board.h>
+#include <mach/gpio.h>
+#include <mach/irqs.h>
+
+#include <media/videobuf2-msm-mem.h>
+
+#include <media/videobuf2-vmalloc.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-fh.h>
+#include <media/v4l2-common.h>
+#include <linux/regulator/consumer.h>
+#include <mach/clk.h>
+#include <linux/clk.h>
+#include <linux/interrupt.h>
+#include <mach/msm_bus.h>
+#include <mach/msm_bus_board.h>
+
+#include <media/vcap_v4l2.h>
+#include <media/vcap_fmt.h>
+#include "vcap_vc.h"
+
+#define NUM_INPUTS 1
+#define MSM_VCAP_DRV_NAME "msm_vcap"
+
+static struct vcap_dev *vcap_ctrl;
+
+static unsigned debug;
+
+#define dprintk(level, fmt, arg...) \
+ do { \
+ if (debug >= level) \
+ printk(KERN_DEBUG "VCAP: " fmt, ## arg); \
+ } while (0)
+
+int get_phys_addr(struct vcap_dev *dev, struct vb2_queue *q,
+ struct v4l2_buffer *b)
+{
+ struct vb2_buffer *vb;
+ struct vcap_buffer *buf;
+ unsigned long len, offset;
+ int rc;
+
+ if (q->fileio) {
+ dprintk(1, "%s: file io in progress\n", __func__);
+ return -EBUSY;
+ }
+
+ if (b->type != q->type) {
+ dprintk(1, "%s: invalid buffer type\n", __func__);
+ return -EINVAL;
+ }
+
+ if (b->index >= q->num_buffers) {
+ dprintk(1, "%s: buffer index out of range\n", __func__);
+ return -EINVAL;
+ }
+
+ vb = q->bufs[b->index];
+ if (NULL == vb) {
+ dprintk(1, "%s: buffer is NULL\n", __func__);
+ return -EINVAL;
+ }
+
+ if (vb->state != VB2_BUF_STATE_DEQUEUED) {
+ dprintk(1, "%s: buffer already in use\n", __func__);
+ return -EINVAL;
+ }
+
+ buf = container_of(vb, struct vcap_buffer, vb);
+
+ buf->ion_handle = ion_import_fd(dev->ion_client, b->m.userptr);
+ if (IS_ERR((void *)buf->ion_handle)) {
+ pr_err("%s: Could not alloc memory\n", __func__);
+ buf->ion_handle = NULL;
+ return -ENOMEM;
+ }
+ rc = ion_phys(dev->ion_client, buf->ion_handle,
+ &buf->paddr, (size_t *)&len);
+ if (rc < 0) {
+ pr_err("%s: Could not get phys addr\n", __func__);
+ return -EFAULT;
+ }
+
+ offset = b->reserved;
+ buf->paddr += offset;
+ return 0;
+}
+
+void free_ion_handle_work(struct vcap_dev *dev, struct vb2_buffer *vb)
+{
+ struct vcap_buffer *buf;
+
+ buf = container_of(vb, struct vcap_buffer, vb);
+ if (buf->ion_handle == NULL) {
+ dprintk(1, "%s: no ION handle to free\n", __func__);
+ return;
+ }
+ buf->paddr = 0;
+ ion_free(dev->ion_client, buf->ion_handle);
+ buf->ion_handle = NULL;
+ return;
+}
+
+int free_ion_handle(struct vcap_dev *dev, struct vb2_queue *q,
+ struct v4l2_buffer *b)
+{
+ struct vb2_buffer *vb;
+
+ if (q->fileio)
+ return -EBUSY;
+
+ if (b->type != q->type)
+ return -EINVAL;
+
+ if (b->index >= q->num_buffers)
+ return -EINVAL;
+
+ vb = q->bufs[b->index];
+ if (NULL == vb)
+ return -EINVAL;
+
+ free_ion_handle_work(dev, vb);
+ return 0;
+}
+
+/* Videobuf operations */
+
+static int capture_queue_setup(struct vb2_queue *vq, unsigned int *nbuffers,
+ unsigned int *nplanes, unsigned long sizes[],
+ void *alloc_ctxs[])
+{
+ *nbuffers = 3;
+ *nplanes = 1;
+ return 0;
+}
+
+static int capture_buffer_init(struct vb2_buffer *vb)
+{
+ return 0;
+}
+
+static int capture_buffer_prepare(struct vb2_buffer *vb)
+{
+ return 0;
+}
+
+static void capture_buffer_queue(struct vb2_buffer *vb)
+{
+ struct vcap_client_data *c_data = vb2_get_drv_priv(vb->vb2_queue);
+ struct vcap_buffer *buf = container_of(vb, struct vcap_buffer, vb);
+ struct vcap_action *vid_vc_action = &c_data->vid_vc_action;
+ struct vb2_queue *q = vb->vb2_queue;
+ unsigned long flags = 0;
+
+ spin_lock_irqsave(&c_data->cap_slock, flags);
+ list_add_tail(&buf->list, &vid_vc_action->active);
+ spin_unlock_irqrestore(&c_data->cap_slock, flags);
+
+ if (atomic_read(&c_data->dev->vc_enabled) == 0) {
+
+ if (atomic_read(&q->queued_count) > 1)
+ if (vc_hw_kick_off(c_data) == 0)
+ atomic_set(&c_data->dev->vc_enabled, 1);
+ }
+}
+
+static int capture_start_streaming(struct vb2_queue *vq)
+{
+ struct vcap_client_data *c_data = vb2_get_drv_priv(vq);
+ dprintk(2, "VC start streaming\n");
+ return vc_start_capture(c_data);
+}
+
+static int capture_stop_streaming(struct vb2_queue *vq)
+{
+ struct vcap_client_data *c_data = vb2_get_drv_priv(vq);
+ struct vb2_buffer *vb;
+
+ vc_stop_capture(c_data);
+
+ while (!list_empty(&c_data->vid_vc_action.active)) {
+ struct vcap_buffer *buf;
+ buf = list_entry(c_data->vid_vc_action.active.next,
+ struct vcap_buffer, list);
+ list_del(&buf->list);
+ vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
+ }
+
+ /* clean ion handles */
+ list_for_each_entry(vb, &vq->queued_list, queued_entry)
+ free_ion_handle_work(c_data->dev, vb);
+ return 0;
+}
+
+static int capture_buffer_finish(struct vb2_buffer *vb)
+{
+ return 0;
+}
+
+static void capture_buffer_cleanup(struct vb2_buffer *vb)
+{
+}
+
+static struct vb2_ops capture_video_qops = {
+ .queue_setup = capture_queue_setup,
+ .buf_init = capture_buffer_init,
+ .buf_prepare = capture_buffer_prepare,
+ .buf_queue = capture_buffer_queue,
+ .start_streaming = capture_start_streaming,
+ .stop_streaming = capture_stop_streaming,
+ .buf_finish = capture_buffer_finish,
+ .buf_cleanup = capture_buffer_cleanup,
+};
+
+/* IOCTL vidioc handling */
+
+static int vidioc_querycap(struct file *file, void *priv,
+ struct v4l2_capability *cap)
+{
+ struct vcap_dev *dev = video_drvdata(file);
+
+ strlcpy(cap->driver, MSM_VCAP_DRV_NAME, sizeof(cap->driver));
+ strlcpy(cap->card, MSM_VCAP_DRV_NAME, sizeof(cap->card));
+ strlcpy(cap->bus_info, dev->v4l2_dev.name, sizeof(cap->bus_info));
+ cap->version = 0x10000000;
+ cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
+ return 0;
+}
+
+static int vidioc_enum_input(struct file *file, void *priv,
+ struct v4l2_input *inp)
+{
+ if (inp->index >= NUM_INPUTS)
+ return -EINVAL;
+ return 0;
+}
+
+static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
+ struct v4l2_format *f)
+{
+ return 0;
+}
+
+static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
+ struct v4l2_format *f)
+{
+ return 0;
+}
+
+static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
+ struct v4l2_format *f)
+{
+ int size;
+#ifdef NEW_S_FMT
+ struct v4l2_format_vc_ext *vc_format;
+#endif
+ struct vcap_client_data *c_data = file->private_data;
+
+ switch (f->type) {
+ case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+#ifdef NEW_S_FMT
+ vc_format = (struct v4l2_format_vc_ext *) f->fmt.raw_data;
+ c_data->vc_format = *vc_format;
+#else
+ c_data->vc_format =
+ vcap_vc_lut[f->fmt.pix.priv];
+#endif
+
+ config_vc_format(c_data);
+
+ size = (c_data->vc_format.hactive_end -
+ c_data->vc_format.hactive_start);
+
+ if (c_data->vc_format.color_space)
+ size *= 3;
+ else
+ size *= 2;
+
+#ifndef NEW_S_FMT
+ f->fmt.pix.bytesperline = size;
+ size *= (c_data->vc_format.vactive_end -
+ c_data->vc_format.vactive_start);
+ f->fmt.pix.sizeimage = size;
+#endif
+ vcap_ctrl->vc_client = c_data;
+ break;
+ case V4L2_BUF_TYPE_INTERLACED_IN_DECODER:
+ c_data->vp_buf_type_field = V4L2_BUF_TYPE_INTERLACED_IN_DECODER;
+ c_data->vp_format.field = f->fmt.pix.field;
+ c_data->vp_format.height = f->fmt.pix.height;
+ c_data->vp_format.width = f->fmt.pix.width;
+ c_data->vp_format.pixelformat = f->fmt.pix.pixelformat;
+ break;
+ case V4L2_BUF_TYPE_INTERLACED_IN_AFE:
+ break;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+static int vidioc_reqbufs(struct file *file, void *priv,
+ struct v4l2_requestbuffers *rb)
+{
+ struct vcap_client_data *c_data = file->private_data;
+ switch (rb->type) {
+ case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+ return vb2_reqbufs(&c_data->vc_vidq, rb);
+ default:
+ pr_err("VCAP Error: %s: Unknown buffer type\n", __func__);
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int vidioc_querybuf(struct file *file, void *priv, struct v4l2_buffer *p)
+{
+ struct vcap_client_data *c_data = file->private_data;
+
+ switch (p->type) {
+ case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+ return vb2_querybuf(&c_data->vc_vidq, p);
+ default:
+ pr_err("VCAP Error: %s: Unknown buffer type\n", __func__);
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *p)
+{
+ struct vcap_client_data *c_data = file->private_data;
+ int rc;
+
+ switch (p->type) {
+ case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+ if (get_phys_addr(c_data->dev, &c_data->vc_vidq, p))
+ return -EINVAL;
+ rc = vb2_qbuf(&c_data->vc_vidq, p);
+ if (rc < 0)
+ free_ion_handle(c_data->dev, &c_data->vc_vidq, p);
+ return rc;
+ default:
+ pr_err("VCAP Error: %s: Unknown buffer type\n", __func__);
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
+{
+ struct vcap_client_data *c_data = file->private_data;
+ int rc;
+
+ switch (p->type) {
+ case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+ rc = vb2_dqbuf(&c_data->vc_vidq, p, file->f_flags & O_NONBLOCK);
+ if (rc < 0)
+ return rc;
+ return free_ion_handle(c_data->dev, &c_data->vc_vidq, p);
+ default:
+ pr_err("VCAP Error: %s: Unknown buffer type", __func__);
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
+{
+ struct vcap_client_data *c_data = file->private_data;
+
+ switch (i) {
+ case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+ return vb2_streamon(&c_data->vc_vidq, i);
+ default:
+ pr_err("VCAP Error: %s: Unknown buffer type", __func__);
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
+{
+ struct vcap_client_data *c_data = file->private_data;
+ int rc;
+
+ switch (i) {
+ case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+ rc = vb2_streamoff(&c_data->vc_vidq, i);
+ if (rc >= 0)
+ atomic_set(&c_data->dev->vc_enabled, 0);
+ return rc;
+ default:
+ pr_err("VCAP Error: %s: Unknown buffer type", __func__);
+ break;
+ }
+ return 0;
+}
+
+/* VCAP fops */
+
+static void *vcap_ops_get_userptr(void *alloc_ctx, unsigned long vaddr,
+ unsigned long size, int write)
+{
+ struct vcap_buf_info *mem;
+ mem = kzalloc(sizeof(*mem), GFP_KERNEL);
+ if (!mem)
+ return ERR_PTR(-ENOMEM);
+ mem->vaddr = vaddr;
+ mem->size = size;
+ return mem;
+}
+
+static void vcap_ops_put_userptr(void *buf_priv)
+{
+ kfree(buf_priv);
+}
+
+const struct vb2_mem_ops vcap_mem_ops = {
+ .get_userptr = vcap_ops_get_userptr,
+ .put_userptr = vcap_ops_put_userptr,
+};
+
+static int vcap_open(struct file *file)
+{
+ struct vcap_dev *dev = video_drvdata(file);
+ struct vcap_client_data *c_data;
+ struct vb2_queue *q;
+ int ret;
+ c_data = kzalloc(sizeof(*c_data), GFP_KERNEL);
+ if (!dev)
+ return -ENOMEM;
+
+ c_data->dev = dev;
+
+ spin_lock_init(&c_data->cap_slock);
+
+ /* initialize queue */
+ q = &c_data->vc_vidq;
+ memset(q, 0, sizeof(c_data->vc_vidq));
+ q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ q->io_modes = VB2_USERPTR;
+ q->drv_priv = c_data;
+ q->buf_struct_size = sizeof(struct vcap_buffer);
+ q->ops = &capture_video_qops;
+ q->mem_ops = &vcap_mem_ops;
+
+ ret = vb2_queue_init(q);
+ if (ret < 0)
+ goto open_failed;
+
+ INIT_LIST_HEAD(&c_data->vid_vc_action.active);
+ file->private_data = c_data;
+
+ return 0;
+
+open_failed:
+ kfree(c_data);
+ return ret;
+}
+
+static int vcap_close(struct file *file)
+{
+ struct vcap_client_data *c_data = file->private_data;
+ vb2_queue_release(&c_data->vc_vidq);
+ c_data->dev->vc_client = NULL;
+ c_data->dev->vp_client = NULL;
+ kfree(c_data);
+ return 0;
+}
+
+static unsigned int vcap_poll(struct file *file,
+ struct poll_table_struct *wait)
+{
+ struct vcap_client_data *c_data = file->private_data;
+ struct vb2_queue *q = &c_data->vc_vidq;
+
+ return vb2_poll(q, file, wait);
+}
+/* V4L2 and video device structures */
+
+static const struct v4l2_file_operations vcap_fops = {
+ .owner = THIS_MODULE,
+ .open = vcap_open,
+ .release = vcap_close,
+ .poll = vcap_poll,
+ .unlocked_ioctl = video_ioctl2, /* V4L2 ioctl handler */
+};
+
+static const struct v4l2_ioctl_ops vcap_ioctl_ops = {
+ .vidioc_querycap = vidioc_querycap,
+ .vidioc_enum_input = vidioc_enum_input,
+ .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
+ .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
+ .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
+ .vidioc_reqbufs = vidioc_reqbufs,
+ .vidioc_querybuf = vidioc_querybuf,
+ .vidioc_qbuf = vidioc_qbuf,
+ .vidioc_dqbuf = vidioc_dqbuf,
+ .vidioc_streamon = vidioc_streamon,
+ .vidioc_streamoff = vidioc_streamoff,
+};
+
+static struct video_device vcap_template = {
+ .name = "vcap",
+ .fops = &vcap_fops,
+ .ioctl_ops = &vcap_ioctl_ops,
+ .release = video_device_release,
+};
+
+int vcap_reg_powerup(struct vcap_dev *dev)
+{
+ dev->fs_vcap = regulator_get(NULL, "fs_vcap");
+ if (IS_ERR(dev->fs_vcap)) {
+ pr_err("%s: Regulator FS_VCAP get failed %ld\n", __func__,
+ PTR_ERR(dev->fs_vcap));
+ dev->fs_vcap = NULL;
+ return -EINVAL;
+ } else if (regulator_enable(dev->fs_vcap)) {
+ pr_err("%s: Regulator FS_VCAP enable failed\n", __func__);
+ regulator_put(dev->fs_vcap);
+ return -EINVAL;
+ }
+ return 0;
+}
+
+void vcap_reg_powerdown(struct vcap_dev *dev)
+{
+ if (dev->fs_vcap == NULL)
+ return;
+ regulator_disable(dev->fs_vcap);
+ regulator_put(dev->fs_vcap);
+ dev->fs_vcap = NULL;
+ return;
+}
+
+int config_gpios(int on, struct vcap_platform_data *pdata)
+{
+ int i, ret;
+ int num_gpios = pdata->num_gpios;
+ unsigned *gpios = pdata->gpios;
+
+ if (on) {
+ for (i = 0; i < num_gpios; i++) {
+ ret = gpio_request(gpios[i], "vcap:vc");
+ if (ret) {
+ pr_err("VCAP: failed at GPIO %d to request\n",
+ gpios[i]);
+ goto gpio_failed;
+ }
+ ret = gpio_direction_input(gpios[i]);
+ if (ret) {
+ pr_err("VCAP: failed at GPIO %d to set to input\n",
+ gpios[i]);
+ i++;
+ goto gpio_failed;
+ }
+ }
+ } else {
+ for (i = 0; i < num_gpios; i++)
+ gpio_free(gpios[i]);
+ }
+ dprintk(2, "GPIO config done\n");
+ return 0;
+gpio_failed:
+ for (i--; i >= 0; i--)
+ gpio_free(gpios[i]);
+ return -EINVAL;
+}
+
+int vcap_clk_powerup(struct vcap_dev *dev, struct device *ddev)
+{
+ int ret = 0;
+
+ dev->vcap_clk = clk_get(ddev, "core_clk");
+ if (IS_ERR(dev->vcap_clk)) {
+ dev->vcap_clk = NULL;
+ pr_err("%s: Could not clk_get core_clk\n", __func__);
+ clk_put(dev->vcap_clk);
+ dev->vcap_clk = NULL;
+ return -EINVAL;
+ }
+
+ clk_prepare(dev->vcap_clk);
+ ret = clk_enable(dev->vcap_clk);
+ if (ret) {
+ pr_err("%s: Failed core clk_enable %d\n", __func__, ret);
+ goto fail_vcap_clk_unprep;
+ }
+
+ clk_set_rate(dev->vcap_clk, 160000000);
+ if (ret) {
+ pr_err("%s: Failed core set_rate %d\n", __func__, ret);
+ goto fail_vcap_clk;
+ }
+
+ dev->vcap_npl_clk = clk_get(ddev, "vcap_npl_clk");
+ if (IS_ERR(dev->vcap_npl_clk)) {
+ dev->vcap_npl_clk = NULL;
+ pr_err("%s: Could not clk_get npl\n", __func__);
+ clk_put(dev->vcap_npl_clk);
+ dev->vcap_npl_clk = NULL;
+ goto fail_vcap_clk;
+ }
+
+ clk_prepare(dev->vcap_npl_clk);
+ ret = clk_enable(dev->vcap_npl_clk);
+ if (ret) {
+ pr_err("%s:Failed npl clk_enable %d\n", __func__, ret);
+ goto fail_vcap_npl_clk_unprep;
+ }
+
+ dev->vcap_p_clk = clk_get(ddev, "iface_clk");
+ if (IS_ERR(dev->vcap_p_clk)) {
+ dev->vcap_p_clk = NULL;
+ pr_err("%s: Could not clk_get pix(AHB)\n", __func__);
+ clk_put(dev->vcap_p_clk);
+ dev->vcap_p_clk = NULL;
+ goto fail_vcap_npl_clk;
+ }
+
+ clk_prepare(dev->vcap_p_clk);
+ ret = clk_enable(dev->vcap_p_clk);
+ if (ret) {
+ pr_err("%s: Failed pix(AHB) clk_enable %d\n", __func__, ret);
+ goto fail_vcap_p_clk_unprep;
+ }
+ return 0;
+
+fail_vcap_p_clk_unprep:
+ clk_unprepare(dev->vcap_p_clk);
+ clk_put(dev->vcap_p_clk);
+ dev->vcap_p_clk = NULL;
+
+fail_vcap_npl_clk:
+ clk_disable(dev->vcap_npl_clk);
+fail_vcap_npl_clk_unprep:
+ clk_unprepare(dev->vcap_npl_clk);
+ clk_put(dev->vcap_npl_clk);
+ dev->vcap_npl_clk = NULL;
+
+fail_vcap_clk:
+ clk_disable(dev->vcap_clk);
+fail_vcap_clk_unprep:
+ clk_unprepare(dev->vcap_clk);
+ clk_put(dev->vcap_clk);
+ dev->vcap_clk = NULL;
+ return -EINVAL;
+}
+
+void vcap_clk_powerdown(struct vcap_dev *dev)
+{
+ if (dev->vcap_p_clk != NULL) {
+ clk_disable(dev->vcap_p_clk);
+ clk_unprepare(dev->vcap_p_clk);
+ clk_put(dev->vcap_p_clk);
+ dev->vcap_p_clk = NULL;
+ }
+
+ if (dev->vcap_npl_clk != NULL) {
+ clk_disable(dev->vcap_npl_clk);
+ clk_unprepare(dev->vcap_npl_clk);
+ clk_put(dev->vcap_npl_clk);
+ dev->vcap_npl_clk = NULL;
+ }
+
+ if (dev->vcap_clk != NULL) {
+ clk_disable(dev->vcap_clk);
+ clk_unprepare(dev->vcap_clk);
+ clk_put(dev->vcap_clk);
+ dev->vcap_clk = NULL;
+ }
+}
+
+int vcap_get_bus_client_handle(struct vcap_dev *dev)
+{
+ struct msm_bus_scale_pdata *vcap_axi_client_pdata =
+ dev->vcap_pdata->bus_client_pdata;
+ dev->bus_client_handle =
+ msm_bus_scale_register_client(vcap_axi_client_pdata);
+
+ return 0;
+}
+
+int vcap_enable(struct vcap_dev *dev, struct device *ddev)
+{
+ int rc;
+
+ rc = vcap_reg_powerup(dev);
+ if (rc < 0)
+ goto reg_failed;
+ rc = vcap_clk_powerup(dev, ddev);
+ if (rc < 0)
+ goto clk_failed;
+ rc = vcap_get_bus_client_handle(dev);
+ if (rc < 0)
+ goto bus_r_failed;
+ config_gpios(1, dev->vcap_pdata);
+ if (rc < 0)
+ goto gpio_failed;
+ return 0;
+
+gpio_failed:
+ msm_bus_scale_unregister_client(dev->bus_client_handle);
+ dev->bus_client_handle = 0;
+bus_r_failed:
+ vcap_clk_powerdown(dev);
+clk_failed:
+ vcap_reg_powerdown(dev);
+reg_failed:
+ return rc;
+}
+
+int vcap_disable(struct vcap_dev *dev)
+{
+ config_gpios(0, dev->vcap_pdata);
+
+ msm_bus_scale_unregister_client(dev->bus_client_handle);
+ dev->bus_client_handle = 0;
+ vcap_clk_powerdown(dev);
+ vcap_reg_powerdown(dev);
+ return 0;
+}
+
+static irqreturn_t vcap_vc_handler(int irq_num, void *data)
+{
+ return vc_handler(vcap_ctrl);
+}
+
+static int __devinit vcap_probe(struct platform_device *pdev)
+{
+ struct vcap_dev *dev;
+ struct video_device *vfd;
+ int ret;
+
+ dprintk(1, "Probe started\n");
+ dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+ if (!dev)
+ return -ENOMEM;
+ vcap_ctrl = dev;
+ dev->vcap_pdata = pdev->dev.platform_data;
+
+ dev->vcapmem = platform_get_resource_byname(pdev,
+ IORESOURCE_MEM, "vcap");
+ if (!dev->vcapmem) {
+ pr_err("VCAP: %s: no mem resource?\n", __func__);
+ ret = -ENODEV;
+ goto free_dev;
+ }
+
+ dev->vcapio = request_mem_region(dev->vcapmem->start,
+ resource_size(dev->vcapmem), pdev->name);
+ if (!dev->vcapio) {
+ pr_err("VCAP: %s: no valid mem region\n", __func__);
+ ret = -EBUSY;
+ goto free_dev;
+ }
+
+ dev->vcapbase = ioremap(dev->vcapmem->start,
+ resource_size(dev->vcapmem));
+ if (!dev->vcapbase) {
+ ret = -ENOMEM;
+ pr_err("VCAP: %s: vcap ioremap failed\n", __func__);
+ goto free_resource;
+ }
+
+ dev->vcapirq = platform_get_resource_byname(pdev,
+ IORESOURCE_IRQ, "vcap");
+ if (!dev->vcapirq) {
+ pr_err("%s: no irq resource?\n", __func__);
+ ret = -ENODEV;
+ goto free_resource;
+ }
+
+ ret = request_irq(dev->vcapirq->start, vcap_vc_handler,
+ IRQF_TRIGGER_RISING, "vcap", 0);
+ if (ret < 0) {
+ pr_err("%s: irq request fail\n", __func__);
+ ret = -EBUSY;
+ goto free_resource;
+ }
+
+ disable_irq(dev->vcapirq->start);
+
+ snprintf(dev->v4l2_dev.name, sizeof(dev->v4l2_dev.name),
+ "%s", MSM_VCAP_DRV_NAME);
+ ret = v4l2_device_register(NULL, &dev->v4l2_dev);
+ if (ret)
+ goto free_resource;
+
+ ret = vcap_enable(dev, &pdev->dev);
+ if (ret)
+ goto unreg_dev;
+ msm_bus_scale_client_update_request(dev->bus_client_handle, 3);
+
+ ret = detect_vc(dev);
+
+ if (ret)
+ goto power_down;
+
+ /* init video device*/
+ vfd = video_device_alloc();
+ if (!vfd)
+ goto deinit_vc;
+
+ *vfd = vcap_template;
+ vfd->v4l2_dev = &dev->v4l2_dev;
+
+ ret = video_register_device(vfd, VFL_TYPE_GRABBER, -1);
+ if (ret < 0)
+ goto rel_vdev;
+
+ dev->vfd = vfd;
+ video_set_drvdata(vfd, dev);
+
+ dev->ion_client = msm_ion_client_create(-1, "vcap");
+ if (IS_ERR((void *)dev->ion_client)) {
+ pr_err("could not get ion client");
+ goto rel_vdev;
+ }
+
+ atomic_set(&dev->vc_enabled, 0);
+
+ dprintk(1, "Exit probe succesfully");
+ return 0;
+
+rel_vdev:
+ video_device_release(vfd);
+deinit_vc:
+ deinit_vc();
+power_down:
+ vcap_disable(dev);
+unreg_dev:
+ v4l2_device_unregister(&dev->v4l2_dev);
+free_resource:
+ iounmap(dev->vcapbase);
+ release_mem_region(dev->vcapmem->start, resource_size(dev->vcapmem));
+free_dev:
+ vcap_ctrl = NULL;
+ kfree(dev);
+ return ret;
+}
+
+static int __devexit vcap_remove(struct platform_device *pdev)
+{
+ struct vcap_dev *dev = vcap_ctrl;
+ ion_client_destroy(dev->ion_client);
+ video_device_release(dev->vfd);
+ deinit_vc();
+ vcap_disable(dev);
+ v4l2_device_unregister(&dev->v4l2_dev);
+ iounmap(dev->vcapbase);
+ release_mem_region(dev->vcapmem->start, resource_size(dev->vcapmem));
+ vcap_ctrl = NULL;
+ kfree(dev);
+
+ return 0;
+}
+
+struct platform_driver vcap_platform_driver = {
+ .driver = {
+ .name = MSM_VCAP_DRV_NAME,
+ .owner = THIS_MODULE,
+ },
+ .probe = vcap_probe,
+ .remove = vcap_remove,
+};
+
+static int __init vcap_init_module(void)
+{
+ return platform_driver_register(&vcap_platform_driver);
+}
+
+static void __exit vcap_exit_module(void)
+{
+ platform_driver_unregister(&vcap_platform_driver);
+}
+
+module_init(vcap_init_module);
+module_exit(vcap_exit_module);
+MODULE_DESCRIPTION("VCAP driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/vcap_vc.c b/drivers/media/video/vcap_vc.c
new file mode 100644
index 0000000..ed0bc25
--- /dev/null
+++ b/drivers/media/video/vcap_vc.c
@@ -0,0 +1,715 @@
+/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/kthread.h>
+#include <linux/freezer.h>
+#include <mach/camera.h>
+#include <linux/io.h>
+#include <linux/regulator/consumer.h>
+#include <mach/clk.h>
+#include <linux/clk.h>
+
+#include <media/vcap_v4l2.h>
+#include <media/vcap_fmt.h>
+#include "vcap_vc.h"
+
+static unsigned debug;
+
+#define dprintk(level, fmt, arg...) \
+ do { \
+ if (debug >= level) \
+ printk(KERN_DEBUG "VC: " fmt, ## arg); \
+ } while (0)
+
+struct v4l2_format_vc_ext vcap_vc_lut[] = {
+ /* 1080p */
+ {
+ HAL_VCAP_YUV_1080p_60_RH, HAL_VCAP_MODE_PRO, HAL_VCAP_POLAR_POS,
+ HAL_VCAP_POLAR_POS, HAL_VCAP_POLAR_POS, HAL_VCAP_YUV, 148.5,
+ 32, 2200, 192, 2112, 4, 24, 0, 2, 0, 44, 0, 0, 0, 0,
+ 0, 0
+ },
+ {
+ HAL_VCAP_YUV_1080p_60_FL, HAL_VCAP_MODE_PRO, HAL_VCAP_POLAR_POS,
+ HAL_VCAP_POLAR_POS, HAL_VCAP_POLAR_POS, HAL_VCAP_YUV, 148.5,
+ 1125, 2200, 192, 2112, 41, 1121, 0, 5, 0, 44, 0, 0, 0,
+ 0, 0, 0
+ },
+ {
+ HAL_VCAP_RGB_1080p_60_FL, HAL_VCAP_MODE_PRO, HAL_VCAP_POLAR_POS,
+ HAL_VCAP_POLAR_POS, HAL_VCAP_POLAR_POS, HAL_VCAP_RGB, 148.5,
+ 1125, 2200, 192, 2112, 41, 1121, 0, 5, 0, 44, 0, 0, 0,
+ 0, 0, 0
+ },
+ {
+ HAL_VCAP_YUV_1080p_24_FL, HAL_VCAP_MODE_PRO, HAL_VCAP_POLAR_POS,
+ HAL_VCAP_POLAR_POS, HAL_VCAP_POLAR_POS, HAL_VCAP_YUV, 74.25,
+ 1125, 2750, 192, 2112, 41, 1121, 0, 5, 0, 44, 0, 0, 0,
+ 0, 0, 0
+ },
+ {
+ HAL_VCAP_YUV_1080p_24_RH, HAL_VCAP_MODE_PRO, HAL_VCAP_POLAR_POS,
+ HAL_VCAP_POLAR_POS, HAL_VCAP_POLAR_POS, HAL_VCAP_YUV, 74.25,
+ 112, 2750, 192, 2112, 4, 110, 0, 2, 0, 44, 0, 0, 0,
+ 0, 0, 0
+ },
+ {
+ HAL_VCAP_YUV_1080p_24_RW, HAL_VCAP_MODE_PRO, HAL_VCAP_POLAR_POS,
+ HAL_VCAP_POLAR_POS, HAL_VCAP_POLAR_POS, HAL_VCAP_YUV, 74.25,
+ 1125, 275, 19, 211, 41, 1121, 0, 5, 0, 16, 0, 0, 0,
+ 0, 0, 0
+ },
+ {
+ HAL_VCAP_YUV_1080p_60_RW, HAL_VCAP_MODE_PRO, HAL_VCAP_POLAR_POS,
+ HAL_VCAP_POLAR_POS, HAL_VCAP_POLAR_POS, HAL_VCAP_YUV, 148.5,
+ 1125, 200, 22, 182, 41, 1121, 0, 5, 0, 16, 0, 0, 0,
+ 0, 0, 0
+ },
+ {
+ HAL_VCAP_YUV_1080p_50_FL, HAL_VCAP_MODE_PRO, HAL_VCAP_POLAR_POS,
+ HAL_VCAP_POLAR_POS, HAL_VCAP_POLAR_POS, HAL_VCAP_YUV, 148.5,
+ 1125, 2640, 192, 2112, 41, 1121, 0, 5, 0, 44, 0, 0, 0,
+ 0, 0, 0
+ },
+ {
+ HAL_VCAP_YUV_1080p_50_RH, HAL_VCAP_MODE_PRO, HAL_VCAP_POLAR_POS,
+ HAL_VCAP_POLAR_POS, HAL_VCAP_POLAR_POS, HAL_VCAP_YUV, 148.5,
+ 15, 2640, 192, 2112, 6, 13, 0, 5, 0, 44, 0, 0, 0,
+ 0, 0, 0
+ },
+ {
+ HAL_VCAP_YUV_1080p_25_FL, HAL_VCAP_MODE_PRO, HAL_VCAP_POLAR_POS,
+ HAL_VCAP_POLAR_POS, HAL_VCAP_POLAR_POS, HAL_VCAP_YUV, 74.25,
+ 1125, 2640, 192, 2112, 41, 1121, 0, 5, 0, 44, 0, 0,
+ 0, 0, 0, 0
+ },
+ {
+ HAL_VCAP_YUV_1080p_25_RH, HAL_VCAP_MODE_PRO, HAL_VCAP_POLAR_POS,
+ HAL_VCAP_POLAR_POS, HAL_VCAP_POLAR_POS, HAL_VCAP_YUV, 74.25,
+ 10, 2640, 192, 2112, 4, 8, 0, 2, 0, 44, 0, 0, 0,
+ 0, 0, 0
+ },
+ {
+ HAL_VCAP_YUV_1080p_30_RH, HAL_VCAP_MODE_PRO, HAL_VCAP_POLAR_POS,
+ HAL_VCAP_POLAR_POS, HAL_VCAP_POLAR_POS, HAL_VCAP_YUV, 74.25,
+ 1125, 2200, 192, 2112, 41, 1121, 0, 5, 0, 44, 0, 0, 0,
+ 0, 0, 0
+ },
+ {
+ HAL_VCAP_RGB_1080p_25_FL, HAL_VCAP_MODE_PRO, HAL_VCAP_POLAR_POS,
+ HAL_VCAP_POLAR_POS, HAL_VCAP_POLAR_POS, HAL_VCAP_RGB, 74.25,
+ 1125, 2640, 192, 2112, 41, 1121, 0, 5, 0, 44, 0, 0, 0,
+ 0, 0, 0
+ },
+ {
+ HAL_VCAP_RGB_1080p_25_RH, HAL_VCAP_MODE_PRO, HAL_VCAP_POLAR_POS,
+ HAL_VCAP_POLAR_POS, HAL_VCAP_POLAR_POS, HAL_VCAP_RGB, 74.25,
+ 10, 2640, 192, 2112, 4, 8, 0, 2, 0, 44, 0, 0, 0,
+ 0, 0, 0
+ },
+ /* 1080i */
+ {
+ HAL_VCAP_YUV_1080i_60_FL, HAL_VCAP_MODE_INT, HAL_VCAP_POLAR_POS,
+ HAL_VCAP_POLAR_POS, HAL_VCAP_POLAR_POS, HAL_VCAP_YUV, 74.25,
+ 1125, 2200, 192, 2112, 20, 560, 0, 5, 0, 44, 583, 1123, 1100,
+ 1100, 563, 568
+ },
+ {
+ HAL_VCAP_YUV_1080i_60_RH, HAL_VCAP_MODE_INT, HAL_VCAP_POLAR_POS,
+ HAL_VCAP_POLAR_POS, HAL_VCAP_POLAR_POS, HAL_VCAP_YUV, 74.25,
+ 18, 2200, 192, 2112, 3, 7, 0, 2, 0, 44, 11, 15, 1100,
+ 1100, 8, 10
+ },
+ {
+ HAL_VCAP_YUV_1080i_60_RW, HAL_VCAP_MODE_INT, HAL_VCAP_POLAR_POS,
+ HAL_VCAP_POLAR_POS, HAL_VCAP_POLAR_POS, HAL_VCAP_YUV, 74.25,
+ 1125, 220, 19, 211, 20, 560, 0, 5, 0, 4, 583, 1123, 110,
+ 110, 563, 568
+ },
+ {
+ HAL_VCAP_YUV_1080i_50_FL, HAL_VCAP_MODE_INT, HAL_VCAP_POLAR_POS,
+ HAL_VCAP_POLAR_POS, HAL_VCAP_POLAR_POS, HAL_VCAP_YUV, 72.00,
+ 1125, 2640, 192, 2112, 20, 560, 0, 5, 0, 44, 583, 1123, 1320,
+ 1320, 563, 568
+ },
+ {
+ HAL_VCAP_YUV_1080i_50_RH, HAL_VCAP_MODE_INT, HAL_VCAP_POLAR_POS,
+ HAL_VCAP_POLAR_POS, HAL_VCAP_POLAR_POS, HAL_VCAP_YUV, 72.00,
+ 52, 2640, 192, 2112, 4, 24, 0, 2, 0, 44, 30, 50, 1320,
+ 1320, 26, 28},
+ {
+ HAL_VCAP_YUV_1080i_50_RW, HAL_VCAP_MODE_INT, HAL_VCAP_POLAR_POS,
+ HAL_VCAP_POLAR_POS, HAL_VCAP_POLAR_POS, HAL_VCAP_YUV, 72.00,
+ 1125, 264, 19, 211, 20, 560, 0, 5, 0, 4, 583, 1123, 110,
+ 110, 563, 568
+ },
+ {
+ HAL_VCAP_RGB_1080i_50_FL, HAL_VCAP_MODE_INT, HAL_VCAP_POLAR_POS,
+ HAL_VCAP_POLAR_POS, HAL_VCAP_POLAR_POS, HAL_VCAP_RGB, 72.00,
+ 1125, 2640, 192, 2112, 20, 560, 0, 5, 0, 44, 583, 1123, 1320,
+ 1320, 563, 568
+ },
+ {
+ HAL_VCAP_RGB_1080i_50_RH, HAL_VCAP_MODE_INT, HAL_VCAP_POLAR_POS,
+ HAL_VCAP_POLAR_POS, HAL_VCAP_POLAR_POS, HAL_VCAP_RGB, 72.00,
+ 52, 2640, 192, 2112, 4, 24, 0, 2, 0, 44, 30, 50, 1320,
+ 1320, 26, 28
+ },
+ /* 480i */
+ {
+ HAL_VCAP_YUV_480i_60_RH, HAL_VCAP_MODE_INT, HAL_VCAP_POLAR_NEG,
+ HAL_VCAP_POLAR_NEG, HAL_VCAP_POLAR_POS, HAL_VCAP_YUV, 27.027,
+ 20, 1716, 238, 1678, 3, 7, 0, 2, 0, 124, 14, 18, 820,
+ 820, 10, 12
+ },
+ {
+ HAL_VCAP_YUV_480i_60_FL, HAL_VCAP_MODE_INT, HAL_VCAP_POLAR_NEG,
+ HAL_VCAP_POLAR_NEG, HAL_VCAP_POLAR_POS, HAL_VCAP_YUV, 27.027,
+ 525, 1716, 238, 1678, 18, 258, 0, 3, 0, 124, 281, 521, 858,
+ 858, 262, 265
+ },
+ {
+ HAL_VCAP_YUV_480i_60_RW, HAL_VCAP_MODE_INT, HAL_VCAP_POLAR_NEG,
+ HAL_VCAP_POLAR_NEG, HAL_VCAP_POLAR_POS, HAL_VCAP_YUV, 27.027,
+ 525, 172, 24, 168, 18, 258, 0, 3, 0, 12, 281, 521, 86,
+ 86, 262, 265
+ },
+ {
+ HAL_VCAP_YUV_2880_480i_60_FL, HAL_VCAP_MODE_INT,
+ HAL_VCAP_POLAR_NEG, HAL_VCAP_POLAR_NEG, HAL_VCAP_POLAR_POS,
+ HAL_VCAP_YUV, 54.000, 525, 3432, 476, 3356, 18, 258, 0, 3,
+ 0, 248, 281, 521, 1716, 1716, 262, 265
+ },
+ {
+ HAL_VCAP_YUV_2880_480i_60_RH, HAL_VCAP_MODE_INT,
+ HAL_VCAP_POLAR_NEG, HAL_VCAP_POLAR_NEG, HAL_VCAP_POLAR_POS,
+ HAL_VCAP_YUV, 54.000, 32, 3432, 476, 3356, 4, 14, 0, 3, 0,
+ 248, 20, 30, 1716, 1716, 16, 19
+ },
+ /* 480p */
+ {
+ HAL_VCAP_YUV_480p_60_RH, HAL_VCAP_MODE_PRO, HAL_VCAP_POLAR_NEG,
+ HAL_VCAP_POLAR_NEG, HAL_VCAP_POLAR_POS, HAL_VCAP_YUV, 27.027,
+ 8, 858, 122, 842, 2, 5, 0, 1, 0, 62, 0, 0, 0,
+ 0, 0, 0
+ },
+ {
+ HAL_VCAP_RGB_480p_60_RH, HAL_VCAP_MODE_PRO, HAL_VCAP_POLAR_NEG,
+ HAL_VCAP_POLAR_NEG, HAL_VCAP_POLAR_POS, HAL_VCAP_RGB, 27.027,
+ 52, 858, 122, 842, 3, 50, 0, 2, 0, 62, 0, 0, 0,
+ 0, 0, 0
+ },
+ {
+ HAL_VCAP_RGB_480p_60_FL, HAL_VCAP_MODE_PRO, HAL_VCAP_POLAR_NEG,
+ HAL_VCAP_POLAR_NEG, HAL_VCAP_POLAR_POS, HAL_VCAP_RGB, 27.027,
+ 525, 858, 122, 842, 36, 516, 0, 6, 0, 62, 0, 0, 0,
+ 0, 0, 0
+ },
+ {
+ HAL_VCAP_YUV_480p_60_FL, HAL_VCAP_MODE_PRO, HAL_VCAP_POLAR_NEG,
+ HAL_VCAP_POLAR_NEG, HAL_VCAP_POLAR_POS, HAL_VCAP_YUV, 27.027,
+ 525, 858, 122, 842, 36, 516, 0, 6, 0, 62, 0, 0, 0, 0, 0, 0
+ },
+ {
+ HAL_VCAP_YUV_480p_60_RW, HAL_VCAP_MODE_PRO, HAL_VCAP_POLAR_NEG,
+ HAL_VCAP_POLAR_NEG, HAL_VCAP_POLAR_POS, HAL_VCAP_YUV, 27.027,
+ 525, 86, 12, 84, 36, 516, 0, 6, 0, 6, 0, 0, 0,
+ 0, 0, 0
+ },
+ {
+ HAL_VCAP_YUV_2880_480p_60_FL, HAL_VCAP_MODE_PRO,
+ HAL_VCAP_POLAR_NEG, HAL_VCAP_POLAR_NEG, HAL_VCAP_POLAR_POS,
+ HAL_VCAP_YUV, 108.000, 525, 3432, 488, 3368, 36, 516, 0, 6,
+ 0, 248, 0, 0, 0, 0, 0, 0
+ },
+ {
+ HAL_VCAP_YUV_2880_480p_60_RH, HAL_VCAP_MODE_PRO,
+ HAL_VCAP_POLAR_NEG, HAL_VCAP_POLAR_NEG, HAL_VCAP_POLAR_POS,
+ HAL_VCAP_YUV, 108.000, 25, 3432, 488, 3368, 8, 22, 0, 6, 0,
+ 248, 0, 0, 0, 0, 0, 0
+ },
+ /* 720p */
+ {
+ HAL_VCAP_YUV_720p_60_FL, HAL_VCAP_MODE_PRO, HAL_VCAP_POLAR_POS,
+ HAL_VCAP_POLAR_POS, HAL_VCAP_POLAR_POS, HAL_VCAP_YUV, 74.25,
+ 750, 1650, 260, 1540, 25, 745, 0, 5, 0, 40, 0, 0, 0,
+ 0, 0, 0
+ },
+ {
+ HAL_VCAP_RGB_720p_60_FL, HAL_VCAP_MODE_PRO, HAL_VCAP_POLAR_POS,
+ HAL_VCAP_POLAR_POS, HAL_VCAP_POLAR_POS, HAL_VCAP_RGB, 74.25,
+ 750, 1650, 260, 1540, 25, 745, 0, 5, 0, 40, 0, 0, 0,
+ 0, 0, 0
+ },
+ {
+ HAL_VCAP_YUV_720p_60_RW, HAL_VCAP_MODE_PRO, HAL_VCAP_POLAR_POS,
+ HAL_VCAP_POLAR_POS, HAL_VCAP_POLAR_POS, HAL_VCAP_YUV, 74.25,
+ 750, 165, 26, 154, 25, 745, 0, 5, 0, 4, 0, 0, 0,
+ 0, 0, 0
+ },
+ {
+ HAL_VCAP_YUV_720p_60_RH, HAL_VCAP_MODE_PRO, HAL_VCAP_POLAR_POS,
+ HAL_VCAP_POLAR_POS, HAL_VCAP_POLAR_POS, HAL_VCAP_YUV, 74.25,
+ 35, 1650, 260, 1540, 5, 32, 0, 3, 0, 40, 0, 0, 0,
+ 0, 0, 0
+ },
+ {
+ HAL_VCAP_YUV_720p_50_FL, HAL_VCAP_MODE_PRO, HAL_VCAP_POLAR_POS,
+ HAL_VCAP_POLAR_POS, HAL_VCAP_POLAR_POS, HAL_VCAP_YUV, 74.25,
+ 750, 1980, 260, 1540, 25, 745, 0, 5, 0, 40, 0, 0, 0,
+ 0, 0, 0
+ },
+ {
+ HAL_VCAP_YUV_720p_50_RW, HAL_VCAP_MODE_PRO, HAL_VCAP_POLAR_POS,
+ HAL_VCAP_POLAR_POS, HAL_VCAP_POLAR_POS, HAL_VCAP_YUV, 74.25,
+ 750, 198, 26, 154, 25, 745, 0, 5, 0, 4, 0, 0, 0,
+ 0, 0, 0
+ },
+ {
+ HAL_VCAP_YUV_720p_50_RH, HAL_VCAP_MODE_PRO, HAL_VCAP_POLAR_POS,
+ HAL_VCAP_POLAR_POS, HAL_VCAP_POLAR_POS, HAL_VCAP_YUV, 74.25,
+ 6, 1980, 260, 1540, 2, 5, 0, 1, 0, 40, 0, 0, 0,
+ 0, 0, 0
+ },
+ /* 576p */
+ {
+ HAL_VCAP_YUV_576p_50_FL, HAL_VCAP_MODE_PRO, HAL_VCAP_POLAR_NEG,
+ HAL_VCAP_POLAR_NEG, HAL_VCAP_POLAR_POS, HAL_VCAP_YUV, 27.0,
+ 625, 864, 132, 852, 44, 620, 0, 5, 0, 64, 0, 0, 0,
+ 0, 0, 0},
+ {
+ HAL_VCAP_RGB_576p_50_FL, HAL_VCAP_MODE_PRO, HAL_VCAP_POLAR_NEG,
+ HAL_VCAP_POLAR_NEG, HAL_VCAP_POLAR_POS, HAL_VCAP_RGB, 27.0,
+ 625, 864, 132, 852, 44, 620, 0, 5, 0, 64, 0, 0, 0,
+ 0, 0, 0
+ },
+ {
+ HAL_VCAP_YUV_576p_50_RW, HAL_VCAP_MODE_PRO, HAL_VCAP_POLAR_NEG,
+ HAL_VCAP_POLAR_NEG, HAL_VCAP_POLAR_POS, HAL_VCAP_YUV, 27.0,
+ 625, 86, 13, 85, 44, 620, 0, 5, 0, 6, 0, 0, 0,
+ 0, 0, 0
+ },
+ {
+ HAL_VCAP_YUV_576p_50_RH, HAL_VCAP_MODE_PRO, HAL_VCAP_POLAR_NEG,
+ HAL_VCAP_POLAR_NEG, HAL_VCAP_POLAR_POS, HAL_VCAP_YUV, 27.0,
+ 25, 864, 132, 852, 4, 23, 0, 3, 0, 64, 0, 0, 0,
+ 0, 0, 0
+ },
+ {
+ HAL_VCAP_YUV_1440_576p_50_RH, HAL_VCAP_MODE_PRO,
+ HAL_VCAP_POLAR_NEG, HAL_VCAP_POLAR_NEG, HAL_VCAP_POLAR_POS,
+ HAL_VCAP_YUV, 54.000, 25, 1728, 264, 1704, 6, 23, 0, 5, 0,
+ 128, 0, 0, 0, 0, 0, 0
+ },
+ {
+ HAL_VCAP_YUV_2880_576p_50_FL, HAL_VCAP_MODE_PRO,
+ HAL_VCAP_POLAR_NEG, HAL_VCAP_POLAR_NEG, HAL_VCAP_POLAR_POS,
+ HAL_VCAP_YUV, 108.000, 625, 3456, 528, 3408, 44, 620, 0, 5,
+ 0, 256, 0, 0, 0, 0, 0, 0
+ },
+ {
+ HAL_VCAP_YUV_2880_576p_50_RH, HAL_VCAP_MODE_PRO,
+ HAL_VCAP_POLAR_NEG, HAL_VCAP_POLAR_NEG, HAL_VCAP_POLAR_POS,
+ HAL_VCAP_YUV, 108.000, 25, 3456, 528, 3408, 6, 23, 0, 5, 0,
+ 256, 0, 0, 0, 0, 0, 0
+ },
+ /* 576i */
+ {
+ HAL_VCAP_YUV_576i_50_FL, HAL_VCAP_MODE_INT, HAL_VCAP_POLAR_NEG,
+ HAL_VCAP_POLAR_NEG, HAL_VCAP_POLAR_POS, HAL_VCAP_YUV, 27.0,
+ 625, 1728, 264, 1704, 22, 310, 0, 3, 0, 126, 335, 623, 864,
+ 864, 313, 316
+ },
+ {
+ HAL_VCAP_YUV_576i_50_RW, HAL_VCAP_MODE_INT, HAL_VCAP_POLAR_NEG,
+ HAL_VCAP_POLAR_NEG, HAL_VCAP_POLAR_POS, HAL_VCAP_YUV, 27.0,
+ 625, 172, 26, 170, 22, 310, 0, 3, 0, 13, 335, 623, 86,
+ 86, 313, 316
+ },
+ {
+ HAL_VCAP_YUV_576i_50_RH, HAL_VCAP_MODE_INT, HAL_VCAP_POLAR_NEG,
+ HAL_VCAP_POLAR_NEG, HAL_VCAP_POLAR_POS, HAL_VCAP_YUV, 27.0,
+ 29, 1728, 264, 1704, 3, 13, 0, 1, 0, 126, 16, 26, 864, 864,
+ 14, 15
+ },
+ /* XGA 1024x768 */
+ {
+ HAL_VCAP_YUV_XGA_FL, HAL_VCAP_MODE_PRO, HAL_VCAP_POLAR_POS,
+ HAL_VCAP_POLAR_POS, HAL_VCAP_POLAR_POS, HAL_VCAP_YUV, 63.5,
+ 798, 1328, 256, 1280, 27, 795, 0, 4, 0, 104, 0, 0, 0,
+ 0, 0, 0
+ },
+ {
+ HAL_VCAP_YUV_XGA_RH, HAL_VCAP_MODE_PRO, HAL_VCAP_POLAR_POS,
+ HAL_VCAP_POLAR_POS, HAL_VCAP_POLAR_POS, HAL_VCAP_YUV, 63.5,
+ 12, 1328, 256, 1280, 6, 10, 0, 4, 0, 104, 0, 0, 0, 0,
+ 0, 0
+ },
+ {
+ HAL_VCAP_YUV_XGA_RB, HAL_VCAP_MODE_PRO, HAL_VCAP_POLAR_POS,
+ HAL_VCAP_POLAR_POS, HAL_VCAP_POLAR_POS, HAL_VCAP_YUV, 63.5,
+ 12, 1216, 112, 1136, 6, 10, 0, 4, 0, 32, 0, 0, 0, 0,
+ 0, 0
+ },
+ /* SXGA 1280x1024 */
+ {
+ HAL_VCAP_YUV_SXGA_FL, HAL_VCAP_MODE_PRO, HAL_VCAP_POLAR_NEG,
+ HAL_VCAP_POLAR_POS, HAL_VCAP_POLAR_POS, HAL_VCAP_YUV, 109.0,
+ 1063, 1712, 352, 1632, 36, 1060, 0, 7, 0, 136, 0, 0, 0,
+ 0, 0, 0
+ },
+ {
+ HAL_VCAP_RGB_SXGA_FL, HAL_VCAP_MODE_PRO, HAL_VCAP_POLAR_NEG,
+ HAL_VCAP_POLAR_POS, HAL_VCAP_POLAR_POS, HAL_VCAP_RGB, 109.0,
+ 1063, 1712, 352, 1632, 36, 1060, 0, 7, 0, 136, 0, 0, 0,
+ 0, 0, 0
+ },
+ {
+ HAL_VCAP_YUV_SXGA_RH, HAL_VCAP_MODE_PRO, HAL_VCAP_POLAR_NEG,
+ HAL_VCAP_POLAR_POS, HAL_VCAP_POLAR_POS, HAL_VCAP_YUV, 109.0,
+ 17, 1712, 352, 1632, 8, 15, 0, 7, 0, 136, 0, 0, 0,
+ 0, 0, 0
+ },
+ {
+ HAL_VCAP_YUV_SXGA_RB, HAL_VCAP_MODE_PRO, HAL_VCAP_POLAR_NEG,
+ HAL_VCAP_POLAR_POS, HAL_VCAP_POLAR_POS, HAL_VCAP_YUV, 109.0,
+ 17, 1440, 112, 1392, 8, 15, 0, 7, 0, 32, 0, 0, 0, 0,
+ 0, 0
+ },
+ /* UXGA 1600x1200 */
+ {
+ HAL_VCAP_YUV_UXGA_FL, HAL_VCAP_MODE_PRO, HAL_VCAP_POLAR_NEG,
+ HAL_VCAP_POLAR_POS, HAL_VCAP_POLAR_POS, HAL_VCAP_YUV, 161.0,
+ 1245, 2160, 448, 2048, 42, 1242, 0, 4, 0, 168, 0,
+ 0, 0, 0, 0, 0
+ },
+ {
+ HAL_VCAP_RGB_UXGA_FL, HAL_VCAP_MODE_PRO, HAL_VCAP_POLAR_NEG,
+ HAL_VCAP_POLAR_POS, HAL_VCAP_POLAR_POS, HAL_VCAP_RGB, 161.0,
+ 1245, 2160, 448, 2048, 42, 1242, 0, 4, 0, 168, 0,
+ 0, 0, 0, 0, 0
+ },
+ {
+ HAL_VCAP_YUV_UXGA_RH, HAL_VCAP_MODE_PRO, HAL_VCAP_POLAR_NEG,
+ HAL_VCAP_POLAR_POS, HAL_VCAP_POLAR_POS, HAL_VCAP_YUV, 161.0,
+ 12, 2160, 448, 2048, 6, 10, 0, 4, 0, 168, 0, 0, 0,
+ 0, 0, 0
+ },
+ {
+ HAL_VCAP_YUV_UXGA_RB, HAL_VCAP_MODE_PRO, HAL_VCAP_POLAR_NEG,
+ HAL_VCAP_POLAR_POS, HAL_VCAP_POLAR_POS, HAL_VCAP_YUV, 161.0,
+ 12, 1808, 112, 1712, 6, 10, 0, 4, 0, 32, 0, 0, 0, 0,
+ 0, 0
+ },
+ /* test odd height */
+ {
+ HAL_VCAP_ODD_HEIGHT, HAL_VCAP_MODE_INT, HAL_VCAP_POLAR_POS,
+ HAL_VCAP_POLAR_POS, HAL_VCAP_POLAR_NEG, HAL_VCAP_YUV, 148.5,
+ 65, 1728, 264, 1704, 5, 20, 0, 3, 0, 126, 25, 40, 864,
+ 864, 21, 24
+ },
+ /* test odd width RGB only */
+ {
+ HAL_VCAP_ODD_WIDTH, HAL_VCAP_MODE_PRO, HAL_VCAP_POLAR_POS,
+ HAL_VCAP_POLAR_POS, HAL_VCAP_POLAR_NEG, HAL_VCAP_RGB, 148.5,
+ 52, 859, 122, 843, 3, 50, 0, 2, 0, 62, 0, 0, 0, 0, 0, 0
+ },
+};
+
+void config_buffer(struct vcap_client_data *c_data,
+ struct vcap_buffer *buf,
+ void __iomem *y_addr,
+ void __iomem *c_addr)
+{
+ if (c_data->vc_format.color_space == HAL_VCAP_RGB) {
+ writel_relaxed(buf->paddr, y_addr);
+ } else {
+ int size = ((c_data->vc_format.hactive_end -
+ c_data->vc_format.hactive_start) *
+ (c_data->vc_format.vactive_end -
+ c_data->vc_format.vactive_start));
+ writel_relaxed(buf->paddr, y_addr);
+ writel_relaxed(buf->paddr + size, c_addr);
+ }
+}
+
+irqreturn_t vc_handler(struct vcap_dev *dev)
+{
+ uint32_t irq, timestamp;
+ enum rdy_buf vc_buf_status, buf_ind;
+ struct vcap_buffer *buf;
+ struct vb2_buffer *vb = NULL;
+ struct vcap_client_data *c_data;
+
+ irq = readl_relaxed(VCAP_VC_INT_STATUS);
+
+ dprintk(1, "%s: irq=0x%08x\n", __func__, irq);
+
+ vc_buf_status = irq & VC_BUFFER_WRITTEN;
+
+ dprintk(1, "Done buf status = %d\n", vc_buf_status);
+
+ if (vc_buf_status == VC_NO_BUF) {
+ writel_relaxed(irq, VCAP_VC_INT_CLEAR);
+ pr_err("VC IRQ shows some error\n");
+ return IRQ_HANDLED;
+ }
+
+ if (dev->vc_client == NULL) {
+ writel_relaxed(irq, VCAP_VC_INT_CLEAR);
+ pr_err("VC: There is no active vc client\n");
+ return IRQ_HANDLED;
+ }
+ c_data = dev->vc_client;
+
+ spin_lock(&dev->vc_client->cap_slock);
+ if (list_empty(&dev->vc_client->vid_vc_action.active)) {
+ /* Just leave we have no new queued buffers */
+ writel_relaxed(irq, VCAP_VC_INT_CLEAR);
+ spin_unlock(&dev->vc_client->cap_slock);
+ dprintk(1, "We have no more avilable buffers\n");
+ return IRQ_HANDLED;
+ }
+ spin_unlock(&dev->vc_client->cap_slock);
+
+ timestamp = readl_relaxed(VCAP_VC_TIMESTAMP);
+
+ buf_ind = dev->vc_client->vid_vc_action.buf_ind;
+
+ if (vc_buf_status == VC_BUF1N2) {
+ /* There are 2 buffer ready */
+ writel_relaxed(irq, VCAP_VC_INT_CLEAR);
+ return IRQ_HANDLED;
+ } else if (buf_ind != vc_buf_status) {
+ /* buffer is out of sync */
+ writel_relaxed(irq, VCAP_VC_INT_CLEAR);
+ return IRQ_HANDLED;
+ }
+
+ if (buf_ind == VC_BUF1) {
+ dprintk(1, "Got BUF1\n");
+ vb = &dev->vc_client->vid_vc_action.buf1->vb;
+ spin_lock(&dev->vc_client->cap_slock);
+ if (list_empty(&dev->vc_client->vid_vc_action.active)) {
+ spin_unlock(&dev->vc_client->cap_slock);
+ writel_relaxed(irq, VCAP_VC_INT_CLEAR);
+ return IRQ_HANDLED;
+ }
+ buf = list_entry(dev->vc_client->vid_vc_action.active.next,
+ struct vcap_buffer, list);
+ list_del(&buf->list);
+ spin_unlock(&dev->vc_client->cap_slock);
+ /* Config vc with this new buffer */
+ config_buffer(c_data, buf, VCAP_VC_Y_ADDR_1,
+ VCAP_VC_C_ADDR_1);
+
+ vb->v4l2_buf.timestamp.tv_usec = timestamp;
+ vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
+ dev->vc_client->vid_vc_action.buf1 = buf;
+ dev->vc_client->vid_vc_action.buf_ind = VC_BUF2;
+ irq = VC_BUF1;
+ } else {
+ dprintk(1, "Got BUF2\n");
+ spin_lock(&dev->vc_client->cap_slock);
+ vb = &dev->vc_client->vid_vc_action.buf2->vb;
+ if (list_empty(&dev->vc_client->vid_vc_action.active)) {
+ writel_relaxed(irq, VCAP_VC_INT_CLEAR);
+ spin_unlock(&dev->vc_client->cap_slock);
+ return IRQ_HANDLED;
+ }
+ buf = list_entry(dev->vc_client->vid_vc_action.active.next,
+ struct vcap_buffer, list);
+ list_del(&buf->list);
+ spin_unlock(&dev->vc_client->cap_slock);
+ /* Config vc with this new buffer */
+ config_buffer(c_data, buf, VCAP_VC_Y_ADDR_2,
+ VCAP_VC_C_ADDR_2);
+
+ vb->v4l2_buf.timestamp.tv_usec = timestamp;
+ vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
+
+ dev->vc_client->vid_vc_action.buf2 = buf;
+ dev->vc_client->vid_vc_action.buf_ind = VC_BUF1;
+ irq = VC_BUF2;
+ }
+ writel_relaxed(irq, VCAP_VC_INT_CLEAR);
+
+ return IRQ_HANDLED;
+}
+
+int vc_start_capture(struct vcap_client_data *c_data)
+{
+ return 0;
+}
+
+int vc_hw_kick_off(struct vcap_client_data *c_data)
+{
+ struct vcap_action *vid_vc_action = &c_data->vid_vc_action;
+ struct vcap_dev *dev;
+ unsigned long flags = 0;
+ int rc, counter = 0;
+ struct vcap_buffer *buf;
+
+ dev = c_data->dev;
+ vid_vc_action->buf_ind = VC_BUF1;
+ dprintk(2, "Start Kickoff\n");
+
+ if (dev->vc_client == NULL) {
+ pr_err("No active vc client\n");
+ return -ENODEV;
+ }
+ spin_lock_irqsave(&dev->vc_client->cap_slock, flags);
+ if (list_empty(&dev->vc_client->vid_vc_action.active)) {
+ spin_unlock_irqrestore(&dev->vc_client->cap_slock, flags);
+ pr_err("%s: VC We have no more avilable buffers\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ list_for_each_entry(buf, &vid_vc_action->active, list)
+ counter++;
+
+ if (counter < 2) {
+ /* not enough buffers have been queued */
+ spin_unlock_irqrestore(&dev->vc_client->cap_slock, flags);
+ return -EINVAL;
+ }
+
+ vid_vc_action->buf1 = list_entry(vid_vc_action->active.next,
+ struct vcap_buffer, list);
+ list_del(&vid_vc_action->buf1->list);
+
+ vid_vc_action->buf2 = list_entry(vid_vc_action->active.next,
+ struct vcap_buffer, list);
+ list_del(&vid_vc_action->buf2->list);
+
+ spin_unlock_irqrestore(&dev->vc_client->cap_slock, flags);
+
+ config_buffer(c_data, vid_vc_action->buf1, VCAP_VC_Y_ADDR_1,
+ VCAP_VC_C_ADDR_1);
+ config_buffer(c_data, vid_vc_action->buf2, VCAP_VC_Y_ADDR_2,
+ VCAP_VC_C_ADDR_2);
+
+ rc = readl_relaxed(VCAP_VC_CTRL);
+ writel_relaxed(rc | 0x1, VCAP_VC_CTRL);
+
+ writel_relaxed(0x6, VCAP_VC_INT_MASK);
+
+ enable_irq(dev->vcapirq->start);
+ return 0;
+}
+
+void vc_stop_capture(struct vcap_client_data *c_data)
+{
+ struct vcap_dev *dev = c_data->dev;
+ int rc;
+
+ rc = readl_relaxed(VCAP_VC_CTRL);
+ writel_relaxed(rc & ~(0x1), VCAP_VC_CTRL);
+
+ disable_irq(c_data->dev->vcapirq->start);
+}
+
+int config_vc_format(struct vcap_client_data *c_data)
+{
+ struct vcap_dev *dev;
+ unsigned int rc;
+ int timeout;
+ struct v4l2_format_vc_ext *vc_format = &c_data->vc_format;
+ dev = c_data->dev;
+
+ /* restart VC */
+ writel_relaxed(0x00000001, VCAP_SW_RESET_REQ);
+ timeout = 10000;
+ while (1) {
+ rc = (readl_relaxed(VCAP_SW_RESET_STATUS) & 0x1);
+ if (!rc)
+ break;
+ timeout--;
+ if (timeout == 0) {
+ pr_err("VC is not resetting properly\n");
+ return -EINVAL;
+ }
+ }
+ writel_relaxed(0x00000000, VCAP_SW_RESET_REQ);
+
+ writel_relaxed(0x00000102, VCAP_VC_NPL_CTRL);
+ rc = readl_relaxed(VCAP_VC_NPL_CTRL);
+ rc = readl_relaxed(VCAP_VC_NPL_CTRL);
+ writel_relaxed(0x00000002, VCAP_VC_NPL_CTRL);
+
+ dprintk(2, "%s: Starting VC configuration\n", __func__);
+ writel_relaxed(0x00000002, VCAP_VC_NPL_CTRL);
+ writel_relaxed(0x00000004 | vc_format->color_space << 1, VCAP_VC_CTRL);
+
+ writel_relaxed(vc_format->h_polar << 4 |
+ vc_format->v_polar << 0, VCAP_VC_POLARITY);
+
+ writel_relaxed(vc_format->h_polar << 4 |
+ vc_format->v_polar << 0, VCAP_VC_POLARITY);
+ writel_relaxed(((vc_format->htotal << 16) | vc_format->vtotal),
+ VCAP_VC_V_H_TOTAL);
+ writel_relaxed(((vc_format->hactive_end << 16) |
+ vc_format->hactive_start), VCAP_VC_H_ACTIVE);
+
+ writel_relaxed(((vc_format->vactive_end << 16) |
+ vc_format->vactive_start), VCAP_VC_V_ACTIVE);
+ writel_relaxed(((vc_format->f2_vactive_end << 16) |
+ vc_format->f2_vactive_start), VCAP_VC_V_ACTIVE_F2);
+ writel_relaxed(((vc_format->vsync_end << 16) | vc_format->vsync_start),
+ VCAP_VC_VSYNC_VPOS);
+ writel_relaxed(((vc_format->f2_vsync_v_end << 16) |
+ vc_format->f2_vsync_v_start), VCAP_VC_VSYNC_F2_VPOS);
+ writel_relaxed(((vc_format->hsync_end << 16) |
+ vc_format->hsync_start), VCAP_VC_HSYNC_HPOS);
+ writel_relaxed(((vc_format->f2_vsync_h_end << 16) |
+ vc_format->f2_vsync_h_start), VCAP_VC_VSYNC_F2_HPOS);
+ writel_relaxed(0x000033FF, VCAP_VC_BUF_CTRL);
+
+ rc = vc_format->hactive_end - vc_format->hactive_start;
+ if (vc_format->color_space)
+ rc *= 3;
+
+ writel_relaxed(rc, VCAP_VC_Y_STRIDE);
+ writel_relaxed(rc, VCAP_VC_C_STRIDE);
+
+ writel_relaxed(0x00010033 , VCAP_OFFSET(0x0898));
+ writel_relaxed(0x00010fff , VCAP_OFFSET(0x089c));
+ writel_relaxed(0x0a418820, VCAP_VC_IN_CTRL1);
+ writel_relaxed(0x16a4a0e6, VCAP_VC_IN_CTRL2);
+ writel_relaxed(0x2307b9ac, VCAP_VC_IN_CTRL3);
+ writel_relaxed(0x2f6ad272, VCAP_VC_IN_CTRL4);
+ writel_relaxed(0x00006b38, VCAP_VC_IN_CTRL5);
+
+ dprintk(2, "%s: Done VC configuration\n", __func__);
+
+ return 0;
+}
+
+int detect_vc(struct vcap_dev *dev)
+{
+ int result;
+ result = readl_relaxed(VCAP_HARDWARE_VERSION_REG);
+ dprintk(1, "Hardware version: %08x\n", result);
+ if (result != VCAP_HARDWARE_VERSION)
+ return -ENODEV;
+ return 0;
+}
+
+int deinit_vc(void)
+{
+ return 0;
+}
diff --git a/drivers/media/video/vcap_vc.h b/drivers/media/video/vcap_vc.h
new file mode 100644
index 0000000..e431038
--- /dev/null
+++ b/drivers/media/video/vcap_vc.h
@@ -0,0 +1,86 @@
+/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+#ifndef VCAP_VC_H
+#define VCAP_VC_H
+
+/* #define NEW_S_FMT */
+#include <linux/interrupt.h>
+
+#include <media/vcap_v4l2.h>
+extern struct v4l2_format_vc_ext vcap_vc_lut[];
+
+#define VCAP_HARDWARE_VERSION 0x10000000
+
+#define VCAP_BASE (dev->vcapbase)
+#define VCAP_OFFSET(off) (VCAP_BASE + off)
+
+#define VCAP_HARDWARE_VERSION_REG (VCAP_BASE + 0x0000)
+
+#define VCAP_SW_RESET_REQ (VCAP_BASE + 0x0024)
+#define VCAP_SW_RESET_STATUS (VCAP_BASE + 0x0028)
+
+#define VCAP_VC_CTRL (VCAP_BASE + 0x0800)
+#define VCAP_VC_NPL_CTRL (VCAP_BASE + 0x0804)
+#define VCAP_VC_POLARITY (VCAP_BASE + 0x081c)
+#define VCAP_VC_V_H_TOTAL (VCAP_BASE + 0x0820)
+#define VCAP_VC_H_ACTIVE (VCAP_BASE + 0x0824)
+#define VCAP_VC_V_ACTIVE (VCAP_BASE + 0x0828)
+#define VCAP_VC_V_ACTIVE_F2 (VCAP_BASE + 0x0830)
+#define VCAP_VC_VSYNC_VPOS (VCAP_BASE + 0x0834)
+#define VCAP_VC_VSYNC_F2_VPOS (VCAP_BASE + 0x0838)
+#define VCAP_VC_HSYNC_HPOS (VCAP_BASE + 0x0840)
+#define VCAP_VC_VSYNC_F2_HPOS (VCAP_BASE + 0x083c)
+#define VCAP_VC_BUF_CTRL (VCAP_BASE + 0x0848)
+
+#define VCAP_VC_Y_STRIDE (VCAP_BASE + 0x084c)
+#define VCAP_VC_C_STRIDE (VCAP_BASE + 0x0850)
+
+#define VCAP_VC_Y_ADDR_1 (VCAP_BASE + 0x0854)
+#define VCAP_VC_C_ADDR_1 (VCAP_BASE + 0x0858)
+#define VCAP_VC_Y_ADDR_2 (VCAP_BASE + 0x085c)
+#define VCAP_VC_C_ADDR_2 (VCAP_BASE + 0x0860)
+#define VCAP_VC_Y_ADDR_3 (VCAP_BASE + 0x0864)
+#define VCAP_VC_C_ADDR_3 (VCAP_BASE + 0x0868)
+#define VCAP_VC_Y_ADDR_4 (VCAP_BASE + 0x086c)
+#define VCAP_VC_C_ADDR_4 (VCAP_BASE + 0x0870)
+#define VCAP_VC_Y_ADDR_5 (VCAP_BASE + 0x0874)
+#define VCAP_VC_C_ADDR_5 (VCAP_BASE + 0x0878)
+#define VCAP_VC_Y_ADDR_6 (VCAP_BASE + 0x087c)
+#define VCAP_VC_C_ADDR_6 (VCAP_BASE + 0x0880)
+
+#define VCAP_VC_IN_CTRL1 (VCAP_BASE + 0x0808)
+#define VCAP_VC_IN_CTRL2 (VCAP_BASE + 0x080c)
+#define VCAP_VC_IN_CTRL3 (VCAP_BASE + 0x0810)
+#define VCAP_VC_IN_CTRL4 (VCAP_BASE + 0x0814)
+#define VCAP_VC_IN_CTRL5 (VCAP_BASE + 0x0818)
+
+#define VCAP_VC_INT_MASK (VCAP_BASE + 0x0884)
+#define VCAP_VC_INT_CLEAR (VCAP_BASE + 0x0888)
+#define VCAP_VC_INT_STATUS (VCAP_BASE + 0x088c)
+#define VCAP_VC_TIMESTAMP (VCAP_BASE + 0x0034)
+
+#define VC_BUFFER_WRITTEN (0x3 << 1)
+
+struct vc_reg_data {
+ unsigned data;
+ unsigned addr;
+};
+
+int vc_start_capture(struct vcap_client_data *c_data);
+int vc_hw_kick_off(struct vcap_client_data *c_data);
+void vc_stop_capture(struct vcap_client_data *c_data);
+int config_vc_format(struct vcap_client_data *c_data);
+int detect_vc(struct vcap_dev *dev);
+int deinit_vc(void);
+irqreturn_t vc_handler(struct vcap_dev *dev);
+#endif
diff --git a/include/media/Kbuild b/include/media/Kbuild
index a60b86c..8dfb0fc 100644
--- a/include/media/Kbuild
+++ b/include/media/Kbuild
@@ -1,6 +1,7 @@
header-y += tavarua.h
header-y += msm_camera.h
+header-y += vcap_fmt.h
header-y += msm_isp.h
header-y += msm_gemini.h
header-y += msm_v4l2_overlay.h
diff --git a/include/media/vcap_fmt.h b/include/media/vcap_fmt.h
new file mode 100644
index 0000000..4a62bc3
--- /dev/null
+++ b/include/media/vcap_fmt.h
@@ -0,0 +1,140 @@
+/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef VCAP_FMT_H
+#define VCAP_FMT_H
+
+#define V4L2_BUF_TYPE_INTERLACED_IN_AFE (V4L2_BUF_TYPE_PRIVATE)
+#define V4L2_BUF_TYPE_INTERLACED_IN_DECODER (V4L2_BUF_TYPE_PRIVATE + 1)
+
+enum hal_vcap_mode {
+ HAL_VCAP_MODE_PRO = 0,
+ HAL_VCAP_MODE_INT,
+};
+
+enum hal_vcap_polar {
+ HAL_VCAP_POLAR_NEG = 0,
+ HAL_VCAP_POLAR_POS,
+};
+
+enum hal_vcap_color {
+ HAL_VCAP_YUV = 0,
+ HAL_VCAP_RGB,
+};
+
+enum hal_vcap_vc_fmt {
+ /* 1080p */
+ HAL_VCAP_YUV_1080p_60_RH = 0,
+ HAL_VCAP_YUV_1080p_60_FL,
+ HAL_VCAP_RGB_1080p_60_FL,
+ HAL_VCAP_YUV_1080p_24_FL,
+ HAL_VCAP_YUV_1080p_24_RH,
+ HAL_VCAP_YUV_1080p_24_RW,
+ HAL_VCAP_YUV_1080p_60_RW,
+ HAL_VCAP_YUV_1080p_50_FL,
+ HAL_VCAP_YUV_1080p_50_RH,
+ HAL_VCAP_YUV_1080p_25_FL,
+ HAL_VCAP_YUV_1080p_25_RH,
+ HAL_VCAP_YUV_1080p_30_RH,
+ HAL_VCAP_RGB_1080p_25_FL,
+ HAL_VCAP_RGB_1080p_25_RH,
+ /* 1080i */
+ HAL_VCAP_YUV_1080i_60_FL,
+ HAL_VCAP_YUV_1080i_60_RH,
+ HAL_VCAP_YUV_1080i_60_RW,
+ HAL_VCAP_YUV_1080i_50_FL,
+ HAL_VCAP_YUV_1080i_50_RH,
+ HAL_VCAP_YUV_1080i_50_RW,
+ HAL_VCAP_RGB_1080i_50_FL,
+ HAL_VCAP_RGB_1080i_50_RH,
+ /* 480i */
+ HAL_VCAP_YUV_480i_60_RH,
+ HAL_VCAP_YUV_480i_60_FL,
+ HAL_VCAP_YUV_480i_60_RW,
+ HAL_VCAP_YUV_2880_480i_60_FL,
+ HAL_VCAP_YUV_2880_480i_60_RH,
+ /* 480p */
+ HAL_VCAP_YUV_480p_60_RH,
+ HAL_VCAP_RGB_480p_60_RH,
+ HAL_VCAP_RGB_480p_60_FL,
+ HAL_VCAP_YUV_480p_60_FL,
+ HAL_VCAP_YUV_480p_60_RW,
+ HAL_VCAP_YUV_2880_480p_60_FL,
+ HAL_VCAP_YUV_2880_480p_60_RH,
+ /* 720p */
+ HAL_VCAP_YUV_720p_60_FL,
+ HAL_VCAP_RGB_720p_60_FL,
+ HAL_VCAP_YUV_720p_60_RW,
+ HAL_VCAP_YUV_720p_60_RH,
+ HAL_VCAP_YUV_720p_50_FL,
+ HAL_VCAP_YUV_720p_50_RW,
+ HAL_VCAP_YUV_720p_50_RH,
+ /* 576p */
+ HAL_VCAP_YUV_576p_50_FL,
+ HAL_VCAP_RGB_576p_50_FL,
+ HAL_VCAP_YUV_576p_50_RW,
+ HAL_VCAP_YUV_576p_50_RH,
+ HAL_VCAP_YUV_1440_576p_50_RH,
+ HAL_VCAP_YUV_2880_576p_50_FL,
+ HAL_VCAP_YUV_2880_576p_50_RH,
+ /* 576i */
+ HAL_VCAP_YUV_576i_50_FL,
+ HAL_VCAP_YUV_576i_50_RW,
+ HAL_VCAP_YUV_576i_50_RH,
+ /* XGA 1024x768 */
+ HAL_VCAP_YUV_XGA_FL,
+ HAL_VCAP_YUV_XGA_RH,
+ HAL_VCAP_YUV_XGA_RB,
+ /* SXGA 1280x1024 */
+ HAL_VCAP_YUV_SXGA_FL,
+ HAL_VCAP_RGB_SXGA_FL,
+ HAL_VCAP_YUV_SXGA_RH,
+ HAL_VCAP_YUV_SXGA_RB,
+ /* UXGA 1600x1200 */
+ HAL_VCAP_YUV_UXGA_FL,
+ HAL_VCAP_RGB_UXGA_FL,
+ HAL_VCAP_YUV_UXGA_RH,
+ HAL_VCAP_YUV_UXGA_RB,
+ /* test odd height */
+ HAL_VCAP_ODD_HEIGHT,
+ /* test odd width RGB only */
+ HAL_VCAP_ODD_WIDTH,
+};
+
+struct v4l2_format_vc_ext {
+ enum hal_vcap_vc_fmt format;
+ enum hal_vcap_mode mode;
+ enum hal_vcap_polar h_polar;
+ enum hal_vcap_polar v_polar;
+ enum hal_vcap_polar d_polar;
+ enum hal_vcap_color color_space;
+
+ float clk_freq;
+ uint32_t vtotal;
+ uint32_t htotal;
+ uint32_t hactive_start;
+ uint32_t hactive_end;
+ uint32_t vactive_start;
+ uint32_t vactive_end;
+ uint32_t vsync_start;
+ uint32_t vsync_end;
+ uint32_t hsync_start;
+ uint32_t hsync_end;
+ uint32_t f2_vactive_start;
+ uint32_t f2_vactive_end;
+ uint32_t f2_vsync_h_start;
+ uint32_t f2_vsync_h_end;
+ uint32_t f2_vsync_v_start;
+ uint32_t f2_vsync_v_end;
+};
+#endif
diff --git a/include/media/vcap_v4l2.h b/include/media/vcap_v4l2.h
new file mode 100644
index 0000000..57f9703
--- /dev/null
+++ b/include/media/vcap_v4l2.h
@@ -0,0 +1,132 @@
+/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef VCAP_V4L2_H
+#define VCAP_V4L2_H
+
+#ifdef __KERNEL__
+#include <linux/types.h>
+#include <linux/videodev2.h>
+#include <linux/platform_device.h>
+#include <linux/workqueue.h>
+#include <media/videobuf2-vmalloc.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-fh.h>
+#include <media/v4l2-common.h>
+#include <media/vcap_fmt.h>
+#include <mach/board.h>
+
+struct vcap_client_data;
+
+enum rdy_buf {
+ VC_NO_BUF = 0,
+ VC_BUF1 = 1 << 1,
+ VC_BUF2 = 1 << 2,
+ VC_BUF1N2 = 0x11 << 1,
+};
+
+struct vcap_buf_info {
+ unsigned long vaddr;
+ unsigned long size;
+};
+
+struct vcap_action {
+ struct list_head active;
+
+ /* thread for generating video stream*/
+ struct task_struct *kthread;
+ wait_queue_head_t wq;
+
+ /* Buffer index */
+ enum rdy_buf buf_ind;
+
+ /* Buffers inside vc */
+ struct vcap_buffer *buf1;
+ struct vcap_buffer *buf2;
+
+ /* Counters to control fps rate */
+ int frame;
+ int ini_jiffies;
+};
+
+struct vcap_dev {
+ struct v4l2_device v4l2_dev;
+
+ struct video_device *vfd;
+ struct ion_client *ion_client;
+
+ struct resource *vcapirq;
+
+ struct resource *vcapmem;
+ struct resource *vcapio;
+ void __iomem *vcapbase;
+
+ struct vcap_platform_data *vcap_pdata;
+
+ struct regulator *fs_vcap;
+ struct clk *vcap_clk;
+ struct clk *vcap_p_clk;
+ struct clk *vcap_npl_clk;
+ /*struct platform_device *pdev;*/
+
+ uint32_t bus_client_handle;
+
+ struct vcap_client_data *vc_client;
+ struct vcap_client_data *vp_client;
+
+ atomic_t vc_enabled;
+ atomic_t vc_resource;
+ atomic_t vp_resource;
+};
+
+struct vp_format_data {
+ unsigned int width, height;
+ unsigned int pixelformat;
+ enum v4l2_field field;
+
+};
+
+struct vcap_buffer {
+ /* common v4l buffer stuff -- must be first */
+ struct vb2_buffer vb;
+ struct list_head list;
+ unsigned long paddr;
+ struct ion_handle *ion_handle;
+};
+
+struct vcap_client_data {
+ struct vcap_dev *dev;
+
+ struct vb2_queue vc_vidq;
+ /*struct vb2_queue vb__vidq;*/
+ /*struct vb2_queue vb_cap_vidq;*/
+
+ struct v4l2_format_vc_ext vc_format;
+
+ enum v4l2_buf_type vp_buf_type_field;
+ struct vp_format_data vp_format;
+
+ struct vcap_action vid_vc_action;
+ struct workqueue_struct *vcap_work_q;
+ struct ion_handle *vc_ion_handle;
+
+ uint32_t hold_vc;
+ uint32_t hold_vp;
+
+ spinlock_t cap_slock;
+};
+
+#endif
+#endif
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
old mode 100755
new mode 100644
index f4f833b..598c310
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -1852,11 +1852,29 @@
if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) {
if (!ev->status) {
- struct hci_cp_set_conn_encrypt cp;
- cp.handle = ev->handle;
- cp.encrypt = 0x01;
- hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT,
- sizeof(cp), &cp);
+ if (conn->link_mode & HCI_LM_ENCRYPT) {
+ /* Encryption implies authentication */
+ conn->link_mode |= HCI_LM_AUTH;
+ conn->link_mode |= HCI_LM_ENCRYPT;
+ conn->sec_level =
+ conn->pending_sec_level;
+ clear_bit(HCI_CONN_ENCRYPT_PEND,
+ &conn->pend);
+ hci_encrypt_cfm(conn, ev->status, 1);
+
+ if (test_bit(HCI_MGMT, &hdev->flags))
+ mgmt_encrypt_change(hdev->id,
+ &conn->dst,
+ ev->status);
+
+ } else {
+ struct hci_cp_set_conn_encrypt cp;
+ cp.handle = ev->handle;
+ cp.encrypt = 0x01;
+ hci_send_cmd(hdev,
+ HCI_OP_SET_CONN_ENCRYPT,
+ sizeof(cp), &cp);
+ }
} else {
clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend);
hci_encrypt_cfm(conn, ev->status, 0x00);
@@ -2653,6 +2671,7 @@
conn->key_type = ev->key_type;
hci_disconnect_amp(conn, 0x06);
+ conn->link_mode &= ~HCI_LM_ENCRYPT;
pin_len = conn->pin_length;
hci_conn_put(conn);
hci_conn_enter_active_mode(conn, 0);
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 04d4ca4..0068c2a 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -67,7 +67,7 @@
* It can be used to eliminate pops between different playback streams, e.g.
* between two audio tracks.
*/
-static int pmdown_time = 5000;
+static int pmdown_time;
module_param(pmdown_time, int, 0);
MODULE_PARM_DESC(pmdown_time, "DAPM stream powerdown time (msecs)");
diff --git a/sound/usb/card.c b/sound/usb/card.c
index 57a8e2d..12dfa0a 100644
--- a/sound/usb/card.c
+++ b/sound/usb/card.c
@@ -47,6 +47,7 @@
#include <linux/mutex.h>
#include <linux/usb/audio.h>
#include <linux/usb/audio-v2.h>
+#include <linux/switch.h>
#include <sound/control.h>
#include <sound/core.h>
@@ -85,6 +86,7 @@
static int async_unlink = 1;
static int device_setup[SNDRV_CARDS]; /* device parameter for this card */
static int ignore_ctl_error;
+struct switch_dev *usbaudiosdev;
module_param_array(index, int, NULL, 0444);
MODULE_PARM_DESC(index, "Index value for the USB audio adapter.");
@@ -418,6 +420,7 @@
}
snd_usb_audio_create_proc(chip);
+ switch_set_state(usbaudiosdev, 1);
*rchip = chip;
return 0;
@@ -580,6 +583,7 @@
mutex_unlock(&chip->shutdown_mutex);
mutex_unlock(®ister_mutex);
}
+ switch_set_state(usbaudiosdev, 0);
}
/*
@@ -712,16 +716,27 @@
static int __init snd_usb_audio_init(void)
{
+ int err;
if (nrpacks < 1 || nrpacks > MAX_PACKS) {
printk(KERN_WARNING "invalid nrpacks value.\n");
return -EINVAL;
}
+
+ usbaudiosdev = kzalloc(sizeof(usbaudiosdev), GFP_KERNEL);
+ usbaudiosdev->name = "usb_audio";
+
+ err = switch_dev_register(usbaudiosdev);
+ if (err)
+ pr_err("Usb-audio switch registration failed\n");
+ else
+ pr_debug("usb hs_detected\n");
return usb_register(&usb_audio_driver);
}
static void __exit snd_usb_audio_cleanup(void)
{
usb_deregister(&usb_audio_driver);
+ kfree(usbaudiosdev);
}
module_init(snd_usb_audio_init);