summaryrefslogtreecommitdiff
path: root/linux/drivers/media/video
diff options
context:
space:
mode:
Diffstat (limited to 'linux/drivers/media/video')
-rw-r--r--linux/drivers/media/video/Kconfig2
-rw-r--r--linux/drivers/media/video/Makefile1
-rw-r--r--linux/drivers/media/video/bt8xx/bttv-driver.c2
-rw-r--r--linux/drivers/media/video/bt8xx/bttv-vbi.c2
-rw-r--r--linux/drivers/media/video/cafe_ccic.c2
-rw-r--r--linux/drivers/media/video/cx25840/cx25840-core.c22
-rw-r--r--linux/drivers/media/video/cx88/Makefile5
-rw-r--r--linux/drivers/media/video/cx88/cx88-dvb.c10
-rw-r--r--linux/drivers/media/video/cx88/cx88-i2c.c2
-rw-r--r--linux/drivers/media/video/cx88/cx88-video.c21
-rw-r--r--linux/drivers/media/video/cx88/cx88.h6
-rw-r--r--linux/drivers/media/video/ir-kbd-i2c.c2
-rw-r--r--linux/drivers/media/video/pvrusb2/pvrusb2-encoder.c223
-rw-r--r--linux/drivers/media/video/pvrusb2/pvrusb2-fx2-cmd.h62
-rw-r--r--linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c109
-rw-r--r--linux/drivers/media/video/pvrusb2/pvrusb2-hdw.h2
-rw-r--r--linux/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c8
-rw-r--r--linux/drivers/media/video/pvrusb2/pvrusb2-v4l2.c13
-rw-r--r--linux/drivers/media/video/pwc/Makefile8
-rw-r--r--linux/drivers/media/video/pwc/pwc-if.c8
-rw-r--r--linux/drivers/media/video/pwc/pwc-v4l.c2
-rw-r--r--linux/drivers/media/video/pwc/pwc.h9
-rw-r--r--linux/drivers/media/video/saa5246a.c10
-rw-r--r--linux/drivers/media/video/saa5246a.h9
-rw-r--r--linux/drivers/media/video/saa5249.c41
-rw-r--r--linux/drivers/media/video/saa7115.c33
-rw-r--r--linux/drivers/media/video/saa7127.c18
-rw-r--r--linux/drivers/media/video/saa7134/Makefile4
-rw-r--r--linux/drivers/media/video/saa7134/saa7134-i2c.c24
-rw-r--r--linux/drivers/media/video/saa7134/saa7134.h10
-rw-r--r--linux/drivers/media/video/tvp5150.c18
-rw-r--r--linux/drivers/media/video/upd64031a.c20
-rw-r--r--linux/drivers/media/video/upd64083.c20
-rw-r--r--linux/drivers/media/video/usbvision/Kconfig2
-rw-r--r--linux/drivers/media/video/usbvision/usbvision-core.c68
-rw-r--r--linux/drivers/media/video/usbvision/usbvision-video.c159
-rw-r--r--linux/drivers/media/video/usbvision/usbvision.h10
-rw-r--r--linux/drivers/media/video/v4l2-common.c22
-rw-r--r--linux/drivers/media/video/video-buf.c4
-rw-r--r--linux/drivers/media/video/videodev.c20
-rw-r--r--linux/drivers/media/video/vivi.c83
41 files changed, 673 insertions, 423 deletions
diff --git a/linux/drivers/media/video/Kconfig b/linux/drivers/media/video/Kconfig
index 57357db31..7a6105153 100644
--- a/linux/drivers/media/video/Kconfig
+++ b/linux/drivers/media/video/Kconfig
@@ -342,7 +342,7 @@ endmenu # encoder / decoder chips
config VIDEO_VIVI
tristate "Virtual Video Driver"
- depends on VIDEO_V4L2 && !SPARC32 && !SPARC64
+ depends on VIDEO_V4L2 && !SPARC32 && !SPARC64 && PCI
select VIDEO_BUF
default n
---help---
diff --git a/linux/drivers/media/video/Makefile b/linux/drivers/media/video/Makefile
index 9b1f3f06b..44ccaed40 100644
--- a/linux/drivers/media/video/Makefile
+++ b/linux/drivers/media/video/Makefile
@@ -113,4 +113,3 @@ obj-$(CONFIG_USB_QUICKCAM_MESSENGER) += usbvideo/
obj-$(CONFIG_VIDEO_VIVI) += vivi.o
EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
-extra-cflags-$(CONFIG_VIDEO_V4L1_COMPAT) += -DCONFIG_VIDEO_V4L1_COMPAT
diff --git a/linux/drivers/media/video/bt8xx/bttv-driver.c b/linux/drivers/media/video/bt8xx/bttv-driver.c
index 118c6e800..4c813a4da 100644
--- a/linux/drivers/media/video/bt8xx/bttv-driver.c
+++ b/linux/drivers/media/video/bt8xx/bttv-driver.c
@@ -1905,7 +1905,7 @@ static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
struct bttv_buffer *buf = container_of(vb,struct bttv_buffer,vb);
struct bttv_fh *fh = q->priv_data;
- bttv_dma_free(&fh->cap,fh->btv,buf);
+ bttv_dma_free(q,fh->btv,buf);
}
static struct videobuf_queue_ops bttv_video_qops = {
diff --git a/linux/drivers/media/video/bt8xx/bttv-vbi.c b/linux/drivers/media/video/bt8xx/bttv-vbi.c
index cac2273f7..689d79404 100644
--- a/linux/drivers/media/video/bt8xx/bttv-vbi.c
+++ b/linux/drivers/media/video/bt8xx/bttv-vbi.c
@@ -225,7 +225,7 @@ static void vbi_buffer_release(struct videobuf_queue *q, struct videobuf_buffer
struct bttv_buffer *buf = container_of(vb,struct bttv_buffer,vb);
dprintk("free %p\n",vb);
- bttv_dma_free(&fh->cap,fh->btv,buf);
+ bttv_dma_free(q,fh->btv,buf);
}
struct videobuf_queue_ops bttv_vbi_qops = {
diff --git a/linux/drivers/media/video/cafe_ccic.c b/linux/drivers/media/video/cafe_ccic.c
index 68f2326dc..a8d0cb910 100644
--- a/linux/drivers/media/video/cafe_ccic.c
+++ b/linux/drivers/media/video/cafe_ccic.c
@@ -1201,7 +1201,7 @@ static int cafe_vidioc_reqbufs(struct file *filp, void *priv,
struct v4l2_requestbuffers *req)
{
struct cafe_camera *cam = filp->private_data;
- int ret;
+ int ret = 0; /* Silence warning */
/*
* Make sure it's something we can do. User pointers could be
diff --git a/linux/drivers/media/video/cx25840/cx25840-core.c b/linux/drivers/media/video/cx25840/cx25840-core.c
index bd6a3d8fb..a1a4907af 100644
--- a/linux/drivers/media/video/cx25840/cx25840-core.c
+++ b/linux/drivers/media/video/cx25840/cx25840-core.c
@@ -639,17 +639,8 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd,
#ifdef CONFIG_VIDEO_ADV_DEBUG
/* ioctls to allow direct access to the
* cx25840 registers for testing */
- case VIDIOC_INT_G_REGISTER:
- {
- struct v4l2_register *reg = arg;
-
- if (reg->i2c_id != I2C_DRIVERID_CX25840)
- return -EINVAL;
- reg->val = cx25840_read(client, reg->reg & 0x0fff);
- break;
- }
-
- case VIDIOC_INT_S_REGISTER:
+ case VIDIOC_DBG_G_REGISTER:
+ case VIDIOC_DBG_S_REGISTER:
{
struct v4l2_register *reg = arg;
@@ -657,7 +648,10 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd,
return -EINVAL;
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
- cx25840_write(client, reg->reg & 0x0fff, reg->val & 0xff);
+ if (cmd == VIDIOC_DBG_G_REGISTER)
+ reg->val = cx25840_read(client, reg->reg & 0x0fff);
+ else
+ cx25840_write(client, reg->reg & 0x0fff, reg->val & 0xff);
break;
}
#endif
@@ -914,9 +908,11 @@ static int cx25840_detect_client(struct i2c_adapter *adapter, int address,
return 0;
}
+ /* Note: revision '(device_id & 0x0f) == 2' was never built. The
+ marking skips from 0x1 == 22 to 0x3 == 23. */
v4l_info(client, "cx25%3x-2%x found @ 0x%x (%s)\n",
(device_id & 0xfff0) >> 4,
- (device_id & 0x0f) < 3 ? (device_id & 0x0f) + 1 : 3,
+ (device_id & 0x0f) < 3 ? (device_id & 0x0f) + 1 : (device_id & 0x0f),
address << 1, adapter->name);
i2c_set_clientdata(client, state);
diff --git a/linux/drivers/media/video/cx88/Makefile b/linux/drivers/media/video/cx88/Makefile
index 639c3b659..532cee35e 100644
--- a/linux/drivers/media/video/cx88/Makefile
+++ b/linux/drivers/media/video/cx88/Makefile
@@ -12,8 +12,3 @@ obj-$(CONFIG_VIDEO_CX88_VP3054) += cx88-vp3054-i2c.o
EXTRA_CFLAGS += -Idrivers/media/video
EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
EXTRA_CFLAGS += -Idrivers/media/dvb/frontends
-
-extra-cflags-$(CONFIG_VIDEO_BUF_DVB) += -DHAVE_VIDEO_BUF_DVB=1
-extra-cflags-$(CONFIG_VIDEO_CX88_VP3054)+= -DHAVE_VP3054_I2C=1
-
-EXTRA_CFLAGS += $(extra-cflags-y) $(extra-cflags-m)
diff --git a/linux/drivers/media/video/cx88/cx88-dvb.c b/linux/drivers/media/video/cx88/cx88-dvb.c
index 779317cc2..70f7f45a8 100644
--- a/linux/drivers/media/video/cx88/cx88-dvb.c
+++ b/linux/drivers/media/video/cx88/cx88-dvb.c
@@ -36,7 +36,7 @@
#include "mt352.h"
#include "mt352_priv.h"
-#ifdef HAVE_VP3054_I2C
+#if defined(CONFIG_VIDEO_CX88_VP3054) || defined(CONFIG_VIDEO_CX88_VP3054_MODULE)
# include "cx88-vp3054-i2c.h"
#endif
#include "zl10353.h"
@@ -201,7 +201,7 @@ static struct mt352_config dvico_fusionhdtv_dual = {
.demod_init = dvico_dual_demod_init,
};
-#ifdef HAVE_VP3054_I2C
+#if defined(CONFIG_VIDEO_CX88_VP3054) || defined(CONFIG_VIDEO_CX88_VP3054_MODULE)
static int dntv_live_dvbt_pro_demod_init(struct dvb_frontend* fe)
{
static u8 clock_config [] = { 0x89, 0x38, 0x38 };
@@ -544,7 +544,7 @@ static int dvb_register(struct cx8802_dev *dev)
}
break;
case CX88_BOARD_DNTV_LIVE_DVB_T_PRO:
-#ifdef HAVE_VP3054_I2C
+#if defined(CONFIG_VIDEO_CX88_VP3054) || defined(CONFIG_VIDEO_CX88_VP3054_MODULE)
dev->core->pll_addr = 0x61;
dev->core->pll_desc = &dvb_pll_fmd1216me;
dev->dvb.frontend = dvb_attach(mt352_attach, &dntv_live_dvbt_pro_config,
@@ -797,7 +797,7 @@ static int cx8802_dvb_probe(struct cx8802_driver *drv)
if (!(cx88_boards[core->board].mpeg & CX88_MPEG_DVB))
goto fail_core;
-#ifdef HAVE_VP3054_I2C
+#if defined(CONFIG_VIDEO_CX88_VP3054) || defined(CONFIG_VIDEO_CX88_VP3054_MODULE)
err = vp3054_i2c_probe(dev);
if (0 != err)
goto fail_core;
@@ -826,7 +826,7 @@ static int cx8802_dvb_remove(struct cx8802_driver *drv)
/* dvb */
videobuf_dvb_unregister(&dev->dvb);
-#ifdef HAVE_VP3054_I2C
+#if defined(CONFIG_VIDEO_CX88_VP3054) || defined(CONFIG_VIDEO_CX88_VP3054_MODULE)
vp3054_i2c_remove(dev);
#endif
diff --git a/linux/drivers/media/video/cx88/cx88-i2c.c b/linux/drivers/media/video/cx88/cx88-i2c.c
index da24a0a56..2f60c957b 100644
--- a/linux/drivers/media/video/cx88/cx88-i2c.c
+++ b/linux/drivers/media/video/cx88/cx88-i2c.c
@@ -154,7 +154,7 @@ void cx88_call_i2c_clients(struct cx88_core *core, unsigned int cmd, void *arg)
if (0 != core->i2c_rc)
return;
-#ifdef HAVE_VIDEO_BUF_DVB
+#if defined(CONFIG_VIDEO_BUF_DVB) || defined(CONFIG_VIDEO_BUF_DVB_MODULE)
if ( (core->dvbdev) && (core->dvbdev->dvb.frontend) ) {
if (core->dvbdev->dvb.frontend->ops.i2c_gate_ctrl)
core->dvbdev->dvb.frontend->ops.i2c_gate_ctrl(core->dvbdev->dvb.frontend, 1);
diff --git a/linux/drivers/media/video/cx88/cx88-video.c b/linux/drivers/media/video/cx88/cx88-video.c
index 8a33b7e16..43c89eec9 100644
--- a/linux/drivers/media/video/cx88/cx88-video.c
+++ b/linux/drivers/media/video/cx88/cx88-video.c
@@ -102,8 +102,6 @@ static LIST_HEAD(cx8800_devlist);
/* ------------------------------------------------------------------- */
/* static data */
-v4l2_std_id radionorms[] = { 0 };
-
static struct cx8800_fmt formats[] = {
{
.name = "8 bpp, gray",
@@ -1666,10 +1664,12 @@ static int vidioc_s_frequency (struct file *file, void *priv,
cx88_set_freq (core,f);
}
-#if 0 //ifdef CONFIG_VIDEO_ADV_DEBUG
-static int vidioc_g_register (struct file *file, void *priv,
- v4l2_register *reg)
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+static int vidioc_g_register (struct file *file, void *fh,
+ struct v4l2_register *reg)
{
+ struct cx88_core *core = ((struct cx8800_fh*)fh)->dev->core;
+
if (reg->i2c_id != 0)
return -EINVAL;
/* cx2388x has a 24-bit register space */
@@ -1678,13 +1678,12 @@ static int vidioc_g_register (struct file *file, void *priv,
}
static int vidioc_s_register (struct file *file, void *fh,
- v4l2_register *reg)
+ struct v4l2_register *reg)
{
+ struct cx88_core *core = ((struct cx8800_fh*)fh)->dev->core;
if (reg->i2c_id != 0)
return -EINVAL;
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
cx_write(reg->reg&0xffffff, reg->val);
return 0;
}
@@ -1966,8 +1965,12 @@ static struct video_device cx8800_video_template =
.vidioc_s_tuner = vidioc_s_tuner,
.vidioc_g_frequency = vidioc_g_frequency,
.vidioc_s_frequency = vidioc_s_frequency,
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+ .vidioc_g_register = vidioc_g_register,
+ .vidioc_s_register = vidioc_s_register,
+#endif
.tvnorms = CX88_NORMS,
- .current_norm = V4L2_STD_NTSC_M,
+ .current_norm = V4L2_STD_NTSC_M,
};
static struct file_operations radio_fops =
diff --git a/linux/drivers/media/video/cx88/cx88.h b/linux/drivers/media/video/cx88/cx88.h
index 5bb190eb2..ddd2c2fe9 100644
--- a/linux/drivers/media/video/cx88/cx88.h
+++ b/linux/drivers/media/video/cx88/cx88.h
@@ -31,7 +31,7 @@
#include <media/video-buf.h>
#include <media/cx2341x.h>
#include <media/audiochip.h>
-#ifdef HAVE_VIDEO_BUF_DVB
+#if defined(CONFIG_VIDEO_BUF_DVB) || defined(CONFIG_VIDEO_BUF_DVB_MODULE)
#include <media/video-buf-dvb.h>
#endif
#include "compat.h"
@@ -321,7 +321,7 @@ struct cx88_core {
unsigned int tuner_formats;
/* config info -- dvb */
-#ifdef HAVE_VIDEO_BUF_DVB
+#if defined(CONFIG_VIDEO_BUF_DVB) || defined(CONFIG_VIDEO_BUF_DVB_MODULE)
struct dvb_pll_desc *pll_desc;
unsigned int pll_addr;
int (*prev_set_voltage)(struct dvb_frontend* fe, fe_sec_voltage_t voltage);
@@ -497,7 +497,7 @@ struct cx8802_dev {
int width;
int height;
-#ifdef HAVE_VIDEO_BUF_DVB
+#if defined(CONFIG_VIDEO_BUF_DVB) || defined(CONFIG_VIDEO_BUF_DVB_MODULE)
/* for dvb only */
struct videobuf_dvb dvb;
void* fe_handle;
diff --git a/linux/drivers/media/video/ir-kbd-i2c.c b/linux/drivers/media/video/ir-kbd-i2c.c
index 95566ff19..380766944 100644
--- a/linux/drivers/media/video/ir-kbd-i2c.c
+++ b/linux/drivers/media/video/ir-kbd-i2c.c
@@ -41,9 +41,9 @@
#include <linux/workqueue.h>
#include <asm/semaphore.h>
-#include "compat.h"
#include <media/ir-common.h>
#include <media/ir-kbd-i2c.h>
+#include "compat.h"
/* ----------------------------------------------------------------------- */
/* insmod parameters */
diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-encoder.c b/linux/drivers/media/video/pvrusb2/pvrusb2-encoder.c
index 95e45be08..fb0a9ca67 100644
--- a/linux/drivers/media/video/pvrusb2/pvrusb2-encoder.c
+++ b/linux/drivers/media/video/pvrusb2/pvrusb2-encoder.c
@@ -27,6 +27,7 @@
#include "pvrusb2-encoder.h"
#include "pvrusb2-hdw-internal.h"
#include "pvrusb2-debug.h"
+#include "pvrusb2-fx2-cmd.h"
@@ -35,34 +36,41 @@
#define IVTV_MBOX_DRIVER_DONE 0x00000002
#define IVTV_MBOX_DRIVER_BUSY 0x00000001
+#define MBOX_BASE 0x44
+
static int pvr2_encoder_write_words(struct pvr2_hdw *hdw,
+ unsigned int offs,
const u32 *data, unsigned int dlen)
{
- unsigned int idx;
+ unsigned int idx,addr;
+ unsigned int bAddr;
int ret;
- unsigned int offs = 0;
unsigned int chunkCnt;
/*
Format: First byte must be 0x01. Remaining 32 bit words are
- spread out into chunks of 7 bytes each, little-endian ordered,
- offset at zero within each 2 blank bytes following and a
- single byte that is 0x44 plus the offset of the word. Repeat
- request for additional words, with offset adjusted
- accordingly.
+ spread out into chunks of 7 bytes each, with the first 4 bytes
+ being the data word (little endian), and the next 3 bytes
+ being the address where that data word is to be written (big
+ endian). Repeat request for additional words, with offset
+ adjusted accordingly.
*/
while (dlen) {
chunkCnt = 8;
if (chunkCnt > dlen) chunkCnt = dlen;
memset(hdw->cmd_buffer,0,sizeof(hdw->cmd_buffer));
- hdw->cmd_buffer[0] = 0x01;
+ bAddr = 0;
+ hdw->cmd_buffer[bAddr++] = FX2CMD_MEM_WRITE_DWORD;
for (idx = 0; idx < chunkCnt; idx++) {
- hdw->cmd_buffer[1+(idx*7)+6] = 0x44 + idx + offs;
- PVR2_DECOMPOSE_LE(hdw->cmd_buffer, 1+(idx*7),
- data[idx]);
+ addr = idx + offs;
+ hdw->cmd_buffer[bAddr+6] = (addr & 0xffu);
+ hdw->cmd_buffer[bAddr+5] = ((addr>>8) & 0xffu);
+ hdw->cmd_buffer[bAddr+4] = ((addr>>16) & 0xffu);
+ PVR2_DECOMPOSE_LE(hdw->cmd_buffer, bAddr,data[idx]);
+ bAddr += 7;
}
ret = pvr2_send_request(hdw,
hdw->cmd_buffer,1+(chunkCnt*7),
@@ -77,33 +85,42 @@ static int pvr2_encoder_write_words(struct pvr2_hdw *hdw,
}
-static int pvr2_encoder_read_words(struct pvr2_hdw *hdw,int statusFl,
+static int pvr2_encoder_read_words(struct pvr2_hdw *hdw,
+ unsigned int offs,
u32 *data, unsigned int dlen)
{
unsigned int idx;
int ret;
- unsigned int offs = 0;
unsigned int chunkCnt;
/*
Format: First byte must be 0x02 (status check) or 0x28 (read
back block of 32 bit words). Next 6 bytes must be zero,
- followed by a single byte of 0x44+offset for portion to be
- read. Returned data is packed set of 32 bits words that were
- read.
+ followed by a single byte of MBOX_BASE+offset for portion to
+ be read. Returned data is packed set of 32 bits words that
+ were read.
*/
while (dlen) {
chunkCnt = 16;
if (chunkCnt > dlen) chunkCnt = dlen;
- memset(hdw->cmd_buffer,0,sizeof(hdw->cmd_buffer));
- hdw->cmd_buffer[0] = statusFl ? 0x02 : 0x28;
- hdw->cmd_buffer[7] = 0x44 + offs;
+ if (chunkCnt < 16) chunkCnt = 1;
+ hdw->cmd_buffer[0] =
+ ((chunkCnt == 1) ?
+ FX2CMD_MEM_READ_DWORD : FX2CMD_MEM_READ_64BYTES);
+ hdw->cmd_buffer[1] = 0;
+ hdw->cmd_buffer[2] = 0;
+ hdw->cmd_buffer[3] = 0;
+ hdw->cmd_buffer[4] = 0;
+ hdw->cmd_buffer[5] = ((offs>>16) & 0xffu);
+ hdw->cmd_buffer[6] = ((offs>>8) & 0xffu);
+ hdw->cmd_buffer[7] = (offs & 0xffu);
ret = pvr2_send_request(hdw,
hdw->cmd_buffer,8,
- hdw->cmd_buffer,chunkCnt * 4);
+ hdw->cmd_buffer,
+ (chunkCnt == 1 ? 4 : 16 * 4));
if (ret) return ret;
for (idx = 0; idx < chunkCnt; idx++) {
@@ -130,6 +147,8 @@ static int pvr2_encoder_cmd(void *ctxt,
u32 *argp)
{
unsigned int poll_count;
+ unsigned int try_count = 0;
+ int retry_flag;
int ret = 0;
unsigned int idx;
/* These sizes look to be limited by the FX2 firmware implementation */
@@ -162,14 +181,15 @@ static int pvr2_encoder_cmd(void *ctxt,
/*
The encoder seems to speak entirely using blocks 32 bit words.
- In ivtv driver terms, this is a mailbox which we populate with
- data and watch what the hardware does with it. The first word
- is a set of flags used to control the transaction, the second
- word is the command to execute, the third byte is zero (ivtv
- driver suggests that this is some kind of return value), and
- the fourth byte is a specified timeout (windows driver always
- uses 0x00060000 except for one case when it is zero). All
- successive words are the argument words for the command.
+ In ivtv driver terms, this is a mailbox at MBOX_BASE which we
+ populate with data and watch what the hardware does with it.
+ The first word is a set of flags used to control the
+ transaction, the second word is the command to execute, the
+ third byte is zero (ivtv driver suggests that this is some
+ kind of return value), and the fourth byte is a specified
+ timeout (windows driver always uses 0x00060000 except for one
+ case when it is zero). All successive words are the argument
+ words for the command.
First, write out the entire set of words, with the first word
being zero.
@@ -178,13 +198,10 @@ static int pvr2_encoder_cmd(void *ctxt,
IVTV_MBOX_DRIVER_DONE | IVTV_DRIVER_BUSY this time (which
probably means "go").
- Next, read back 16 words as status. Check the first word,
+ Next, read back the return count words. Check the first word,
which should have IVTV_MBOX_FIRMWARE_DONE set. If however
that bit is not set, then the command isn't done so repeat the
- read.
-
- Next, read back 32 words and compare with the original
- arugments. Hopefully they will match.
+ read until it is set.
Finally, write out just the first word again, but set it to
0x0 this time (which probably means "idle").
@@ -214,6 +231,9 @@ static int pvr2_encoder_cmd(void *ctxt,
LOCK_TAKE(hdw->ctl_lock); do {
+ retry_flag = 0;
+ try_count++;
+ ret = 0;
wrData[0] = 0;
wrData[1] = cmd;
wrData[2] = 0;
@@ -225,48 +245,64 @@ static int pvr2_encoder_cmd(void *ctxt,
wrData[idx+4] = 0;
}
- ret = pvr2_encoder_write_words(hdw,wrData,idx);
+ ret = pvr2_encoder_write_words(hdw,MBOX_BASE,wrData,idx);
if (ret) break;
wrData[0] = IVTV_MBOX_DRIVER_DONE|IVTV_MBOX_DRIVER_BUSY;
- ret = pvr2_encoder_write_words(hdw,wrData,1);
+ ret = pvr2_encoder_write_words(hdw,MBOX_BASE,wrData,1);
if (ret) break;
poll_count = 0;
while (1) {
- if (poll_count < 10000000) poll_count++;
- ret = pvr2_encoder_read_words(hdw,!0,rdData,1);
- if (ret) break;
+ poll_count++;
+ ret = pvr2_encoder_read_words(hdw,MBOX_BASE,rdData,
+ arg_cnt_recv+4);
+ if (ret) {
+ break;
+ }
if (rdData[0] & IVTV_MBOX_FIRMWARE_DONE) {
break;
}
- if (poll_count == 100) {
+ if (rdData[0] && (poll_count < 1000)) continue;
+ if (!rdData[0]) {
+ retry_flag = !0;
pvr2_trace(
PVR2_TRACE_ERROR_LEGS,
- "***WARNING*** device's encoder"
- " appears to be stuck"
- " (status=0%08x)",rdData[0]);
+ "Encoder timed out waiting for us"
+ "; arranging to retry");
+ } else {
pvr2_trace(
PVR2_TRACE_ERROR_LEGS,
- "Encoder command: 0x%02x",cmd);
- for (idx = 4; idx < arg_cnt_send; idx++) {
- pvr2_trace(
- PVR2_TRACE_ERROR_LEGS,
- "Encoder arg%d: 0x%08x",
- idx-3,wrData[idx]);
- }
+ "***WARNING*** device's encoder"
+ " appears to be stuck"
+ " (status=0x%08x)",rdData[0]);
+ }
+ pvr2_trace(
+ PVR2_TRACE_ERROR_LEGS,
+ "Encoder command: 0x%02x",cmd);
+ for (idx = 4; idx < arg_cnt_send; idx++) {
pvr2_trace(
PVR2_TRACE_ERROR_LEGS,
- "Giving up waiting."
- " It is likely that"
- " this is a bad idea...");
- ret = -EBUSY;
- break;
+ "Encoder arg%d: 0x%08x",
+ idx-3,wrData[idx]);
}
+ ret = -EBUSY;
+ break;
+ }
+ if (retry_flag) {
+ if (try_count < 20) continue;
+ pvr2_trace(
+ PVR2_TRACE_ERROR_LEGS,
+ "Too many retries...");
+ ret = -EBUSY;
+ }
+ if (ret) {
+ pvr2_trace(
+ PVR2_TRACE_ERROR_LEGS,
+ "Giving up on command."
+ " It is likely that"
+ " this is a bad idea...");
+ break;
}
- if (ret) break;
wrData[0] = 0x7;
- ret = pvr2_encoder_read_words(
- hdw,0,rdData, ARRAY_SIZE(rdData));
- if (ret) break;
#if 0
for (idx = 0; idx < args; idx++) {
if (rdData[idx] != wrData[idx]) {
@@ -283,7 +319,7 @@ static int pvr2_encoder_cmd(void *ctxt,
}
wrData[0] = 0x0;
- ret = pvr2_encoder_write_words(hdw,wrData,1);
+ ret = pvr2_encoder_write_words(hdw,MBOX_BASE,wrData,1);
if (ret) break;
} while(0); LOCK_GIVE(hdw->ctl_lock);
@@ -318,6 +354,73 @@ static int pvr2_encoder_vcmd(struct pvr2_hdw *hdw, int cmd,
return pvr2_encoder_cmd(hdw,cmd,args,0,data);
}
+
+/* This implements some extra setup for the encoder that seems to be
+ specific to the PVR USB2 hardware. */
+int pvr2_encoder_prep_config(struct pvr2_hdw *hdw)
+{
+ int ret = 0;
+ int encMisc3Arg = 0;
+
+#if 0 /* keep */
+ /* This inexplicable bit happens in the Hauppage windows
+ driver (for both 24xxx and 29xxx devices). However I
+ currently see no difference in behavior with or without
+ this stuff. Leave this here as a note of its existence,
+ but don't use it. */
+ LOCK_TAKE(hdw->ctl_lock); do {
+ u32 dat[1];
+ dat[0] = 0x80000640;
+ pvr2_encoder_write_words(hdw,0x01fe,dat,1);
+ pvr2_encoder_write_words(hdw,0x023e,dat,1);
+ } while(0); LOCK_GIVE(hdw->ctl_lock);
+#endif
+
+ /* Mike Isely <isely@pobox.com> 26-Jan-2006 The windows driver
+ sends the following list of ENC_MISC commands (for both
+ 24xxx and 29xxx devices). Meanings are not entirely clear,
+ however without the ENC_MISC(3,1) command then we risk
+ random perpetual video corruption whenever the video input
+ breaks up for a moment (like when switching channels). */
+
+
+#if 0 /* keep */
+ /* This ENC_MISC(5,0) command seems to hurt 29xxx sync
+ performance on channel changes, but is not a problem on
+ 24xxx devices. */
+ ret |= pvr2_encoder_vcmd(hdw, CX2341X_ENC_MISC,4, 5,0,0,0);
+#endif
+
+ /* This ENC_MISC(3,encMisc3Arg) command is critical - without
+ it there will eventually be video corruption. Also, the
+ 29xxx case is strange - the Windows driver is passing 1
+ regardless of device type but if we have 1 for 29xxx device
+ the video turns sluggish. */
+ switch (hdw->hdw_type) {
+ case PVR2_HDW_TYPE_24XXX: encMisc3Arg = 1; break;
+ case PVR2_HDW_TYPE_29XXX: encMisc3Arg = 0; break;
+ default: break;
+ }
+ ret |= pvr2_encoder_vcmd(hdw, CX2341X_ENC_MISC,4, 3,
+ encMisc3Arg,0,0);
+
+ ret |= pvr2_encoder_vcmd(hdw, CX2341X_ENC_MISC,4, 8,0,0,0);
+
+#if 0 /* keep */
+ /* This ENC_MISC(4,1) command is poisonous, so it is commented
+ out. But I'm leaving it here anyway to document its
+ existence in the Windows driver. The effect of this
+ command is that apps displaying the stream become sluggish
+ with stuttering video. */
+ ret |= pvr2_encoder_vcmd(hdw, CX2341X_ENC_MISC,4, 4,1,0,0);
+#endif
+
+ ret |= pvr2_encoder_vcmd(hdw, CX2341X_ENC_MISC,4, 0,3,0,0);
+ ret |= pvr2_encoder_vcmd(hdw, CX2341X_ENC_MISC,4,15,0,0,0);
+
+ return ret;
+}
+
int pvr2_encoder_configure(struct pvr2_hdw *hdw)
{
int ret;
@@ -332,6 +435,8 @@ int pvr2_encoder_configure(struct pvr2_hdw *hdw)
ret = 0;
+ ret |= pvr2_encoder_prep_config(hdw);
+
if (!ret) ret = pvr2_encoder_vcmd(
hdw,CX2341X_ENC_SET_NUM_VSYNC_LINES, 2,
0xf0, 0xf0);
diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-fx2-cmd.h b/linux/drivers/media/video/pvrusb2/pvrusb2-fx2-cmd.h
new file mode 100644
index 000000000..ffbc6d096
--- /dev/null
+++ b/linux/drivers/media/video/pvrusb2/pvrusb2-fx2-cmd.h
@@ -0,0 +1,62 @@
+/*
+ *
+ * $Id$
+ *
+ * Copyright (C) 2007 Michael Krufky <mkrufky@linuxtv.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef _PVRUSB2_FX2_CMD_H_
+#define _PVRUSB2_FX2_CMD_H_
+
+#define FX2CMD_MEM_WRITE_DWORD 0x01
+#define FX2CMD_MEM_READ_DWORD 0x02
+
+#define FX2CMD_MEM_READ_64BYTES 0x28
+
+#define FX2CMD_REG_WRITE 0x04
+#define FX2CMD_REG_READ 0x05
+#define FX2CMD_MEMSEL 0x06
+
+#define FX2CMD_I2C_WRITE 0x08
+#define FX2CMD_I2C_READ 0x09
+
+#define FX2CMD_GET_USB_SPEED 0x0b
+
+#define FX2CMD_STREAMING_ON 0x36
+#define FX2CMD_STREAMING_OFF 0x37
+
+#define FX2CMD_FWPOST1 0x52
+
+#define FX2CMD_POWER_OFF 0xdc
+#define FX2CMD_POWER_ON 0xde
+
+#define FX2CMD_DEEP_RESET 0xdd
+
+#define FX2CMD_GET_EEPROM_ADDR 0xeb
+#define FX2CMD_GET_IR_CODE 0xec
+
+#endif /* _PVRUSB2_FX2_CMD_H_ */
+
+/*
+ Stuff for Emacs to see, in order to encourage consistent editing style:
+ *** Local Variables: ***
+ *** mode: c ***
+ *** fill-column: 75 ***
+ *** tab-width: 8 ***
+ *** c-basic-offset: 8 ***
+ *** End: ***
+ */
diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c
index b07bd58ea..d80136377 100644
--- a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c
+++ b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c
@@ -37,6 +37,7 @@
#include "pvrusb2-hdw-internal.h"
#include "pvrusb2-encoder.h"
#include "pvrusb2-debug.h"
+#include "pvrusb2-fx2-cmd.h"
#define TV_MIN_FREQ 55250000L
#define TV_MAX_FREQ 850000000L
@@ -271,8 +272,6 @@ static int pvr2_send_request_ex(struct pvr2_hdw *hdw,
unsigned int timeout,int probe_fl,
void *write_data,unsigned int write_len,
void *read_data,unsigned int read_len);
-static int pvr2_write_u16(struct pvr2_hdw *hdw, u16 data, int res);
-static int pvr2_write_u8(struct pvr2_hdw *hdw, u8 data, int res);
static int ctrl_channelfreq_get(struct pvr2_ctrl *cptr,int *vp)
{
@@ -1220,7 +1219,7 @@ int pvr2_upload_firmware2(struct pvr2_hdw *hdw)
{
const struct firmware *fw_entry = NULL;
void *fw_ptr;
- unsigned int pipe, fw_len, fw_done;
+ unsigned int pipe, fw_len, fw_done, bcnt, icnt;
int actual_length;
int ret = 0;
int fwidx;
@@ -1257,8 +1256,13 @@ int pvr2_upload_firmware2(struct pvr2_hdw *hdw)
ret |= pvr2_write_register(hdw, 0xaa04, 0x00057810); /*unknown*/
ret |= pvr2_write_register(hdw, 0xaa10, 0x00148500); /*unknown*/
ret |= pvr2_write_register(hdw, 0xaa18, 0x00840000); /*unknown*/
- ret |= pvr2_write_u8(hdw, 0x52, 0);
- ret |= pvr2_write_u16(hdw, 0x0600, 0);
+ LOCK_TAKE(hdw->ctl_lock); do {
+ hdw->cmd_buffer[0] = FX2CMD_FWPOST1;
+ ret |= pvr2_send_request(hdw,hdw->cmd_buffer,1,0,0);
+ hdw->cmd_buffer[0] = FX2CMD_MEMSEL;
+ hdw->cmd_buffer[1] = 0;
+ ret |= pvr2_send_request(hdw,hdw->cmd_buffer,2,0,0);
+ } while (0); LOCK_GIVE(hdw->ctl_lock);
if (ret) {
pvr2_trace(PVR2_TRACE_ERROR_LEGS,
@@ -1271,11 +1275,11 @@ int pvr2_upload_firmware2(struct pvr2_hdw *hdw)
fw_len = fw_entry->size;
- if (fw_len % FIRMWARE_CHUNK_SIZE) {
+ if (fw_len % sizeof(u32)) {
pvr2_trace(PVR2_TRACE_ERROR_LEGS,
"size of %s firmware"
- " must be a multiple of 8192B",
- fw_files[fwidx]);
+ " must be a multiple of %u bytes",
+ fw_files[fwidx],sizeof(u32));
release_firmware(fw_entry);
return -1;
}
@@ -1290,18 +1294,21 @@ int pvr2_upload_firmware2(struct pvr2_hdw *hdw)
pipe = usb_sndbulkpipe(hdw->usb_dev, PVR2_FIRMWARE_ENDPOINT);
- for (fw_done = 0 ; (fw_done < fw_len) && !ret ;
- fw_done += FIRMWARE_CHUNK_SIZE ) {
- int i;
- memcpy(fw_ptr, fw_entry->data + fw_done, FIRMWARE_CHUNK_SIZE);
- /* Usbsnoop log shows that we must swap bytes... */
- for (i = 0; i < FIRMWARE_CHUNK_SIZE/4 ; i++)
- ((u32 *)fw_ptr)[i] = ___swab32(((u32 *)fw_ptr)[i]);
-
- ret |= usb_bulk_msg(hdw->usb_dev, pipe, fw_ptr,
- FIRMWARE_CHUNK_SIZE,
+ fw_done = 0;
+ for (fw_done = 0; fw_done < fw_len;) {
+ bcnt = fw_len - fw_done;
+ if (bcnt > FIRMWARE_CHUNK_SIZE) bcnt = FIRMWARE_CHUNK_SIZE;
+ memcpy(fw_ptr, fw_entry->data + fw_done, bcnt);
+ /* Usbsnoop log shows that we must swap bytes... */
+ for (icnt = 0; icnt < bcnt/4 ; icnt++)
+ ((u32 *)fw_ptr)[icnt] =
+ ___swab32(((u32 *)fw_ptr)[icnt]);
+
+ ret |= usb_bulk_msg(hdw->usb_dev, pipe, fw_ptr,bcnt,
&actual_length, HZ);
- ret |= (actual_length != FIRMWARE_CHUNK_SIZE);
+ ret |= (actual_length != bcnt);
+ if (ret) break;
+ fw_done += bcnt;
}
trace_firmware("upload of %s : %i / %i ",
@@ -1320,7 +1327,11 @@ int pvr2_upload_firmware2(struct pvr2_hdw *hdw)
ret |= pvr2_write_register(hdw, 0x9054, 0xffffffff); /*reset hw blocks*/
ret |= pvr2_write_register(hdw, 0x9058, 0xffffffe8); /*VPU ctrl*/
- ret |= pvr2_write_u16(hdw, 0x0600, 0);
+ LOCK_TAKE(hdw->ctl_lock); do {
+ hdw->cmd_buffer[0] = FX2CMD_MEMSEL;
+ hdw->cmd_buffer[1] = 0;
+ ret |= pvr2_send_request(hdw,hdw->cmd_buffer,2,0,0);
+ } while (0); LOCK_GIVE(hdw->ctl_lock);
if (ret) {
pvr2_trace(PVR2_TRACE_ERROR_LEGS,
@@ -1674,7 +1685,7 @@ static int pvr2_hdw_check_firmware(struct pvr2_hdw *hdw)
firmware needs be loaded. */
int result;
LOCK_TAKE(hdw->ctl_lock); do {
- hdw->cmd_buffer[0] = 0xeb;
+ hdw->cmd_buffer[0] = FX2CMD_GET_EEPROM_ADDR;
result = pvr2_send_request_ex(hdw,HZ*1,!0,
hdw->cmd_buffer,1,
hdw->cmd_buffer,1);
@@ -2565,7 +2576,7 @@ int pvr2_hdw_is_hsm(struct pvr2_hdw *hdw)
{
int result;
LOCK_TAKE(hdw->ctl_lock); do {
- hdw->cmd_buffer[0] = 0x0b;
+ hdw->cmd_buffer[0] = FX2CMD_GET_USB_SPEED;
result = pvr2_send_request(hdw,
hdw->cmd_buffer,1,
hdw->cmd_buffer,1);
@@ -3089,7 +3100,7 @@ int pvr2_write_register(struct pvr2_hdw *hdw, u16 reg, u32 data)
LOCK_TAKE(hdw->ctl_lock);
- hdw->cmd_buffer[0] = 0x04; /* write register prefix */
+ hdw->cmd_buffer[0] = FX2CMD_REG_WRITE; /* write register prefix */
PVR2_DECOMPOSE_LE(hdw->cmd_buffer,1,data);
hdw->cmd_buffer[5] = 0;
hdw->cmd_buffer[6] = (reg >> 8) & 0xff;
@@ -3110,7 +3121,7 @@ static int pvr2_read_register(struct pvr2_hdw *hdw, u16 reg, u32 *data)
LOCK_TAKE(hdw->ctl_lock);
- hdw->cmd_buffer[0] = 0x05; /* read register prefix */
+ hdw->cmd_buffer[0] = FX2CMD_REG_READ; /* read register prefix */
hdw->cmd_buffer[1] = 0;
hdw->cmd_buffer[2] = 0;
hdw->cmd_buffer[3] = 0;
@@ -3128,39 +3139,6 @@ static int pvr2_read_register(struct pvr2_hdw *hdw, u16 reg, u32 *data)
}
-static int pvr2_write_u16(struct pvr2_hdw *hdw, u16 data, int res)
-{
- int ret;
-
- LOCK_TAKE(hdw->ctl_lock);
-
- hdw->cmd_buffer[0] = (data >> 8) & 0xff;
- hdw->cmd_buffer[1] = data & 0xff;
-
- ret = pvr2_send_request(hdw, hdw->cmd_buffer, 2, hdw->cmd_buffer, res);
-
- LOCK_GIVE(hdw->ctl_lock);
-
- return ret;
-}
-
-
-static int pvr2_write_u8(struct pvr2_hdw *hdw, u8 data, int res)
-{
- int ret;
-
- LOCK_TAKE(hdw->ctl_lock);
-
- hdw->cmd_buffer[0] = data;
-
- ret = pvr2_send_request(hdw, hdw->cmd_buffer, 1, hdw->cmd_buffer, res);
-
- LOCK_GIVE(hdw->ctl_lock);
-
- return ret;
-}
-
-
static void pvr2_hdw_render_useless_unlocked(struct pvr2_hdw *hdw)
{
if (!hdw->flag_ok) return;
@@ -3234,7 +3212,7 @@ int pvr2_hdw_cmd_deep_reset(struct pvr2_hdw *hdw)
LOCK_TAKE(hdw->ctl_lock); do {
pvr2_trace(PVR2_TRACE_INIT,"Requesting uproc hard reset");
hdw->flag_ok = !0;
- hdw->cmd_buffer[0] = 0xdd;
+ hdw->cmd_buffer[0] = FX2CMD_DEEP_RESET;
status = pvr2_send_request(hdw,hdw->cmd_buffer,1,NULL,0);
} while (0); LOCK_GIVE(hdw->ctl_lock);
return status;
@@ -3246,7 +3224,7 @@ int pvr2_hdw_cmd_powerup(struct pvr2_hdw *hdw)
int status;
LOCK_TAKE(hdw->ctl_lock); do {
pvr2_trace(PVR2_TRACE_INIT,"Requesting powerup");
- hdw->cmd_buffer[0] = 0xde;
+ hdw->cmd_buffer[0] = FX2CMD_POWER_ON;
status = pvr2_send_request(hdw,hdw->cmd_buffer,1,NULL,0);
} while (0); LOCK_GIVE(hdw->ctl_lock);
return status;
@@ -3279,7 +3257,8 @@ static int pvr2_hdw_cmd_usbstream(struct pvr2_hdw *hdw,int runFl)
{
int status;
LOCK_TAKE(hdw->ctl_lock); do {
- hdw->cmd_buffer[0] = (runFl ? 0x36 : 0x37);
+ hdw->cmd_buffer[0] =
+ (runFl ? FX2CMD_STREAMING_ON : FX2CMD_STREAMING_OFF);
status = pvr2_send_request(hdw,hdw->cmd_buffer,1,NULL,0);
} while (0); LOCK_GIVE(hdw->ctl_lock);
if (!status) {
@@ -3378,7 +3357,7 @@ static int pvr2_hdw_get_eeprom_addr(struct pvr2_hdw *hdw)
{
int result;
LOCK_TAKE(hdw->ctl_lock); do {
- hdw->cmd_buffer[0] = 0xeb;
+ hdw->cmd_buffer[0] = FX2CMD_GET_EEPROM_ADDR;
result = pvr2_send_request(hdw,
hdw->cmd_buffer,1,
hdw->cmd_buffer,1);
@@ -3390,7 +3369,7 @@ static int pvr2_hdw_get_eeprom_addr(struct pvr2_hdw *hdw)
int pvr2_hdw_register_access(struct pvr2_hdw *hdw,
- u32 chip_id,unsigned long reg_id,
+ u32 chip_id, u64 reg_id,
int setFl,u32 *val_ptr)
{
#ifdef CONFIG_VIDEO_ADV_DEBUG
@@ -3400,6 +3379,8 @@ int pvr2_hdw_register_access(struct pvr2_hdw *hdw,
int stat = 0;
int okFl = 0;
+ if (!capable(CAP_SYS_ADMIN)) return -EPERM;
+
req.i2c_id = chip_id;
req.reg = reg_id;
if (setFl) req.val = *val_ptr;
@@ -3408,8 +3389,8 @@ int pvr2_hdw_register_access(struct pvr2_hdw *hdw,
cp = list_entry(item,struct pvr2_i2c_client,list);
if (cp->client->driver->id != chip_id) continue;
stat = pvr2_i2c_client_cmd(
- cp,(setFl ? VIDIOC_INT_S_REGISTER :
- VIDIOC_INT_G_REGISTER),&req);
+ cp,(setFl ? VIDIOC_DBG_S_REGISTER :
+ VIDIOC_DBG_G_REGISTER),&req);
if (!setFl) *val_ptr = req.val;
okFl = !0;
break;
diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.h b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.h
index ab99bea88..aa45114ba 100644
--- a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.h
+++ b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.h
@@ -231,7 +231,7 @@ void pvr2_hdw_v4l_store_minor_number(struct pvr2_hdw *,
setFl - true to set the register, false to read it
val_ptr - storage location for source / result. */
int pvr2_hdw_register_access(struct pvr2_hdw *,
- u32 chip_id,unsigned long reg_id,
+ u32 chip_id,u64 reg_id,
int setFl,u32 *val_ptr);
/* The following entry points are all lower level things you normally don't
diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c b/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
index 4a4f1d64b..215fbf473 100644
--- a/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
+++ b/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
@@ -23,6 +23,7 @@
#include "pvrusb2-i2c-core.h"
#include "pvrusb2-hdw-internal.h"
#include "pvrusb2-debug.h"
+#include "pvrusb2-fx2-cmd.h"
#define trace_i2c(...) pvr2_trace(PVR2_TRACE_I2C,__VA_ARGS__)
@@ -70,7 +71,7 @@ static int pvr2_i2c_write(struct pvr2_hdw *hdw, /* Context */
memset(hdw->cmd_buffer, 0, sizeof(hdw->cmd_buffer));
/* Set up command buffer for an I2C write */
- hdw->cmd_buffer[0] = 0x08; /* write prefix */
+ hdw->cmd_buffer[0] = FX2CMD_I2C_WRITE; /* write prefix */
hdw->cmd_buffer[1] = i2c_addr; /* i2c addr of chip */
hdw->cmd_buffer[2] = length; /* length of what follows */
if (length) memcpy(hdw->cmd_buffer + 3, data, length);
@@ -139,7 +140,7 @@ static int pvr2_i2c_read(struct pvr2_hdw *hdw, /* Context */
memset(hdw->cmd_buffer, 0, sizeof(hdw->cmd_buffer));
/* Set up command buffer for an I2C write followed by a read */
- hdw->cmd_buffer[0] = 0x09; /* read prefix */
+ hdw->cmd_buffer[0] = FX2CMD_I2C_READ; /* read prefix */
hdw->cmd_buffer[1] = dlen; /* arg length */
hdw->cmd_buffer[2] = rlen; /* answer length. Device will send one
more byte (status). */
@@ -296,7 +297,7 @@ static int i2c_24xxx_ir(struct pvr2_hdw *hdw,
/* Issue a command to the FX2 to read the IR receiver. */
LOCK_TAKE(hdw->ctl_lock); do {
- hdw->cmd_buffer[0] = 0xec;
+ hdw->cmd_buffer[0] = FX2CMD_GET_IR_CODE;
stat = pvr2_send_request(hdw,
hdw->cmd_buffer,1,
hdw->cmd_buffer,4);
@@ -1089,6 +1090,7 @@ void pvr2_i2c_core_init(struct pvr2_hdw *hdw)
memcpy(&hdw->i2c_adap,&pvr2_i2c_adap_template,sizeof(hdw->i2c_adap));
memcpy(&hdw->i2c_algo,&pvr2_i2c_algo_template,sizeof(hdw->i2c_algo));
strlcpy(hdw->i2c_adap.name,hdw->name,sizeof(hdw->i2c_adap.name));
+ hdw->i2c_adap.dev.parent = &hdw->usb_dev->dev;
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14)
strlcpy(hdw->i2c_algo.name,hdw->name,sizeof(hdw->i2c_algo.name));
#endif
diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-v4l2.c b/linux/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
index 621a0dd31..165c00f44 100644
--- a/linux/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
+++ b/linux/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
@@ -367,8 +367,7 @@ static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file,
{
struct v4l2_tuner *vt = (struct v4l2_tuner *)arg;
- if (vt->index != 0)
- break;
+ if (vt->index != 0) break; /* Only answer for the 1st tuner */
pvr2_hdw_execute_tuner_poll(hdw);
ret = pvr2_hdw_get_tuner_status(hdw,vt);
@@ -739,16 +738,16 @@ static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file,
break;
}
#ifdef CONFIG_VIDEO_ADV_DEBUG
- case VIDIOC_INT_G_REGISTER:
- case VIDIOC_INT_S_REGISTER:
+ case VIDIOC_DBG_S_REGISTER:
+ case VIDIOC_DBG_G_REGISTER:
{
u32 val;
struct v4l2_register *req = (struct v4l2_register *)arg;
- if (cmd == VIDIOC_INT_S_REGISTER) val = req->val;
+ if (cmd == VIDIOC_DBG_S_REGISTER) val = req->val;
ret = pvr2_hdw_register_access(
hdw,req->i2c_id,req->reg,
- cmd == VIDIOC_INT_S_REGISTER,&val);
- if (cmd == VIDIOC_INT_G_REGISTER) req->val = val;
+ cmd == VIDIOC_DBG_S_REGISTER,&val);
+ if (cmd == VIDIOC_DBG_G_REGISTER) req->val = val;
break;
}
#endif
diff --git a/linux/drivers/media/video/pwc/Makefile b/linux/drivers/media/video/pwc/Makefile
index 9db2260d1..f5c8ec261 100644
--- a/linux/drivers/media/video/pwc/Makefile
+++ b/linux/drivers/media/video/pwc/Makefile
@@ -2,11 +2,3 @@ pwc-objs := pwc-if.o pwc-misc.o pwc-ctrl.o pwc-v4l.o pwc-uncompress.o
pwc-objs += pwc-dec1.o pwc-dec23.o pwc-kiara.o pwc-timon.o
obj-$(CONFIG_USB_PWC) += pwc.o
-
-ifeq ($(CONFIG_USB_PWC_DEBUG),y)
-EXTRA_CFLAGS += -DCONFIG_PWC_DEBUG=1
-else
-EXTRA_CFLAGS += -DCONFIG_PWC_DEBUG=0
-endif
-
-
diff --git a/linux/drivers/media/video/pwc/pwc-if.c b/linux/drivers/media/video/pwc/pwc-if.c
index 39aca8e12..444148f02 100644
--- a/linux/drivers/media/video/pwc/pwc-if.c
+++ b/linux/drivers/media/video/pwc/pwc-if.c
@@ -128,7 +128,7 @@ static int default_size = PSZ_QCIF;
static int default_fps = 10;
static int default_fbufs = 3; /* Default number of frame buffers */
int pwc_mbufs = 2; /* Default number of mmap() buffers */
-#if CONFIG_PWC_DEBUG
+#ifdef CONFIG_USB_PWC_DEBUG
int pwc_trace = PWC_DEBUG_LEVEL;
#endif
static int power_save = 0;
@@ -1088,7 +1088,7 @@ static void pwc_remove_sysfs_files(struct video_device *vdev)
video_device_remove_file(vdev, &class_device_attr_button);
}
-#if CONFIG_PWC_DEBUG
+#ifdef CONFIG_USB_PWC_DEBUG
static const char *pwc_sensor_type_to_string(unsigned int sensor_type)
{
switch(sensor_type) {
@@ -1887,7 +1887,7 @@ module_param(size, charp, 0444);
module_param(fps, int, 0444);
module_param(fbufs, int, 0444);
module_param(mbufs, int, 0444);
-#if CONFIG_PWC_DEBUG
+#ifdef CONFIG_USB_PWC_DEBUG
module_param_named(trace, pwc_trace, int, 0644);
#endif
module_param(power_save, int, 0444);
@@ -1965,7 +1965,7 @@ static int __init usb_pwc_init(void)
default_fbufs = fbufs;
PWC_DEBUG_MODULE("Number of frame buffers set to %d.\n", default_fbufs);
}
-#if CONFIG_PWC_DEBUG
+#ifdef CONFIG_USB_PWC_DEBUG
if (pwc_trace >= 0) {
PWC_DEBUG_MODULE("Trace options: 0x%04x\n", pwc_trace);
}
diff --git a/linux/drivers/media/video/pwc/pwc-v4l.c b/linux/drivers/media/video/pwc/pwc-v4l.c
index bd918b87c..2d5bb48f3 100644
--- a/linux/drivers/media/video/pwc/pwc-v4l.c
+++ b/linux/drivers/media/video/pwc/pwc-v4l.c
@@ -352,7 +352,7 @@ int pwc_video_do_ioctl(struct inode *inode, struct file *file,
if (pdev == NULL)
return -EFAULT;
-#if CONFIG_PWC_DEBUG
+#ifdef CONFIG_USB_PWC_DEBUG
if (PWC_DEBUG_LEVEL_IOCTL & pwc_trace)
v4l_printk_ioctl(cmd);
#endif
diff --git a/linux/drivers/media/video/pwc/pwc.h b/linux/drivers/media/video/pwc/pwc.h
index 7e9c4237d..e778a2b8c 100644
--- a/linux/drivers/media/video/pwc/pwc.h
+++ b/linux/drivers/media/video/pwc/pwc.h
@@ -39,11 +39,6 @@
#include "pwc-uncompress.h"
#include <media/pwc-ioctl.h>
-/* Turn some debugging options on/off */
-#ifndef CONFIG_PWC_DEBUG
-#define CONFIG_PWC_DEBUG 1
-#endif
-
/* Version block */
#define PWC_MAJOR 10
#define PWC_MINOR 0
@@ -76,7 +71,7 @@
#define PWC_DEBUG_TRACE(fmt, args...) PWC_DEBUG(TRACE, fmt, ##args)
-#if CONFIG_PWC_DEBUG
+#ifdef CONFIG_USB_PWC_DEBUG
#define PWC_DEBUG_LEVEL (PWC_DEBUG_LEVEL_MODULE)
@@ -270,7 +265,7 @@ extern "C" {
#endif
/* Global variables */
-#if CONFIG_PWC_DEBUG
+#ifdef CONFIG_USB_PWC_DEBUG
extern int pwc_trace;
#endif
extern int pwc_mbufs;
diff --git a/linux/drivers/media/video/saa5246a.c b/linux/drivers/media/video/saa5246a.c
index 8de0cbc87..752ab1651 100644
--- a/linux/drivers/media/video/saa5246a.c
+++ b/linux/drivers/media/video/saa5246a.c
@@ -122,7 +122,7 @@ static int saa5246a_attach(struct i2c_adapter *adap, int addr, int kind)
for (pgbuf = 0; pgbuf < NUM_DAUS; pgbuf++)
{
memset(t->pgbuf[pgbuf], ' ', sizeof(t->pgbuf[0]));
- t->is_searching[pgbuf] = FALSE;
+ t->is_searching[pgbuf] = false;
}
vd->priv=t;
@@ -209,7 +209,7 @@ static int i2c_senddata(struct saa5246a_device *t, ...)
/* Get count number of bytes from I²C-device at address adr, store them in buf.
* Start & stop handshaking is done by this routine, ack will be sent after the
- * last byte to inhibit further sending of data. If uaccess is TRUE, data is
+ * last byte to inhibit further sending of data. If uaccess is 'true', data is
* written to user-space with put_user. Returns -1 if I²C-device didn't send
* acknowledge, 0 otherwise
*/
@@ -349,7 +349,7 @@ static int saa5246a_request_page(struct saa5246a_device *t,
return -EIO;
}
- t->is_searching[req->pgbuf] = TRUE;
+ t->is_searching[req->pgbuf] = true;
return 0;
}
@@ -463,7 +463,7 @@ static inline int saa5246a_get_status(struct saa5246a_device *t,
}
}
if (!info->hamming && !info->notfound)
- t->is_searching[dau_no] = FALSE;
+ t->is_searching[dau_no] = false;
return 0;
}
@@ -575,7 +575,7 @@ static inline int saa5246a_stop_dau(struct saa5246a_device *t,
{
return -EIO;
}
- t->is_searching[dau_no] = FALSE;
+ t->is_searching[dau_no] = false;
return 0;
}
diff --git a/linux/drivers/media/video/saa5246a.h b/linux/drivers/media/video/saa5246a.h
index 7b9111230..64394c036 100644
--- a/linux/drivers/media/video/saa5246a.h
+++ b/linux/drivers/media/video/saa5246a.h
@@ -41,23 +41,18 @@
#define POS_HEADER_START 7
#define POS_HEADER_END 31
-/* Returns TRUE if the part of the videotext page described with req contains
+/* Returns 'true' if the part of the videotext page described with req contains
(at least parts of) the time field */
#define REQ_CONTAINS_TIME(p_req) \
((p_req)->start <= POS_TIME_END && \
(p_req)->end >= POS_TIME_START)
-/* Returns TRUE if the part of the videotext page described with req contains
+/* Returns 'true' if the part of the videotext page described with req contains
(at least parts of) the page header */
#define REQ_CONTAINS_HEADER(p_req) \
((p_req)->start <= POS_HEADER_END && \
(p_req)->end >= POS_HEADER_START)
-#ifndef FALSE
-#define FALSE 0
-#define TRUE 1
-#endif
-
/*****************************************************************************/
/* Mode register numbers of the SAA5246A */
/*****************************************************************************/
diff --git a/linux/drivers/media/video/saa5249.c b/linux/drivers/media/video/saa5249.c
index 04ca4c336..040b521f0 100644
--- a/linux/drivers/media/video/saa5249.c
+++ b/linux/drivers/media/video/saa5249.c
@@ -131,11 +131,6 @@ struct saa5249_device
/* General defines and debugging support */
-#ifndef FALSE
-#define FALSE 0
-#define TRUE 1
-#endif
-
#define RESCHED do { cond_resched(); } while(0)
static struct video_device saa_template; /* Declared near bottom */
@@ -193,9 +188,9 @@ static int saa5249_attach(struct i2c_adapter *adap, int addr, int kind)
memset(t->vdau[pgbuf].sregs, 0, sizeof(t->vdau[0].sregs));
memset(t->vdau[pgbuf].laststat, 0, sizeof(t->vdau[0].laststat));
t->vdau[pgbuf].expire = 0;
- t->vdau[pgbuf].clrfound = TRUE;
- t->vdau[pgbuf].stopped = TRUE;
- t->is_searching[pgbuf] = FALSE;
+ t->vdau[pgbuf].clrfound = true;
+ t->vdau[pgbuf].stopped = true;
+ t->is_searching[pgbuf] = false;
}
vd->priv=t;
@@ -308,7 +303,7 @@ static int i2c_senddata(struct saa5249_device *t, ...)
/* Get count number of bytes from I²C-device at address adr, store them in buf. Start & stop
* handshaking is done by this routine, ack will be sent after the last byte to inhibit further
- * sending of data. If uaccess is TRUE, data is written to user-space with put_user.
+ * sending of data. If uaccess is 'true', data is written to user-space with put_user.
* Returns -1 if I²C-device didn't send acknowledge, 0 otherwise
*/
@@ -327,7 +322,7 @@ static int i2c_getdata(struct saa5249_device *t, int count, u8 *buf)
static int do_saa5249_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, void *arg)
{
- static int virtual_mode = FALSE;
+ static int virtual_mode = false;
struct video_device *vd = video_devdata(file);
struct saa5249_device *t=vd->priv;
@@ -350,7 +345,7 @@ static int do_saa5249_ioctl(struct inode *inode, struct file *file,
if (req->pgbuf < 0 || req->pgbuf >= NUM_DAUS)
return -EINVAL;
memset(t->vdau[req->pgbuf].pgbuf, ' ', sizeof(t->vdau[0].pgbuf));
- t->vdau[req->pgbuf].clrfound = TRUE;
+ t->vdau[req->pgbuf].clrfound = true;
return 0;
}
@@ -360,7 +355,7 @@ static int do_saa5249_ioctl(struct inode *inode, struct file *file,
if (req->pgbuf < 0 || req->pgbuf >= NUM_DAUS)
return -EINVAL;
- t->vdau[req->pgbuf].clrfound = TRUE;
+ t->vdau[req->pgbuf].clrfound = true;
return 0;
}
@@ -386,9 +381,9 @@ static int do_saa5249_ioctl(struct inode *inode, struct file *file,
t->vdau[req->pgbuf].sregs[4] = (req->pagemask & HR_UNIT ? 0x10 : 0) | (req->hour & 0xf);
t->vdau[req->pgbuf].sregs[5] = (req->pagemask & MIN_TEN ? 0x10 : 0) | (req->minute / 0x10);
t->vdau[req->pgbuf].sregs[6] = (req->pagemask & MIN_UNIT ? 0x10 : 0) | (req->minute & 0xf);
- t->vdau[req->pgbuf].stopped = FALSE;
- t->vdau[req->pgbuf].clrfound = TRUE;
- t->is_searching[req->pgbuf] = TRUE;
+ t->vdau[req->pgbuf].stopped = false;
+ t->vdau[req->pgbuf].clrfound = true;
+ t->is_searching[req->pgbuf] = true;
return 0;
}
@@ -440,7 +435,7 @@ static int do_saa5249_ioctl(struct inode *inode, struct file *file,
i2c_getdata(t, 40, t->vdau[req->pgbuf].pgbuf + VTX_PAGESIZE + 23 * 40))
return -EIO;
}
- t->vdau[req->pgbuf].clrfound = FALSE;
+ t->vdau[req->pgbuf].clrfound = false;
memcpy(t->vdau[req->pgbuf].laststat, infobits, sizeof(infobits));
}
else
@@ -484,7 +479,7 @@ static int do_saa5249_ioctl(struct inode *inode, struct file *file,
return -EFAULT;
if (!info.hamming && !info.notfound)
{
- t->is_searching[req->pgbuf] = FALSE;
+ t->is_searching[req->pgbuf] = false;
}
return 0;
}
@@ -540,8 +535,8 @@ static int do_saa5249_ioctl(struct inode *inode, struct file *file,
if (req->pgbuf < 0 || req->pgbuf >= NUM_DAUS)
return -EINVAL;
- t->vdau[req->pgbuf].stopped = TRUE;
- t->is_searching[req->pgbuf] = FALSE;
+ t->vdau[req->pgbuf].stopped = true;
+ t->is_searching[req->pgbuf] = false;
return 0;
}
@@ -670,11 +665,11 @@ static int saa5249_open(struct inode *inode, struct file *file)
memset(t->vdau[pgbuf].sregs, 0, sizeof(t->vdau[0].sregs));
memset(t->vdau[pgbuf].laststat, 0, sizeof(t->vdau[0].laststat));
t->vdau[pgbuf].expire = 0;
- t->vdau[pgbuf].clrfound = TRUE;
- t->vdau[pgbuf].stopped = TRUE;
- t->is_searching[pgbuf] = FALSE;
+ t->vdau[pgbuf].clrfound = true;
+ t->vdau[pgbuf].stopped = true;
+ t->is_searching[pgbuf] = false;
}
- t->virtual_mode=FALSE;
+ t->virtual_mode = false;
return 0;
fail:
diff --git a/linux/drivers/media/video/saa7115.c b/linux/drivers/media/video/saa7115.c
index 462c5dd7f..6163a68e3 100644
--- a/linux/drivers/media/video/saa7115.c
+++ b/linux/drivers/media/video/saa7115.c
@@ -1399,6 +1399,9 @@ static int saa711x_command(struct i2c_client *client, unsigned int cmd, void *ar
{
struct v4l2_sliced_vbi_data *data = arg;
+ /* Note: the internal field ID is inverted for NTSC,
+ so data->field 0 maps to the saa7115 even field,
+ whereas for PAL it maps to the saa7115 odd field. */
switch (data->id) {
case V4L2_SLICED_WSS_625:
if (saa711x_read(client, 0x6b) & 0xc0)
@@ -1409,17 +1412,17 @@ static int saa711x_command(struct i2c_client *client, unsigned int cmd, void *ar
case V4L2_SLICED_CAPTION_525:
if (data->field == 0) {
/* CC */
- if (saa711x_read(client, 0x66) & 0xc0)
+ if (saa711x_read(client, 0x66) & 0x30)
return -EIO;
- data->data[0] = saa711x_read(client, 0x67);
- data->data[1] = saa711x_read(client, 0x68);
+ data->data[0] = saa711x_read(client, 0x69);
+ data->data[1] = saa711x_read(client, 0x6a);
return 0;
}
/* XDS */
- if (saa711x_read(client, 0x66) & 0x30)
+ if (saa711x_read(client, 0x66) & 0xc0)
return -EIO;
- data->data[0] = saa711x_read(client, 0x69);
- data->data[1] = saa711x_read(client, 0x6a);
+ data->data[0] = saa711x_read(client, 0x67);
+ data->data[1] = saa711x_read(client, 0x68);
return 0;
default:
return -EINVAL;
@@ -1428,17 +1431,8 @@ static int saa711x_command(struct i2c_client *client, unsigned int cmd, void *ar
}
#ifdef CONFIG_VIDEO_ADV_DEBUG
- case VIDIOC_INT_G_REGISTER:
- {
- struct v4l2_register *reg = arg;
-
- if (reg->i2c_id != I2C_DRIVERID_SAA711X)
- return -EINVAL;
- reg->val = saa711x_read(client, reg->reg & 0xff);
- break;
- }
-
- case VIDIOC_INT_S_REGISTER:
+ case VIDIOC_DBG_G_REGISTER:
+ case VIDIOC_DBG_S_REGISTER:
{
struct v4l2_register *reg = arg;
@@ -1446,7 +1440,10 @@ static int saa711x_command(struct i2c_client *client, unsigned int cmd, void *ar
return -EINVAL;
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
- saa711x_write(client, reg->reg & 0xff, reg->val & 0xff);
+ if (cmd == VIDIOC_DBG_G_REGISTER)
+ reg->val = saa711x_read(client, reg->reg & 0xff);
+ else
+ saa711x_write(client, reg->reg & 0xff, reg->val & 0xff);
break;
}
#endif
diff --git a/linux/drivers/media/video/saa7127.c b/linux/drivers/media/video/saa7127.c
index f23f2799b..e1e697579 100644
--- a/linux/drivers/media/video/saa7127.c
+++ b/linux/drivers/media/video/saa7127.c
@@ -626,17 +626,8 @@ static int saa7127_command(struct i2c_client *client,
break;
#ifdef CONFIG_VIDEO_ADV_DEBUG
- case VIDIOC_INT_G_REGISTER:
- {
- struct v4l2_register *reg = arg;
-
- if (reg->i2c_id != I2C_DRIVERID_SAA7127)
- return -EINVAL;
- reg->val = saa7127_read(client, reg->reg & 0xff);
- break;
- }
-
- case VIDIOC_INT_S_REGISTER:
+ case VIDIOC_DBG_G_REGISTER:
+ case VIDIOC_DBG_S_REGISTER:
{
struct v4l2_register *reg = arg;
@@ -644,7 +635,10 @@ static int saa7127_command(struct i2c_client *client,
return -EINVAL;
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
- saa7127_write(client, reg->reg & 0xff, reg->val & 0xff);
+ if (cmd == VIDIOC_DBG_G_REGISTER)
+ reg->val = saa7127_read(client, reg->reg & 0xff);
+ else
+ saa7127_write(client, reg->reg & 0xff, reg->val & 0xff);
break;
}
#endif
diff --git a/linux/drivers/media/video/saa7134/Makefile b/linux/drivers/media/video/saa7134/Makefile
index 89a1565b4..c85c8a8ec 100644
--- a/linux/drivers/media/video/saa7134/Makefile
+++ b/linux/drivers/media/video/saa7134/Makefile
@@ -14,7 +14,3 @@ obj-$(CONFIG_VIDEO_SAA7134_DVB) += saa7134-dvb.o
EXTRA_CFLAGS += -Idrivers/media/video
EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
EXTRA_CFLAGS += -Idrivers/media/dvb/frontends
-
-extra-cflags-$(CONFIG_VIDEO_BUF_DVB) += -DHAVE_VIDEO_BUF_DVB=1
-
-EXTRA_CFLAGS += $(extra-cflags-y) $(extra-cflags-m)
diff --git a/linux/drivers/media/video/saa7134/saa7134-i2c.c b/linux/drivers/media/video/saa7134/saa7134-i2c.c
index 0f572899c..8b070d617 100644
--- a/linux/drivers/media/video/saa7134/saa7134-i2c.c
+++ b/linux/drivers/media/video/saa7134/saa7134-i2c.c
@@ -121,9 +121,9 @@ static inline int i2c_is_error(enum i2c_status status)
case ARB_LOST:
case SEQ_ERR:
case ST_ERR:
- return TRUE;
+ return true;
default:
- return FALSE;
+ return false;
}
}
@@ -132,9 +132,9 @@ static inline int i2c_is_idle(enum i2c_status status)
switch (status) {
case IDLE:
case DONE_STOP:
- return TRUE;
+ return true;
default:
- return FALSE;
+ return false;
}
}
@@ -142,9 +142,9 @@ static inline int i2c_is_busy(enum i2c_status status)
{
switch (status) {
case BUSY:
- return TRUE;
+ return true;
default:
- return FALSE;
+ return false;
}
}
@@ -160,8 +160,8 @@ static int i2c_is_busy_wait(struct saa7134_dev *dev)
saa_wait(I2C_WAIT_DELAY);
}
if (I2C_WAIT_RETRY == count)
- return FALSE;
- return TRUE;
+ return false;
+ return true;
}
static int i2c_reset(struct saa7134_dev *dev)
@@ -172,7 +172,7 @@ static int i2c_reset(struct saa7134_dev *dev)
d2printk(KERN_DEBUG "%s: i2c reset\n",dev->name);
status = i2c_get_status(dev);
if (!i2c_is_error(status))
- return TRUE;
+ return true;
i2c_set_status(dev,status);
for (count = 0; count < I2C_WAIT_RETRY; count++) {
@@ -182,13 +182,13 @@ static int i2c_reset(struct saa7134_dev *dev)
udelay(I2C_WAIT_DELAY);
}
if (I2C_WAIT_RETRY == count)
- return FALSE;
+ return false;
if (!i2c_is_idle(status))
- return FALSE;
+ return false;
i2c_set_attr(dev,NOP);
- return TRUE;
+ return true;
}
static inline int i2c_send_byte(struct saa7134_dev *dev,
diff --git a/linux/drivers/media/video/saa7134/saa7134.h b/linux/drivers/media/video/saa7134/saa7134.h
index 764bd4e71..6ca439741 100644
--- a/linux/drivers/media/video/saa7134/saa7134.h
+++ b/linux/drivers/media/video/saa7134/saa7134.h
@@ -48,16 +48,10 @@
#include <sound/core.h>
#include <sound/pcm.h>
#endif
-#ifdef HAVE_VIDEO_BUF_DVB
+#if defined(CONFIG_VIDEO_BUF_DVB) || defined(CONFIG_VIDEO_BUF_DVB_MODULE)
#include <media/video-buf-dvb.h>
#endif
-#ifndef TRUE
-# define TRUE (1==1)
-#endif
-#ifndef FALSE
-# define FALSE (1==0)
-#endif
#define UNSET (-1U)
/* ----------------------------------------------------------- */
@@ -555,7 +549,7 @@ struct saa7134_dev {
struct work_struct empress_workqueue;
int empress_started;
-#ifdef HAVE_VIDEO_BUF_DVB
+#if defined(CONFIG_VIDEO_BUF_DVB) || defined(CONFIG_VIDEO_BUF_DVB_MODULE)
/* SAA7134_MPEG_DVB only */
struct videobuf_dvb dvb;
int (*original_demod_sleep)(struct dvb_frontend* fe);
diff --git a/linux/drivers/media/video/tvp5150.c b/linux/drivers/media/video/tvp5150.c
index 1eb6e96bd..46b97d9b1 100644
--- a/linux/drivers/media/video/tvp5150.c
+++ b/linux/drivers/media/video/tvp5150.c
@@ -1046,17 +1046,8 @@ static int tvp5150_command(struct i2c_client *c,
#endif
#ifdef CONFIG_VIDEO_ADV_DEBUG
- case VIDIOC_INT_G_REGISTER:
- {
- struct v4l2_register *reg = arg;
-
- if (reg->i2c_id != I2C_DRIVERID_TVP5150)
- return -EINVAL;
- reg->val = tvp5150_read(c, reg->reg & 0xff);
- break;
- }
-
- case VIDIOC_INT_S_REGISTER:
+ case VIDIOC_DBG_G_REGISTER:
+ case VIDIOC_DBG_S_REGISTER:
{
struct v4l2_register *reg = arg;
@@ -1064,7 +1055,10 @@ static int tvp5150_command(struct i2c_client *c,
return -EINVAL;
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
- tvp5150_write(c, reg->reg & 0xff, reg->val & 0xff);
+ if (cmd == VIDIOC_DBG_G_REGISTER)
+ reg->val = tvp5150_read(c, reg->reg & 0xff);
+ else
+ tvp5150_write(c, reg->reg & 0xff, reg->val & 0xff);
break;
}
#endif
diff --git a/linux/drivers/media/video/upd64031a.c b/linux/drivers/media/video/upd64031a.c
index 66254bad4..ae0a843ff 100644
--- a/linux/drivers/media/video/upd64031a.c
+++ b/linux/drivers/media/video/upd64031a.c
@@ -170,27 +170,19 @@ static int upd64031a_command(struct i2c_client *client, unsigned int cmd, void *
break;
#ifdef CONFIG_VIDEO_ADV_DEBUG
- case VIDIOC_INT_G_REGISTER:
+ case VIDIOC_DBG_G_REGISTER:
+ case VIDIOC_DBG_S_REGISTER:
{
struct v4l2_register *reg = arg;
if (reg->i2c_id != I2C_DRIVERID_UPD64031A)
return -EINVAL;
- reg->val = upd64031a_read(client, reg->reg & 0xff);
- break;
- }
-
- case VIDIOC_INT_S_REGISTER:
- {
- struct v4l2_register *reg = arg;
- u8 addr = reg->reg & 0xff;
- u8 val = reg->val & 0xff;
-
- if (reg->i2c_id != I2C_DRIVERID_UPD64031A)
- return -EINVAL;
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
- upd64031a_write(client, addr, val);
+ if (cmd == VIDIOC_DBG_G_REGISTER)
+ reg->val = upd64031a_read(client, reg->reg & 0xff);
+ else
+ upd64031a_write(client, reg->reg & 0xff, reg->val & 0xff);
break;
}
#endif
diff --git a/linux/drivers/media/video/upd64083.c b/linux/drivers/media/video/upd64083.c
index 861d9b114..61be85abd 100644
--- a/linux/drivers/media/video/upd64083.c
+++ b/linux/drivers/media/video/upd64083.c
@@ -147,27 +147,19 @@ static int upd64083_command(struct i2c_client *client, unsigned int cmd, void *a
break;
#ifdef CONFIG_VIDEO_ADV_DEBUG
- case VIDIOC_INT_G_REGISTER:
+ case VIDIOC_DBG_G_REGISTER:
+ case VIDIOC_DBG_S_REGISTER:
{
struct v4l2_register *reg = arg;
if (reg->i2c_id != I2C_DRIVERID_UPD64083)
return -EINVAL;
- reg->val = upd64083_read(client, reg->reg & 0xff);
- break;
- }
-
- case VIDIOC_INT_S_REGISTER:
- {
- struct v4l2_register *reg = arg;
- u8 addr = reg->reg & 0xff;
- u8 val = reg->val & 0xff;
-
- if (reg->i2c_id != I2C_DRIVERID_UPD64083)
- return -EINVAL;
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
- upd64083_write(client, addr, val);
+ if (cmd == VIDIOC_DBG_G_REGISTER)
+ reg->val = upd64083_read(client, reg->reg & 0xff);
+ else
+ upd64083_write(client, reg->reg & 0xff, reg->val & 0xff);
break;
}
#endif
diff --git a/linux/drivers/media/video/usbvision/Kconfig b/linux/drivers/media/video/usbvision/Kconfig
index fc24ef05b..c43a5d899 100644
--- a/linux/drivers/media/video/usbvision/Kconfig
+++ b/linux/drivers/media/video/usbvision/Kconfig
@@ -1,6 +1,6 @@
config VIDEO_USBVISION
tristate "USB video devices based on Nogatech NT1003/1004/1005"
- depends on I2C && VIDEO_V4L2
+ depends on I2C && VIDEO_V4L2 && USB
select VIDEO_TUNER
select VIDEO_SAA711X if VIDEO_HELPER_CHIPS_AUTO
---help---
diff --git a/linux/drivers/media/video/usbvision/usbvision-core.c b/linux/drivers/media/video/usbvision/usbvision-core.c
index db466ea0d..54b9ce08e 100644
--- a/linux/drivers/media/video/usbvision/usbvision-core.c
+++ b/linux/drivers/media/video/usbvision/usbvision-core.c
@@ -1916,28 +1916,33 @@ int usbvision_set_output(struct usb_usbvision *usbvision, int width,
/*
* usbvision_frames_alloc
- * allocate the maximum frames this driver can manage
+ * allocate the required frames
*/
-int usbvision_frames_alloc(struct usb_usbvision *usbvision)
+int usbvision_frames_alloc(struct usb_usbvision *usbvision, int number_of_frames)
{
int i;
- /* Allocate memory for the frame buffers */
- usbvision->max_frame_size = MAX_FRAME_SIZE;
- usbvision->fbuf_size = USBVISION_NUMFRAMES * usbvision->max_frame_size;
- usbvision->fbuf = usbvision_rvmalloc(usbvision->fbuf_size);
+ /*needs to be page aligned cause the buffers can be mapped individually! */
+ usbvision->max_frame_size = PAGE_ALIGN(usbvision->curwidth *
+ usbvision->curheight *
+ usbvision->palette.bytes_per_pixel);
- if(usbvision->fbuf == NULL) {
- err("%s: unable to allocate %d bytes for fbuf ",
- __FUNCTION__, usbvision->fbuf_size);
- return -ENOMEM;
+ /* Try to do my best to allocate the frames the user want in the remaining memory */
+ usbvision->num_frames = number_of_frames;
+ while (usbvision->num_frames > 0) {
+ usbvision->fbuf_size = usbvision->num_frames * usbvision->max_frame_size;
+ if((usbvision->fbuf = usbvision_rvmalloc(usbvision->fbuf_size))) {
+ break;
+ }
+ usbvision->num_frames--;
}
+
spin_lock_init(&usbvision->queue_lock);
init_waitqueue_head(&usbvision->wait_frame);
init_waitqueue_head(&usbvision->wait_stream);
/* Allocate all buffers */
- for (i = 0; i < USBVISION_NUMFRAMES; i++) {
+ for (i = 0; i < usbvision->num_frames; i++) {
usbvision->frame[i].index = i;
usbvision->frame[i].grabstate = FrameState_Unused;
usbvision->frame[i].data = usbvision->fbuf +
@@ -1951,7 +1956,8 @@ int usbvision_frames_alloc(struct usb_usbvision *usbvision)
usbvision->frame[i].height = usbvision->curheight;
usbvision->frame[i].bytes_read = 0;
}
- return 0;
+ PDEBUG(DBG_FUNC, "allocated %d frames (%d bytes per frame)",usbvision->num_frames,usbvision->max_frame_size);
+ return usbvision->num_frames;
}
/*
@@ -1961,9 +1967,13 @@ int usbvision_frames_alloc(struct usb_usbvision *usbvision)
void usbvision_frames_free(struct usb_usbvision *usbvision)
{
/* Have to free all that memory */
+ PDEBUG(DBG_FUNC, "free %d frames",usbvision->num_frames);
+
if (usbvision->fbuf != NULL) {
usbvision_rvfree(usbvision->fbuf, usbvision->fbuf_size);
usbvision->fbuf = NULL;
+
+ usbvision->num_frames = 0;
}
}
/*
@@ -2432,6 +2442,32 @@ int usbvision_setup(struct usb_usbvision *usbvision,int format)
return USBVISION_IS_OPERATIONAL(usbvision);
}
+int usbvision_set_alternate(struct usb_usbvision *dev)
+{
+ int errCode, prev_alt = dev->ifaceAlt;
+ int i;
+
+ dev->ifaceAlt=0;
+ for(i=0;i< dev->num_alt; i++)
+ if(dev->alt_max_pkt_size[i]>dev->alt_max_pkt_size[dev->ifaceAlt])
+ dev->ifaceAlt=i;
+
+ if (dev->ifaceAlt != prev_alt) {
+ dev->isocPacketSize = dev->alt_max_pkt_size[dev->ifaceAlt];
+ PDEBUG(DBG_FUNC,"setting alternate %d with wMaxPacketSize=%u", dev->ifaceAlt,dev->isocPacketSize);
+ errCode = usb_set_interface(dev->dev, dev->iface, dev->ifaceAlt);
+ if (errCode < 0) {
+ err ("cannot change alternate number to %d (error=%i)",
+ dev->ifaceAlt, errCode);
+ return errCode;
+ }
+ }
+
+ PDEBUG(DBG_ISOC, "ISO Packet Length:%d", dev->isocPacketSize);
+
+ return 0;
+}
+
/*
* usbvision_init_isoc()
*
@@ -2449,15 +2485,13 @@ int usbvision_init_isoc(struct usb_usbvision *usbvision)
scratch_reset(usbvision);
/* Alternate interface 1 is is the biggest frame size */
- errCode = usb_set_interface(dev, usbvision->iface, usbvision->ifaceAltActive);
+ errCode = usbvision_set_alternate(usbvision);
if (errCode < 0) {
usbvision->last_error = errCode;
return -EBUSY;
}
regValue = (16 - usbvision_read_reg(usbvision, USBVISION_ALTER_REG)) & 0x0F;
- usbvision->isocPacketSize = (regValue == 0) ? 0 : (regValue * 64) - 1;
- PDEBUG(DBG_ISOC, "ISO Packet Length:%d", usbvision->isocPacketSize);
usbvision->usb_bandwidth = regValue >> 1;
PDEBUG(DBG_ISOC, "USB Bandwidth Usage: %dMbit/Sec", usbvision->usb_bandwidth);
@@ -2584,8 +2618,9 @@ void usbvision_stop_isoc(struct usb_usbvision *usbvision)
if (!usbvision->remove_pending) {
/* Set packet size to 0 */
+ usbvision->ifaceAlt=0;
errCode = usb_set_interface(usbvision->dev, usbvision->iface,
- usbvision->ifaceAltInactive);
+ usbvision->ifaceAlt);
if (errCode < 0) {
err("%s: usb_set_interface() failed: error %d", __FUNCTION__, errCode);
usbvision->last_error = errCode;
@@ -2612,6 +2647,7 @@ int usbvision_muxsel(struct usb_usbvision *usbvision, int channel)
RESTRICT_TO_RANGE(channel, 0, usbvision->video_inputs);
usbvision->ctl_input = channel;
route.input = SAA7115_COMPOSITE1;
+ route.output = 0;
call_i2c_clients(usbvision, VIDIOC_INT_S_VIDEO_ROUTING,&route);
call_i2c_clients(usbvision, VIDIOC_S_INPUT, &usbvision->ctl_input);
diff --git a/linux/drivers/media/video/usbvision/usbvision-video.c b/linux/drivers/media/video/usbvision/usbvision-video.c
index d5e1b6b21..e49064de8 100644
--- a/linux/drivers/media/video/usbvision/usbvision-video.c
+++ b/linux/drivers/media/video/usbvision/usbvision-video.c
@@ -241,7 +241,7 @@ static ssize_t show_hue(struct class_device *cd, char *buf)
ctrl.value = 0;
if(usbvision->user)
call_i2c_clients(usbvision, VIDIOC_G_CTRL, &ctrl);
- return sprintf(buf, "%d\n", ctrl.value >> 8);
+ return sprintf(buf, "%d\n", ctrl.value);
}
static CLASS_DEVICE_ATTR(hue, S_IRUGO, show_hue, NULL);
@@ -254,7 +254,7 @@ static ssize_t show_contrast(struct class_device *cd, char *buf)
ctrl.value = 0;
if(usbvision->user)
call_i2c_clients(usbvision, VIDIOC_G_CTRL, &ctrl);
- return sprintf(buf, "%d\n", ctrl.value >> 8);
+ return sprintf(buf, "%d\n", ctrl.value);
}
static CLASS_DEVICE_ATTR(contrast, S_IRUGO, show_contrast, NULL);
@@ -267,7 +267,7 @@ static ssize_t show_brightness(struct class_device *cd, char *buf)
ctrl.value = 0;
if(usbvision->user)
call_i2c_clients(usbvision, VIDIOC_G_CTRL, &ctrl);
- return sprintf(buf, "%d\n", ctrl.value >> 8);
+ return sprintf(buf, "%d\n", ctrl.value);
}
static CLASS_DEVICE_ATTR(brightness, S_IRUGO, show_brightness, NULL);
@@ -280,7 +280,7 @@ static ssize_t show_saturation(struct class_device *cd, char *buf)
ctrl.value = 0;
if(usbvision->user)
call_i2c_clients(usbvision, VIDIOC_G_CTRL, &ctrl);
- return sprintf(buf, "%d\n", ctrl.value >> 8);
+ return sprintf(buf, "%d\n", ctrl.value);
}
static CLASS_DEVICE_ATTR(saturation, S_IRUGO, show_saturation, NULL);
@@ -412,19 +412,14 @@ static int usbvision_v4l2_open(struct inode *inode, struct file *file)
if (usbvision->user)
errCode = -EBUSY;
else {
- /* Allocate memory for the frame buffers */
- errCode = usbvision_frames_alloc(usbvision);
- if(!errCode) {
- /* Allocate memory for the scratch ring buffer */
- errCode = usbvision_scratch_alloc(usbvision);
- if ((!errCode) && (isocMode==ISOC_MODE_COMPRESS)) {
- /* Allocate intermediate decompression buffers only if needed */
- errCode = usbvision_decompress_alloc(usbvision);
- }
+ /* Allocate memory for the scratch ring buffer */
+ errCode = usbvision_scratch_alloc(usbvision);
+ if (isocMode==ISOC_MODE_COMPRESS) {
+ /* Allocate intermediate decompression buffers only if needed */
+ errCode = usbvision_decompress_alloc(usbvision);
}
if (errCode) {
/* Deallocate all buffers if trouble */
- usbvision_frames_free(usbvision);
usbvision_scratch_free(usbvision);
usbvision_decompress_free(usbvision);
}
@@ -506,6 +501,7 @@ static int usbvision_v4l2_close(struct inode *inode, struct file *file)
usbvision_decompress_free(usbvision);
usbvision_frames_free(usbvision);
+ usbvision_empty_framequeues(usbvision);
usbvision_scratch_free(usbvision);
usbvision->user--;
@@ -560,27 +556,8 @@ static int usbvision_v4l2_do_ioctl(struct inode *inode, struct file *file,
#ifdef CONFIG_VIDEO_ADV_DEBUG
/* ioctls to allow direct acces to the NT100x registers */
- case VIDIOC_INT_G_REGISTER:
- {
- struct v4l2_register *reg = arg;
- int errCode;
-
- if (reg->i2c_id != 0)
- return -EINVAL;
- /* NT100x has a 8-bit register space */
- errCode = usbvision_read_reg(usbvision, reg->reg&0xff);
- if (errCode < 0) {
- err("%s: VIDIOC_INT_G_REGISTER failed: error %d", __FUNCTION__, errCode);
- }
- else {
- reg->val=(unsigned char)errCode;
- PDEBUG(DBG_IOCTL, "VIDIOC_INT_G_REGISTER reg=0x%02X, value=0x%02X",
- (unsigned int)reg->reg, reg->val);
- errCode = 0; // No error
- }
- return errCode;
- }
- case VIDIOC_INT_S_REGISTER:
+ case VIDIOC_DBG_G_REGISTER:
+ case VIDIOC_DBG_S_REGISTER:
{
struct v4l2_register *reg = arg;
int errCode;
@@ -589,15 +566,22 @@ static int usbvision_v4l2_do_ioctl(struct inode *inode, struct file *file,
return -EINVAL;
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
- errCode = usbvision_write_reg(usbvision, reg->reg&0xff, reg->val);
+ /* NT100x has a 8-bit register space */
+ if (cmd == VIDIOC_DBG_G_REGISTER)
+ errCode = usbvision_read_reg(usbvision, reg->reg&0xff);
+ else
+ errCode = usbvision_write_reg(usbvision, reg->reg&0xff, reg->val);
if (errCode < 0) {
- err("%s: VIDIOC_INT_S_REGISTER failed: error %d", __FUNCTION__, errCode);
- }
- else {
- PDEBUG(DBG_IOCTL, "VIDIOC_INT_S_REGISTER reg=0x%02X, value=0x%02X",
- (unsigned int)reg->reg, reg->val);
- errCode = 0;
+ err("%s: VIDIOC_DBG_%c_REGISTER failed: error %d", __FUNCTION__,
+ cmd == VIDIOC_DBG_G_REGISTER ? 'G' : 'S', errCode);
+ return errCode;
}
+ if (cmd == VIDIOC_DBG_S_REGISTER)
+ reg->val = (u8)errCode;
+
+ PDEBUG(DBG_IOCTL, "VIDIOC_DBG_%c_REGISTER reg=0x%02X, value=0x%02X",
+ cmd == VIDIOC_DBG_G_REGISTER ? 'G' : 'S',
+ (unsigned int)reg->reg, reg->val);
return 0;
}
#endif
@@ -833,8 +817,8 @@ static int usbvision_v4l2_do_ioctl(struct inode *inode, struct file *file,
case VIDIOC_G_CTRL:
{
struct v4l2_control *ctrl = arg;
- PDEBUG(DBG_IOCTL,"VIDIOC_G_CTRL id=%x value=%x",ctrl->id,ctrl->value);
call_i2c_clients(usbvision, VIDIOC_G_CTRL, ctrl);
+ PDEBUG(DBG_IOCTL,"VIDIOC_G_CTRL id=%x value=%x",ctrl->id,ctrl->value);
return 0;
}
case VIDIOC_S_CTRL:
@@ -862,7 +846,9 @@ static int usbvision_v4l2_do_ioctl(struct inode *inode, struct file *file,
return ret;
}
+ usbvision_frames_free(usbvision);
usbvision_empty_framequeues(usbvision);
+ vr->count = usbvision_frames_alloc(usbvision,vr->count);
usbvision->curFrame = NULL;
@@ -879,7 +865,7 @@ static int usbvision_v4l2_do_ioctl(struct inode *inode, struct file *file,
if(vb->type != V4L2_CAP_VIDEO_CAPTURE) {
return -EINVAL;
}
- if(vb->index>=USBVISION_NUMFRAMES) {
+ if(vb->index>=usbvision->num_frames) {
return -EINVAL;
}
// Updating the corresponding frame state
@@ -893,7 +879,7 @@ static int usbvision_v4l2_do_ioctl(struct inode *inode, struct file *file,
vb->flags |= V4L2_BUF_FLAG_MAPPED;
vb->memory = V4L2_MEMORY_MMAP;
- vb->m.offset = vb->index*usbvision->max_frame_size;
+ vb->m.offset = vb->index*PAGE_ALIGN(usbvision->max_frame_size);
vb->memory = V4L2_MEMORY_MMAP;
vb->field = V4L2_FIELD_NONE;
@@ -912,7 +898,7 @@ static int usbvision_v4l2_do_ioctl(struct inode *inode, struct file *file,
if(vb->type != V4L2_CAP_VIDEO_CAPTURE) {
return -EINVAL;
}
- if(vb->index>=USBVISION_NUMFRAMES) {
+ if(vb->index>=usbvision->num_frames) {
return -EINVAL;
}
@@ -1082,6 +1068,7 @@ static int usbvision_v4l2_do_ioctl(struct inode *inode, struct file *file,
if ((ret = usbvision_stream_interrupt(usbvision)))
return ret;
}
+ usbvision_frames_free(usbvision);
usbvision_empty_framequeues(usbvision);
usbvision->curFrame = NULL;
@@ -1142,12 +1129,24 @@ static ssize_t usbvision_v4l2_read(struct file *file, char *buf,
if (!USBVISION_IS_OPERATIONAL(usbvision) || (buf == NULL))
return -EFAULT;
- /* no stream is running, make it running ! */
- usbvision->streaming = Stream_On;
- call_i2c_clients(usbvision,VIDIOC_STREAMON , NULL);
+ /* This entry point is compatible with the mmap routines so that a user can do either
+ VIDIOC_QBUF/VIDIOC_DQBUF to get frames or call read on the device. */
+ if(!usbvision->num_frames) {
+ /* First, allocate some frames to work with if this has not been done with
+ VIDIOC_REQBUF */
+ usbvision_frames_free(usbvision);
+ usbvision_empty_framequeues(usbvision);
+ usbvision_frames_alloc(usbvision,USBVISION_NUMFRAMES);
+ }
+
+ if(usbvision->streaming != Stream_On) {
+ /* no stream is running, make it running ! */
+ usbvision->streaming = Stream_On;
+ call_i2c_clients(usbvision,VIDIOC_STREAMON , NULL);
+ }
- /* First, enqueue as many frames as possible (like a user of VIDIOC_QBUF would do) */
- for(i=0;i<USBVISION_NUMFRAMES;i++) {
+ /* Then, enqueue as many frames as possible (like a user of VIDIOC_QBUF would do) */
+ for(i=0;i<usbvision->num_frames;i++) {
frame = &usbvision->frame[i];
if(frame->grabstate == FrameState_Unused) {
/* Mark it as ready and enqueue frame */
@@ -1224,6 +1223,8 @@ static int usbvision_v4l2_mmap(struct file *file, struct vm_area_struct *vma)
struct video_device *dev = video_devdata(file);
struct usb_usbvision *usbvision = (struct usb_usbvision *) video_get_drvdata(dev);
+ PDEBUG(DBG_MMAP, "mmap");
+
down(&usbvision->lock);
if (!USBVISION_IS_OPERATIONAL(usbvision)) {
@@ -1232,16 +1233,16 @@ static int usbvision_v4l2_mmap(struct file *file, struct vm_area_struct *vma)
}
if (!(vma->vm_flags & VM_WRITE) ||
- size != PAGE_ALIGN(usbvision->curwidth*usbvision->curheight*usbvision->palette.bytes_per_pixel)) {
+ size != PAGE_ALIGN(usbvision->max_frame_size)) {
up(&usbvision->lock);
return -EINVAL;
}
- for (i = 0; i < USBVISION_NUMFRAMES; i++) {
- if (((usbvision->max_frame_size*i) >> PAGE_SHIFT) == vma->vm_pgoff)
+ for (i = 0; i < usbvision->num_frames; i++) {
+ if (((PAGE_ALIGN(usbvision->max_frame_size)*i) >> PAGE_SHIFT) == vma->vm_pgoff)
break;
}
- if (i == USBVISION_NUMFRAMES) {
+ if (i == usbvision->num_frames) {
PDEBUG(DBG_MMAP, "mmap: user supplied mapping address is out of range");
up(&usbvision->lock);
return -EINVAL;
@@ -1316,6 +1317,13 @@ static int usbvision_radio_open(struct inode *inode, struct file *file)
}
}
+ /* Alternate interface 1 is is the biggest frame size */
+ errCode = usbvision_set_alternate(usbvision);
+ if (errCode < 0) {
+ usbvision->last_error = errCode;
+ return -EBUSY;
+ }
+
// If so far no errors then we shall start the radio
usbvision->radio = 1;
call_i2c_clients(usbvision,AUDC_SET_RADIO,&usbvision->tuner_type);
@@ -1356,6 +1364,11 @@ static int usbvision_radio_close(struct inode *inode, struct file *file)
down(&usbvision->lock);
+ /* Set packet size to 0 */
+ usbvision->ifaceAlt=0;
+ errCode = usb_set_interface(usbvision->dev, usbvision->iface,
+ usbvision->ifaceAlt);
+
usbvision_audio_off(usbvision);
usbvision->radio=0;
usbvision->user--;
@@ -1950,16 +1963,18 @@ static void *usbvision_probe(struct usb_device *dev, unsigned int ifnum,
#else
static int __devinit usbvision_probe(struct usb_interface *intf, const struct usb_device_id *devid)
{
- struct usb_device *dev = interface_to_usbdev(intf);
+ struct usb_device *dev = usb_get_dev(interface_to_usbdev(intf));
+ struct usb_interface *uif;
__u8 ifnum = intf->altsetting->desc.bInterfaceNumber;
const struct usb_host_interface *interface;
#endif
struct usb_usbvision *usbvision = NULL;
const struct usb_endpoint_descriptor *endpoint;
- int model;
+ int model,i;
PDEBUG(DBG_PROBE, "VID=%#04x, PID=%#04x, ifnum=%u",
dev->descriptor.idVendor, dev->descriptor.idProduct, ifnum);
+
/* Is it an USBVISION video dev? */
model = 0;
for(model = 0; usbvision_device_data[model].idVendor; model++) {
@@ -1988,7 +2003,7 @@ static int __devinit usbvision_probe(struct usb_interface *intf, const struct us
if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_ISOC) {
err("%s: USBVision interface %d. has non-ISO endpoint!", __FUNCTION__, ifnum);
- err("%s: USBVision Endpoint attribures %d", __FUNCTION__, endpoint->bmAttributes);
+ err("%s: USBVision Endpoint attributes %d", __FUNCTION__, endpoint->bmAttributes);
return NULL;
}
if ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT) {
@@ -1998,6 +2013,7 @@ static int __devinit usbvision_probe(struct usb_interface *intf, const struct us
MOD_INC_USE_COUNT;
+ /* Allocate the usbvision device structure so that we can set some variables */
if ((usbvision = usbvision_alloc(dev)) == NULL) {
err("%s: couldn't allocate USBVision struct", __FUNCTION__);
MOD_DEC_USE_COUNT;
@@ -2016,7 +2032,7 @@ static int __devinit usbvision_probe(struct usb_interface *intf, const struct us
endpoint = &interface->endpoint[1].desc;
if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_ISOC) {
err("%s: interface %d. has non-ISO endpoint!", __FUNCTION__, ifnum);
- err("%s: Endpoint attribures %d", __FUNCTION__, endpoint->bmAttributes);
+ err("%s: Endpoint attributes %d", __FUNCTION__, endpoint->bmAttributes);
return -ENODEV;
}
if ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT) {
@@ -2044,6 +2060,28 @@ static int __devinit usbvision_probe(struct usb_interface *intf, const struct us
down(&usbvision->lock);
+ /* compute alternate max packet sizes */
+ uif = dev->actconfig->interface[0];
+
+ usbvision->num_alt=uif->num_altsetting;
+ PDEBUG(DBG_PROBE, "Alternate settings: %i",usbvision->num_alt);
+ usbvision->alt_max_pkt_size = kmalloc(32*
+ usbvision->num_alt,GFP_KERNEL);
+ if (usbvision->alt_max_pkt_size == NULL) {
+ err("usbvision: out of memory!\n");
+ return -ENOMEM;
+ }
+
+ for (i = 0; i < usbvision->num_alt ; i++) {
+ u16 tmp = le16_to_cpu(uif->altsetting[i].endpoint[1].desc.
+ wMaxPacketSize);
+ usbvision->alt_max_pkt_size[i] =
+ (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1);
+ PDEBUG(DBG_PROBE, "Alternate setting %i, max size= %i",i,
+ usbvision->alt_max_pkt_size[i]);
+ }
+
+
usbvision->nr = usbvision_nr++;
usbvision->have_tuner = usbvision_device_data[model].Tuner;
@@ -2056,8 +2094,7 @@ static int __devinit usbvision_probe(struct usb_interface *intf, const struct us
usbvision->DevModel = model;
usbvision->remove_pending = 0;
usbvision->iface = ifnum;
- usbvision->ifaceAltInactive = 0;
- usbvision->ifaceAltActive = 1;
+ usbvision->ifaceAlt = 0;
usbvision->video_endp = endpoint->bEndpointAddress;
usbvision->isocPacketSize = 0;
usbvision->usb_bandwidth = 0;
diff --git a/linux/drivers/media/video/usbvision/usbvision.h b/linux/drivers/media/video/usbvision/usbvision.h
index 04ef1a062..bee7d06bc 100644
--- a/linux/drivers/media/video/usbvision/usbvision.h
+++ b/linux/drivers/media/video/usbvision/usbvision.h
@@ -33,6 +33,7 @@
#include <linux/list.h>
#include <linux/usb.h>
+#include <linux/i2c.h>
#include <media/v4l2-common.h>
#include <media/tuner.h>
#include <linux/videodev2.h>
@@ -396,8 +397,11 @@ struct usb_usbvision {
/* Device structure */
struct usb_device *dev;
+ /* usb transfer */
+ int num_alt; /* Number of alternative settings */
+ unsigned int *alt_max_pkt_size; /* array of wMaxPacketSize */
unsigned char iface; /* Video interface number */
- unsigned char ifaceAltActive, ifaceAltInactive; /* Alt settings */
+ unsigned char ifaceAlt; /* Alt settings */
unsigned char Vin_Reg2_Preset;
struct semaphore lock;
struct timer_list powerOffTimer;
@@ -425,6 +429,7 @@ struct usb_usbvision {
wait_queue_head_t wait_stream; /* Processes waiting */
struct usbvision_frame *curFrame; // pointer to current frame, set by usbvision_find_header
struct usbvision_frame frame[USBVISION_NUMFRAMES]; // frame buffer
+ int num_frames; // number of frames allocated
struct usbvision_sbuf sbuf[USBVISION_NUMSBUF]; // S buffering
volatile int remove_pending; /* If set then about to exit */
@@ -515,7 +520,7 @@ int usbvision_read_reg(struct usb_usbvision *usbvision, unsigned char reg);
int usbvision_write_reg(struct usb_usbvision *usbvision, unsigned char reg,
unsigned char value);
-int usbvision_frames_alloc(struct usb_usbvision *usbvision);
+int usbvision_frames_alloc(struct usb_usbvision *usbvision, int number_of_frames);
void usbvision_frames_free(struct usb_usbvision *usbvision);
int usbvision_scratch_alloc(struct usb_usbvision *usbvision);
void usbvision_scratch_free(struct usb_usbvision *usbvision);
@@ -526,6 +531,7 @@ int usbvision_setup(struct usb_usbvision *usbvision,int format);
int usbvision_init_isoc(struct usb_usbvision *usbvision);
int usbvision_restart_isoc(struct usb_usbvision *usbvision);
void usbvision_stop_isoc(struct usb_usbvision *usbvision);
+int usbvision_set_alternate(struct usb_usbvision *dev);
int usbvision_set_audio(struct usb_usbvision *usbvision, int AudioChannel);
int usbvision_audio_off(struct usb_usbvision *usbvision);
diff --git a/linux/drivers/media/video/v4l2-common.c b/linux/drivers/media/video/v4l2-common.c
index 8fa62d5b4..f31a1bb61 100644
--- a/linux/drivers/media/video/v4l2-common.c
+++ b/linux/drivers/media/video/v4l2-common.c
@@ -290,11 +290,13 @@ char *v4l2_type_names[] = {
[V4L2_BUF_TYPE_SLICED_VBI_OUTPUT] = "slicec-vbi-out",
};
+#if 0
static char *v4l2_memory_names[] = {
[V4L2_MEMORY_MMAP] = "mmap",
[V4L2_MEMORY_USERPTR] = "userptr",
[V4L2_MEMORY_OVERLAY] = "overlay",
};
+#endif /* 0 */
#define prt_names(a,arr) (((a)>=0)&&((a)<ARRAY_SIZE(arr)))?arr[a]:"unknown"
@@ -421,9 +423,10 @@ static const char *v4l2_int_ioctls[] = {
[_IOC_NR(TUNER_SET_STANDBY)] = "TUNER_SET_STANDBY",
[_IOC_NR(TDA9887_SET_CONFIG)] = "TDA9887_SET_CONFIG",
+ [_IOC_NR(VIDIOC_DBG_S_REGISTER)] = "VIDIOC_DBG_S_REGISTER",
+ [_IOC_NR(VIDIOC_DBG_G_REGISTER)] = "VIDIOC_DBG_G_REGISTER",
+
[_IOC_NR(VIDIOC_INT_S_TUNER_MODE)] = "VIDIOC_INT_S_TUNER_MODE",
- [_IOC_NR(VIDIOC_INT_S_REGISTER)] = "VIDIOC_INT_S_REGISTER",
- [_IOC_NR(VIDIOC_INT_G_REGISTER)] = "VIDIOC_INT_G_REGISTER",
[_IOC_NR(VIDIOC_INT_RESET)] = "VIDIOC_INT_RESET",
[_IOC_NR(VIDIOC_INT_AUDIO_CLOCK_FREQ)] = "VIDIOC_INT_AUDIO_CLOCK_FREQ",
[_IOC_NR(VIDIOC_INT_DECODE_VBI_LINE)] = "VIDIOC_INT_DECODE_VBI_LINE",
@@ -440,6 +443,7 @@ static const char *v4l2_int_ioctls[] = {
};
#define V4L2_INT_IOCTLS ARRAY_SIZE(v4l2_int_ioctls)
+#if 0
static void v4l_print_pix_fmt (char *s, struct v4l2_pix_format *fmt)
{
printk ("%s: width=%d, height=%d, format=%d, field=%s, "
@@ -448,6 +452,7 @@ static void v4l_print_pix_fmt (char *s, struct v4l2_pix_format *fmt)
prt_names(fmt->field,v4l2_field_names),
fmt->bytesperline,fmt->sizeimage,fmt->colorspace);
};
+#endif /* 0 */
/* Common ioctl debug function. This function can be used by
external ioctl messages as well as internal V4L ioctl */
@@ -487,6 +492,7 @@ void v4l_printk_ioctl(unsigned int cmd)
}
}
+#if 0
/* Common ioctl debug function. This function can be used by
external ioctl messages as well as internal V4L ioctl and its
arguments */
@@ -785,15 +791,17 @@ void v4l_printk_ioctl_arg(char *s,unsigned int cmd, void *arg)
p->id,p->index,p->name);
break;
}
- case VIDIOC_INT_G_REGISTER:
- case VIDIOC_INT_S_REGISTER:
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+ case VIDIOC_DBG_G_REGISTER:
+ case VIDIOC_DBG_S_REGISTER:
{
struct v4l2_register *p=arg;
- printk ("%s: i2c_id=%d, reg=%lu, val=%d\n", s,
- p->i2c_id,p->reg,p->val);
+ printk ("%s: i2c_id=%d, reg=%llu, val=%u\n", s,
+ p->i2c_id,(unsigned long long)p->reg,p->val);
break;
}
+#endif
case VIDIOC_REQBUFS:
{
struct v4l2_requestbuffers *p=arg;
@@ -1068,6 +1076,7 @@ void v4l_printk_ioctl_arg(char *s,unsigned int cmd, void *arg)
}
}
}
+#endif /* 0 */
/* ----------------------------------------------------------------- */
@@ -1576,7 +1585,6 @@ EXPORT_SYMBOL(v4l2_prio_check);
EXPORT_SYMBOL(v4l2_field_names);
EXPORT_SYMBOL(v4l2_type_names);
EXPORT_SYMBOL(v4l_printk_ioctl);
-EXPORT_SYMBOL(v4l_printk_ioctl_arg);
EXPORT_SYMBOL(v4l2_ctrl_next);
EXPORT_SYMBOL(v4l2_ctrl_check);
diff --git a/linux/drivers/media/video/video-buf.c b/linux/drivers/media/video/video-buf.c
index 6d6a74c60..a2251c7e3 100644
--- a/linux/drivers/media/video/video-buf.c
+++ b/linux/drivers/media/video/video-buf.c
@@ -149,6 +149,8 @@ int videobuf_dma_init_user(struct videobuf_dmabuf *dma, int direction,
dprintk(1,"init user [0x%lx+0x%lx => %d pages]\n",
data,size,dma->nr_pages);
+ dma->varea = (void *) data;
+
down_read(&current->mm->mmap_sem);
err = get_user_pages(current,current->mm,
data & PAGE_MASK, dma->nr_pages,
@@ -286,6 +288,7 @@ int videobuf_dma_free(struct videobuf_dmabuf *dma)
vfree(dma->vmalloc);
dma->vmalloc = NULL;
+ dma->varea = NULL;
if (dma->bus_addr) {
dma->bus_addr = 0;
@@ -706,6 +709,7 @@ videobuf_qbuf(struct videobuf_queue *q,
goto done;
}
if (buf->state == STATE_QUEUED ||
+ buf->state == STATE_PREPARED ||
buf->state == STATE_ACTIVE) {
dprintk(1,"qbuf: buffer is already queued or active.\n");
goto done;
diff --git a/linux/drivers/media/video/videodev.c b/linux/drivers/media/video/videodev.c
index b0009fe0f..707757237 100644
--- a/linux/drivers/media/video/videodev.c
+++ b/linux/drivers/media/video/videodev.c
@@ -1477,6 +1477,26 @@ static int __video_do_ioctl(struct inode *inode, struct file *file,
ret=vfd->vidioc_log_status(file, fh);
break;
}
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+ case VIDIOC_DBG_G_REGISTER:
+ {
+ struct v4l2_register *p=arg;
+ if (!capable(CAP_SYS_ADMIN))
+ ret=-EPERM;
+ else if (vfd->vidioc_g_register)
+ ret=vfd->vidioc_g_register(file, fh, p);
+ break;
+ }
+ case VIDIOC_DBG_S_REGISTER:
+ {
+ struct v4l2_register *p=arg;
+ if (!capable(CAP_SYS_ADMIN))
+ ret=-EPERM;
+ else if (vfd->vidioc_s_register)
+ ret=vfd->vidioc_s_register(file, fh, p);
+ break;
+ }
+#endif
} /* switch */
if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) {
diff --git a/linux/drivers/media/video/vivi.c b/linux/drivers/media/video/vivi.c
index ddedd7fbb..1756ff277 100644
--- a/linux/drivers/media/video/vivi.c
+++ b/linux/drivers/media/video/vivi.c
@@ -150,7 +150,9 @@ struct vivi_buffer {
struct vivi_fmt *fmt;
+#ifdef CONFIG_VIVI_SCATTER
struct sg_to_addr *to_addr;
+#endif
};
struct vivi_dmaqueue {
@@ -239,6 +241,7 @@ static u8 bars[8][3] = {
#define TSTAMP_MAX_Y TSTAMP_MIN_Y+15
#define TSTAMP_MIN_X 64
+#ifdef CONFIG_VIVI_SCATTER
static void prep_to_addr(struct sg_to_addr to_addr[],
struct videobuf_buffer *vb)
{
@@ -271,14 +274,24 @@ static int get_addr_pos(int pos, int pages, struct sg_to_addr to_addr[])
return (p1);
}
+#endif
+#ifdef CONFIG_VIVI_SCATTER
static void gen_line(struct sg_to_addr to_addr[],int inipos,int pages,int wmax,
int hmax, int line, char *timestr)
+#else
+static void gen_line(char *basep,int inipos,int wmax,
+ int hmax, int line, char *timestr)
+#endif
{
- int w,i,j,pos=inipos,pgpos,oldpg,y;
- char *p,*s,*basep;
- struct page *pg;
+ int w,i,j,pos=inipos,y;
+ char *p,*s;
u8 chr,r,g,b,color;
+#ifdef CONFIG_VIVI_SCATTER
+ int pgpos,oldpg;
+ char *basep;
+ struct page *pg;
+
unsigned long flags;
spinlock_t spinlock;
@@ -289,6 +302,7 @@ static void gen_line(struct sg_to_addr to_addr[],int inipos,int pages,int wmax,
pg=pfn_to_page(sg_dma_address(to_addr[oldpg].sg) >> PAGE_SHIFT);
spin_lock_irqsave(&spinlock,flags);
basep = kmap_atomic(pg, KM_BOUNCE_READ)+to_addr[oldpg].sg->offset;
+#endif
/* We will just duplicate the second pixel at the packet */
wmax/=2;
@@ -300,6 +314,7 @@ static void gen_line(struct sg_to_addr to_addr[],int inipos,int pages,int wmax,
b=bars[w*7/wmax][2];
for (color=0;color<4;color++) {
+#ifdef CONFIG_VIVI_SCATTER
pgpos=get_addr_pos(pos,pages,to_addr);
if (pgpos!=oldpg) {
pg=pfn_to_page(sg_dma_address(to_addr[pgpos].sg) >> PAGE_SHIFT);
@@ -308,6 +323,9 @@ static void gen_line(struct sg_to_addr to_addr[],int inipos,int pages,int wmax,
oldpg=pgpos;
}
p=basep+pos-to_addr[pgpos].pos;
+#else
+ p=basep+pos;
+#endif
switch (color) {
case 0:
@@ -352,6 +370,7 @@ static void gen_line(struct sg_to_addr to_addr[],int inipos,int pages,int wmax,
pos=inipos+j*2;
for (color=0;color<4;color++) {
+#ifdef CONFIG_VIVI_SCATTER
pgpos=get_addr_pos(pos,pages,to_addr);
if (pgpos!=oldpg) {
pg=pfn_to_page(sg_dma_address(
@@ -365,6 +384,9 @@ static void gen_line(struct sg_to_addr to_addr[],int inipos,int pages,int wmax,
oldpg=pgpos;
}
p=basep+pos-to_addr[pgpos].pos;
+#else
+ p=basep+pos;
+#endif
y=TO_Y(r,g,b);
@@ -401,19 +423,27 @@ static void gen_line(struct sg_to_addr to_addr[],int inipos,int pages,int wmax,
#endif
end:
+#ifdef CONFIG_VIVI_SCATTER
kunmap_atomic(basep, KM_BOUNCE_READ);
spin_unlock_irqrestore(&spinlock,flags);
-
+#else
+ return;
+#endif
}
static void vivi_fillbuff(struct vivi_dev *dev,struct vivi_buffer *buf)
{
int h,pos=0;
int hmax = buf->vb.height;
int wmax = buf->vb.width;
- struct videobuf_buffer *vb=&buf->vb;
- struct sg_to_addr *to_addr=buf->to_addr;
struct timeval ts;
+#ifdef CONFIG_VIVI_SCATTER
+ struct sg_to_addr *to_addr=buf->to_addr;
+ struct videobuf_buffer *vb=&buf->vb;
+#else
+ char *tmpbuf;
+#endif
+#ifdef CONFIG_VIVI_SCATTER
/* Test if DMA mapping is ready */
if (!sg_dma_address(&vb->dma.sglist[0]))
return;
@@ -422,9 +452,27 @@ static void vivi_fillbuff(struct vivi_dev *dev,struct vivi_buffer *buf)
/* Check if there is enough memory */
BUG_ON(buf->vb.dma.nr_pages << PAGE_SHIFT < (buf->vb.width*buf->vb.height)*2);
+#else
+ if (buf->vb.dma.varea) {
+ tmpbuf=kmalloc (wmax*2, GFP_KERNEL);
+ } else {
+ tmpbuf=buf->vb.dma.vmalloc;
+ }
+
+#endif
for (h=0;h<hmax;h++) {
+#ifdef CONFIG_VIVI_SCATTER
gen_line(to_addr,pos,vb->dma.nr_pages,wmax,hmax,h,dev->timestr);
+#else
+ if (buf->vb.dma.varea) {
+ gen_line(tmpbuf,0,wmax,hmax,h,dev->timestr);
+ /* FIXME: replacing to __copy_to_user */
+ copy_to_user(buf->vb.dma.varea+pos,tmpbuf,wmax*2);
+ } else {
+ gen_line(tmpbuf,pos,wmax,hmax,h,dev->timestr);
+ }
+#endif
pos += wmax*2;
}
@@ -450,7 +498,7 @@ static void vivi_fillbuff(struct vivi_dev *dev,struct vivi_buffer *buf)
dev->h,dev->m,dev->s,(dev->us+500)/1000);
dprintk(2,"vivifill at %s: Buffer 0x%08lx size= %d\n",dev->timestr,
- (unsigned long)buf->vb.dma.vmalloc,pos);
+ (unsigned long)buf->vb.dma.varea,pos);
/* Advice that buffer was filled */
buf->vb.state = STATE_DONE;
@@ -753,9 +801,11 @@ static void free_buffer(struct videobuf_queue *vq, struct vivi_buffer *buf)
if (in_interrupt())
BUG();
+#ifdef CONFIG_VIVI_SCATTER
/*FIXME: Maybe a spinlock is required here */
kfree(buf->to_addr);
buf->to_addr=NULL;
+#endif
videobuf_waiton(&buf->vb,0,0);
videobuf_dma_unmap(vq, &buf->vb.dma);
@@ -801,11 +851,12 @@ buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb,
buf->vb.state = STATE_PREPARED;
+#ifdef CONFIG_VIVI_SCATTER
if (NULL == (buf->to_addr = kmalloc(sizeof(*buf->to_addr) * vb->dma.nr_pages,GFP_KERNEL))) {
rc=-ENOMEM;
goto fail;
}
-
+#endif
return 0;
fail:
@@ -870,6 +921,7 @@ static void buffer_release(struct videobuf_queue *vq, struct videobuf_buffer *vb
free_buffer(vq,buf);
}
+#ifdef CONFIG_VIVI_SCATTER
static int vivi_map_sg(void *dev, struct scatterlist *sg, int nents,
int direction)
{
@@ -902,6 +954,7 @@ static int vivi_dma_sync_sg(void *dev,struct scatterlist *sglist, int nr_pages,
// flush_write_buffers();
return 0;
}
+#endif
static struct videobuf_queue_ops vivi_video_qops = {
.buf_setup = buffer_setup,
@@ -910,9 +963,9 @@ static struct videobuf_queue_ops vivi_video_qops = {
.buf_release = buffer_release,
/* Non-pci handling routines */
- .vb_map_sg = vivi_map_sg,
- .vb_dma_sync_sg = vivi_dma_sync_sg,
- .vb_unmap_sg = vivi_unmap_sg,
+// .vb_map_sg = vivi_map_sg,
+// .vb_dma_sync_sg = vivi_dma_sync_sg,
+// .vb_unmap_sg = vivi_unmap_sg,
};
/* ------------------------------------------------------------------
@@ -1296,11 +1349,19 @@ static int vivi_open(struct inode *inode, struct file *file)
sprintf(dev->timestr,"%02d:%02d:%02d:%03d",
dev->h,dev->m,dev->s,(dev->us+500)/1000);
+#ifdef CONFIG_VIVI_SCATTER
+ videobuf_queue_init(&fh->vb_vidq,VIDEOBUF_DMA_SCATTER, &vivi_video_qops,
+ NULL, NULL,
+ fh->type,
+ V4L2_FIELD_INTERLACED,
+ sizeof(struct vivi_buffer),fh);
+#else
videobuf_queue_init(&fh->vb_vidq, &vivi_video_qops,
NULL, NULL,
fh->type,
V4L2_FIELD_INTERLACED,
sizeof(struct vivi_buffer),fh);
+#endif
return 0;
}