diff options
Diffstat (limited to 'linux/drivers/media/video/zoran')
-rw-r--r-- | linux/drivers/media/video/zoran/Kconfig | 8 | ||||
-rw-r--r-- | linux/drivers/media/video/zoran/videocodec.h | 9 | ||||
-rw-r--r-- | linux/drivers/media/video/zoran/zoran.h | 40 | ||||
-rw-r--r-- | linux/drivers/media/video/zoran/zoran_card.c | 421 | ||||
-rw-r--r-- | linux/drivers/media/video/zoran/zoran_card.h | 3 | ||||
-rw-r--r-- | linux/drivers/media/video/zoran/zoran_device.c | 523 | ||||
-rw-r--r-- | linux/drivers/media/video/zoran/zoran_device.h | 15 | ||||
-rw-r--r-- | linux/drivers/media/video/zoran/zoran_driver.c | 3471 | ||||
-rw-r--r-- | linux/drivers/media/video/zoran/zoran_procfs.c | 2 | ||||
-rw-r--r-- | linux/drivers/media/video/zoran/zr36016.c | 5 | ||||
-rw-r--r-- | linux/drivers/media/video/zoran/zr36050.c | 4 | ||||
-rw-r--r-- | linux/drivers/media/video/zoran/zr36060.c | 4 |
12 files changed, 1645 insertions, 2860 deletions
diff --git a/linux/drivers/media/video/zoran/Kconfig b/linux/drivers/media/video/zoran/Kconfig index 4ea5fa71d..925fb5159 100644 --- a/linux/drivers/media/video/zoran/Kconfig +++ b/linux/drivers/media/video/zoran/Kconfig @@ -1,6 +1,6 @@ config VIDEO_ZORAN tristate "Zoran ZR36057/36067 Video For Linux" - depends on PCI && I2C_ALGOBIT && VIDEO_V4L1 && VIRT_TO_BUS + depends on PCI && I2C_ALGOBIT && VIDEO_V4L2 && VIRT_TO_BUS help Say Y for support for MJPEG capture cards based on the Zoran 36057/36067 PCI controller chipset. This includes the Iomega @@ -32,7 +32,7 @@ config VIDEO_ZORAN_ZR36060 config VIDEO_ZORAN_BUZ tristate "Iomega Buz support" depends on VIDEO_ZORAN_ZR36060 - select VIDEO_SAA7111 if VIDEO_HELPER_CHIPS_AUTO + select VIDEO_SAA711X if VIDEO_HELPER_CHIPS_AUTO select VIDEO_SAA7185 if VIDEO_HELPER_CHIPS_AUTO help Support for the Iomega Buz MJPEG capture/playback card. @@ -58,7 +58,7 @@ config VIDEO_ZORAN_LML33 config VIDEO_ZORAN_LML33R10 tristate "Linux Media Labs LML33R10 support" depends on VIDEO_ZORAN_ZR36060 - select VIDEO_SAA7114 if VIDEO_HELPER_CHIPS_AUTO + select VIDEO_SAA711X if VIDEO_HELPER_CHIPS_AUTO select VIDEO_ADV7170 if VIDEO_HELPER_CHIPS_AUTO help support for the Linux Media Labs LML33R10 MJPEG capture/playback @@ -66,7 +66,7 @@ config VIDEO_ZORAN_LML33R10 config VIDEO_ZORAN_AVS6EYES tristate "AverMedia 6 Eyes support (EXPERIMENTAL)" - depends on VIDEO_ZORAN_ZR36060 && EXPERIMENTAL && VIDEO_V4L1 + depends on VIDEO_ZORAN_ZR36060 && EXPERIMENTAL select VIDEO_BT856 if VIDEO_HELPER_CHIPS_AUTO select VIDEO_KS0127 if VIDEO_HELPER_CHIPS_AUTO help diff --git a/linux/drivers/media/video/zoran/videocodec.h b/linux/drivers/media/video/zoran/videocodec.h index 1b40df14f..5fc11caf2 100644 --- a/linux/drivers/media/video/zoran/videocodec.h +++ b/linux/drivers/media/video/zoran/videocodec.h @@ -97,7 +97,7 @@ available) - it returns 0 if the mode is possible set_size -> this fn-ref. sets the norm and image size for compression/decompression (returns 0 on success) - the norm param is defined in videodev.h (VIDEO_MODE_*) + the norm param is defined in videodev2.h (V4L2_STD_*) additional setup may be available, too - but the codec should work with some default values even without this @@ -145,9 +145,8 @@ M zr36055[1] 0001 0000c001 00000000 (zr36050[1]) #define __LINUX_VIDEOCODEC_H #include "compat.h" -#include <linux/videodev.h> +#include <linux/videodev2.h> -//should be in videodev.h ??? (VID_DO_....) #define CODEC_DO_COMPRESSION 0 #define CODEC_DO_EXPANSION 1 @@ -238,10 +237,6 @@ struct vfe_settings { __u32 width, height; /* Area to capture */ __u16 decimation; /* Decimation divider */ __u16 flags; /* Flags for capture */ -/* flags are the same as in struct video_capture - see videodev.h: -#define VIDEO_CAPTURE_ODD 0 -#define VIDEO_CAPTURE_EVEN 1 -*/ __u16 quality; /* quality of the video */ }; diff --git a/linux/drivers/media/video/zoran/zoran.h b/linux/drivers/media/video/zoran/zoran.h index e873a9162..8beada961 100644 --- a/linux/drivers/media/video/zoran/zoran.h +++ b/linux/drivers/media/video/zoran/zoran.h @@ -31,6 +31,8 @@ #ifndef _BUZ_H_ #define _BUZ_H_ +#include <media/v4l2-device.h> + struct zoran_requestbuffers { unsigned long count; /* Number of buffers for MJPEG grabbing */ unsigned long size; /* Size PER BUFFER in bytes */ @@ -170,8 +172,6 @@ Private IOCTL to set up for displaying MJPEG #endif #define V4L_MASK_FRAME (V4L_MAX_FRAME - 1) -#define MAX_KMALLOC_MEM (128*1024) - #include "zr36057.h" enum card_type { @@ -240,9 +240,6 @@ enum gpcs_type { struct zoran_format { char *name; -#ifdef CONFIG_VIDEO_V4L1_COMPAT - int palette; -#endif __u32 fourcc; int colorspace; int depth; @@ -312,7 +309,6 @@ struct zoran_jpg_struct { struct zoran_jpg_buffer buffer[BUZ_MAX_FRAME]; /* buffers */ int num_buffers, buffer_size; u8 allocated; /* Flag if buffers are allocated */ - u8 ready_to_be_freed; /* hack - see zoran_driver.c */ u8 need_contiguous; /* Flag if contiguous buffers are needed */ }; @@ -321,7 +317,6 @@ struct zoran_v4l_struct { struct zoran_v4l_buffer buffer[VIDEO_MAX_FRAME]; /* buffers */ int num_buffers, buffer_size; u8 allocated; /* Flag if buffers are allocated */ - u8 ready_to_be_freed; /* hack - see zoran_driver.c */ }; struct zoran; @@ -346,7 +341,12 @@ struct zoran_fh { struct card_info { enum card_type type; char name[32]; - u16 i2c_decoder, i2c_encoder; /* I2C types */ + const char *i2c_decoder; /* i2c decoder device */ + const char *mod_decoder; /* i2c decoder module */ + const unsigned short *addrs_decoder; + const char *i2c_encoder; /* i2c encoder device */ + const char *mod_encoder; /* i2c encoder module */ + const unsigned short *addrs_encoder; u16 video_vfe, video_codec; /* videocodec types */ u16 audio_chip; /* audio type */ @@ -356,7 +356,7 @@ struct card_info { char name[32]; } input[BUZ_MAX_INPUT]; - int norms; + v4l2_std_id norms; struct tvnorm *tvn[3]; /* supported TV norms */ u32 jpeg_int; /* JPEG interrupt */ @@ -377,14 +377,15 @@ struct card_info { }; struct zoran { + struct v4l2_device v4l2_dev; struct video_device *video_dev; struct i2c_adapter i2c_adapter; /* */ struct i2c_algo_bit_data i2c_algo; /* */ u32 i2cbr; - struct i2c_client *decoder; /* video decoder i2c client */ - struct i2c_client *encoder; /* video encoder i2c client */ + struct v4l2_subdev *decoder; /* video decoder sub-device */ + struct v4l2_subdev *encoder; /* video encoder sub-device */ struct videocodec *codec; /* video codec */ struct videocodec *vfe; /* video front end */ @@ -405,9 +406,15 @@ struct zoran { spinlock_t spinlock; /* Spinlock */ /* Video for Linux parameters */ - int input, norm; /* card's norm and input - norm=VIDEO_MODE_* */ - int hue, saturation, contrast, brightness; /* Current picture params */ - struct video_buffer buffer; /* Current buffer params */ + int input; /* card's norm and input - norm=VIDEO_MODE_* */ + v4l2_std_id norm; + + /* Current buffer params */ + void *vbuf_base; + int vbuf_height, vbuf_width; + int vbuf_depth; + int vbuf_bytesperline; + struct zoran_overlay_settings overlay_settings; u32 *overlay_mask; /* overlay mask */ enum zoran_lock_activity overlay_active; /* feature currently in use? */ @@ -488,6 +495,11 @@ struct zoran { wait_queue_head_t test_q; }; +static inline struct zoran *to_zoran(struct v4l2_device *v4l2_dev) +{ + return container_of(v4l2_dev, struct zoran, v4l2_dev); +} + /* There was something called _ALPHA_BUZ that used the PCI address instead of * the kernel iomapped address for btread/btwrite. */ #define btwrite(dat,adr) writel((dat), zr->zr36057_mem+(adr)) diff --git a/linux/drivers/media/video/zoran/zoran_card.c b/linux/drivers/media/video/zoran/zoran_card.c index 5d0fa99f2..57cc62d82 100644 --- a/linux/drivers/media/video/zoran/zoran_card.c +++ b/linux/drivers/media/video/zoran/zoran_card.c @@ -39,7 +39,7 @@ #include <linux/i2c.h> #include <linux/i2c-algo-bit.h> #include "compat.h" -#include <linux/videodev.h> +#include <linux/videodev2.h> #include <media/v4l2-common.h> #include <linux/spinlock.h> #include <linux/sem.h> @@ -48,8 +48,6 @@ #include <linux/pci.h> #include <linux/interrupt.h> -#include <linux/video_decoder.h> -#include <linux/video_encoder.h> #include <linux/mutex.h> #include <asm/io.h> @@ -109,25 +107,8 @@ static int video_nr[BUZ_MAX] = { [0 ... (BUZ_MAX-1)] = -1 }; module_param_array(video_nr, int, NULL, 0444); MODULE_PARM_DESC(video_nr, "Video device number (-1=Auto)"); -/* - Number and size of grab buffers for Video 4 Linux - The vast majority of applications should not need more than 2, - the very popular BTTV driver actually does ONLY have 2. - Time sensitive applications might need more, the maximum - is VIDEO_MAX_FRAME (defined in <linux/videodev.h>). - - The size is set so that the maximum possible request - can be satisfied. Decrease it, if bigphys_area alloc'd - memory is low. If you don't have the bigphys_area patch, - set it to 128 KB. Will you allow only to grab small - images with V4L, but that's better than nothing. - - v4l_bufsize has to be given in KB ! - -*/ - -int v4l_nbufs = 2; -int v4l_bufsize = 128; /* Everybody should be able to work with this setting */ +int v4l_nbufs = 4; +int v4l_bufsize = 864; /* Everybody should be able to work with this setting */ module_param(v4l_nbufs, int, 0644); MODULE_PARM_DESC(v4l_nbufs, "Maximum number of V4L buffers to use"); module_param(v4l_bufsize, int, 0644); @@ -333,50 +314,6 @@ avs6eyes_init (struct zoran *zr) } static char * -i2cid_to_modulename (u16 i2c_id) -{ - char *name = NULL; - - switch (i2c_id) { - case I2C_DRIVERID_SAA7110: - name = "saa7110"; - break; - case I2C_DRIVERID_SAA7111A: - name = "saa7111"; - break; - case I2C_DRIVERID_SAA7114: - name = "saa7114"; - break; - case I2C_DRIVERID_SAA7185B: - name = "saa7185"; - break; - case I2C_DRIVERID_ADV7170: - name = "adv7170"; - break; - case I2C_DRIVERID_ADV7175: - name = "adv7175"; - break; - case I2C_DRIVERID_BT819: - name = "bt819"; - break; - case I2C_DRIVERID_BT856: - name = "bt856"; - break; - case I2C_DRIVERID_BT866: - name = "bt866"; - break; - case I2C_DRIVERID_VPX3220: - name = "vpx3220"; - break; - case I2C_DRIVERID_KS0127: - name = "ks0127"; - break; - } - - return name; -} - -static char * codecid_to_modulename (u16 codecid) { char *name = NULL; @@ -426,11 +363,24 @@ static struct tvnorm f60ccir601_lm33r10 = { 858, 720, 56+54, 788, 525, 480, 16 } static struct tvnorm f50ccir601_avs6eyes = { 864, 720, 74, 804, 625, 576, 18 }; static struct tvnorm f60ccir601_avs6eyes = { 858, 720, 56, 788, 525, 480, 16 }; +static const unsigned short vpx3220_addrs[] = { 0x43, 0x47, I2C_CLIENT_END }; +static const unsigned short saa7110_addrs[] = { 0x4e, 0x4f, I2C_CLIENT_END }; +static const unsigned short saa7111_addrs[] = { 0x25, 0x24, I2C_CLIENT_END }; +static const unsigned short saa7114_addrs[] = { 0x21, 0x20, I2C_CLIENT_END }; +static const unsigned short adv717x_addrs[] = { 0x6a, 0x6b, 0x2a, 0x2b, I2C_CLIENT_END }; +static const unsigned short ks0127_addrs[] = { 0x6c, 0x6d, I2C_CLIENT_END }; +static const unsigned short saa7185_addrs[] = { 0x44, I2C_CLIENT_END }; +static const unsigned short bt819_addrs[] = { 0x45, I2C_CLIENT_END }; +static const unsigned short bt856_addrs[] = { 0x44, I2C_CLIENT_END }; +static const unsigned short bt866_addrs[] = { 0x44, I2C_CLIENT_END }; + static struct card_info zoran_cards[NUM_CARDS] __devinitdata = { { .type = DC10_old, .name = "DC10(old)", - .i2c_decoder = I2C_DRIVERID_VPX3220, + .i2c_decoder = "vpx3220a", + .mod_decoder = "vpx3220", + .addrs_decoder = vpx3220_addrs, .video_codec = CODEC_TYPE_ZR36050, .video_vfe = CODEC_TYPE_ZR36016, @@ -440,7 +390,7 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = { { 2, "S-Video" }, { 0, "Internal/comp" } }, - .norms = 3, + .norms = V4L2_STD_NTSC|V4L2_STD_PAL|V4L2_STD_SECAM, .tvn = { &f50sqpixel_dc10, &f60sqpixel_dc10, @@ -458,8 +408,12 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = { }, { .type = DC10_new, .name = "DC10(new)", - .i2c_decoder = I2C_DRIVERID_SAA7110, - .i2c_encoder = I2C_DRIVERID_ADV7175, + .i2c_decoder = "saa7110", + .mod_decoder = "saa7110", + .addrs_decoder = saa7110_addrs, + .i2c_encoder = "adv7175", + .mod_encoder = "adv7175", + .addrs_encoder = adv717x_addrs, .video_codec = CODEC_TYPE_ZR36060, .inputs = 3, @@ -468,7 +422,7 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = { { 7, "S-Video" }, { 5, "Internal/comp" } }, - .norms = 3, + .norms = V4L2_STD_NTSC|V4L2_STD_PAL|V4L2_STD_SECAM, .tvn = { &f50sqpixel, &f60sqpixel, @@ -485,8 +439,12 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = { }, { .type = DC10plus, .name = "DC10plus", - .i2c_decoder = I2C_DRIVERID_SAA7110, - .i2c_encoder = I2C_DRIVERID_ADV7175, + .i2c_decoder = "saa7110", + .mod_decoder = "saa7110", + .addrs_decoder = saa7110_addrs, + .i2c_encoder = "adv7175", + .mod_encoder = "adv7175", + .addrs_encoder = adv717x_addrs, .video_codec = CODEC_TYPE_ZR36060, .inputs = 3, @@ -495,7 +453,7 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = { { 7, "S-Video" }, { 5, "Internal/comp" } }, - .norms = 3, + .norms = V4L2_STD_NTSC|V4L2_STD_PAL|V4L2_STD_SECAM, .tvn = { &f50sqpixel, &f60sqpixel, @@ -513,8 +471,12 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = { }, { .type = DC30, .name = "DC30", - .i2c_decoder = I2C_DRIVERID_VPX3220, - .i2c_encoder = I2C_DRIVERID_ADV7175, + .i2c_decoder = "vpx3220a", + .mod_decoder = "vpx3220", + .addrs_decoder = vpx3220_addrs, + .i2c_encoder = "adv7175", + .mod_encoder = "adv7175", + .addrs_encoder = adv717x_addrs, .video_codec = CODEC_TYPE_ZR36050, .video_vfe = CODEC_TYPE_ZR36016, @@ -524,7 +486,7 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = { { 2, "S-Video" }, { 0, "Internal/comp" } }, - .norms = 3, + .norms = V4L2_STD_NTSC|V4L2_STD_PAL|V4L2_STD_SECAM, .tvn = { &f50sqpixel_dc10, &f60sqpixel_dc10, @@ -542,8 +504,12 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = { }, { .type = DC30plus, .name = "DC30plus", - .i2c_decoder = I2C_DRIVERID_VPX3220, - .i2c_encoder = I2C_DRIVERID_ADV7175, + .i2c_decoder = "vpx3220a", + .mod_decoder = "vpx3220", + .addrs_decoder = vpx3220_addrs, + .i2c_encoder = "adv7175", + .mod_encoder = "adv7175", + .addrs_encoder = adv717x_addrs, .video_codec = CODEC_TYPE_ZR36050, .video_vfe = CODEC_TYPE_ZR36016, @@ -553,7 +519,7 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = { { 2, "S-Video" }, { 0, "Internal/comp" } }, - .norms = 3, + .norms = V4L2_STD_NTSC|V4L2_STD_PAL|V4L2_STD_SECAM, .tvn = { &f50sqpixel_dc10, &f60sqpixel_dc10, @@ -571,8 +537,12 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = { }, { .type = LML33, .name = "LML33", - .i2c_decoder = I2C_DRIVERID_BT819, - .i2c_encoder = I2C_DRIVERID_BT856, + .i2c_decoder = "bt819a", + .mod_decoder = "bt819", + .addrs_decoder = bt819_addrs, + .i2c_encoder = "bt856", + .mod_encoder = "bt856", + .addrs_encoder = bt856_addrs, .video_codec = CODEC_TYPE_ZR36060, .inputs = 2, @@ -580,7 +550,7 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = { { 0, "Composite" }, { 7, "S-Video" } }, - .norms = 2, + .norms = V4L2_STD_NTSC|V4L2_STD_PAL, .tvn = { &f50ccir601_lml33, &f60ccir601_lml33, @@ -598,8 +568,12 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = { }, { .type = LML33R10, .name = "LML33R10", - .i2c_decoder = I2C_DRIVERID_SAA7114, - .i2c_encoder = I2C_DRIVERID_ADV7170, + .i2c_decoder = "saa7114", + .mod_decoder = "saa7115", + .addrs_decoder = saa7114_addrs, + .i2c_encoder = "adv7170", + .mod_encoder = "adv7170", + .addrs_encoder = adv717x_addrs, .video_codec = CODEC_TYPE_ZR36060, .inputs = 2, @@ -607,7 +581,7 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = { { 0, "Composite" }, { 7, "S-Video" } }, - .norms = 2, + .norms = V4L2_STD_NTSC|V4L2_STD_PAL, .tvn = { &f50ccir601_lm33r10, &f60ccir601_lm33r10, @@ -625,8 +599,12 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = { }, { .type = BUZ, .name = "Buz", - .i2c_decoder = I2C_DRIVERID_SAA7111A, - .i2c_encoder = I2C_DRIVERID_SAA7185B, + .i2c_decoder = "saa7111", + .mod_decoder = "saa7115", + .addrs_decoder = saa7111_addrs, + .i2c_encoder = "saa7185", + .mod_encoder = "saa7185", + .addrs_encoder = saa7185_addrs, .video_codec = CODEC_TYPE_ZR36060, .inputs = 2, @@ -634,7 +612,7 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = { { 3, "Composite" }, { 7, "S-Video" } }, - .norms = 3, + .norms = V4L2_STD_NTSC|V4L2_STD_PAL|V4L2_STD_SECAM, .tvn = { &f50ccir601, &f60ccir601, @@ -654,8 +632,12 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = { .name = "6-Eyes", /* AverMedia chose not to brand the 6-Eyes. Thus it can't be autodetected, and requires card=x. */ - .i2c_decoder = I2C_DRIVERID_KS0127, - .i2c_encoder = I2C_DRIVERID_BT866, + .i2c_decoder = "ks0127", + .mod_decoder = "ks0127", + .addrs_decoder = ks0127_addrs, + .i2c_encoder = "bt866", + .mod_encoder = "bt866", + .addrs_encoder = bt866_addrs, .video_codec = CODEC_TYPE_ZR36060, .inputs = 10, @@ -671,7 +653,7 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = { {10, "S-Video 3" }, {15, "YCbCr" } }, - .norms = 2, + .norms = V4L2_STD_NTSC|V4L2_STD_PAL, .tvn = { &f50ccir601_avs6eyes, &f60ccir601_avs6eyes, @@ -736,69 +718,6 @@ zoran_i2c_setscl (void *data, btwrite(zr->i2cbr, ZR36057_I2CBR); } -static int -zoran_i2c_client_register (struct i2c_client *client) -{ - struct zoran *zr = (struct zoran *) i2c_get_adapdata(client->adapter); - int res = 0; - - dprintk(2, - KERN_DEBUG "%s: i2c_client_register() - driver id = %d\n", - ZR_DEVNAME(zr), client->driver->id); - - mutex_lock(&zr->resource_lock); - - if (zr->user > 0) { - /* we're already busy, so we keep a reference to - * them... Could do a lot of stuff here, but this - * is easiest. (Did I ever mention I'm a lazy ass?) - */ - res = -EBUSY; - goto clientreg_unlock_and_return; - } - - if (client->driver->id == zr->card.i2c_decoder) - zr->decoder = client; - else if (client->driver->id == zr->card.i2c_encoder) - zr->encoder = client; - else { - res = -ENODEV; - goto clientreg_unlock_and_return; - } - -clientreg_unlock_and_return: - mutex_unlock(&zr->resource_lock); - - return res; -} - -static int -zoran_i2c_client_unregister (struct i2c_client *client) -{ - struct zoran *zr = (struct zoran *) i2c_get_adapdata(client->adapter); - int res = 0; - - dprintk(2, KERN_DEBUG "%s: i2c_client_unregister()\n", ZR_DEVNAME(zr)); - - mutex_lock(&zr->resource_lock); - - if (zr->user > 0) { - res = -EBUSY; - goto clientunreg_unlock_and_return; - } - - /* try to locate it */ - if (client == zr->encoder) { - zr->encoder = NULL; - } else if (client == zr->decoder) { - zr->decoder = NULL; - snprintf(ZR_DEVNAME(zr), sizeof(ZR_DEVNAME(zr)), "MJPEG[%d]", zr->id); - } -clientunreg_unlock_and_return: - mutex_unlock(&zr->resource_lock); - return res; -} - static const struct i2c_algo_bit_data zoran_i2c_bit_data_template = { .setsda = zoran_i2c_setsda, .setscl = zoran_i2c_setscl, @@ -814,13 +733,10 @@ zoran_register_i2c (struct zoran *zr) memcpy(&zr->i2c_algo, &zoran_i2c_bit_data_template, sizeof(struct i2c_algo_bit_data)); zr->i2c_algo.data = zr; - zr->i2c_adapter.class = I2C_CLASS_TV_ANALOG; zr->i2c_adapter.id = I2C_HW_B_ZR36067; - zr->i2c_adapter.client_register = zoran_i2c_client_register; - zr->i2c_adapter.client_unregister = zoran_i2c_client_unregister; strlcpy(zr->i2c_adapter.name, ZR_DEVNAME(zr), sizeof(zr->i2c_adapter.name)); - i2c_set_adapdata(&zr->i2c_adapter, zr); + i2c_set_adapdata(&zr->i2c_adapter, &zr->v4l2_dev); zr->i2c_adapter.algo_data = &zr->i2c_algo; zr->i2c_adapter.dev.parent = &zr->pci_dev->dev; return i2c_bit_add_bus(&zr->i2c_adapter); @@ -836,7 +752,8 @@ zoran_unregister_i2c (struct zoran *zr) int zoran_check_jpg_settings (struct zoran *zr, - struct zoran_jpg_settings *settings) + struct zoran_jpg_settings *settings, + int try) { int err = 0, err0 = 0; @@ -901,38 +818,61 @@ zoran_check_jpg_settings (struct zoran *zr, /* We have to check the data the user has set */ if (settings->HorDcm != 1 && settings->HorDcm != 2 && - (zr->card.type == DC10_new || settings->HorDcm != 4)) + (zr->card.type == DC10_new || settings->HorDcm != 4)) { + settings->HorDcm = clamp(settings->HorDcm, 1, 2); err0++; - if (settings->VerDcm != 1 && settings->VerDcm != 2) + } + if (settings->VerDcm != 1 && settings->VerDcm != 2) { + settings->VerDcm = clamp(settings->VerDcm, 1, 2); err0++; - if (settings->TmpDcm != 1 && settings->TmpDcm != 2) + } + if (settings->TmpDcm != 1 && settings->TmpDcm != 2) { + settings->TmpDcm = clamp(settings->TmpDcm, 1, 2); err0++; + } if (settings->field_per_buff != 1 && - settings->field_per_buff != 2) + settings->field_per_buff != 2) { + settings->field_per_buff = clamp(settings->field_per_buff, 1, 2); + err0++; + } + if (settings->img_x < 0) { + settings->img_x = 0; + err0++; + } + if (settings->img_y < 0) { + settings->img_y = 0; err0++; - if (settings->img_x < 0) + } + if (settings->img_width < 0 || settings->img_width > BUZ_MAX_WIDTH) { + settings->img_width = clamp(settings->img_width, 0, (int)BUZ_MAX_WIDTH); err0++; - if (settings->img_y < 0) + } + if (settings->img_height < 0 || settings->img_height > BUZ_MAX_HEIGHT / 2) { + settings->img_height = clamp(settings->img_height, 0, BUZ_MAX_HEIGHT / 2); err0++; - if (settings->img_width < 0) + } + if (settings->img_x + settings->img_width > BUZ_MAX_WIDTH) { + settings->img_x = BUZ_MAX_WIDTH - settings->img_width; err0++; - if (settings->img_height < 0) + } + if (settings->img_y + settings->img_height > BUZ_MAX_HEIGHT / 2) { + settings->img_y = BUZ_MAX_HEIGHT / 2 - settings->img_height; err0++; - if (settings->img_x + settings->img_width > BUZ_MAX_WIDTH) + } + if (settings->img_width % (16 * settings->HorDcm) != 0) { + settings->img_width -= settings->img_width % (16 * settings->HorDcm); + if (settings->img_width == 0) + settings->img_width = 16 * settings->HorDcm; err0++; - if (settings->img_y + settings->img_height > - BUZ_MAX_HEIGHT / 2) + } + if (settings->img_height % (8 * settings->VerDcm) != 0) { + settings->img_height -= settings->img_height % (8 * settings->VerDcm); + if (settings->img_height == 0) + settings->img_height = 8 * settings->VerDcm; err0++; - if (settings->HorDcm && settings->VerDcm) { - if (settings->img_width % - (16 * settings->HorDcm) != 0) - err0++; - if (settings->img_height % - (8 * settings->VerDcm) != 0) - err0++; } - if (err0) { + if (!try && err0) { dprintk(1, KERN_ERR "%s: check_jpg_settings() - error in params for decimation = 0\n", @@ -1022,7 +962,7 @@ zoran_open_init_params (struct zoran *zr) sizeof(zr->jpg_settings.jpg_comp.COM_data)); zr->jpg_settings.jpg_comp.jpeg_markers = JPEG_MARKER_DHT | JPEG_MARKER_DQT; - i = zoran_check_jpg_settings(zr, &zr->jpg_settings); + i = zoran_check_jpg_settings(zr, &zr->jpg_settings, 0); if (i) dprintk(1, KERN_ERR @@ -1063,8 +1003,6 @@ static int __devinit zr36057_init (struct zoran *zr) { int j, err; - int two = 2; - int zero = 0; dprintk(1, KERN_INFO @@ -1080,24 +1018,32 @@ zr36057_init (struct zoran *zr) zr->jpg_buffers.allocated = 0; zr->v4l_buffers.allocated = 0; - zr->buffer.base = (void *) vidmem; - zr->buffer.width = 0; - zr->buffer.height = 0; - zr->buffer.depth = 0; - zr->buffer.bytesperline = 0; + zr->vbuf_base = (void *) vidmem; + zr->vbuf_width = 0; + zr->vbuf_height = 0; + zr->vbuf_depth = 0; + zr->vbuf_bytesperline = 0; /* Avoid nonsense settings from user for default input/norm */ - if (default_norm < VIDEO_MODE_PAL && - default_norm > VIDEO_MODE_SECAM) - default_norm = VIDEO_MODE_PAL; - zr->norm = default_norm; - if (!(zr->timing = zr->card.tvn[zr->norm])) { + if (default_norm < 0 && default_norm > 2) + default_norm = 0; + if (default_norm == 0) { + zr->norm = V4L2_STD_PAL; + zr->timing = zr->card.tvn[0]; + } else if (default_norm == 1) { + zr->norm = V4L2_STD_NTSC; + zr->timing = zr->card.tvn[1]; + } else { + zr->norm = V4L2_STD_SECAM; + zr->timing = zr->card.tvn[2]; + } + if (zr->timing == NULL) { dprintk(1, KERN_WARNING "%s: zr36057_init() - default TV standard not supported by hardware. PAL will be used.\n", ZR_DEVNAME(zr)); - zr->norm = VIDEO_MODE_PAL; - zr->timing = zr->card.tvn[zr->norm]; + zr->norm = V4L2_STD_PAL; + zr->timing = zr->card.tvn[0]; } if (default_input > zr->card.inputs-1) { @@ -1109,12 +1055,6 @@ zr36057_init (struct zoran *zr) } zr->input = default_input; - /* Should the following be reset at every open ? */ - zr->hue = 32768; - zr->contrast = 32768; - zr->saturation = 32768; - zr->brightness = 32768; - /* default setup (will be repeated at every open) */ zoran_open_init_params(zr); @@ -1138,6 +1078,7 @@ zr36057_init (struct zoran *zr) * Now add the template and register the device unit. */ memcpy(zr->video_dev, &zoran_template, sizeof(zoran_template)); + zr->video_dev->parent = &zr->pci_dev->dev; strcpy(zr->video_dev->name, ZR_DEVNAME(zr)); err = video_register_device(zr->video_dev, VFL_TYPE_GRABBER, video_nr[zr->id]); if (err < 0) @@ -1149,8 +1090,10 @@ zr36057_init (struct zoran *zr) detect_guest_activity(zr); test_interrupts(zr); if (!pass_through) { - decoder_command(zr, DECODER_ENABLE_OUTPUT, &zero); - encoder_command(zr, ENCODER_SET_INPUT, &two); + struct v4l2_routing route = { 2, 0 }; + + decoder_call(zr, video, s_stream, 0); + encoder_call(zr, video, s_routing, &route); } zr->zoran_proc = NULL; @@ -1165,7 +1108,8 @@ exit_free: static void __devexit zoran_remove(struct pci_dev *pdev) { - struct zoran *zr = pci_get_drvdata(pdev); + struct v4l2_device *v4l2_dev = dev_get_drvdata(&pdev->dev); + struct zoran *zr = to_zoran(v4l2_dev); if (!zr->initialized) goto exit_free; @@ -1198,7 +1142,7 @@ static void __devexit zoran_remove(struct pci_dev *pdev) pci_disable_device(zr->pci_dev); video_unregister_device(zr->video_dev); exit_free: - pci_set_drvdata(pdev, NULL); + v4l2_device_unregister(&zr->v4l2_dev); kfree(zr); } @@ -1270,7 +1214,7 @@ static int __devinit zoran_probe(struct pci_dev *pdev, struct videocodec_master *master_vfe = NULL; struct videocodec_master *master_codec = NULL; int card_num; - char *i2c_enc_name, *i2c_dec_name, *codec_name, *vfe_name; + char *codec_name, *vfe_name; unsigned int nr; @@ -1291,13 +1235,15 @@ static int __devinit zoran_probe(struct pci_dev *pdev, ZORAN_NAME); return -ENOMEM; } + if (v4l2_device_register(&pdev->dev, &zr->v4l2_dev)) + goto zr_free_mem; zr->pci_dev = pdev; zr->id = nr; snprintf(ZR_DEVNAME(zr), sizeof(ZR_DEVNAME(zr)), "MJPEG[%u]", zr->id); spin_lock_init(&zr->spinlock); mutex_init(&zr->resource_lock); if (pci_enable_device(pdev)) - goto zr_free_mem; + goto zr_unreg; pci_read_config_byte(zr->pci_dev, PCI_CLASS_REVISION, &zr->revision); dprintk(1, @@ -1324,7 +1270,7 @@ static int __devinit zoran_probe(struct pci_dev *pdev, KERN_ERR "%s: It is not possible to auto-detect ZR36057 based cards\n", ZR_DEVNAME(zr)); - goto zr_free_mem; + goto zr_unreg; } card_num = ent->driver_data; @@ -1333,7 +1279,7 @@ static int __devinit zoran_probe(struct pci_dev *pdev, KERN_ERR "%s: Unknown card, try specifying card=X module parameter\n", ZR_DEVNAME(zr)); - goto zr_free_mem; + goto zr_unreg; } dprintk(3, KERN_DEBUG @@ -1346,7 +1292,7 @@ static int __devinit zoran_probe(struct pci_dev *pdev, KERN_ERR "%s: User specified card type %d out of range (0 .. %d)\n", ZR_DEVNAME(zr), card_num, NUM_CARDS - 1); - goto zr_free_mem; + goto zr_unreg; } } @@ -1365,7 +1311,7 @@ static int __devinit zoran_probe(struct pci_dev *pdev, KERN_ERR "%s: %s() - ioremap failed\n", ZR_DEVNAME(zr), __func__); - goto zr_free_mem; + goto zr_unreg; } result = request_irq(zr->pci_dev->irq, zoran_irq, @@ -1408,46 +1354,6 @@ static int __devinit zoran_probe(struct pci_dev *pdev, dprintk(2, KERN_INFO "%s: Initializing i2c bus...\n", ZR_DEVNAME(zr)); - /* i2c decoder */ - if (decoder[zr->id] != -1) { - i2c_dec_name = i2cid_to_modulename(decoder[zr->id]); - zr->card.i2c_decoder = decoder[zr->id]; - } else if (zr->card.i2c_decoder != 0) { - i2c_dec_name = i2cid_to_modulename(zr->card.i2c_decoder); - } else { - i2c_dec_name = NULL; - } - - if (i2c_dec_name) { - result = request_module(i2c_dec_name); - if (result < 0) { - dprintk(1, - KERN_ERR - "%s: failed to load module %s: %d\n", - ZR_DEVNAME(zr), i2c_dec_name, result); - } - } - - /* i2c encoder */ - if (encoder[zr->id] != -1) { - i2c_enc_name = i2cid_to_modulename(encoder[zr->id]); - zr->card.i2c_encoder = encoder[zr->id]; - } else if (zr->card.i2c_encoder != 0) { - i2c_enc_name = i2cid_to_modulename(zr->card.i2c_encoder); - } else { - i2c_enc_name = NULL; - } - - if (i2c_enc_name) { - result = request_module(i2c_enc_name); - if (result < 0) { - dprintk(1, - KERN_ERR - "%s: failed to load module %s: %d\n", - ZR_DEVNAME(zr), i2c_enc_name, result); - } - } - if (zoran_register_i2c(zr) < 0) { dprintk(1, KERN_ERR @@ -1456,6 +1362,14 @@ static int __devinit zoran_probe(struct pci_dev *pdev, goto zr_free_irq; } + zr->decoder = v4l2_i2c_new_probed_subdev(&zr->i2c_adapter, + zr->card.mod_decoder, zr->card.i2c_decoder, zr->card.addrs_decoder); + + if (zr->card.mod_encoder) + zr->encoder = v4l2_i2c_new_probed_subdev(&zr->i2c_adapter, + zr->card.mod_encoder, zr->card.i2c_encoder, + zr->card.addrs_encoder); + dprintk(2, KERN_INFO "%s: Initializing videocodec bus...\n", ZR_DEVNAME(zr)); @@ -1545,8 +1459,6 @@ static int __devinit zoran_probe(struct pci_dev *pdev, zoran_proc_init(zr); - pci_set_drvdata(pdev, zr); - return 0; zr_detach_vfe: @@ -1564,6 +1476,8 @@ zr_free_irq: free_irq(zr->pci_dev->irq, zr); zr_unmap: iounmap(zr->zr36057_mem); +zr_unreg: + v4l2_device_unregister(&zr->v4l2_dev); zr_free_mem: kfree(zr); @@ -1614,9 +1528,6 @@ static int __init zoran_init(void) ZORAN_NAME, vidmem); } - /* random nonsense */ - dprintk(6, KERN_DEBUG "Jotti is een held!\n"); - /* some mainboards might not do PCI-PCI data transfer well */ if (pci_pci_problems & (PCIPCI_FAIL|PCIAGP_FAIL|PCIPCI_ALIMAGIK)) { dprintk(1, diff --git a/linux/drivers/media/video/zoran/zoran_card.h b/linux/drivers/media/video/zoran/zoran_card.h index 4507bdc5e..4936fead7 100644 --- a/linux/drivers/media/video/zoran/zoran_card.h +++ b/linux/drivers/media/video/zoran/zoran_card.h @@ -44,7 +44,8 @@ extern int zr36067_debug; extern struct video_device zoran_template; extern int zoran_check_jpg_settings(struct zoran *zr, - struct zoran_jpg_settings *settings); + struct zoran_jpg_settings *settings, + int try); extern void zoran_open_init_params(struct zoran *zr); extern void zoran_vdev_release(struct video_device *vdev); diff --git a/linux/drivers/media/video/zoran/zoran_device.c b/linux/drivers/media/video/zoran/zoran_device.c index 87f894fa2..c2dfd4b67 100644 --- a/linux/drivers/media/video/zoran/zoran_device.c +++ b/linux/drivers/media/video/zoran/zoran_device.c @@ -37,13 +37,12 @@ #include <linux/i2c.h> #include <linux/i2c-algo-bit.h> #include "compat.h" -#include <linux/videodev.h> +#include <linux/videodev2.h> +#include <media/v4l2-common.h> #include <linux/spinlock.h> #include <linux/sem.h> #include <linux/pci.h> -#include <linux/video_decoder.h> -#include <linux/video_encoder.h> #include <linux/delay.h> #include <linux/wait.h> @@ -313,9 +312,9 @@ zr36057_adjust_vfe (struct zoran *zr, case BUZ_MODE_MOTION_COMPRESS: case BUZ_MODE_IDLE: default: - if (zr->norm == VIDEO_MODE_NTSC || + if ((zr->norm & V4L2_STD_NTSC) || (zr->card.type == LML33R10 && - zr->norm == VIDEO_MODE_PAL)) + (zr->norm & V4L2_STD_PAL))) btand(~ZR36057_VFESPFR_ExtFl, ZR36057_VFESPFR); else btor(ZR36057_VFESPFR_ExtFl, ZR36057_VFESPFR); @@ -356,14 +355,6 @@ zr36057_set_vfe (struct zoran *zr, dprintk(2, KERN_INFO "%s: set_vfe() - width = %d, height = %d\n", ZR_DEVNAME(zr), video_width, video_height); - if (zr->norm != VIDEO_MODE_PAL && - zr->norm != VIDEO_MODE_NTSC && - zr->norm != VIDEO_MODE_SECAM) { - dprintk(1, - KERN_ERR "%s: set_vfe() - norm = %d not valid\n", - ZR_DEVNAME(zr), zr->norm); - return; - } if (video_width < BUZ_MIN_WIDTH || video_height < BUZ_MIN_HEIGHT || video_width > Wa || video_height > Ha) { @@ -427,7 +418,7 @@ zr36057_set_vfe (struct zoran *zr, * we get the correct colors when uncompressing to the screen */ //reg |= ZR36057_VFESPFR_VCLKPol; /**/ /* RJ: Don't know if that is needed for NTSC also */ - if (zr->norm != VIDEO_MODE_NTSC) + if (!(zr->norm & V4L2_STD_NTSC)) reg |= ZR36057_VFESPFR_ExtFl; // NEEDED!!!!!!! Wolfgang reg |= ZR36057_VFESPFR_TopField; if (HorDcm >= 48) { @@ -498,11 +489,11 @@ zr36057_overlay (struct zoran *zr, * All error messages are internal driver checking only! */ /* video display top and bottom registers */ - reg = (long) zr->buffer.base + + reg = (long) zr->vbuf_base + zr->overlay_settings.x * ((zr->overlay_settings.format->depth + 7) / 8) + zr->overlay_settings.y * - zr->buffer.bytesperline; + zr->vbuf_bytesperline; btwrite(reg, ZR36057_VDTR); if (reg & 3) dprintk(1, @@ -510,15 +501,15 @@ zr36057_overlay (struct zoran *zr, "%s: zr36057_overlay() - video_address not aligned\n", ZR_DEVNAME(zr)); if (zr->overlay_settings.height > BUZ_MAX_HEIGHT / 2) - reg += zr->buffer.bytesperline; + reg += zr->vbuf_bytesperline; btwrite(reg, ZR36057_VDBR); /* video stride, status, and frame grab register */ - reg = zr->buffer.bytesperline - + reg = zr->vbuf_bytesperline - zr->overlay_settings.width * ((zr->overlay_settings.format->depth + 7) / 8); if (zr->overlay_settings.height > BUZ_MAX_HEIGHT / 2) - reg += zr->buffer.bytesperline; + reg += zr->vbuf_bytesperline; if (reg & 3) dprintk(1, KERN_ERR @@ -547,7 +538,7 @@ zr36057_overlay (struct zoran *zr, void write_overlay_mask (struct file *file, - struct video_clip *vp, + struct v4l2_clip *vp, int count) { struct zoran_fh *fh = file->private_data; @@ -564,10 +555,10 @@ write_overlay_mask (struct file *file, for (i = 0; i < count; ++i) { /* pick up local copy of clip */ - x = vp[i].x; - y = vp[i].y; - width = vp[i].width; - height = vp[i].height; + x = vp[i].c.left; + y = vp[i].c.top; + width = vp[i].c.width; + height = vp[i].c.height; /* trim clips that extend beyond the window */ if (x < 0) { @@ -982,11 +973,10 @@ void zr36057_enable_jpg (struct zoran *zr, enum zoran_codec_mode mode) { - static int zero; - static int one = 1; struct vfe_settings cap; int field_size = zr->jpg_buffers.buffer_size / zr->jpg_settings.field_per_buff; + struct v4l2_routing route = { 0, 0 }; zr->codec_mode = mode; @@ -1008,8 +998,9 @@ zr36057_enable_jpg (struct zoran *zr, * the video bus direction set to input. */ set_videobus_dir(zr, 0); - decoder_command(zr, DECODER_ENABLE_OUTPUT, &one); - encoder_command(zr, ENCODER_SET_INPUT, &zero); + decoder_call(zr, video, s_stream, 1); + route.input = 0; + encoder_call(zr, video, s_routing, &route); /* Take the JPEG codec and the VFE out of sleep */ jpeg_codec_sleep(zr, 0); @@ -1055,9 +1046,10 @@ zr36057_enable_jpg (struct zoran *zr, /* In motion decompression mode, the decoder output must be disabled, and * the video bus direction set to output. */ - decoder_command(zr, DECODER_ENABLE_OUTPUT, &zero); + decoder_call(zr, video, s_stream, 0); set_videobus_dir(zr, 1); - encoder_command(zr, ENCODER_SET_INPUT, &one); + route.input = 1; + encoder_call(zr, video, s_routing, &route); /* Take the JPEG codec and the VFE out of sleep */ jpeg_codec_sleep(zr, 0); @@ -1101,8 +1093,9 @@ zr36057_enable_jpg (struct zoran *zr, jpeg_codec_sleep(zr, 1); zr36057_adjust_vfe(zr, mode); - decoder_command(zr, DECODER_ENABLE_OUTPUT, &one); - encoder_command(zr, ENCODER_SET_INPUT, &zero); + decoder_call(zr, video, s_stream, 1); + route.input = 0; + encoder_call(zr, video, s_routing, &route); dprintk(2, KERN_INFO "%s: enable_jpg(IDLE)\n", ZR_DEVNAME(zr)); break; @@ -1209,22 +1202,52 @@ zoran_reap_stat_com (struct zoran *zr) } } +static void zoran_restart(struct zoran *zr) +{ + /* Now the stat_comm buffer is ready for restart */ + int status = 0, mode; + + if (zr->codec_mode == BUZ_MODE_MOTION_COMPRESS) { + decoder_call(zr, video, g_input_status, &status); + mode = CODEC_DO_COMPRESSION; + } else { + status = V4L2_IN_ST_NO_SIGNAL; + mode = CODEC_DO_EXPANSION; + } + if (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS || + !(status & V4L2_IN_ST_NO_SIGNAL)) { + /********** RESTART code *************/ + jpeg_codec_reset(zr); + zr->codec->set_mode(zr->codec, mode); + zr36057_set_jpg(zr, zr->codec_mode); + jpeg_start(zr); + + if (zr->num_errors <= 8) + dprintk(2, KERN_INFO "%s: Restart\n", + ZR_DEVNAME(zr)); + + zr->JPEG_missed = 0; + zr->JPEG_error = 2; + /********** End RESTART code ***********/ + } +} + static void error_handler (struct zoran *zr, u32 astat, u32 stat) { + int i, j; + /* This is JPEG error handling part */ - if ((zr->codec_mode != BUZ_MODE_MOTION_COMPRESS) && - (zr->codec_mode != BUZ_MODE_MOTION_DECOMPRESS)) { - //dprintk(1, KERN_ERR "%s: Internal error: error handling request in mode %d\n", ZR_DEVNAME(zr), zr->codec_mode); + if (zr->codec_mode != BUZ_MODE_MOTION_COMPRESS && + zr->codec_mode != BUZ_MODE_MOTION_DECOMPRESS) { return; } if ((stat & 1) == 0 && zr->codec_mode == BUZ_MODE_MOTION_COMPRESS && - zr->jpg_dma_tail - zr->jpg_que_tail >= - zr->jpg_buffers.num_buffers) { + zr->jpg_dma_tail - zr->jpg_que_tail >= zr->jpg_buffers.num_buffers) { /* No free buffers... */ zoran_reap_stat_com(zr); zoran_feed_stat_com(zr); @@ -1233,142 +1256,95 @@ error_handler (struct zoran *zr, return; } - if (zr->JPEG_error != 1) { - /* - * First entry: error just happened during normal operation - * - * In BUZ_MODE_MOTION_COMPRESS: - * - * Possible glitch in TV signal. In this case we should - * stop the codec and wait for good quality signal before - * restarting it to avoid further problems - * - * In BUZ_MODE_MOTION_DECOMPRESS: - * - * Bad JPEG frame: we have to mark it as processed (codec crashed - * and was not able to do it itself), and to remove it from queue. - */ - btand(~ZR36057_JMC_Go_en, ZR36057_JMC); - udelay(1); - stat = stat | (post_office_read(zr, 7, 0) & 3) << 8; - btwrite(0, ZR36057_JPC); - btor(ZR36057_MCTCR_CFlush, ZR36057_MCTCR); - jpeg_codec_reset(zr); - jpeg_codec_sleep(zr, 1); - zr->JPEG_error = 1; - zr->num_errors++; - - /* Report error */ - if (zr36067_debug > 1 && zr->num_errors <= 8) { - long frame; - frame = - zr->jpg_pend[zr->jpg_dma_tail & BUZ_MASK_FRAME]; - printk(KERN_ERR - "%s: JPEG error stat=0x%08x(0x%08x) queue_state=%ld/%ld/%ld/%ld seq=%ld frame=%ld. Codec stopped. ", - ZR_DEVNAME(zr), stat, zr->last_isr, - zr->jpg_que_tail, zr->jpg_dma_tail, - zr->jpg_dma_head, zr->jpg_que_head, - zr->jpg_seq_num, frame); - printk("stat_com frames:"); - { - int i, j; - for (j = 0; j < BUZ_NUM_STAT_COM; j++) { - for (i = 0; - i < zr->jpg_buffers.num_buffers; - i++) { - if (le32_to_cpu(zr->stat_com[j]) == - zr->jpg_buffers. - buffer[i]. - frag_tab_bus) { - printk("% d->%d", - j, i); - } - } - } - printk("\n"); - } - } - /* Find an entry in stat_com and rotate contents */ - { - int i; - - if (zr->jpg_settings.TmpDcm == 1) - i = (zr->jpg_dma_tail - - zr->jpg_err_shift) & BUZ_MASK_STAT_COM; - else - i = ((zr->jpg_dma_tail - - zr->jpg_err_shift) & 1) * 2; - if (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS) { - /* Mimic zr36067 operation */ - zr->stat_com[i] |= cpu_to_le32(1); - if (zr->jpg_settings.TmpDcm != 1) - zr->stat_com[i + 1] |= cpu_to_le32(1); - /* Refill */ - zoran_reap_stat_com(zr); - zoran_feed_stat_com(zr); - wake_up_interruptible(&zr->jpg_capq); - /* Find an entry in stat_com again after refill */ - if (zr->jpg_settings.TmpDcm == 1) - i = (zr->jpg_dma_tail - - zr->jpg_err_shift) & - BUZ_MASK_STAT_COM; - else - i = ((zr->jpg_dma_tail - - zr->jpg_err_shift) & 1) * 2; - } - if (i) { - /* Rotate stat_comm entries to make current entry first */ - int j; - __le32 bus_addr[BUZ_NUM_STAT_COM]; - - /* Here we are copying the stat_com array, which - * is already in little endian format, so - * no endian conversions here - */ - memcpy(bus_addr, zr->stat_com, - sizeof(bus_addr)); - for (j = 0; j < BUZ_NUM_STAT_COM; j++) { - zr->stat_com[j] = - bus_addr[(i + j) & - BUZ_MASK_STAT_COM]; + if (zr->JPEG_error == 1) { + zoran_restart(zr); + return; + } - } - zr->jpg_err_shift += i; - zr->jpg_err_shift &= BUZ_MASK_STAT_COM; + /* + * First entry: error just happened during normal operation + * + * In BUZ_MODE_MOTION_COMPRESS: + * + * Possible glitch in TV signal. In this case we should + * stop the codec and wait for good quality signal before + * restarting it to avoid further problems + * + * In BUZ_MODE_MOTION_DECOMPRESS: + * + * Bad JPEG frame: we have to mark it as processed (codec crashed + * and was not able to do it itself), and to remove it from queue. + */ + btand(~ZR36057_JMC_Go_en, ZR36057_JMC); + udelay(1); + stat = stat | (post_office_read(zr, 7, 0) & 3) << 8; + btwrite(0, ZR36057_JPC); + btor(ZR36057_MCTCR_CFlush, ZR36057_MCTCR); + jpeg_codec_reset(zr); + jpeg_codec_sleep(zr, 1); + zr->JPEG_error = 1; + zr->num_errors++; + + /* Report error */ + if (zr36067_debug > 1 && zr->num_errors <= 8) { + long frame; + + frame = zr->jpg_pend[zr->jpg_dma_tail & BUZ_MASK_FRAME]; + printk(KERN_ERR + "%s: JPEG error stat=0x%08x(0x%08x) queue_state=%ld/%ld/%ld/%ld seq=%ld frame=%ld. Codec stopped. ", + ZR_DEVNAME(zr), stat, zr->last_isr, + zr->jpg_que_tail, zr->jpg_dma_tail, + zr->jpg_dma_head, zr->jpg_que_head, + zr->jpg_seq_num, frame); + printk(KERN_INFO "stat_com frames:"); + for (j = 0; j < BUZ_NUM_STAT_COM; j++) { + for (i = 0; i < zr->jpg_buffers.num_buffers; i++) { + if (le32_to_cpu(zr->stat_com[j]) == zr->jpg_buffers.buffer[i].frag_tab_bus) + printk(KERN_CONT "% d->%d", j, i); } - if (zr->codec_mode == BUZ_MODE_MOTION_COMPRESS) - zr->jpg_err_seq = zr->jpg_seq_num; /* + 1; */ } + printk(KERN_CONT "\n"); } + /* Find an entry in stat_com and rotate contents */ + if (zr->jpg_settings.TmpDcm == 1) + i = (zr->jpg_dma_tail - zr->jpg_err_shift) & BUZ_MASK_STAT_COM; + else + i = ((zr->jpg_dma_tail - zr->jpg_err_shift) & 1) * 2; + if (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS) { + /* Mimic zr36067 operation */ + zr->stat_com[i] |= cpu_to_le32(1); + if (zr->jpg_settings.TmpDcm != 1) + zr->stat_com[i + 1] |= cpu_to_le32(1); + /* Refill */ + zoran_reap_stat_com(zr); + zoran_feed_stat_com(zr); + wake_up_interruptible(&zr->jpg_capq); + /* Find an entry in stat_com again after refill */ + if (zr->jpg_settings.TmpDcm == 1) + i = (zr->jpg_dma_tail - zr->jpg_err_shift) & BUZ_MASK_STAT_COM; + else + i = ((zr->jpg_dma_tail - zr->jpg_err_shift) & 1) * 2; + } + if (i) { + /* Rotate stat_comm entries to make current entry first */ + int j; + __le32 bus_addr[BUZ_NUM_STAT_COM]; + + /* Here we are copying the stat_com array, which + * is already in little endian format, so + * no endian conversions here + */ + memcpy(bus_addr, zr->stat_com, sizeof(bus_addr)); - /* Now the stat_comm buffer is ready for restart */ - do { - int status, mode; - - if (zr->codec_mode == BUZ_MODE_MOTION_COMPRESS) { - decoder_command(zr, DECODER_GET_STATUS, &status); - mode = CODEC_DO_COMPRESSION; - } else { - status = 0; - mode = CODEC_DO_EXPANSION; - } - if (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS || - (status & DECODER_STATUS_GOOD)) { - /********** RESTART code *************/ - jpeg_codec_reset(zr); - zr->codec->set_mode(zr->codec, mode); - zr36057_set_jpg(zr, zr->codec_mode); - jpeg_start(zr); - - if (zr->num_errors <= 8) - dprintk(2, KERN_INFO "%s: Restart\n", - ZR_DEVNAME(zr)); + for (j = 0; j < BUZ_NUM_STAT_COM; j++) + zr->stat_com[j] = bus_addr[(i + j) & BUZ_MASK_STAT_COM]; - zr->JPEG_missed = 0; - zr->JPEG_error = 2; - /********** End RESTART code ***********/ - } - } while (0); + zr->jpg_err_shift += i; + zr->jpg_err_shift &= BUZ_MASK_STAT_COM; + } + if (zr->codec_mode == BUZ_MODE_MOTION_COMPRESS) + zr->jpg_err_seq = zr->jpg_seq_num; /* + 1; */ + zoran_restart(zr); } irqreturn_t @@ -1431,10 +1407,8 @@ zoran_irq (int irq, * We simply ignore them */ if (zr->v4l_memgrab_active) { - /* A lot more checks should be here ... */ - if ((btread(ZR36057_VSSFGR) & - ZR36057_VSSFGR_SnapShot) == 0) + if ((btread(ZR36057_VSSFGR) & ZR36057_VSSFGR_SnapShot) == 0) dprintk(1, KERN_WARNING "%s: BuzIRQ with SnapShot off ???\n", @@ -1442,10 +1416,7 @@ zoran_irq (int irq, if (zr->v4l_grab_frame != NO_GRAB_ACTIVE) { /* There is a grab on a frame going on, check if it has finished */ - - if ((btread(ZR36057_VSSFGR) & - ZR36057_VSSFGR_FrameGrab) == - 0) { + if ((btread(ZR36057_VSSFGR) & ZR36057_VSSFGR_FrameGrab) == 0) { /* it is finished, notify the user */ zr->v4l_buffers.buffer[zr->v4l_grab_frame].state = BUZ_STATE_DONE; @@ -1463,9 +1434,7 @@ zoran_irq (int irq, if (zr->v4l_grab_frame == NO_GRAB_ACTIVE && zr->v4l_pend_tail != zr->v4l_pend_head) { - - int frame = zr->v4l_pend[zr->v4l_pend_tail & - V4L_MASK_FRAME]; + int frame = zr->v4l_pend[zr->v4l_pend_tail & V4L_MASK_FRAME]; u32 reg; zr->v4l_grab_frame = frame; @@ -1474,27 +1443,17 @@ zoran_irq (int irq, /* Buffer address */ - reg = - zr->v4l_buffers.buffer[frame]. - fbuffer_bus; + reg = zr->v4l_buffers.buffer[frame].fbuffer_bus; btwrite(reg, ZR36057_VDTR); - if (zr->v4l_settings.height > - BUZ_MAX_HEIGHT / 2) - reg += - zr->v4l_settings. - bytesperline; + if (zr->v4l_settings.height > BUZ_MAX_HEIGHT / 2) + reg += zr->v4l_settings.bytesperline; btwrite(reg, ZR36057_VDBR); /* video stride, status, and frame grab register */ reg = 0; - if (zr->v4l_settings.height > - BUZ_MAX_HEIGHT / 2) - reg += - zr->v4l_settings. - bytesperline; - reg = - (reg << - ZR36057_VSSFGR_DispStride); + if (zr->v4l_settings.height > BUZ_MAX_HEIGHT / 2) + reg += zr->v4l_settings.bytesperline; + reg = (reg << ZR36057_VSSFGR_DispStride); reg |= ZR36057_VSSFGR_VidOvf; reg |= ZR36057_VSSFGR_SnapShot; reg |= ZR36057_VSSFGR_FrameGrab; @@ -1512,77 +1471,66 @@ zoran_irq (int irq, #if (IRQ_MASK & ZR36057_ISR_CodRepIRQ) if (astat & ZR36057_ISR_CodRepIRQ) { zr->intr_counter_CodRepIRQ++; - IDEBUG(printk - (KERN_DEBUG "%s: ZR36057_ISR_CodRepIRQ\n", + IDEBUG(printk(KERN_DEBUG "%s: ZR36057_ISR_CodRepIRQ\n", ZR_DEVNAME(zr))); btand(~ZR36057_ICR_CodRepIRQ, ZR36057_ICR); } #endif /* (IRQ_MASK & ZR36057_ISR_CodRepIRQ) */ #if (IRQ_MASK & ZR36057_ISR_JPEGRepIRQ) - if (astat & ZR36057_ISR_JPEGRepIRQ) { - - if (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS || - zr->codec_mode == BUZ_MODE_MOTION_COMPRESS) { - if (zr36067_debug > 1 && - (!zr->frame_num || zr->JPEG_error)) { - printk(KERN_INFO - "%s: first frame ready: state=0x%08x odd_even=%d field_per_buff=%d delay=%d\n", - ZR_DEVNAME(zr), stat, - zr->jpg_settings.odd_even, - zr->jpg_settings. - field_per_buff, - zr->JPEG_missed); - { - char sc[] = "0000"; - char sv[5]; - int i; - strcpy(sv, sc); - for (i = 0; i < 4; i++) { - if (le32_to_cpu(zr->stat_com[i]) & 1) - sv[i] = '1'; - } - sv[4] = 0; - printk(KERN_INFO - "%s: stat_com=%s queue_state=%ld/%ld/%ld/%ld\n", - ZR_DEVNAME(zr), sv, - zr->jpg_que_tail, - zr->jpg_dma_tail, - zr->jpg_dma_head, - zr->jpg_que_head); - } - } else { - if (zr->JPEG_missed > zr->JPEG_max_missed) // Get statistics - zr->JPEG_max_missed = - zr->JPEG_missed; - if (zr->JPEG_missed < - zr->JPEG_min_missed) - zr->JPEG_min_missed = - zr->JPEG_missed; + if ((astat & ZR36057_ISR_JPEGRepIRQ) && + (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS || + zr->codec_mode == BUZ_MODE_MOTION_COMPRESS)) { + if (zr36067_debug > 1 && (!zr->frame_num || zr->JPEG_error)) { + char sc[] = "0000"; + char sv[5]; + int i; + + printk(KERN_INFO + "%s: first frame ready: state=0x%08x odd_even=%d field_per_buff=%d delay=%d\n", + ZR_DEVNAME(zr), stat, + zr->jpg_settings.odd_even, + zr->jpg_settings.field_per_buff, + zr->JPEG_missed); + + strcpy(sv, sc); + for (i = 0; i < 4; i++) { + if (le32_to_cpu(zr->stat_com[i]) & 1) + sv[i] = '1'; } + sv[4] = 0; + printk(KERN_INFO + "%s: stat_com=%s queue_state=%ld/%ld/%ld/%ld\n", + ZR_DEVNAME(zr), sv, + zr->jpg_que_tail, + zr->jpg_dma_tail, + zr->jpg_dma_head, + zr->jpg_que_head); + } else { + /* Get statistics */ + if (zr->JPEG_missed > zr->JPEG_max_missed) + zr->JPEG_max_missed = zr->JPEG_missed; + if (zr->JPEG_missed < zr->JPEG_min_missed) + zr->JPEG_min_missed = zr->JPEG_missed; + } - if (zr36067_debug > 2 && zr->frame_num < 6) { - int i; - printk("%s: seq=%ld stat_com:", - ZR_DEVNAME(zr), zr->jpg_seq_num); - for (i = 0; i < 4; i++) { - printk(" %08x", - le32_to_cpu(zr->stat_com[i])); - } - printk("\n"); + if (zr36067_debug > 2 && zr->frame_num < 6) { + int i; + + printk(KERN_INFO "%s: seq=%ld stat_com:", + ZR_DEVNAME(zr), zr->jpg_seq_num); + for (i = 0; i < 4; i++) { + printk(KERN_CONT " %08x", + le32_to_cpu(zr->stat_com[i])); } - zr->frame_num++; - zr->JPEG_missed = 0; - zr->JPEG_error = 0; - zoran_reap_stat_com(zr); - zoran_feed_stat_com(zr); - wake_up_interruptible(&zr->jpg_capq); - } /*else { - dprintk(1, - KERN_ERR - "%s: JPEG interrupt while not in motion (de)compress mode!\n", - ZR_DEVNAME(zr)); - }*/ + printk(KERN_CONT "\n"); + } + zr->frame_num++; + zr->JPEG_missed = 0; + zr->JPEG_error = 0; + zoran_reap_stat_com(zr); + zoran_feed_stat_com(zr); + wake_up_interruptible(&zr->jpg_capq); } #endif /* (IRQ_MASK & ZR36057_ISR_JPEGRepIRQ) */ @@ -1591,8 +1539,7 @@ zoran_irq (int irq, zr->JPEG_missed > 25 || zr->JPEG_error == 1 || ((zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS) && - (zr->frame_num & (zr->JPEG_missed > - zr->jpg_settings.field_per_buff)))) { + (zr->frame_num & (zr->JPEG_missed > zr->jpg_settings.field_per_buff)))) { error_handler(zr, astat, stat); } @@ -1634,7 +1581,7 @@ zoran_set_pci_master (struct zoran *zr, void zoran_init_hardware (struct zoran *zr) { - int j, zero = 0; + struct v4l2_routing route = { 0, 0 }; /* Enable bus-mastering */ zoran_set_pci_master(zr, 1); @@ -1644,15 +1591,16 @@ zoran_init_hardware (struct zoran *zr) zr->card.init(zr); } - j = zr->card.input[zr->input].muxsel; + route.input = zr->card.input[zr->input].muxsel; - decoder_command(zr, 0, NULL); - decoder_command(zr, DECODER_SET_NORM, &zr->norm); - decoder_command(zr, DECODER_SET_INPUT, &j); + decoder_call(zr, core, init, 0); + decoder_s_std(zr, zr->norm); + decoder_s_routing(zr, &route); - encoder_command(zr, 0, NULL); - encoder_command(zr, ENCODER_SET_NORM, &zr->norm); - encoder_command(zr, ENCODER_SET_INPUT, &zero); + encoder_call(zr, core, init, 0); + encoder_call(zr, video, s_std_output, zr->norm); + route.input = 0; + encoder_call(zr, video, s_routing, &route); /* toggle JPEG codec sleep to sync PLL */ jpeg_codec_sleep(zr, 1); @@ -1717,37 +1665,30 @@ zr36057_init_vfe (struct zoran *zr) * Interface to decoder and encoder chips using i2c bus */ -int -decoder_command (struct zoran *zr, - int cmd, - void *data) +int decoder_s_std(struct zoran *zr, v4l2_std_id std) { - if (zr->decoder == NULL) - return -EIO; + int res; - if (zr->card.type == LML33 && - (cmd == DECODER_SET_NORM || cmd == DECODER_SET_INPUT)) { - int res; - - // Bt819 needs to reset its FIFO buffer using #FRST pin and - // LML33 card uses GPIO(7) for that. + /* Bt819 needs to reset its FIFO buffer using #FRST pin and + LML33 card uses GPIO(7) for that. */ + if (zr->card.type == LML33) GPIO(zr, 7, 0); - res = zr->decoder->driver->command(zr->decoder, cmd, data); - // Pull #FRST high. - GPIO(zr, 7, 1); - return res; - } else - return zr->decoder->driver->command(zr->decoder, cmd, - data); + res = decoder_call(zr, tuner, s_std, std); + if (zr->card.type == LML33) + GPIO(zr, 7, 1); /* Pull #FRST high. */ + return res; } -int -encoder_command (struct zoran *zr, - int cmd, - void *data) +int decoder_s_routing(struct zoran *zr, struct v4l2_routing *route) { - if (zr->encoder == NULL) - return -1; + int res; - return zr->encoder->driver->command(zr->encoder, cmd, data); + /* Bt819 needs to reset its FIFO buffer using #FRST pin and + LML33 card uses GPIO(7) for that. */ + if (zr->card.type == LML33) + GPIO(zr, 7, 0); + res = decoder_call(zr, video, s_routing, route); + if (zr->card.type == LML33) + GPIO(zr, 7, 1); /* Pull #FRST high. */ + return res; } diff --git a/linux/drivers/media/video/zoran/zoran_device.h b/linux/drivers/media/video/zoran/zoran_device.h index d4e0b9b5a..2eb645904 100644 --- a/linux/drivers/media/video/zoran/zoran_device.h +++ b/linux/drivers/media/video/zoran/zoran_device.h @@ -55,7 +55,7 @@ extern int jpeg_codec_reset(struct zoran *zr); extern void zr36057_overlay(struct zoran *zr, int on); extern void write_overlay_mask(struct file *file, - struct video_clip *vp, + struct v4l2_clip *vp, int count); extern void zr36057_set_memgrab(struct zoran *zr, int mode); @@ -93,11 +93,12 @@ extern int jpg_bufsize; extern int pass_through; /* i2c */ -extern int decoder_command(struct zoran *zr, - int cmd, - void *data); -extern int encoder_command(struct zoran *zr, - int cmd, - void *data); +#define decoder_call(zr, o, f, args...) \ + v4l2_subdev_call(zr->decoder, o, f, ##args) +#define encoder_call(zr, o, f, args...) \ + v4l2_subdev_call(zr->encoder, o, f, ##args) + +int decoder_s_std(struct zoran *zr, v4l2_std_id std); +int decoder_s_routing(struct zoran *zr, struct v4l2_routing *route); #endif /* __ZORAN_DEVICE_H__ */ diff --git a/linux/drivers/media/video/zoran/zoran_driver.c b/linux/drivers/media/video/zoran/zoran_driver.c index 2609f54d7..7ddbdf37d 100644 --- a/linux/drivers/media/video/zoran/zoran_driver.c +++ b/linux/drivers/media/video/zoran/zoran_driver.c @@ -58,18 +58,8 @@ #include <linux/i2c-algo-bit.h> #include <linux/spinlock.h> -#define MAP_NR(x) virt_to_page(x) -#define ZORAN_VID_TYPE ( \ - VID_TYPE_CAPTURE | \ - VID_TYPE_OVERLAY | \ - VID_TYPE_CLIPPING | \ - VID_TYPE_FRAMERAM | \ - VID_TYPE_SCALES | \ - VID_TYPE_MJPEG_DECODER | \ - VID_TYPE_MJPEG_ENCODER \ - ) - -#include <linux/videodev.h> + +#include <linux/videodev2.h> #include <media/v4l2-common.h> #include <media/v4l2-ioctl.h> #include "videocodec.h" @@ -79,37 +69,18 @@ #include <asm/uaccess.h> #include <linux/proc_fs.h> -#include <linux/video_decoder.h> -#include <linux/video_encoder.h> #include "compat.h" #include <linux/mutex.h> #include "zoran.h" #include "zoran_device.h" #include "zoran_card.h" - /* we declare some card type definitions here, they mean - * the same as the v4l1 ZORAN_VID_TYPE above, except it's v4l2 */ -#define ZORAN_V4L2_VID_FLAGS ( \ - V4L2_CAP_STREAMING |\ - V4L2_CAP_VIDEO_CAPTURE |\ - V4L2_CAP_VIDEO_OUTPUT |\ - V4L2_CAP_VIDEO_OVERLAY \ - ) - - -#if defined(CONFIG_VIDEO_V4L1_COMPAT) -#define ZFMT(pal, fcc, cs) \ - .palette = (pal), .fourcc = (fcc), .colorspace = (cs) -#else -#define ZFMT(pal, fcc, cs) \ - .fourcc = (fcc), .colorspace = (cs) -#endif const struct zoran_format zoran_formats[] = { { .name = "15-bit RGB LE", - ZFMT(VIDEO_PALETTE_RGB555, - V4L2_PIX_FMT_RGB555, V4L2_COLORSPACE_SRGB), + .fourcc = V4L2_PIX_FMT_RGB555, + .colorspace = V4L2_COLORSPACE_SRGB, .depth = 15, .flags = ZORAN_FORMAT_CAPTURE | ZORAN_FORMAT_OVERLAY, @@ -117,16 +88,16 @@ const struct zoran_format zoran_formats[] = { ZR36057_VFESPFR_LittleEndian, }, { .name = "15-bit RGB BE", - ZFMT(-1, - V4L2_PIX_FMT_RGB555X, V4L2_COLORSPACE_SRGB), + .fourcc = V4L2_PIX_FMT_RGB555X, + .colorspace = V4L2_COLORSPACE_SRGB, .depth = 15, .flags = ZORAN_FORMAT_CAPTURE | ZORAN_FORMAT_OVERLAY, .vfespfr = ZR36057_VFESPFR_RGB555|ZR36057_VFESPFR_ErrDif, }, { .name = "16-bit RGB LE", - ZFMT(VIDEO_PALETTE_RGB565, - V4L2_PIX_FMT_RGB565, V4L2_COLORSPACE_SRGB), + .fourcc = V4L2_PIX_FMT_RGB565, + .colorspace = V4L2_COLORSPACE_SRGB, .depth = 16, .flags = ZORAN_FORMAT_CAPTURE | ZORAN_FORMAT_OVERLAY, @@ -134,56 +105,56 @@ const struct zoran_format zoran_formats[] = { ZR36057_VFESPFR_LittleEndian, }, { .name = "16-bit RGB BE", - ZFMT(-1, - V4L2_PIX_FMT_RGB565X, V4L2_COLORSPACE_SRGB), + .fourcc = V4L2_PIX_FMT_RGB565X, + .colorspace = V4L2_COLORSPACE_SRGB, .depth = 16, .flags = ZORAN_FORMAT_CAPTURE | ZORAN_FORMAT_OVERLAY, .vfespfr = ZR36057_VFESPFR_RGB565|ZR36057_VFESPFR_ErrDif, }, { .name = "24-bit RGB", - ZFMT(VIDEO_PALETTE_RGB24, - V4L2_PIX_FMT_BGR24, V4L2_COLORSPACE_SRGB), + .fourcc = V4L2_PIX_FMT_BGR24, + .colorspace = V4L2_COLORSPACE_SRGB, .depth = 24, .flags = ZORAN_FORMAT_CAPTURE | ZORAN_FORMAT_OVERLAY, .vfespfr = ZR36057_VFESPFR_RGB888|ZR36057_VFESPFR_Pack24, }, { .name = "32-bit RGB LE", - ZFMT(VIDEO_PALETTE_RGB32, - V4L2_PIX_FMT_BGR32, V4L2_COLORSPACE_SRGB), + .fourcc = V4L2_PIX_FMT_BGR32, + .colorspace = V4L2_COLORSPACE_SRGB, .depth = 32, .flags = ZORAN_FORMAT_CAPTURE | ZORAN_FORMAT_OVERLAY, .vfespfr = ZR36057_VFESPFR_RGB888|ZR36057_VFESPFR_LittleEndian, }, { .name = "32-bit RGB BE", - ZFMT(-1, - V4L2_PIX_FMT_RGB32, V4L2_COLORSPACE_SRGB), + .fourcc = V4L2_PIX_FMT_RGB32, + .colorspace = V4L2_COLORSPACE_SRGB, .depth = 32, .flags = ZORAN_FORMAT_CAPTURE | ZORAN_FORMAT_OVERLAY, .vfespfr = ZR36057_VFESPFR_RGB888, }, { .name = "4:2:2, packed, YUYV", - ZFMT(VIDEO_PALETTE_YUV422, - V4L2_PIX_FMT_YUYV, V4L2_COLORSPACE_SMPTE170M), + .fourcc = V4L2_PIX_FMT_YUYV, + .colorspace = V4L2_COLORSPACE_SMPTE170M, .depth = 16, .flags = ZORAN_FORMAT_CAPTURE | ZORAN_FORMAT_OVERLAY, .vfespfr = ZR36057_VFESPFR_YUV422, }, { .name = "4:2:2, packed, UYVY", - ZFMT(VIDEO_PALETTE_UYVY, - V4L2_PIX_FMT_UYVY, V4L2_COLORSPACE_SMPTE170M), + .fourcc = V4L2_PIX_FMT_UYVY, + .colorspace = V4L2_COLORSPACE_SMPTE170M, .depth = 16, .flags = ZORAN_FORMAT_CAPTURE | ZORAN_FORMAT_OVERLAY, .vfespfr = ZR36057_VFESPFR_YUV422|ZR36057_VFESPFR_LittleEndian, }, { .name = "Hardware-encoded Motion-JPEG", - ZFMT(-1, - V4L2_PIX_FMT_MJPEG, V4L2_COLORSPACE_SMPTE170M), + .fourcc = V4L2_PIX_FMT_MJPEG, + .colorspace = V4L2_COLORSPACE_SMPTE170M, .depth = 0, .flags = ZORAN_FORMAT_CAPTURE | ZORAN_FORMAT_PLAYBACK | @@ -192,16 +163,6 @@ const struct zoran_format zoran_formats[] = { }; #define NUM_FORMATS ARRAY_SIZE(zoran_formats) -// RJ: Test only - want to test BUZ_USE_HIMEM even when CONFIG_BIGPHYS_AREA is defined -#if !defined(CONFIG_BIGPHYS_AREA) && !defined(BUZ_USE_HIMEM) -//#undef CONFIG_BIGPHYS_AREA -#define BUZ_USE_HIMEM -#endif - -#if defined(CONFIG_BIGPHYS_AREA) -# include <linux/bigphysarea.h> -#endif - static int lock_norm; /* 0 = default 1 = Don't change TV standard (norm) */ module_param(lock_norm, int, 0644); MODULE_PARM_DESC(lock_norm, "Prevent norm changes (1 = ignore, >1 = fail)"); @@ -237,79 +198,8 @@ static void jpg_fbuffer_free(struct file *file); * Allocate the V4L grab buffers * * These have to be pysically contiguous. - * If v4l_bufsize <= MAX_KMALLOC_MEM we use kmalloc - * else we try to allocate them with bigphysarea_alloc_pages - * if the bigphysarea patch is present in the kernel, - * else we try to use high memory (if the user has bootet - * Linux with the necessary memory left over). */ -#if defined(BUZ_USE_HIMEM) && !defined(CONFIG_BIGPHYS_AREA) -static unsigned long -get_high_mem (unsigned long size) -{ -/* - * Check if there is usable memory at the end of Linux memory - * of at least size. Return the physical address of this memory, - * return 0 on failure. - * - * The idea is from Alexandro Rubini's book "Linux device drivers". - * The driver from him which is downloadable from O'Reilly's - * web site misses the "virt_to_phys(high_memory)" part - * (and therefore doesn't work at all - at least with 2.2.x kernels). - * - * It should be unnecessary to mention that THIS IS DANGEROUS, - * if more than one driver at a time has the idea to use this memory!!!! - */ - - volatile unsigned char __iomem *mem; - unsigned char c; - unsigned long hi_mem_ph; - unsigned long i; - - /* Map the high memory to user space */ - - hi_mem_ph = virt_to_phys(high_memory); - - mem = ioremap(hi_mem_ph, size); - if (!mem) { - dprintk(1, - KERN_ERR "%s: get_high_mem() - ioremap failed\n", - ZORAN_NAME); - return 0; - } - - for (i = 0; i < size; i++) { - /* Check if it is memory */ - c = i & 0xff; - writeb(c, mem + i); - if (readb(mem + i) != c) - break; - c = 255 - c; - writeb(c, mem + i); - if (readb(mem + i) != c) - break; - writeb(0, mem + i); /* zero out memory */ - - /* give the kernel air to breath */ - if ((i & 0x3ffff) == 0x3ffff) - schedule(); - } - - iounmap(mem); - - if (i != size) { - dprintk(1, - KERN_ERR - "%s: get_high_mem() - requested %lu, avail %lu\n", - ZORAN_NAME, size, i); - return 0; - } - - return hi_mem_ph; -} -#endif - static int v4l_fbuffer_alloc (struct file *file) { @@ -317,137 +207,37 @@ v4l_fbuffer_alloc (struct file *file) struct zoran *zr = fh->zr; int i, off; unsigned char *mem; -#if defined(BUZ_USE_HIMEM) && !defined(CONFIG_BIGPHYS_AREA) - unsigned long pmem = 0; -#endif - - /* we might have old buffers lying around... */ - if (fh->v4l_buffers.ready_to_be_freed) { - v4l_fbuffer_free(file); - } for (i = 0; i < fh->v4l_buffers.num_buffers; i++) { if (fh->v4l_buffers.buffer[i].fbuffer) dprintk(2, KERN_WARNING - "%s: v4l_fbuffer_alloc() - buffer %d allready allocated!?\n", + "%s: v4l_fbuffer_alloc() - buffer %d already allocated!?\n", ZR_DEVNAME(zr), i); //udelay(20); - if (fh->v4l_buffers.buffer_size <= MAX_KMALLOC_MEM) { - /* Use kmalloc */ - - mem = kmalloc(fh->v4l_buffers.buffer_size, GFP_KERNEL); - if (!mem) { - dprintk(1, - KERN_ERR - "%s: v4l_fbuffer_alloc() - kmalloc for V4L buf %d failed\n", - ZR_DEVNAME(zr), i); - v4l_fbuffer_free(file); - return -ENOBUFS; - } - fh->v4l_buffers.buffer[i].fbuffer = mem; - fh->v4l_buffers.buffer[i].fbuffer_phys = - virt_to_phys(mem); - fh->v4l_buffers.buffer[i].fbuffer_bus = - virt_to_bus(mem); - for (off = 0; off < fh->v4l_buffers.buffer_size; - off += PAGE_SIZE) - SetPageReserved(MAP_NR(mem + off)); - dprintk(4, - KERN_INFO - "%s: v4l_fbuffer_alloc() - V4L frame %d mem 0x%lx (bus: 0x%lx)\n", - ZR_DEVNAME(zr), i, (unsigned long) mem, - virt_to_bus(mem)); - } else { -#if defined(CONFIG_BIGPHYS_AREA) - /* Use bigphysarea_alloc_pages */ - - int n = - (fh->v4l_buffers.buffer_size + PAGE_SIZE - - 1) / PAGE_SIZE; - - mem = - (unsigned char *) bigphysarea_alloc_pages(n, 0, - GFP_KERNEL); - if (mem == 0) { - dprintk(1, - KERN_ERR - "%s: v4l_fbuffer_alloc() - bigphysarea_alloc_pages for V4L buf %d failed\n", - ZR_DEVNAME(zr), i); - v4l_fbuffer_free(file); - return -ENOBUFS; - } - fh->v4l_buffers.buffer[i].fbuffer = mem; - fh->v4l_buffers.buffer[i].fbuffer_phys = - virt_to_phys(mem); - fh->v4l_buffers.buffer[i].fbuffer_bus = - virt_to_bus(mem); - dprintk(4, - KERN_INFO - "%s: Bigphysarea frame %d mem %p (bus: 0x%lx)\n", - ZR_DEVNAME(zr), i, mem, virt_to_bus(mem)); - - /* Zero out the allocated memory */ - memset(fh->v4l_buffers.buffer[i].fbuffer, 0, - fh->v4l_buffers.buffer_size); -#else -#if defined(BUZ_USE_HIMEM) - - /* Use high memory which has been left at boot time */ - - /* Ok., Ok. this is an evil hack - we make - * the assumption that physical addresses are - * the same as bus addresses (true at least - * for Intel processors). The whole method of - * obtaining and using this memory is not very - * nice - but I hope it saves some poor users - * from kernel hacking, which might have even - * more evil results */ - - if (i == 0) { - int size = - fh->v4l_buffers.num_buffers * - fh->v4l_buffers.buffer_size; - - pmem = get_high_mem(size); - if (pmem == 0) { - dprintk(1, - KERN_ERR - "%s: v4l_fbuffer_alloc() - get_high_mem (size = %d KB) for V4L bufs failed\n", - ZR_DEVNAME(zr), size >> 10); - return -ENOBUFS; - } - fh->v4l_buffers.buffer[0].fbuffer = NULL; - fh->v4l_buffers.buffer[0].fbuffer_phys = pmem; - fh->v4l_buffers.buffer[0].fbuffer_bus = pmem; - dprintk(4, - KERN_INFO - "%s: v4l_fbuffer_alloc() - using %d KB high memory\n", - ZR_DEVNAME(zr), size >> 10); - } else { - fh->v4l_buffers.buffer[i].fbuffer = NULL; - fh->v4l_buffers.buffer[i].fbuffer_phys = - pmem + i * fh->v4l_buffers.buffer_size; - fh->v4l_buffers.buffer[i].fbuffer_bus = - pmem + i * fh->v4l_buffers.buffer_size; - } -#else - /* No bigphysarea present, usage of high memory disabled, - * but user wants buffers of more than MAX_KMALLOC_MEM */ + mem = kmalloc(fh->v4l_buffers.buffer_size, GFP_KERNEL); + if (!mem) { dprintk(1, KERN_ERR - "%s: v4l_fbuffer_alloc() - no bigphysarea_patch present, usage of high memory disabled,\n", - ZR_DEVNAME(zr)); - dprintk(1, - KERN_ERR - "%s: v4l_fbuffer_alloc() - sorry, could not allocate %d V4L buffers of size %d KB.\n", - ZR_DEVNAME(zr), fh->v4l_buffers.num_buffers, - fh->v4l_buffers.buffer_size >> 10); + "%s: v4l_fbuffer_alloc() - kmalloc for V4L buf %d failed\n", + ZR_DEVNAME(zr), i); + v4l_fbuffer_free(file); return -ENOBUFS; -#endif -#endif } + fh->v4l_buffers.buffer[i].fbuffer = mem; + fh->v4l_buffers.buffer[i].fbuffer_phys = + virt_to_phys(mem); + fh->v4l_buffers.buffer[i].fbuffer_bus = + virt_to_bus(mem); + for (off = 0; off < fh->v4l_buffers.buffer_size; + off += PAGE_SIZE) + SetPageReserved(virt_to_page(mem + off)); + dprintk(4, + KERN_INFO + "%s: v4l_fbuffer_alloc() - V4L frame %d mem 0x%lx (bus: 0x%lx)\n", + ZR_DEVNAME(zr), i, (unsigned long) mem, + virt_to_bus(mem)); } fh->v4l_buffers.allocated = 1; @@ -470,38 +260,24 @@ v4l_fbuffer_free (struct file *file) if (!fh->v4l_buffers.buffer[i].fbuffer) continue; - if (fh->v4l_buffers.buffer_size <= MAX_KMALLOC_MEM) { - mem = fh->v4l_buffers.buffer[i].fbuffer; - for (off = 0; off < fh->v4l_buffers.buffer_size; - off += PAGE_SIZE) - ClearPageReserved(MAP_NR(mem + off)); - kfree((void *) fh->v4l_buffers.buffer[i].fbuffer); - } -#if defined(CONFIG_BIGPHYS_AREA) - else - bigphysarea_free_pages((void *) fh->v4l_buffers. - buffer[i].fbuffer); -#endif + mem = fh->v4l_buffers.buffer[i].fbuffer; + for (off = 0; off < fh->v4l_buffers.buffer_size; + off += PAGE_SIZE) + ClearPageReserved(virt_to_page(mem + off)); + kfree((void *) fh->v4l_buffers.buffer[i].fbuffer); fh->v4l_buffers.buffer[i].fbuffer = NULL; } fh->v4l_buffers.allocated = 0; - fh->v4l_buffers.ready_to_be_freed = 0; } /* * Allocate the MJPEG grab buffers. * - * If the requested buffer size is smaller than MAX_KMALLOC_MEM, - * kmalloc is used to request a physically contiguous area, - * else we allocate the memory in framgents with get_zeroed_page. - * * If a Natoma chipset is present and this is a revision 1 zr36057, * each MJPEG buffer needs to be physically contiguous. * (RJ: This statement is from Dave Perks' original driver, * I could never check it because I have a zr36067) - * The driver cares about this because it reduces the buffer - * size to MAX_KMALLOC_MEM in that case (which forces contiguous allocation). * * RJ: The contents grab buffers needs never be accessed in the driver. * Therefore there is no need to allocate them with vmalloc in order @@ -531,16 +307,11 @@ jpg_fbuffer_alloc (struct file *file) int i, j, off; unsigned long mem; - /* we might have old buffers lying around */ - if (fh->jpg_buffers.ready_to_be_freed) { - jpg_fbuffer_free(file); - } - for (i = 0; i < fh->jpg_buffers.num_buffers; i++) { if (fh->jpg_buffers.buffer[i].frag_tab) dprintk(2, KERN_WARNING - "%s: jpg_fbuffer_alloc() - buffer %d allready allocated!?\n", + "%s: jpg_fbuffer_alloc() - buffer %d already allocated!?\n", ZR_DEVNAME(zr), i); /* Allocate fragment table for this buffer */ @@ -578,9 +349,9 @@ jpg_fbuffer_alloc (struct file *file) cpu_to_le32(((fh->jpg_buffers.buffer_size / 4) << 1) | 1); for (off = 0; off < fh->jpg_buffers.buffer_size; off += PAGE_SIZE) - SetPageReserved(MAP_NR(mem + off)); + SetPageReserved(virt_to_page(mem + off)); } else { - /* jpg_bufsize is allreay page aligned */ + /* jpg_bufsize is already page aligned */ for (j = 0; j < fh->jpg_buffers.buffer_size / PAGE_SIZE; j++) { @@ -599,7 +370,7 @@ jpg_fbuffer_alloc (struct file *file) fh->jpg_buffers.buffer[i].frag_tab[2 * j + 1] = cpu_to_le32((PAGE_SIZE / 4) << 1); - SetPageReserved(MAP_NR(mem)); + SetPageReserved(virt_to_page(mem)); } fh->jpg_buffers.buffer[i].frag_tab[2 * j - 1] |= cpu_to_le32(1); @@ -625,6 +396,7 @@ jpg_fbuffer_free (struct file *file) struct zoran *zr = fh->zr; int i, j, off; unsigned char *mem; + __le32 frag_tab; dprintk(4, KERN_DEBUG "%s: jpg_fbuffer_free()\n", ZR_DEVNAME(zr)); @@ -632,53 +404,35 @@ jpg_fbuffer_free (struct file *file) if (!fh->jpg_buffers.buffer[i].frag_tab) continue; - //if (alloc_contig) { if (fh->jpg_buffers.need_contiguous) { - if (fh->jpg_buffers.buffer[i].frag_tab[0]) { - mem = (unsigned char *) bus_to_virt(le32_to_cpu( - fh->jpg_buffers.buffer[i].frag_tab[0])); - for (off = 0; - off < fh->jpg_buffers.buffer_size; - off += PAGE_SIZE) - ClearPageReserved(MAP_NR - (mem + off)); + frag_tab = fh->jpg_buffers.buffer[i].frag_tab[0]; + + if (frag_tab) { + mem = (unsigned char *)bus_to_virt(le32_to_cpu(frag_tab)); + for (off = 0; off < fh->jpg_buffers.buffer_size; off += PAGE_SIZE) + ClearPageReserved(virt_to_page(mem + off)); kfree(mem); fh->jpg_buffers.buffer[i].frag_tab[0] = 0; fh->jpg_buffers.buffer[i].frag_tab[1] = 0; } } else { - for (j = 0; - j < fh->jpg_buffers.buffer_size / PAGE_SIZE; - j++) { - if (!fh->jpg_buffers.buffer[i]. - frag_tab[2 * j]) + for (j = 0; j < fh->jpg_buffers.buffer_size / PAGE_SIZE; j++) { + frag_tab = fh->jpg_buffers.buffer[i].frag_tab[2 * j]; + + if (!frag_tab) break; - ClearPageReserved(MAP_NR - (bus_to_virt - (le32_to_cpu - (fh->jpg_buffers. - buffer[i].frag_tab[2 * - j])))); - free_page((unsigned long) - bus_to_virt - (le32_to_cpu - (fh->jpg_buffers. - buffer[i]. - frag_tab[2 * j]))); - fh->jpg_buffers.buffer[i].frag_tab[2 * j] = - 0; - fh->jpg_buffers.buffer[i].frag_tab[2 * j + - 1] = 0; + ClearPageReserved(virt_to_page(bus_to_virt(le32_to_cpu(frag_tab)))); + free_page((unsigned long)bus_to_virt(le32_to_cpu(frag_tab))); + fh->jpg_buffers.buffer[i].frag_tab[2 * j] = 0; + fh->jpg_buffers.buffer[i].frag_tab[2 * j + 1] = 0; } } - free_page((unsigned long) fh->jpg_buffers.buffer[i]. - frag_tab); + free_page((unsigned long)fh->jpg_buffers.buffer[i].frag_tab); fh->jpg_buffers.buffer[i].frag_tab = NULL; } fh->jpg_buffers.allocated = 0; - fh->jpg_buffers.ready_to_be_freed = 0; } /* @@ -722,7 +476,7 @@ zoran_v4l_set_format (struct file *file, if ((bpp == 2 && (width & 1)) || (bpp == 3 && (width & 3))) { dprintk(1, KERN_ERR - "%s: v4l_set_format() - wrong frame alingment\n", + "%s: v4l_set_format() - wrong frame alignment\n", ZR_DEVNAME(zr)); return -EINVAL; } @@ -815,64 +569,6 @@ zoran_v4l_queue_frame (struct file *file, return res; } -static int -v4l_grab (struct file *file, - struct video_mmap *mp) -{ - struct zoran_fh *fh = file->private_data; - struct zoran *zr = fh->zr; - int res = 0, i; - - for (i = 0; i < NUM_FORMATS; i++) { - if (zoran_formats[i].palette == mp->format && - zoran_formats[i].flags & ZORAN_FORMAT_CAPTURE && - !(zoran_formats[i].flags & ZORAN_FORMAT_COMPRESSED)) - break; - } - if (i == NUM_FORMATS || zoran_formats[i].depth == 0) { - dprintk(1, - KERN_ERR - "%s: v4l_grab() - wrong bytes-per-pixel format\n", - ZR_DEVNAME(zr)); - return -EINVAL; - } - - /* - * To minimize the time spent in the IRQ routine, we avoid setting up - * the video front end there. - * If this grab has different parameters from a running streaming capture - * we stop the streaming capture and start it over again. - */ - if (zr->v4l_memgrab_active && - (zr->v4l_settings.width != mp->width || - zr->v4l_settings.height != mp->height || - zr->v4l_settings.format->palette != mp->format)) { - res = wait_grab_pending(zr); - if (res) - return res; - } - if ((res = zoran_v4l_set_format(file, - mp->width, - mp->height, - &zoran_formats[i]))) - return res; - zr->v4l_settings = fh->v4l_settings; - - /* queue the frame in the pending queue */ - if ((res = zoran_v4l_queue_frame(file, mp->frame))) { - fh->v4l_buffers.active = ZORAN_FREE; - return res; - } - - /* put the 36057 into frame grabbing mode */ - if (!res && !zr->v4l_memgrab_active) - zr36057_set_memgrab(zr, 1); - - //dprintk(4, KERN_INFO "%s: Frame grab 3...\n", ZR_DEVNAME(zr)); - - return res; -} - /* * Sync on a V4L buffer */ @@ -1187,7 +883,6 @@ zoran_open_init_session (struct file *file) fh->v4l_buffers.buffer[i].bs.frame = i; } fh->v4l_buffers.allocated = 0; - fh->v4l_buffers.ready_to_be_freed = 0; fh->v4l_buffers.active = ZORAN_FREE; fh->v4l_buffers.buffer_size = v4l_bufsize; fh->v4l_buffers.num_buffers = v4l_nbufs; @@ -1203,7 +898,6 @@ zoran_open_init_session (struct file *file) } fh->jpg_buffers.need_contiguous = zr->jpg_buffers.need_contiguous; fh->jpg_buffers.allocated = 0; - fh->jpg_buffers.ready_to_be_freed = 0; fh->jpg_buffers.active = ZORAN_FREE; fh->jpg_buffers.buffer_size = jpg_bufsize; fh->jpg_buffers.num_buffers = jpg_nbufs; @@ -1237,10 +931,8 @@ zoran_close_end_session (struct file *file) } /* v4l buffers */ - if (fh->v4l_buffers.allocated || - fh->v4l_buffers.ready_to_be_freed) { + if (fh->v4l_buffers.allocated) v4l_fbuffer_free(file); - } /* jpg capture */ if (fh->jpg_buffers.active != ZORAN_FREE) { @@ -1251,10 +943,8 @@ zoran_close_end_session (struct file *file) } /* jpg buffers */ - if (fh->jpg_buffers.allocated || - fh->jpg_buffers.ready_to_be_freed) { + if (fh->jpg_buffers.allocated) jpg_fbuffer_free(file); - } } /* @@ -1272,10 +962,6 @@ static int zoran_open(struct file *file) lock_kernel(); - /* see fs/device.c - the kernel already locks during open(), - * so locking ourselves only causes deadlocks */ - /*mutex_lock(&zr->resource_lock);*/ - if (zr->user >= 2048) { dprintk(1, KERN_ERR "%s: too many users (%d) on device\n", ZR_DEVNAME(zr), zr->user); @@ -1283,32 +969,6 @@ static int zoran_open(struct file *file) goto fail_unlock; } - if (!zr->decoder) { - dprintk(1, - KERN_ERR "%s: no TV decoder loaded for device!\n", - ZR_DEVNAME(zr)); - res = -EIO; - goto fail_unlock; - } - - if (!try_module_get(zr->decoder->driver->driver.owner)) { - dprintk(1, - KERN_ERR - "%s: failed to grab ownership of video decoder\n", - ZR_DEVNAME(zr)); - res = -EIO; - goto fail_unlock; - } - if (zr->encoder && - !try_module_get(zr->encoder->driver->driver.owner)) { - dprintk(1, - KERN_ERR - "%s: failed to grab ownership of video encoder\n", - ZR_DEVNAME(zr)); - res = -EIO; - goto fail_decoder; - } - /* now, create the open()-specific file_ops struct */ fh = kzalloc(sizeof(struct zoran_fh), GFP_KERNEL); if (!fh) { @@ -1317,7 +977,7 @@ static int zoran_open(struct file *file) "%s: zoran_open() - allocation of zoran_fh failed\n", ZR_DEVNAME(zr)); res = -ENOMEM; - goto fail_encoder; + goto fail_unlock; } /* used to be BUZ_MAX_WIDTH/HEIGHT, but that gives overflows * on norm-change! */ @@ -1356,11 +1016,6 @@ static int zoran_open(struct file *file) fail_fh: kfree(fh); -fail_encoder: - if (zr->encoder) - module_put(zr->encoder->driver->driver.owner); -fail_decoder: - module_put(zr->decoder->driver->driver.owner); fail_unlock: unlock_kernel(); @@ -1411,9 +1066,10 @@ zoran_close(struct file *file) zoran_set_pci_master(zr, 0); if (!pass_through) { /* Switch to color bar */ - int zero = 0, two = 2; - decoder_command(zr, DECODER_ENABLE_OUTPUT, &zero); - encoder_command(zr, ENCODER_SET_INPUT, &two); + struct v4l2_routing route = { 2, 0 }; + + decoder_call(zr, video, s_stream, 0); + encoder_call(zr, video, s_routing, &route); } } @@ -1421,13 +1077,6 @@ zoran_close(struct file *file) kfree(fh->overlay_mask); kfree(fh); - /* release locks on the i2c modules */ - module_put(zr->decoder->driver->driver.owner); - if (zr->encoder) - module_put(zr->encoder->driver->driver.owner); - - /*mutex_unlock(&zr->resource_lock);*/ - dprintk(4, KERN_INFO "%s: zoran_close() done\n", ZR_DEVNAME(zr)); return 0; @@ -1520,12 +1169,12 @@ setup_fbuffer (struct file *file, return -EINVAL; } - zr->buffer.base = (void *) ((unsigned long) base & ~3); - zr->buffer.height = height; - zr->buffer.width = width; - zr->buffer.depth = fmt->depth; + zr->vbuf_base = (void *) ((unsigned long) base & ~3); + zr->vbuf_height = height; + zr->vbuf_width = width; + zr->vbuf_depth = fmt->depth; zr->overlay_settings.format = fmt; - zr->buffer.bytesperline = bytesperline; + zr->vbuf_bytesperline = bytesperline; /* The user should set new window parameters */ zr->overlay_settings.is_set = 0; @@ -1540,17 +1189,17 @@ setup_window (struct file *file, int y, int width, int height, - struct video_clip __user *clips, + struct v4l2_clip __user *clips, int clipcount, void __user *bitmap) { struct zoran_fh *fh = file->private_data; struct zoran *zr = fh->zr; - struct video_clip *vcp = NULL; + struct v4l2_clip *vcp = NULL; int on, end; - if (!zr->buffer.base) { + if (!zr->vbuf_base) { dprintk(1, KERN_ERR "%s: setup_window() - frame buffer has to be set first\n", @@ -1570,13 +1219,13 @@ setup_window (struct file *file, * The video front end needs 4-byte alinged line sizes, we correct that * silently here if necessary */ - if (zr->buffer.depth == 15 || zr->buffer.depth == 16) { + if (zr->vbuf_depth == 15 || zr->vbuf_depth == 16) { end = (x + width) & ~1; /* round down */ x = (x + 1) & ~1; /* round up */ width = end - x; } - if (zr->buffer.depth == 24) { + if (zr->vbuf_depth == 24) { end = (x + width) & ~3; /* round down */ x = (x + 3) & ~3; /* round up */ width = end - x; @@ -1631,7 +1280,7 @@ setup_window (struct file *file, } } else if (clipcount > 0) { /* write our own bitmap from the clips */ - vcp = vmalloc(sizeof(struct video_clip) * (clipcount + 4)); + vcp = vmalloc(sizeof(struct v4l2_clip) * (clipcount + 4)); if (vcp == NULL) { dprintk(1, KERN_ERR @@ -1640,7 +1289,7 @@ setup_window (struct file *file, return -ENOMEM; } if (copy_from_user - (vcp, clips, sizeof(struct video_clip) * clipcount)) { + (vcp, clips, sizeof(struct v4l2_clip) * clipcount)) { vfree(vcp); return -EFAULT; } @@ -1699,7 +1348,7 @@ setup_overlay (struct file *file, zr36057_overlay(zr, 0); zr->overlay_mask = NULL; } else { - if (!zr->buffer.base || !fh->overlay_settings.is_set) { + if (!zr->vbuf_base || !fh->overlay_settings.is_set) { dprintk(1, KERN_ERR "%s: setup_overlay() - buffer or window not set\n", @@ -1835,9 +1484,9 @@ zoran_v4l2_buffer_status (struct file *file, static int zoran_set_norm (struct zoran *zr, - int norm) /* VIDEO_MODE_* */ + v4l2_std_id norm) { - int norm_encoder, on; + int on; if (zr->v4l_buffers.active != ZORAN_FREE || zr->jpg_buffers.active != ZORAN_FREE) { @@ -1864,52 +1513,42 @@ zoran_set_norm (struct zoran *zr, } } - if (norm != VIDEO_MODE_AUTO && - (norm < 0 || norm >= zr->card.norms || - !zr->card.tvn[norm])) { + if (!(norm & zr->card.norms)) { dprintk(1, - KERN_ERR "%s: set_norm() - unsupported norm %d\n", + KERN_ERR "%s: set_norm() - unsupported norm %llx\n", ZR_DEVNAME(zr), norm); return -EINVAL; } - if (norm == VIDEO_MODE_AUTO) { - int status; - - /* if we have autodetect, ... */ - struct video_decoder_capability caps; - decoder_command(zr, DECODER_GET_CAPABILITIES, &caps); - if (!(caps.flags & VIDEO_DECODER_AUTO)) { - dprintk(1, KERN_ERR "%s: norm=auto unsupported\n", - ZR_DEVNAME(zr)); - return -EINVAL; - } + if (norm == V4L2_STD_ALL) { + int status = 0; + v4l2_std_id std = 0; - decoder_command(zr, DECODER_SET_NORM, &norm); + decoder_call(zr, video, querystd, &std); + decoder_s_std(zr, std); /* let changes come into effect */ ssleep(2); - decoder_command(zr, DECODER_GET_STATUS, &status); - if (!(status & DECODER_STATUS_GOOD)) { + decoder_call(zr, video, g_input_status, &status); + if (status & V4L2_IN_ST_NO_SIGNAL) { dprintk(1, KERN_ERR "%s: set_norm() - no norm detected\n", ZR_DEVNAME(zr)); /* reset norm */ - decoder_command(zr, DECODER_SET_NORM, &zr->norm); + decoder_s_std(zr, zr->norm); return -EIO; } - if (status & DECODER_STATUS_NTSC) - norm = VIDEO_MODE_NTSC; - else if (status & DECODER_STATUS_SECAM) - norm = VIDEO_MODE_SECAM; - else - norm = VIDEO_MODE_PAL; + norm = std; } - zr->timing = zr->card.tvn[norm]; - norm_encoder = norm; + if (norm & V4L2_STD_SECAM) + zr->timing = zr->card.tvn[2]; + else if (norm & V4L2_STD_NTSC) + zr->timing = zr->card.tvn[1]; + else + zr->timing = zr->card.tvn[0]; /* We switch overlay off and on since a change in the * norm needs different VFE settings */ @@ -1917,8 +1556,8 @@ zoran_set_norm (struct zoran *zr, if (on) zr36057_overlay(zr, 0); - decoder_command(zr, DECODER_SET_NORM, &norm); - encoder_command(zr, ENCODER_SET_NORM, &norm_encoder); + decoder_s_std(zr, norm); + encoder_call(zr, video, s_std_output, norm); if (on) zr36057_overlay(zr, 1); @@ -1933,7 +1572,7 @@ static int zoran_set_input (struct zoran *zr, int input) { - int realinput; + struct v4l2_routing route = { 0, 0 }; if (input == zr->input) { return 0; @@ -1956,10 +1595,10 @@ zoran_set_input (struct zoran *zr, return -EINVAL; } - realinput = zr->card.input[input].muxsel; + route.input = zr->card.input[input].muxsel; zr->input = input; - decoder_command(zr, DECODER_SET_INPUT, &realinput); + decoder_s_routing(zr, &route); return 0; } @@ -1968,410 +1607,14 @@ zoran_set_input (struct zoran *zr, * ioctl routine */ -static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg) +#ifdef CONFIG_VIDEO_V4L1_COMPAT +static long zoran_default(struct file *file, void *__fh, int cmd, void *arg) { - struct zoran_fh *fh = file->private_data; + struct zoran_fh *fh = __fh; struct zoran *zr = fh->zr; - /* CAREFUL: used in multiple places here */ struct zoran_jpg_settings settings; - /* we might have older buffers lying around... We don't want - * to wait, but we do want to try cleaning them up ASAP. So - * we try to obtain the lock and free them. If that fails, we - * don't do anything and wait for the next turn. In the end, - * zoran_close() or a new allocation will still free them... - * This is just a 'the sooner the better' extra 'feature' - * - * We don't free the buffers right on munmap() because that - * causes oopses (kfree() inside munmap() oopses for no - * apparent reason - it's also not reproduceable in any way, - * but moving the free code outside the munmap() handler fixes - * all this... If someone knows why, please explain me (Ronald) - */ - if (mutex_trylock(&zr->resource_lock)) { - /* we obtained it! Let's try to free some things */ - if (fh->jpg_buffers.ready_to_be_freed) - jpg_fbuffer_free(file); - if (fh->v4l_buffers.ready_to_be_freed) - v4l_fbuffer_free(file); - - mutex_unlock(&zr->resource_lock); - } - switch (cmd) { - - case VIDIOCGCAP: - { - struct video_capability *vcap = arg; - - dprintk(3, KERN_DEBUG "%s: VIDIOCGCAP\n", ZR_DEVNAME(zr)); - - memset(vcap, 0, sizeof(struct video_capability)); - strncpy(vcap->name, ZR_DEVNAME(zr), sizeof(vcap->name)-1); - vcap->type = ZORAN_VID_TYPE; - - vcap->channels = zr->card.inputs; - vcap->audios = 0; - mutex_lock(&zr->resource_lock); - vcap->maxwidth = BUZ_MAX_WIDTH; - vcap->maxheight = BUZ_MAX_HEIGHT; - vcap->minwidth = BUZ_MIN_WIDTH; - vcap->minheight = BUZ_MIN_HEIGHT; - mutex_unlock(&zr->resource_lock); - - return 0; - } - break; - - case VIDIOCGCHAN: - { - struct video_channel *vchan = arg; - int channel = vchan->channel; - - dprintk(3, KERN_DEBUG "%s: VIDIOCGCHAN - channel=%d\n", - ZR_DEVNAME(zr), vchan->channel); - - memset(vchan, 0, sizeof(struct video_channel)); - if (channel > zr->card.inputs || channel < 0) { - dprintk(1, - KERN_ERR - "%s: VIDIOCGCHAN on not existing channel %d\n", - ZR_DEVNAME(zr), channel); - return -EINVAL; - } - - strcpy(vchan->name, zr->card.input[channel].name); - - vchan->tuners = 0; - vchan->flags = 0; - vchan->type = VIDEO_TYPE_CAMERA; - mutex_lock(&zr->resource_lock); - vchan->norm = zr->norm; - mutex_unlock(&zr->resource_lock); - vchan->channel = channel; - - return 0; - } - break; - - /* RJ: the documentation at http://roadrunner.swansea.linux.org.uk/v4lapi.shtml says: - * - * * "The VIDIOCSCHAN ioctl takes an integer argument and switches the capture to this input." - * * ^^^^^^^ - * * The famos BTTV driver has it implemented with a struct video_channel argument - * * and we follow it for compatibility reasons - * * - * * BTW: this is the only way the user can set the norm! - */ - - case VIDIOCSCHAN: - { - struct video_channel *vchan = arg; - int res; - - dprintk(3, - KERN_DEBUG - "%s: VIDIOCSCHAN - channel=%d, norm=%d\n", - ZR_DEVNAME(zr), vchan->channel, vchan->norm); - - mutex_lock(&zr->resource_lock); - if ((res = zoran_set_input(zr, vchan->channel))) - goto schan_unlock_and_return; - if ((res = zoran_set_norm(zr, vchan->norm))) - goto schan_unlock_and_return; - - /* Make sure the changes come into effect */ - res = wait_grab_pending(zr); - schan_unlock_and_return: - mutex_unlock(&zr->resource_lock); - return res; - } - break; - - case VIDIOCGPICT: - { - struct video_picture *vpict = arg; - - dprintk(3, KERN_DEBUG "%s: VIDIOCGPICT\n", ZR_DEVNAME(zr)); - - memset(vpict, 0, sizeof(struct video_picture)); - mutex_lock(&zr->resource_lock); - vpict->hue = zr->hue; - vpict->brightness = zr->brightness; - vpict->contrast = zr->contrast; - vpict->colour = zr->saturation; - if (fh->overlay_settings.format) { - vpict->depth = fh->overlay_settings.format->depth; - vpict->palette = fh->overlay_settings.format->palette; - } else { - vpict->depth = 0; - } - mutex_unlock(&zr->resource_lock); - - return 0; - } - break; - - case VIDIOCSPICT: - { - struct video_picture *vpict = arg; - int i; - - dprintk(3, - KERN_DEBUG - "%s: VIDIOCSPICT - bri=%d, hue=%d, col=%d, con=%d, dep=%d, pal=%d\n", - ZR_DEVNAME(zr), vpict->brightness, vpict->hue, - vpict->colour, vpict->contrast, vpict->depth, - vpict->palette); - - for (i = 0; i < NUM_FORMATS; i++) { - const struct zoran_format *fmt = &zoran_formats[i]; - - if (fmt->palette != -1 && - fmt->flags & ZORAN_FORMAT_OVERLAY && - fmt->palette == vpict->palette && - fmt->depth == vpict->depth) - break; - } - if (i == NUM_FORMATS) { - dprintk(1, - KERN_ERR - "%s: VIDIOCSPICT - Invalid palette %d\n", - ZR_DEVNAME(zr), vpict->palette); - return -EINVAL; - } - - mutex_lock(&zr->resource_lock); - - decoder_command(zr, DECODER_SET_PICTURE, vpict); - - zr->hue = vpict->hue; - zr->contrast = vpict->contrast; - zr->saturation = vpict->colour; - zr->brightness = vpict->brightness; - - fh->overlay_settings.format = &zoran_formats[i]; - - mutex_unlock(&zr->resource_lock); - - return 0; - } - break; - - case VIDIOCCAPTURE: - { - int *on = arg, res; - - dprintk(3, KERN_DEBUG "%s: VIDIOCCAPTURE - on=%d\n", - ZR_DEVNAME(zr), *on); - - mutex_lock(&zr->resource_lock); - res = setup_overlay(file, *on); - mutex_unlock(&zr->resource_lock); - - return res; - } - break; - - case VIDIOCGWIN: - { - struct video_window *vwin = arg; - - dprintk(3, KERN_DEBUG "%s: VIDIOCGWIN\n", ZR_DEVNAME(zr)); - - memset(vwin, 0, sizeof(struct video_window)); - mutex_lock(&zr->resource_lock); - vwin->x = fh->overlay_settings.x; - vwin->y = fh->overlay_settings.y; - vwin->width = fh->overlay_settings.width; - vwin->height = fh->overlay_settings.height; - mutex_unlock(&zr->resource_lock); - vwin->clipcount = 0; - return 0; - } - break; - - case VIDIOCSWIN: - { - struct video_window *vwin = arg; - int res; - - dprintk(3, - KERN_DEBUG - "%s: VIDIOCSWIN - x=%d, y=%d, w=%d, h=%d, clipcount=%d\n", - ZR_DEVNAME(zr), vwin->x, vwin->y, vwin->width, - vwin->height, vwin->clipcount); - - mutex_lock(&zr->resource_lock); - res = - setup_window(file, vwin->x, vwin->y, vwin->width, - vwin->height, vwin->clips, - vwin->clipcount, NULL); - mutex_unlock(&zr->resource_lock); - - return res; - } - break; - - case VIDIOCGFBUF: - { - struct video_buffer *vbuf = arg; - - dprintk(3, KERN_DEBUG "%s: VIDIOCGFBUF\n", ZR_DEVNAME(zr)); - - mutex_lock(&zr->resource_lock); - *vbuf = zr->buffer; - mutex_unlock(&zr->resource_lock); - return 0; - } - break; - - case VIDIOCSFBUF: - { - struct video_buffer *vbuf = arg; - int i, res = 0; - - dprintk(3, - KERN_DEBUG - "%s: VIDIOCSFBUF - base=%p, w=%d, h=%d, depth=%d, bpl=%d\n", - ZR_DEVNAME(zr), vbuf->base, vbuf->width, - vbuf->height, vbuf->depth, vbuf->bytesperline); - - for (i = 0; i < NUM_FORMATS; i++) - if (zoran_formats[i].depth == vbuf->depth) - break; - if (i == NUM_FORMATS) { - dprintk(1, - KERN_ERR - "%s: VIDIOCSFBUF - invalid fbuf depth %d\n", - ZR_DEVNAME(zr), vbuf->depth); - return -EINVAL; - } - - mutex_lock(&zr->resource_lock); - res = - setup_fbuffer(file, vbuf->base, &zoran_formats[i], - vbuf->width, vbuf->height, - vbuf->bytesperline); - mutex_unlock(&zr->resource_lock); - - return res; - } - break; - - case VIDIOCSYNC: - { - int *frame = arg, res; - - dprintk(3, KERN_DEBUG "%s: VIDIOCSYNC - frame=%d\n", - ZR_DEVNAME(zr), *frame); - - mutex_lock(&zr->resource_lock); - res = v4l_sync(file, *frame); - mutex_unlock(&zr->resource_lock); - if (!res) - zr->v4l_sync_tail++; - return res; - } - break; - - case VIDIOCMCAPTURE: - { - struct video_mmap *vmap = arg; - int res; - - dprintk(3, - KERN_DEBUG - "%s: VIDIOCMCAPTURE - frame=%d, geom=%dx%d, fmt=%d\n", - ZR_DEVNAME(zr), vmap->frame, vmap->width, vmap->height, - vmap->format); - - mutex_lock(&zr->resource_lock); - res = v4l_grab(file, vmap); - mutex_unlock(&zr->resource_lock); - return res; - } - break; - - case VIDIOCGMBUF: - { - struct video_mbuf *vmbuf = arg; - int i, res = 0; - - dprintk(3, KERN_DEBUG "%s: VIDIOCGMBUF\n", ZR_DEVNAME(zr)); - - vmbuf->size = - fh->v4l_buffers.num_buffers * - fh->v4l_buffers.buffer_size; - vmbuf->frames = fh->v4l_buffers.num_buffers; - for (i = 0; i < vmbuf->frames; i++) { - vmbuf->offsets[i] = - i * fh->v4l_buffers.buffer_size; - } - - mutex_lock(&zr->resource_lock); - - if (fh->jpg_buffers.allocated || fh->v4l_buffers.allocated) { - dprintk(1, - KERN_ERR - "%s: VIDIOCGMBUF - buffers already allocated\n", - ZR_DEVNAME(zr)); - res = -EINVAL; - goto v4l1reqbuf_unlock_and_return; - } - - if (v4l_fbuffer_alloc(file)) { - res = -ENOMEM; - goto v4l1reqbuf_unlock_and_return; - } - - /* The next mmap will map the V4L buffers */ - fh->map_mode = ZORAN_MAP_MODE_RAW; - v4l1reqbuf_unlock_and_return: - mutex_unlock(&zr->resource_lock); - - return res; - } - break; - - case VIDIOCGUNIT: - { - struct video_unit *vunit = arg; - - dprintk(3, KERN_DEBUG "%s: VIDIOCGUNIT\n", ZR_DEVNAME(zr)); - - vunit->video = zr->video_dev->minor; - vunit->vbi = VIDEO_NO_UNIT; - vunit->radio = VIDEO_NO_UNIT; - vunit->audio = VIDEO_NO_UNIT; - vunit->teletext = VIDEO_NO_UNIT; - - return 0; - } - break; - - /* - * RJ: In principal we could support subcaptures for V4L grabbing. - * Not even the famous BTTV driver has them, however. - * If there should be a strong demand, one could consider - * to implement them. - */ - case VIDIOCGCAPTURE: - { - dprintk(3, KERN_ERR "%s: VIDIOCGCAPTURE not supported\n", - ZR_DEVNAME(zr)); - return -EINVAL; - } - break; - - case VIDIOCSCAPTURE: - { - dprintk(3, KERN_ERR "%s: VIDIOCSCAPTURE not supported\n", - ZR_DEVNAME(zr)); - return -EINVAL; - } - break; - case BUZIOC_G_PARAMS: { struct zoran_params *bparams = arg; @@ -2384,7 +1627,13 @@ static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg) mutex_lock(&zr->resource_lock); - bparams->norm = zr->norm; + if (zr->norm & V4L2_STD_NTSC) + bparams->norm = VIDEO_MODE_NTSC; + else if (zr->norm & V4L2_STD_PAL) + bparams->norm = VIDEO_MODE_PAL; + else + bparams->norm = VIDEO_MODE_SECAM; + bparams->input = zr->input; bparams->decimation = fh->jpg_settings.decimation; @@ -2417,7 +1666,6 @@ static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg) return 0; } - break; case BUZIOC_S_PARAMS: { @@ -2460,18 +1708,17 @@ static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg) /* Check the params first before overwriting our * nternal values */ - if (zoran_check_jpg_settings(zr, &settings)) { + if (zoran_check_jpg_settings(zr, &settings, 0)) { res = -EINVAL; goto sparams_unlock_and_return; } fh->jpg_settings = settings; - sparams_unlock_and_return: +sparams_unlock_and_return: mutex_unlock(&zr->resource_lock); return res; } - break; case BUZIOC_REQBUFS: { @@ -2495,16 +1742,13 @@ static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg) * tables to a Maximum of 2 MB */ if (breq->size > jpg_bufsize) breq->size = jpg_bufsize; - if (fh->jpg_buffers.need_contiguous && - breq->size > MAX_KMALLOC_MEM) - breq->size = MAX_KMALLOC_MEM; mutex_lock(&zr->resource_lock); if (fh->jpg_buffers.allocated || fh->v4l_buffers.allocated) { dprintk(1, KERN_ERR - "%s: BUZIOC_REQBUFS - buffers allready allocated\n", + "%s: BUZIOC_REQBUFS - buffers already allocated\n", ZR_DEVNAME(zr)); res = -EBUSY; goto jpgreqbuf_unlock_and_return; @@ -2521,12 +1765,11 @@ static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg) /* The next mmap will map the MJPEG buffers - could * also be *_PLAY, but it doesn't matter here */ fh->map_mode = ZORAN_MAP_MODE_JPG_REC; - jpgreqbuf_unlock_and_return: +jpgreqbuf_unlock_and_return: mutex_unlock(&zr->resource_lock); return res; } - break; case BUZIOC_QBUF_CAPT: { @@ -2541,7 +1784,6 @@ static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg) return res; } - break; case BUZIOC_QBUF_PLAY: { @@ -2556,7 +1798,6 @@ static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg) return res; } - break; case BUZIOC_SYNC: { @@ -2571,12 +1812,13 @@ static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg) return res; } - break; case BUZIOC_G_STATUS: { struct zoran_status *bstat = arg; - int norm, input, status, res = 0; + struct v4l2_routing route = { 0, 0 }; + int status = 0, res = 0; + v4l2_std_id norm; dprintk(3, KERN_DEBUG "%s: BUZIOC_G_STATUS\n", ZR_DEVNAME(zr)); @@ -2588,8 +1830,7 @@ static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg) return -EINVAL; } - input = zr->card.input[bstat->input].muxsel; - norm = VIDEO_MODE_AUTO; + route.input = zr->card.input[bstat->input].muxsel; mutex_lock(&zr->resource_lock); @@ -2602,1629 +1843,1284 @@ static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg) goto gstat_unlock_and_return; } - decoder_command(zr, DECODER_SET_INPUT, &input); - decoder_command(zr, DECODER_SET_NORM, &norm); + decoder_s_routing(zr, &route); /* sleep 1 second */ ssleep(1); /* Get status of video decoder */ - decoder_command(zr, DECODER_GET_STATUS, &status); + decoder_call(zr, video, querystd, &norm); + decoder_call(zr, video, g_input_status, &status); /* restore previous input and norm */ - input = zr->card.input[zr->input].muxsel; - decoder_command(zr, DECODER_SET_INPUT, &input); - decoder_command(zr, DECODER_SET_NORM, &zr->norm); - gstat_unlock_and_return: + route.input = zr->card.input[zr->input].muxsel; + decoder_s_routing(zr, &route); +gstat_unlock_and_return: mutex_unlock(&zr->resource_lock); if (!res) { bstat->signal = - (status & DECODER_STATUS_GOOD) ? 1 : 0; - if (status & DECODER_STATUS_NTSC) + (status & V4L2_IN_ST_NO_SIGNAL) ? 0 : 1; + if (norm & V4L2_STD_NTSC) bstat->norm = VIDEO_MODE_NTSC; - else if (status & DECODER_STATUS_SECAM) + else if (norm & V4L2_STD_SECAM) bstat->norm = VIDEO_MODE_SECAM; else bstat->norm = VIDEO_MODE_PAL; bstat->color = - (status & DECODER_STATUS_COLOR) ? 1 : 0; + (status & V4L2_IN_ST_NO_COLOR) ? 0 : 1; } return res; } - break; - /* The new video4linux2 capture interface - much nicer than video4linux1, since - * it allows for integrating the JPEG capturing calls inside standard v4l2 - */ + default: + return -EINVAL; + } +} - case VIDIOC_QUERYCAP: - { - struct v4l2_capability *cap = arg; +static int zoran_vidiocgmbuf(struct file *file, void *__fh, struct video_mbuf *vmbuf) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; + int i, res = 0; - dprintk(3, KERN_DEBUG "%s: VIDIOC_QUERYCAP\n", ZR_DEVNAME(zr)); + vmbuf->size = + fh->v4l_buffers.num_buffers * + fh->v4l_buffers.buffer_size; + vmbuf->frames = fh->v4l_buffers.num_buffers; + for (i = 0; i < vmbuf->frames; i++) { + vmbuf->offsets[i] = + i * fh->v4l_buffers.buffer_size; + } - memset(cap, 0, sizeof(*cap)); - strncpy(cap->card, ZR_DEVNAME(zr), sizeof(cap->card)-1); - strncpy(cap->driver, "zoran", sizeof(cap->driver)-1); - snprintf(cap->bus_info, sizeof(cap->bus_info), "PCI:%s", - pci_name(zr->pci_dev)); - cap->version = - KERNEL_VERSION(MAJOR_VERSION, MINOR_VERSION, - RELEASE_VERSION); - cap->capabilities = ZORAN_V4L2_VID_FLAGS; + mutex_lock(&zr->resource_lock); - return 0; + if (fh->jpg_buffers.allocated || fh->v4l_buffers.allocated) { + dprintk(1, + KERN_ERR + "%s: VIDIOCGMBUF - buffers already allocated\n", + ZR_DEVNAME(zr)); + res = -EINVAL; + goto v4l1reqbuf_unlock_and_return; } - break; - case VIDIOC_ENUM_FMT: - { - struct v4l2_fmtdesc *fmt = arg; - int index = fmt->index, num = -1, i, flag = 0, type = - fmt->type; + if (v4l_fbuffer_alloc(file)) { + res = -ENOMEM; + goto v4l1reqbuf_unlock_and_return; + } - dprintk(3, KERN_DEBUG "%s: VIDIOC_ENUM_FMT - index=%d\n", - ZR_DEVNAME(zr), fmt->index); + /* The next mmap will map the V4L buffers */ + fh->map_mode = ZORAN_MAP_MODE_RAW; +v4l1reqbuf_unlock_and_return: + mutex_unlock(&zr->resource_lock); - switch (fmt->type) { - case V4L2_BUF_TYPE_VIDEO_CAPTURE: - flag = ZORAN_FORMAT_CAPTURE; - break; - case V4L2_BUF_TYPE_VIDEO_OUTPUT: - flag = ZORAN_FORMAT_PLAYBACK; - break; - case V4L2_BUF_TYPE_VIDEO_OVERLAY: - flag = ZORAN_FORMAT_OVERLAY; - break; - default: - dprintk(1, - KERN_ERR - "%s: VIDIOC_ENUM_FMT - unknown type %d\n", - ZR_DEVNAME(zr), fmt->type); - return -EINVAL; - } + return res; +} +#endif - for (i = 0; i < NUM_FORMATS; i++) { - if (zoran_formats[i].flags & flag) - num++; - if (num == fmt->index) - break; - } - if (fmt->index < 0 /* late, but not too late */ || - i == NUM_FORMATS) - return -EINVAL; +static int zoran_querycap(struct file *file, void *__fh, struct v4l2_capability *cap) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; - memset(fmt, 0, sizeof(*fmt)); - fmt->index = index; - fmt->type = type; - strncpy(fmt->description, zoran_formats[i].name, sizeof(fmt->description)-1); - fmt->pixelformat = zoran_formats[i].fourcc; - if (zoran_formats[i].flags & ZORAN_FORMAT_COMPRESSED) - fmt->flags |= V4L2_FMT_FLAG_COMPRESSED; + memset(cap, 0, sizeof(*cap)); + strncpy(cap->card, ZR_DEVNAME(zr), sizeof(cap->card)-1); + strncpy(cap->driver, "zoran", sizeof(cap->driver)-1); + snprintf(cap->bus_info, sizeof(cap->bus_info), "PCI:%s", + pci_name(zr->pci_dev)); + cap->version = KERNEL_VERSION(MAJOR_VERSION, MINOR_VERSION, + RELEASE_VERSION); + cap->capabilities = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_CAPTURE | + V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_VIDEO_OVERLAY; + return 0; +} - return 0; +static int zoran_enum_fmt(struct zoran *zr, struct v4l2_fmtdesc *fmt, int flag) +{ + int num = -1, i; + + for (i = 0; i < NUM_FORMATS; i++) { + if (zoran_formats[i].flags & flag) + num++; + if (num == fmt->index) + break; } - break; + if (fmt->index < 0 /* late, but not too late */ || i == NUM_FORMATS) + return -EINVAL; - case VIDIOC_G_FMT: - { - struct v4l2_format *fmt = arg; - int type = fmt->type; + strncpy(fmt->description, zoran_formats[i].name, sizeof(fmt->description)-1); + fmt->pixelformat = zoran_formats[i].fourcc; + if (zoran_formats[i].flags & ZORAN_FORMAT_COMPRESSED) + fmt->flags |= V4L2_FMT_FLAG_COMPRESSED; + return 0; +} - dprintk(5, KERN_DEBUG "%s: VIDIOC_G_FMT\n", ZR_DEVNAME(zr)); +static int zoran_enum_fmt_vid_cap(struct file *file, void *__fh, + struct v4l2_fmtdesc *f) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; - memset(fmt, 0, sizeof(*fmt)); - fmt->type = type; + return zoran_enum_fmt(zr, f, ZORAN_FORMAT_CAPTURE); +} - switch (fmt->type) { - case V4L2_BUF_TYPE_VIDEO_OVERLAY: +static int zoran_enum_fmt_vid_out(struct file *file, void *__fh, + struct v4l2_fmtdesc *f) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; - mutex_lock(&zr->resource_lock); + return zoran_enum_fmt(zr, f, ZORAN_FORMAT_PLAYBACK); +} - fmt->fmt.win.w.left = fh->overlay_settings.x; - fmt->fmt.win.w.top = fh->overlay_settings.y; - fmt->fmt.win.w.width = fh->overlay_settings.width; - fmt->fmt.win.w.height = - fh->overlay_settings.height; - if (fh->overlay_settings.width * 2 > - BUZ_MAX_HEIGHT) - fmt->fmt.win.field = V4L2_FIELD_INTERLACED; - else - fmt->fmt.win.field = V4L2_FIELD_TOP; +static int zoran_enum_fmt_vid_overlay(struct file *file, void *__fh, + struct v4l2_fmtdesc *f) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; - mutex_unlock(&zr->resource_lock); + return zoran_enum_fmt(zr, f, ZORAN_FORMAT_OVERLAY); +} - break; +static int zoran_g_fmt_vid_out(struct file *file, void *__fh, + struct v4l2_format *fmt) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; - case V4L2_BUF_TYPE_VIDEO_CAPTURE: - case V4L2_BUF_TYPE_VIDEO_OUTPUT: - - mutex_lock(&zr->resource_lock); - - if (fmt->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && - fh->map_mode == ZORAN_MAP_MODE_RAW) { - - fmt->fmt.pix.width = - fh->v4l_settings.width; - fmt->fmt.pix.height = - fh->v4l_settings.height; - fmt->fmt.pix.sizeimage = - fh->v4l_settings.bytesperline * - fh->v4l_settings.height; - fmt->fmt.pix.pixelformat = - fh->v4l_settings.format->fourcc; - fmt->fmt.pix.colorspace = - fh->v4l_settings.format->colorspace; - fmt->fmt.pix.bytesperline = - fh->v4l_settings.bytesperline; - if (BUZ_MAX_HEIGHT < - (fh->v4l_settings.height * 2)) - fmt->fmt.pix.field = - V4L2_FIELD_INTERLACED; - else - fmt->fmt.pix.field = - V4L2_FIELD_TOP; - - } else { - - fmt->fmt.pix.width = - fh->jpg_settings.img_width / - fh->jpg_settings.HorDcm; - fmt->fmt.pix.height = - fh->jpg_settings.img_height / - (fh->jpg_settings.VerDcm * - fh->jpg_settings.TmpDcm); - fmt->fmt.pix.sizeimage = - zoran_v4l2_calc_bufsize(&fh-> - jpg_settings); - fmt->fmt.pix.pixelformat = - V4L2_PIX_FMT_MJPEG; - if (fh->jpg_settings.TmpDcm == 1) - fmt->fmt.pix.field = - (fh->jpg_settings. - odd_even ? V4L2_FIELD_SEQ_BT : - V4L2_FIELD_SEQ_BT); - else - fmt->fmt.pix.field = - (fh->jpg_settings. - odd_even ? V4L2_FIELD_TOP : - V4L2_FIELD_BOTTOM); - - fmt->fmt.pix.bytesperline = 0; - fmt->fmt.pix.colorspace = - V4L2_COLORSPACE_SMPTE170M; - } + mutex_lock(&zr->resource_lock); - mutex_unlock(&zr->resource_lock); + fmt->fmt.pix.width = fh->jpg_settings.img_width / fh->jpg_settings.HorDcm; + fmt->fmt.pix.height = fh->jpg_settings.img_height * 2 / + (fh->jpg_settings.VerDcm * fh->jpg_settings.TmpDcm); + fmt->fmt.pix.sizeimage = zoran_v4l2_calc_bufsize(&fh->jpg_settings); + fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_MJPEG; + if (fh->jpg_settings.TmpDcm == 1) + fmt->fmt.pix.field = (fh->jpg_settings.odd_even ? + V4L2_FIELD_SEQ_TB : V4L2_FIELD_SEQ_BT); + else + fmt->fmt.pix.field = (fh->jpg_settings.odd_even ? + V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM); + fmt->fmt.pix.bytesperline = 0; + fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; - break; + mutex_unlock(&zr->resource_lock); + return 0; +} - default: - dprintk(1, - KERN_ERR - "%s: VIDIOC_G_FMT - unsupported type %d\n", - ZR_DEVNAME(zr), fmt->type); - return -EINVAL; - } - return 0; - } - break; +static int zoran_g_fmt_vid_cap(struct file *file, void *__fh, + struct v4l2_format *fmt) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; - case VIDIOC_S_FMT: - { - struct v4l2_format *fmt = arg; - int i, res = 0; - __le32 printformat; - - dprintk(3, KERN_DEBUG "%s: VIDIOC_S_FMT - type=%d, ", - ZR_DEVNAME(zr), fmt->type); - - switch (fmt->type) { - case V4L2_BUF_TYPE_VIDEO_OVERLAY: - - dprintk(3, "x=%d, y=%d, w=%d, h=%d, cnt=%d, map=0x%p\n", - fmt->fmt.win.w.left, fmt->fmt.win.w.top, - fmt->fmt.win.w.width, - fmt->fmt.win.w.height, - fmt->fmt.win.clipcount, - fmt->fmt.win.bitmap); - mutex_lock(&zr->resource_lock); - res = - setup_window(file, fmt->fmt.win.w.left, - fmt->fmt.win.w.top, - fmt->fmt.win.w.width, - fmt->fmt.win.w.height, - (struct video_clip __user *) - fmt->fmt.win.clips, - fmt->fmt.win.clipcount, - fmt->fmt.win.bitmap); - mutex_unlock(&zr->resource_lock); - return res; - break; + if (fh->map_mode != ZORAN_MAP_MODE_RAW) + return zoran_g_fmt_vid_out(file, fh, fmt); - case V4L2_BUF_TYPE_VIDEO_CAPTURE: - case V4L2_BUF_TYPE_VIDEO_OUTPUT: - - printformat = - __cpu_to_le32(fmt->fmt.pix.pixelformat); - dprintk(3, "size=%dx%d, fmt=0x%x (%4.4s)\n", - fmt->fmt.pix.width, fmt->fmt.pix.height, - fmt->fmt.pix.pixelformat, - (char *) &printformat); - - /* we can be requested to do JPEG/raw playback/capture */ - if (! - (fmt->type == V4L2_BUF_TYPE_VIDEO_CAPTURE || - (fmt->type == V4L2_BUF_TYPE_VIDEO_OUTPUT && - fmt->fmt.pix.pixelformat == - V4L2_PIX_FMT_MJPEG))) { - dprintk(1, - KERN_ERR - "%s: VIDIOC_S_FMT - unknown type %d/0x%x(%4.4s) combination\n", - ZR_DEVNAME(zr), fmt->type, - fmt->fmt.pix.pixelformat, - (char *) &printformat); - return -EINVAL; - } + mutex_lock(&zr->resource_lock); + fmt->fmt.pix.width = fh->v4l_settings.width; + fmt->fmt.pix.height = fh->v4l_settings.height; + fmt->fmt.pix.sizeimage = fh->v4l_settings.bytesperline * + fh->v4l_settings.height; + fmt->fmt.pix.pixelformat = fh->v4l_settings.format->fourcc; + fmt->fmt.pix.colorspace = fh->v4l_settings.format->colorspace; + fmt->fmt.pix.bytesperline = fh->v4l_settings.bytesperline; + if (BUZ_MAX_HEIGHT < (fh->v4l_settings.height * 2)) + fmt->fmt.pix.field = V4L2_FIELD_INTERLACED; + else + fmt->fmt.pix.field = V4L2_FIELD_TOP; + mutex_unlock(&zr->resource_lock); + return 0; +} - if (fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_MJPEG) { - mutex_lock(&zr->resource_lock); +static int zoran_g_fmt_vid_overlay(struct file *file, void *__fh, + struct v4l2_format *fmt) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; - settings = fh->jpg_settings; + mutex_lock(&zr->resource_lock); - if (fh->v4l_buffers.allocated || - fh->jpg_buffers.allocated) { - dprintk(1, - KERN_ERR - "%s: VIDIOC_S_FMT - cannot change capture mode\n", - ZR_DEVNAME(zr)); - res = -EBUSY; - goto sfmtjpg_unlock_and_return; - } + fmt->fmt.win.w.left = fh->overlay_settings.x; + fmt->fmt.win.w.top = fh->overlay_settings.y; + fmt->fmt.win.w.width = fh->overlay_settings.width; + fmt->fmt.win.w.height = fh->overlay_settings.height; + if (fh->overlay_settings.width * 2 > BUZ_MAX_HEIGHT) + fmt->fmt.win.field = V4L2_FIELD_INTERLACED; + else + fmt->fmt.win.field = V4L2_FIELD_TOP; - /* we actually need to set 'real' parameters now */ - if ((fmt->fmt.pix.height * 2) > - BUZ_MAX_HEIGHT) - settings.TmpDcm = 1; - else - settings.TmpDcm = 2; - settings.decimation = 0; - if (fmt->fmt.pix.height <= - fh->jpg_settings.img_height / 2) - settings.VerDcm = 2; - else - settings.VerDcm = 1; - if (fmt->fmt.pix.width <= - fh->jpg_settings.img_width / 4) - settings.HorDcm = 4; - else if (fmt->fmt.pix.width <= - fh->jpg_settings.img_width / 2) - settings.HorDcm = 2; - else - settings.HorDcm = 1; - if (settings.TmpDcm == 1) - settings.field_per_buff = 2; - else - settings.field_per_buff = 1; - - /* check */ - if ((res = - zoran_check_jpg_settings(zr, - &settings))) - goto sfmtjpg_unlock_and_return; - - /* it's ok, so set them */ - fh->jpg_settings = settings; - - /* tell the user what we actually did */ - fmt->fmt.pix.width = - settings.img_width / settings.HorDcm; - fmt->fmt.pix.height = - settings.img_height * 2 / - (settings.TmpDcm * settings.VerDcm); - if (settings.TmpDcm == 1) - fmt->fmt.pix.field = - (fh->jpg_settings. - odd_even ? V4L2_FIELD_SEQ_TB : - V4L2_FIELD_SEQ_BT); - else - fmt->fmt.pix.field = - (fh->jpg_settings. - odd_even ? V4L2_FIELD_TOP : - V4L2_FIELD_BOTTOM); - fh->jpg_buffers.buffer_size = - zoran_v4l2_calc_bufsize(&fh-> - jpg_settings); - fmt->fmt.pix.bytesperline = 0; - fmt->fmt.pix.sizeimage = - fh->jpg_buffers.buffer_size; - fmt->fmt.pix.colorspace = - V4L2_COLORSPACE_SMPTE170M; - - /* we hereby abuse this variable to show that - * we're gonna do mjpeg capture */ - fh->map_mode = - (fmt->type == - V4L2_BUF_TYPE_VIDEO_CAPTURE) ? - ZORAN_MAP_MODE_JPG_REC : - ZORAN_MAP_MODE_JPG_PLAY; - sfmtjpg_unlock_and_return: - mutex_unlock(&zr->resource_lock); - } else { - for (i = 0; i < NUM_FORMATS; i++) - if (fmt->fmt.pix.pixelformat == - zoran_formats[i].fourcc) - break; - if (i == NUM_FORMATS) { - dprintk(1, - KERN_ERR - "%s: VIDIOC_S_FMT - unknown/unsupported format 0x%x (%4.4s)\n", - ZR_DEVNAME(zr), - fmt->fmt.pix.pixelformat, - (char *) &printformat); - return -EINVAL; - } - mutex_lock(&zr->resource_lock); - if (fh->jpg_buffers.allocated || - (fh->v4l_buffers.allocated && - fh->v4l_buffers.active != - ZORAN_FREE)) { - dprintk(1, - KERN_ERR - "%s: VIDIOC_S_FMT - cannot change capture mode\n", - ZR_DEVNAME(zr)); - res = -EBUSY; - goto sfmtv4l_unlock_and_return; - } - if (fmt->fmt.pix.height > BUZ_MAX_HEIGHT) - fmt->fmt.pix.height = - BUZ_MAX_HEIGHT; - if (fmt->fmt.pix.width > BUZ_MAX_WIDTH) - fmt->fmt.pix.width = BUZ_MAX_WIDTH; - - if ((res = - zoran_v4l_set_format(file, - fmt->fmt.pix. - width, - fmt->fmt.pix. - height, - &zoran_formats - [i]))) - goto sfmtv4l_unlock_and_return; - - /* tell the user the - * results/missing stuff */ - fmt->fmt.pix.bytesperline = - fh->v4l_settings.bytesperline; - fmt->fmt.pix.sizeimage = - fh->v4l_settings.height * - fh->v4l_settings.bytesperline; - fmt->fmt.pix.colorspace = - fh->v4l_settings.format->colorspace; - if (BUZ_MAX_HEIGHT < - (fh->v4l_settings.height * 2)) - fmt->fmt.pix.field = - V4L2_FIELD_INTERLACED; - else - fmt->fmt.pix.field = - V4L2_FIELD_TOP; - - fh->map_mode = ZORAN_MAP_MODE_RAW; - sfmtv4l_unlock_and_return: - mutex_unlock(&zr->resource_lock); - } + mutex_unlock(&zr->resource_lock); + return 0; +} - break; +static int zoran_try_fmt_vid_overlay(struct file *file, void *__fh, + struct v4l2_format *fmt) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; - default: - dprintk(1, - KERN_ERR - "%s: VIDIOC_S_FMT - unsupported type %d\n", - ZR_DEVNAME(zr), fmt->type); - return -EINVAL; - } + mutex_lock(&zr->resource_lock); - return res; - } - break; + if (fmt->fmt.win.w.width > BUZ_MAX_WIDTH) + fmt->fmt.win.w.width = BUZ_MAX_WIDTH; + if (fmt->fmt.win.w.width < BUZ_MIN_WIDTH) + fmt->fmt.win.w.width = BUZ_MIN_WIDTH; + if (fmt->fmt.win.w.height > BUZ_MAX_HEIGHT) + fmt->fmt.win.w.height = BUZ_MAX_HEIGHT; + if (fmt->fmt.win.w.height < BUZ_MIN_HEIGHT) + fmt->fmt.win.w.height = BUZ_MIN_HEIGHT; - case VIDIOC_G_FBUF: - { - struct v4l2_framebuffer *fb = arg; + mutex_unlock(&zr->resource_lock); + return 0; +} - dprintk(3, KERN_DEBUG "%s: VIDIOC_G_FBUF\n", ZR_DEVNAME(zr)); +static int zoran_try_fmt_vid_out(struct file *file, void *__fh, + struct v4l2_format *fmt) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; + struct zoran_jpg_settings settings; + int res = 0; - memset(fb, 0, sizeof(*fb)); - mutex_lock(&zr->resource_lock); - fb->base = zr->buffer.base; - fb->fmt.width = zr->buffer.width; - fb->fmt.height = zr->buffer.height; - if (zr->overlay_settings.format) { - fb->fmt.pixelformat = - fh->overlay_settings.format->fourcc; - } - fb->fmt.bytesperline = zr->buffer.bytesperline; - mutex_unlock(&zr->resource_lock); - fb->fmt.colorspace = V4L2_COLORSPACE_SRGB; - fb->fmt.field = V4L2_FIELD_INTERLACED; - fb->flags = V4L2_FBUF_FLAG_OVERLAY; - fb->capability = V4L2_FBUF_CAP_LIST_CLIPPING; + if (fmt->fmt.pix.pixelformat != V4L2_PIX_FMT_MJPEG) + return -EINVAL; - return 0; - } - break; + mutex_lock(&zr->resource_lock); + settings = fh->jpg_settings; - case VIDIOC_S_FBUF: - { - int i, res = 0; - struct v4l2_framebuffer *fb = arg; - __le32 printformat = __cpu_to_le32(fb->fmt.pixelformat); + /* we actually need to set 'real' parameters now */ + if ((fmt->fmt.pix.height * 2) > BUZ_MAX_HEIGHT) + settings.TmpDcm = 1; + else + settings.TmpDcm = 2; + settings.decimation = 0; + if (fmt->fmt.pix.height <= fh->jpg_settings.img_height / 2) + settings.VerDcm = 2; + else + settings.VerDcm = 1; + if (fmt->fmt.pix.width <= fh->jpg_settings.img_width / 4) + settings.HorDcm = 4; + else if (fmt->fmt.pix.width <= fh->jpg_settings.img_width / 2) + settings.HorDcm = 2; + else + settings.HorDcm = 1; + if (settings.TmpDcm == 1) + settings.field_per_buff = 2; + else + settings.field_per_buff = 1; - dprintk(3, - KERN_DEBUG - "%s: VIDIOC_S_FBUF - base=0x%p, size=%dx%d, bpl=%d, fmt=0x%x (%4.4s)\n", - ZR_DEVNAME(zr), fb->base, fb->fmt.width, fb->fmt.height, - fb->fmt.bytesperline, fb->fmt.pixelformat, - (char *) &printformat); + if (settings.HorDcm > 1) { + settings.img_x = (BUZ_MAX_WIDTH == 720) ? 8 : 0; + settings.img_width = (BUZ_MAX_WIDTH == 720) ? 704 : BUZ_MAX_WIDTH; + } else { + settings.img_x = 0; + settings.img_width = BUZ_MAX_WIDTH; + } + + /* check */ + res = zoran_check_jpg_settings(zr, &settings, 1); + if (res) + goto tryfmt_unlock_and_return; + + /* tell the user what we actually did */ + fmt->fmt.pix.width = settings.img_width / settings.HorDcm; + fmt->fmt.pix.height = settings.img_height * 2 / + (settings.TmpDcm * settings.VerDcm); + if (settings.TmpDcm == 1) + fmt->fmt.pix.field = (fh->jpg_settings.odd_even ? + V4L2_FIELD_SEQ_TB : V4L2_FIELD_SEQ_BT); + else + fmt->fmt.pix.field = (fh->jpg_settings.odd_even ? + V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM); - for (i = 0; i < NUM_FORMATS; i++) - if (zoran_formats[i].fourcc == fb->fmt.pixelformat) - break; - if (i == NUM_FORMATS) { - dprintk(1, - KERN_ERR - "%s: VIDIOC_S_FBUF - format=0x%x (%4.4s) not allowed\n", - ZR_DEVNAME(zr), fb->fmt.pixelformat, - (char *) &printformat); - return -EINVAL; - } + fmt->fmt.pix.sizeimage = zoran_v4l2_calc_bufsize(&settings); + fmt->fmt.pix.bytesperline = 0; + fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; +tryfmt_unlock_and_return: + mutex_unlock(&zr->resource_lock); + return res; +} - mutex_lock(&zr->resource_lock); - res = - setup_fbuffer(file, fb->base, &zoran_formats[i], - fb->fmt.width, fb->fmt.height, - fb->fmt.bytesperline); - mutex_unlock(&zr->resource_lock); +static int zoran_try_fmt_vid_cap(struct file *file, void *__fh, + struct v4l2_format *fmt) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; + int bpp; + int i; - return res; - } - break; + if (fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_MJPEG) + return zoran_try_fmt_vid_out(file, fh, fmt); - case VIDIOC_OVERLAY: - { - int *on = arg, res; + mutex_lock(&zr->resource_lock); - dprintk(3, KERN_DEBUG "%s: VIDIOC_PREVIEW - on=%d\n", - ZR_DEVNAME(zr), *on); + for (i = 0; i < NUM_FORMATS; i++) + if (zoran_formats[i].fourcc == fmt->fmt.pix.pixelformat) + break; - mutex_lock(&zr->resource_lock); - res = setup_overlay(file, *on); + if (i == NUM_FORMATS) { mutex_unlock(&zr->resource_lock); - - return res; + return -EINVAL; } - break; - case VIDIOC_REQBUFS: - { - struct v4l2_requestbuffers *req = arg; - int res = 0; - - dprintk(3, KERN_DEBUG "%s: VIDIOC_REQBUFS - type=%d\n", - ZR_DEVNAME(zr), req->type); - - if (req->memory != V4L2_MEMORY_MMAP) { - dprintk(1, - KERN_ERR - "%s: only MEMORY_MMAP capture is supported, not %d\n", - ZR_DEVNAME(zr), req->memory); - return -EINVAL; - } - - mutex_lock(&zr->resource_lock); - - if (fh->v4l_buffers.allocated || fh->jpg_buffers.allocated) { - dprintk(1, - KERN_ERR - "%s: VIDIOC_REQBUFS - buffers allready allocated\n", - ZR_DEVNAME(zr)); - res = -EBUSY; - goto v4l2reqbuf_unlock_and_return; - } - - if (fh->map_mode == ZORAN_MAP_MODE_RAW && - req->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { + bpp = (zoran_formats[i].depth + 7) / 8; + fmt->fmt.pix.width &= ~((bpp == 2) ? 1 : 3); + if (fmt->fmt.pix.width > BUZ_MAX_WIDTH) + fmt->fmt.pix.width = BUZ_MAX_WIDTH; + if (fmt->fmt.pix.width < BUZ_MIN_WIDTH) + fmt->fmt.pix.width = BUZ_MIN_WIDTH; + if (fmt->fmt.pix.height > BUZ_MAX_HEIGHT) + fmt->fmt.pix.height = BUZ_MAX_HEIGHT; + if (fmt->fmt.pix.height < BUZ_MIN_HEIGHT) + fmt->fmt.pix.height = BUZ_MIN_HEIGHT; + mutex_unlock(&zr->resource_lock); - /* control user input */ - if (req->count < 2) - req->count = 2; - if (req->count > v4l_nbufs) - req->count = v4l_nbufs; - fh->v4l_buffers.num_buffers = req->count; + return 0; +} - if (v4l_fbuffer_alloc(file)) { - res = -ENOMEM; - goto v4l2reqbuf_unlock_and_return; - } +static int zoran_s_fmt_vid_overlay(struct file *file, void *__fh, + struct v4l2_format *fmt) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; + int res; + + dprintk(3, "x=%d, y=%d, w=%d, h=%d, cnt=%d, map=0x%p\n", + fmt->fmt.win.w.left, fmt->fmt.win.w.top, + fmt->fmt.win.w.width, + fmt->fmt.win.w.height, + fmt->fmt.win.clipcount, + fmt->fmt.win.bitmap); + mutex_lock(&zr->resource_lock); + res = setup_window(file, fmt->fmt.win.w.left, + fmt->fmt.win.w.top, + fmt->fmt.win.w.width, + fmt->fmt.win.w.height, + (struct v4l2_clip __user *) + fmt->fmt.win.clips, + fmt->fmt.win.clipcount, + fmt->fmt.win.bitmap); + mutex_unlock(&zr->resource_lock); + return res; +} - /* The next mmap will map the V4L buffers */ - fh->map_mode = ZORAN_MAP_MODE_RAW; +static int zoran_s_fmt_vid_out(struct file *file, void *__fh, + struct v4l2_format *fmt) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; + __le32 printformat = __cpu_to_le32(fmt->fmt.pix.pixelformat); + struct zoran_jpg_settings settings; + int res = 0; - } else if (fh->map_mode == ZORAN_MAP_MODE_JPG_REC || - fh->map_mode == ZORAN_MAP_MODE_JPG_PLAY) { + dprintk(3, "size=%dx%d, fmt=0x%x (%4.4s)\n", + fmt->fmt.pix.width, fmt->fmt.pix.height, + fmt->fmt.pix.pixelformat, + (char *) &printformat); + if (fmt->fmt.pix.pixelformat != V4L2_PIX_FMT_MJPEG) + return -EINVAL; - /* we need to calculate size ourselves now */ - if (req->count < 4) - req->count = 4; - if (req->count > jpg_nbufs) - req->count = jpg_nbufs; - fh->jpg_buffers.num_buffers = req->count; - fh->jpg_buffers.buffer_size = - zoran_v4l2_calc_bufsize(&fh->jpg_settings); + mutex_lock(&zr->resource_lock); - if (jpg_fbuffer_alloc(file)) { - res = -ENOMEM; - goto v4l2reqbuf_unlock_and_return; - } + settings = fh->jpg_settings; - /* The next mmap will map the MJPEG buffers */ - if (req->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) - fh->map_mode = ZORAN_MAP_MODE_JPG_REC; - else - fh->map_mode = ZORAN_MAP_MODE_JPG_PLAY; + if (fh->v4l_buffers.allocated || fh->jpg_buffers.allocated) { + dprintk(1, KERN_ERR "%s: VIDIOC_S_FMT - cannot change capture mode\n", + ZR_DEVNAME(zr)); + res = -EBUSY; + goto sfmtjpg_unlock_and_return; + } - } else { - dprintk(1, - KERN_ERR - "%s: VIDIOC_REQBUFS - unknown type %d\n", - ZR_DEVNAME(zr), req->type); - res = -EINVAL; - goto v4l2reqbuf_unlock_and_return; - } - v4l2reqbuf_unlock_and_return: - mutex_unlock(&zr->resource_lock); + /* we actually need to set 'real' parameters now */ + if (fmt->fmt.pix.height * 2 > BUZ_MAX_HEIGHT) + settings.TmpDcm = 1; + else + settings.TmpDcm = 2; + settings.decimation = 0; + if (fmt->fmt.pix.height <= fh->jpg_settings.img_height / 2) + settings.VerDcm = 2; + else + settings.VerDcm = 1; + if (fmt->fmt.pix.width <= fh->jpg_settings.img_width / 4) + settings.HorDcm = 4; + else if (fmt->fmt.pix.width <= fh->jpg_settings.img_width / 2) + settings.HorDcm = 2; + else + settings.HorDcm = 1; + if (settings.TmpDcm == 1) + settings.field_per_buff = 2; + else + settings.field_per_buff = 1; - return 0; + if (settings.HorDcm > 1) { + settings.img_x = (BUZ_MAX_WIDTH == 720) ? 8 : 0; + settings.img_width = (BUZ_MAX_WIDTH == 720) ? 704 : BUZ_MAX_WIDTH; + } else { + settings.img_x = 0; + settings.img_width = BUZ_MAX_WIDTH; } - break; - case VIDIOC_QUERYBUF: - { - struct v4l2_buffer *buf = arg; - __u32 type = buf->type; - int index = buf->index, res; + /* check */ + res = zoran_check_jpg_settings(zr, &settings, 0); + if (res) + goto sfmtjpg_unlock_and_return; - dprintk(3, - KERN_DEBUG - "%s: VIDIOC_QUERYBUF - index=%d, type=%d\n", - ZR_DEVNAME(zr), buf->index, buf->type); + /* it's ok, so set them */ + fh->jpg_settings = settings; - memset(buf, 0, sizeof(*buf)); - buf->type = type; - buf->index = index; - - mutex_lock(&zr->resource_lock); - res = zoran_v4l2_buffer_status(file, buf, buf->index); - mutex_unlock(&zr->resource_lock); + /* tell the user what we actually did */ + fmt->fmt.pix.width = settings.img_width / settings.HorDcm; + fmt->fmt.pix.height = settings.img_height * 2 / + (settings.TmpDcm * settings.VerDcm); + if (settings.TmpDcm == 1) + fmt->fmt.pix.field = (fh->jpg_settings.odd_even ? + V4L2_FIELD_SEQ_TB : V4L2_FIELD_SEQ_BT); + else + fmt->fmt.pix.field = (fh->jpg_settings.odd_even ? + V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM); + fh->jpg_buffers.buffer_size = zoran_v4l2_calc_bufsize(&fh->jpg_settings); + fmt->fmt.pix.bytesperline = 0; + fmt->fmt.pix.sizeimage = fh->jpg_buffers.buffer_size; + fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; + + /* we hereby abuse this variable to show that + * we're gonna do mjpeg capture */ + fh->map_mode = (fmt->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) ? + ZORAN_MAP_MODE_JPG_REC : ZORAN_MAP_MODE_JPG_PLAY; +sfmtjpg_unlock_and_return: + mutex_unlock(&zr->resource_lock); + return res; +} - return res; - } - break; +static int zoran_s_fmt_vid_cap(struct file *file, void *__fh, + struct v4l2_format *fmt) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; + int i; + int res = 0; - case VIDIOC_QBUF: - { - struct v4l2_buffer *buf = arg; - int res = 0, codec_mode, buf_type; + if (fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_MJPEG) + return zoran_s_fmt_vid_out(file, fh, fmt); - dprintk(3, - KERN_DEBUG "%s: VIDIOC_QBUF - type=%d, index=%d\n", - ZR_DEVNAME(zr), buf->type, buf->index); + for (i = 0; i < NUM_FORMATS; i++) + if (fmt->fmt.pix.pixelformat == zoran_formats[i].fourcc) + break; + if (i == NUM_FORMATS) { + dprintk(1, KERN_ERR "%s: VIDIOC_S_FMT - unknown/unsupported format 0x%x\n", + ZR_DEVNAME(zr), fmt->fmt.pix.pixelformat); + return -EINVAL; + } + mutex_lock(&zr->resource_lock); + if (fh->jpg_buffers.allocated || + (fh->v4l_buffers.allocated && fh->v4l_buffers.active != ZORAN_FREE)) { + dprintk(1, KERN_ERR "%s: VIDIOC_S_FMT - cannot change capture mode\n", + ZR_DEVNAME(zr)); + res = -EBUSY; + goto sfmtv4l_unlock_and_return; + } + if (fmt->fmt.pix.height > BUZ_MAX_HEIGHT) + fmt->fmt.pix.height = BUZ_MAX_HEIGHT; + if (fmt->fmt.pix.width > BUZ_MAX_WIDTH) + fmt->fmt.pix.width = BUZ_MAX_WIDTH; + + res = zoran_v4l_set_format(file, fmt->fmt.pix.width, + fmt->fmt.pix.height, &zoran_formats[i]); + if (res) + goto sfmtv4l_unlock_and_return; + + /* tell the user the + * results/missing stuff */ + fmt->fmt.pix.bytesperline = fh->v4l_settings.bytesperline; + fmt->fmt.pix.sizeimage = fh->v4l_settings.height * fh->v4l_settings.bytesperline; + fmt->fmt.pix.colorspace = fh->v4l_settings.format->colorspace; + if (BUZ_MAX_HEIGHT < (fh->v4l_settings.height * 2)) + fmt->fmt.pix.field = V4L2_FIELD_INTERLACED; + else + fmt->fmt.pix.field = V4L2_FIELD_TOP; - mutex_lock(&zr->resource_lock); + fh->map_mode = ZORAN_MAP_MODE_RAW; +sfmtv4l_unlock_and_return: + mutex_unlock(&zr->resource_lock); + return res; +} - switch (fh->map_mode) { - case ZORAN_MAP_MODE_RAW: - if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { - dprintk(1, - KERN_ERR - "%s: VIDIOC_QBUF - invalid buf->type=%d for map_mode=%d\n", - ZR_DEVNAME(zr), buf->type, fh->map_mode); - res = -EINVAL; - goto qbuf_unlock_and_return; - } +static int zoran_g_fbuf(struct file *file, void *__fh, + struct v4l2_framebuffer *fb) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; - res = zoran_v4l_queue_frame(file, buf->index); - if (res) - goto qbuf_unlock_and_return; - if (!zr->v4l_memgrab_active && - fh->v4l_buffers.active == ZORAN_LOCKED) - zr36057_set_memgrab(zr, 1); - break; + memset(fb, 0, sizeof(*fb)); + mutex_lock(&zr->resource_lock); + fb->base = zr->vbuf_base; + fb->fmt.width = zr->vbuf_width; + fb->fmt.height = zr->vbuf_height; + if (zr->overlay_settings.format) + fb->fmt.pixelformat = fh->overlay_settings.format->fourcc; + fb->fmt.bytesperline = zr->vbuf_bytesperline; + mutex_unlock(&zr->resource_lock); + fb->fmt.colorspace = V4L2_COLORSPACE_SRGB; + fb->fmt.field = V4L2_FIELD_INTERLACED; + fb->flags = V4L2_FBUF_FLAG_OVERLAY; + fb->capability = V4L2_FBUF_CAP_LIST_CLIPPING; - case ZORAN_MAP_MODE_JPG_REC: - case ZORAN_MAP_MODE_JPG_PLAY: - if (fh->map_mode == ZORAN_MAP_MODE_JPG_PLAY) { - buf_type = V4L2_BUF_TYPE_VIDEO_OUTPUT; - codec_mode = BUZ_MODE_MOTION_DECOMPRESS; - } else { - buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - codec_mode = BUZ_MODE_MOTION_COMPRESS; - } + return 0; +} - if (buf->type != buf_type) { - dprintk(1, - KERN_ERR - "%s: VIDIOC_QBUF - invalid buf->type=%d for map_mode=%d\n", - ZR_DEVNAME(zr), buf->type, fh->map_mode); - res = -EINVAL; - goto qbuf_unlock_and_return; - } +static int zoran_s_fbuf(struct file *file, void *__fh, + struct v4l2_framebuffer *fb) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; + int i, res = 0; + __le32 printformat = __cpu_to_le32(fb->fmt.pixelformat); - res = - zoran_jpg_queue_frame(file, buf->index, - codec_mode); - if (res != 0) - goto qbuf_unlock_and_return; - if (zr->codec_mode == BUZ_MODE_IDLE && - fh->jpg_buffers.active == ZORAN_LOCKED) { - zr36057_enable_jpg(zr, codec_mode); - } + for (i = 0; i < NUM_FORMATS; i++) + if (zoran_formats[i].fourcc == fb->fmt.pixelformat) break; - - default: - dprintk(1, - KERN_ERR - "%s: VIDIOC_QBUF - unsupported type %d\n", - ZR_DEVNAME(zr), buf->type); - res = -EINVAL; - goto qbuf_unlock_and_return; - } - qbuf_unlock_and_return: - mutex_unlock(&zr->resource_lock); - - return res; + if (i == NUM_FORMATS) { + dprintk(1, KERN_ERR "%s: VIDIOC_S_FBUF - format=0x%x (%4.4s) not allowed\n", + ZR_DEVNAME(zr), fb->fmt.pixelformat, + (char *)&printformat); + return -EINVAL; } - break; - case VIDIOC_DQBUF: - { - struct v4l2_buffer *buf = arg; - int res = 0, buf_type, num = -1; /* compiler borks here (?) */ - - dprintk(3, KERN_DEBUG "%s: VIDIOC_DQBUF - type=%d\n", - ZR_DEVNAME(zr), buf->type); + mutex_lock(&zr->resource_lock); + res = setup_fbuffer(file, fb->base, &zoran_formats[i], + fb->fmt.width, fb->fmt.height, + fb->fmt.bytesperline); + mutex_unlock(&zr->resource_lock); - mutex_lock(&zr->resource_lock); + return res; +} - switch (fh->map_mode) { - case ZORAN_MAP_MODE_RAW: - if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { - dprintk(1, - KERN_ERR - "%s: VIDIOC_QBUF - invalid buf->type=%d for map_mode=%d\n", - ZR_DEVNAME(zr), buf->type, fh->map_mode); - res = -EINVAL; - goto dqbuf_unlock_and_return; - } +static int zoran_overlay(struct file *file, void *__fh, unsigned int on) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; + int res; - num = zr->v4l_pend[zr->v4l_sync_tail & V4L_MASK_FRAME]; - if (file->f_flags & O_NONBLOCK && - zr->v4l_buffers.buffer[num].state != - BUZ_STATE_DONE) { - res = -EAGAIN; - goto dqbuf_unlock_and_return; - } - res = v4l_sync(file, num); - if (res) - goto dqbuf_unlock_and_return; - else - zr->v4l_sync_tail++; - res = zoran_v4l2_buffer_status(file, buf, num); - break; + mutex_lock(&zr->resource_lock); + res = setup_overlay(file, on); + mutex_unlock(&zr->resource_lock); - case ZORAN_MAP_MODE_JPG_REC: - case ZORAN_MAP_MODE_JPG_PLAY: - { - struct zoran_sync bs; + return res; +} - if (fh->map_mode == ZORAN_MAP_MODE_JPG_PLAY) - buf_type = V4L2_BUF_TYPE_VIDEO_OUTPUT; - else - buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE; +static int zoran_streamoff(struct file *file, void *__fh, enum v4l2_buf_type type); - if (buf->type != buf_type) { - dprintk(1, - KERN_ERR - "%s: VIDIOC_QBUF - invalid buf->type=%d for map_mode=%d\n", - ZR_DEVNAME(zr), buf->type, fh->map_mode); - res = -EINVAL; - goto dqbuf_unlock_and_return; - } +static int zoran_reqbufs(struct file *file, void *__fh, struct v4l2_requestbuffers *req) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; + int res = 0; - num = - zr->jpg_pend[zr-> - jpg_que_tail & BUZ_MASK_FRAME]; + if (req->memory != V4L2_MEMORY_MMAP) { + dprintk(2, + KERN_ERR + "%s: only MEMORY_MMAP capture is supported, not %d\n", + ZR_DEVNAME(zr), req->memory); + return -EINVAL; + } - if (file->f_flags & O_NONBLOCK && - zr->jpg_buffers.buffer[num].state != - BUZ_STATE_DONE) { - res = -EAGAIN; - goto dqbuf_unlock_and_return; - } - res = jpg_sync(file, &bs); - if (res) - goto dqbuf_unlock_and_return; - res = - zoran_v4l2_buffer_status(file, buf, bs.frame); - break; - } + if (req->count == 0) + return zoran_streamoff(file, fh, req->type); - default: - dprintk(1, + mutex_lock(&zr->resource_lock); + if (fh->v4l_buffers.allocated || fh->jpg_buffers.allocated) { + dprintk(2, KERN_ERR - "%s: VIDIOC_DQBUF - unsupported type %d\n", - ZR_DEVNAME(zr), buf->type); - res = -EINVAL; - goto dqbuf_unlock_and_return; - } - dqbuf_unlock_and_return: - mutex_unlock(&zr->resource_lock); - - return res; + "%s: VIDIOC_REQBUFS - buffers already allocated\n", + ZR_DEVNAME(zr)); + res = -EBUSY; + goto v4l2reqbuf_unlock_and_return; } - break; - case VIDIOC_STREAMON: - { - int res = 0; + if (fh->map_mode == ZORAN_MAP_MODE_RAW && + req->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { - dprintk(3, KERN_DEBUG "%s: VIDIOC_STREAMON\n", ZR_DEVNAME(zr)); + /* control user input */ + if (req->count < 2) + req->count = 2; + if (req->count > v4l_nbufs) + req->count = v4l_nbufs; + fh->v4l_buffers.num_buffers = req->count; - mutex_lock(&zr->resource_lock); + if (v4l_fbuffer_alloc(file)) { + res = -ENOMEM; + goto v4l2reqbuf_unlock_and_return; + } - switch (fh->map_mode) { - case ZORAN_MAP_MODE_RAW: /* raw capture */ - if (zr->v4l_buffers.active != ZORAN_ACTIVE || - fh->v4l_buffers.active != ZORAN_ACTIVE) { - res = -EBUSY; - goto strmon_unlock_and_return; - } + /* The next mmap will map the V4L buffers */ + fh->map_mode = ZORAN_MAP_MODE_RAW; - zr->v4l_buffers.active = fh->v4l_buffers.active = - ZORAN_LOCKED; - zr->v4l_settings = fh->v4l_settings; + } else if (fh->map_mode == ZORAN_MAP_MODE_JPG_REC || + fh->map_mode == ZORAN_MAP_MODE_JPG_PLAY) { - zr->v4l_sync_tail = zr->v4l_pend_tail; - if (!zr->v4l_memgrab_active && - zr->v4l_pend_head != zr->v4l_pend_tail) { - zr36057_set_memgrab(zr, 1); - } - break; + /* we need to calculate size ourselves now */ + if (req->count < 4) + req->count = 4; + if (req->count > jpg_nbufs) + req->count = jpg_nbufs; + fh->jpg_buffers.num_buffers = req->count; + fh->jpg_buffers.buffer_size = + zoran_v4l2_calc_bufsize(&fh->jpg_settings); - case ZORAN_MAP_MODE_JPG_REC: - case ZORAN_MAP_MODE_JPG_PLAY: - /* what is the codec mode right now? */ - if (zr->jpg_buffers.active != ZORAN_ACTIVE || - fh->jpg_buffers.active != ZORAN_ACTIVE) { - res = -EBUSY; - goto strmon_unlock_and_return; - } - - zr->jpg_buffers.active = fh->jpg_buffers.active = - ZORAN_LOCKED; + if (jpg_fbuffer_alloc(file)) { + res = -ENOMEM; + goto v4l2reqbuf_unlock_and_return; + } - if (zr->jpg_que_head != zr->jpg_que_tail) { - /* Start the jpeg codec when the first frame is queued */ - jpeg_start(zr); - } + /* The next mmap will map the MJPEG buffers */ + if (req->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) + fh->map_mode = ZORAN_MAP_MODE_JPG_REC; + else + fh->map_mode = ZORAN_MAP_MODE_JPG_PLAY; - break; - default: - dprintk(1, + } else { + dprintk(1, KERN_ERR - "%s: VIDIOC_STREAMON - invalid map mode %d\n", - ZR_DEVNAME(zr), fh->map_mode); - res = -EINVAL; - goto strmon_unlock_and_return; - } - strmon_unlock_and_return: - mutex_unlock(&zr->resource_lock); - - return res; + "%s: VIDIOC_REQBUFS - unknown type %d\n", + ZR_DEVNAME(zr), req->type); + res = -EINVAL; + goto v4l2reqbuf_unlock_and_return; } - break; - - case VIDIOC_STREAMOFF: - { - int i, res = 0; - - dprintk(3, KERN_DEBUG "%s: VIDIOC_STREAMOFF\n", ZR_DEVNAME(zr)); - - mutex_lock(&zr->resource_lock); +v4l2reqbuf_unlock_and_return: + mutex_unlock(&zr->resource_lock); - switch (fh->map_mode) { - case ZORAN_MAP_MODE_RAW: /* raw capture */ - if (fh->v4l_buffers.active == ZORAN_FREE && - zr->v4l_buffers.active != ZORAN_FREE) { - res = -EPERM; /* stay off other's settings! */ - goto strmoff_unlock_and_return; - } - if (zr->v4l_buffers.active == ZORAN_FREE) - goto strmoff_unlock_and_return; + return res; +} - /* unload capture */ - if (zr->v4l_memgrab_active) { - unsigned long flags; +static int zoran_querybuf(struct file *file, void *__fh, struct v4l2_buffer *buf) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; + __u32 type = buf->type; + int index = buf->index, res; - spin_lock_irqsave(&zr->spinlock, flags); - zr36057_set_memgrab(zr, 0); - spin_unlock_irqrestore(&zr->spinlock, flags); - } + memset(buf, 0, sizeof(*buf)); + buf->type = type; + buf->index = index; - for (i = 0; i < fh->v4l_buffers.num_buffers; i++) - zr->v4l_buffers.buffer[i].state = - BUZ_STATE_USER; - fh->v4l_buffers = zr->v4l_buffers; + mutex_lock(&zr->resource_lock); + res = zoran_v4l2_buffer_status(file, buf, buf->index); + mutex_unlock(&zr->resource_lock); - zr->v4l_buffers.active = fh->v4l_buffers.active = - ZORAN_FREE; + return res; +} - zr->v4l_grab_seq = 0; - zr->v4l_pend_head = zr->v4l_pend_tail = 0; - zr->v4l_sync_tail = 0; +static int zoran_qbuf(struct file *file, void *__fh, struct v4l2_buffer *buf) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; + int res = 0, codec_mode, buf_type; - break; + mutex_lock(&zr->resource_lock); - case ZORAN_MAP_MODE_JPG_REC: - case ZORAN_MAP_MODE_JPG_PLAY: - if (fh->jpg_buffers.active == ZORAN_FREE && - zr->jpg_buffers.active != ZORAN_FREE) { - res = -EPERM; /* stay off other's settings! */ - goto strmoff_unlock_and_return; - } - if (zr->jpg_buffers.active == ZORAN_FREE) - goto strmoff_unlock_and_return; - - res = - jpg_qbuf(file, -1, - (fh->map_mode == - ZORAN_MAP_MODE_JPG_REC) ? - BUZ_MODE_MOTION_COMPRESS : - BUZ_MODE_MOTION_DECOMPRESS); - if (res) - goto strmoff_unlock_and_return; - break; - default: - dprintk(1, - KERN_ERR - "%s: VIDIOC_STREAMOFF - invalid map mode %d\n", - ZR_DEVNAME(zr), fh->map_mode); + switch (fh->map_mode) { + case ZORAN_MAP_MODE_RAW: + if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { + dprintk(1, KERN_ERR + "%s: VIDIOC_QBUF - invalid buf->type=%d for map_mode=%d\n", + ZR_DEVNAME(zr), buf->type, fh->map_mode); res = -EINVAL; - goto strmoff_unlock_and_return; + goto qbuf_unlock_and_return; } - strmoff_unlock_and_return: - mutex_unlock(&zr->resource_lock); - return res; - } + res = zoran_v4l_queue_frame(file, buf->index); + if (res) + goto qbuf_unlock_and_return; + if (!zr->v4l_memgrab_active && + fh->v4l_buffers.active == ZORAN_LOCKED) + zr36057_set_memgrab(zr, 1); break; - case VIDIOC_QUERYCTRL: - { - struct v4l2_queryctrl *ctrl = arg; - - dprintk(3, KERN_DEBUG "%s: VIDIOC_QUERYCTRL - id=%d\n", - ZR_DEVNAME(zr), ctrl->id); - - /* we only support hue/saturation/contrast/brightness */ - if (ctrl->id < V4L2_CID_BRIGHTNESS || - ctrl->id > V4L2_CID_HUE) - return -EINVAL; - else { - int id = ctrl->id; - memset(ctrl, 0, sizeof(*ctrl)); - ctrl->id = id; + case ZORAN_MAP_MODE_JPG_REC: + case ZORAN_MAP_MODE_JPG_PLAY: + if (fh->map_mode == ZORAN_MAP_MODE_JPG_PLAY) { + buf_type = V4L2_BUF_TYPE_VIDEO_OUTPUT; + codec_mode = BUZ_MODE_MOTION_DECOMPRESS; + } else { + buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + codec_mode = BUZ_MODE_MOTION_COMPRESS; } - switch (ctrl->id) { - case V4L2_CID_BRIGHTNESS: - strncpy(ctrl->name, "Brightness", sizeof(ctrl->name)-1); - break; - case V4L2_CID_CONTRAST: - strncpy(ctrl->name, "Contrast", sizeof(ctrl->name)-1); - break; - case V4L2_CID_SATURATION: - strncpy(ctrl->name, "Saturation", sizeof(ctrl->name)-1); - break; - case V4L2_CID_HUE: - strncpy(ctrl->name, "Hue", sizeof(ctrl->name)-1); - break; + if (buf->type != buf_type) { + dprintk(1, KERN_ERR + "%s: VIDIOC_QBUF - invalid buf->type=%d for map_mode=%d\n", + ZR_DEVNAME(zr), buf->type, fh->map_mode); + res = -EINVAL; + goto qbuf_unlock_and_return; } - ctrl->minimum = 0; - ctrl->maximum = 65535; - ctrl->step = 1; - ctrl->default_value = 32768; - ctrl->type = V4L2_CTRL_TYPE_INTEGER; - - return 0; - } - break; - - case VIDIOC_G_CTRL: - { - struct v4l2_control *ctrl = arg; - - dprintk(3, KERN_DEBUG "%s: VIDIOC_G_CTRL - id=%d\n", - ZR_DEVNAME(zr), ctrl->id); - - /* we only support hue/saturation/contrast/brightness */ - if (ctrl->id < V4L2_CID_BRIGHTNESS || - ctrl->id > V4L2_CID_HUE) - return -EINVAL; - - mutex_lock(&zr->resource_lock); - switch (ctrl->id) { - case V4L2_CID_BRIGHTNESS: - ctrl->value = zr->brightness; - break; - case V4L2_CID_CONTRAST: - ctrl->value = zr->contrast; - break; - case V4L2_CID_SATURATION: - ctrl->value = zr->saturation; - break; - case V4L2_CID_HUE: - ctrl->value = zr->hue; - break; + res = zoran_jpg_queue_frame(file, buf->index, + codec_mode); + if (res != 0) + goto qbuf_unlock_and_return; + if (zr->codec_mode == BUZ_MODE_IDLE && + fh->jpg_buffers.active == ZORAN_LOCKED) { + zr36057_enable_jpg(zr, codec_mode); } - mutex_unlock(&zr->resource_lock); + break; - return 0; - } + default: + dprintk(1, KERN_ERR + "%s: VIDIOC_QBUF - unsupported type %d\n", + ZR_DEVNAME(zr), buf->type); + res = -EINVAL; break; + } +qbuf_unlock_and_return: + mutex_unlock(&zr->resource_lock); - case VIDIOC_S_CTRL: - { - struct v4l2_control *ctrl = arg; - struct video_picture pict; + return res; +} - dprintk(3, KERN_DEBUG "%s: VIDIOC_S_CTRL - id=%d\n", - ZR_DEVNAME(zr), ctrl->id); +static int zoran_dqbuf(struct file *file, void *__fh, struct v4l2_buffer *buf) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; + int res = 0, buf_type, num = -1; /* compiler borks here (?) */ - /* we only support hue/saturation/contrast/brightness */ - if (ctrl->id < V4L2_CID_BRIGHTNESS || - ctrl->id > V4L2_CID_HUE) - return -EINVAL; + mutex_lock(&zr->resource_lock); - if (ctrl->value < 0 || ctrl->value > 65535) { - dprintk(1, - KERN_ERR - "%s: VIDIOC_S_CTRL - invalid value %d for id=%d\n", - ZR_DEVNAME(zr), ctrl->value, ctrl->id); - return -EINVAL; + switch (fh->map_mode) { + case ZORAN_MAP_MODE_RAW: + if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { + dprintk(1, KERN_ERR + "%s: VIDIOC_QBUF - invalid buf->type=%d for map_mode=%d\n", + ZR_DEVNAME(zr), buf->type, fh->map_mode); + res = -EINVAL; + goto dqbuf_unlock_and_return; } - mutex_lock(&zr->resource_lock); - switch (ctrl->id) { - case V4L2_CID_BRIGHTNESS: - zr->brightness = ctrl->value; - break; - case V4L2_CID_CONTRAST: - zr->contrast = ctrl->value; - break; - case V4L2_CID_SATURATION: - zr->saturation = ctrl->value; - break; - case V4L2_CID_HUE: - zr->hue = ctrl->value; - break; + num = zr->v4l_pend[zr->v4l_sync_tail & V4L_MASK_FRAME]; + if (file->f_flags & O_NONBLOCK && + zr->v4l_buffers.buffer[num].state != BUZ_STATE_DONE) { + res = -EAGAIN; + goto dqbuf_unlock_and_return; } - pict.brightness = zr->brightness; - pict.contrast = zr->contrast; - pict.colour = zr->saturation; - pict.hue = zr->hue; - - decoder_command(zr, DECODER_SET_PICTURE, &pict); - - mutex_unlock(&zr->resource_lock); - - return 0; - } + res = v4l_sync(file, num); + if (res) + goto dqbuf_unlock_and_return; + zr->v4l_sync_tail++; + res = zoran_v4l2_buffer_status(file, buf, num); break; - case VIDIOC_ENUMSTD: + case ZORAN_MAP_MODE_JPG_REC: + case ZORAN_MAP_MODE_JPG_PLAY: { - struct v4l2_standard *std = arg; + struct zoran_sync bs; - dprintk(3, KERN_DEBUG "%s: VIDIOC_ENUMSTD - index=%d\n", - ZR_DEVNAME(zr), std->index); + if (fh->map_mode == ZORAN_MAP_MODE_JPG_PLAY) + buf_type = V4L2_BUF_TYPE_VIDEO_OUTPUT; + else + buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - if (std->index < 0 || std->index >= (zr->card.norms + 1)) - return -EINVAL; - else { - int id = std->index; - memset(std, 0, sizeof(*std)); - std->index = id; + if (buf->type != buf_type) { + dprintk(1, KERN_ERR + "%s: VIDIOC_QBUF - invalid buf->type=%d for map_mode=%d\n", + ZR_DEVNAME(zr), buf->type, fh->map_mode); + res = -EINVAL; + goto dqbuf_unlock_and_return; } - if (std->index == zr->card.norms) { - /* if we have autodetect, ... */ - struct video_decoder_capability caps; - decoder_command(zr, DECODER_GET_CAPABILITIES, - &caps); - if (caps.flags & VIDEO_DECODER_AUTO) { - std->id = V4L2_STD_ALL; - strncpy(std->name, "Autodetect", sizeof(std->name)-1); - return 0; - } else - return -EINVAL; - } - switch (std->index) { - case 0: - std->id = V4L2_STD_PAL; - strncpy(std->name, "PAL", sizeof(std->name)-1); - std->frameperiod.numerator = 1; - std->frameperiod.denominator = 25; - std->framelines = zr->card.tvn[0]->Ht; - break; - case 1: - std->id = V4L2_STD_NTSC; - strncpy(std->name, "NTSC", sizeof(std->name)-1); - std->frameperiod.numerator = 1001; - std->frameperiod.denominator = 30000; - std->framelines = zr->card.tvn[1]->Ht; - break; - case 2: - std->id = V4L2_STD_SECAM; - strncpy(std->name, "SECAM", sizeof(std->name)-1); - std->frameperiod.numerator = 1; - std->frameperiod.denominator = 25; - std->framelines = zr->card.tvn[2]->Ht; - break; - } + num = zr->jpg_pend[zr->jpg_que_tail & BUZ_MASK_FRAME]; - return 0; + if (file->f_flags & O_NONBLOCK && + zr->jpg_buffers.buffer[num].state != BUZ_STATE_DONE) { + res = -EAGAIN; + goto dqbuf_unlock_and_return; + } + res = jpg_sync(file, &bs); + if (res) + goto dqbuf_unlock_and_return; + res = zoran_v4l2_buffer_status(file, buf, bs.frame); + break; } + + default: + dprintk(1, KERN_ERR + "%s: VIDIOC_DQBUF - unsupported type %d\n", + ZR_DEVNAME(zr), buf->type); + res = -EINVAL; break; + } +dqbuf_unlock_and_return: + mutex_unlock(&zr->resource_lock); - case VIDIOC_G_STD: - { - v4l2_std_id *std = arg; - int norm; + return res; +} - dprintk(3, KERN_DEBUG "%s: VIDIOC_G_STD\n", ZR_DEVNAME(zr)); +static int zoran_streamon(struct file *file, void *__fh, enum v4l2_buf_type type) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; + int res = 0; - mutex_lock(&zr->resource_lock); - norm = zr->norm; - mutex_unlock(&zr->resource_lock); + mutex_lock(&zr->resource_lock); - switch (norm) { - case VIDEO_MODE_PAL: - *std = V4L2_STD_PAL; - break; - case VIDEO_MODE_NTSC: - *std = V4L2_STD_NTSC; - break; - case VIDEO_MODE_SECAM: - *std = V4L2_STD_SECAM; - break; + switch (fh->map_mode) { + case ZORAN_MAP_MODE_RAW: /* raw capture */ + if (zr->v4l_buffers.active != ZORAN_ACTIVE || + fh->v4l_buffers.active != ZORAN_ACTIVE) { + res = -EBUSY; + goto strmon_unlock_and_return; } - return 0; - } + zr->v4l_buffers.active = fh->v4l_buffers.active = ZORAN_LOCKED; + zr->v4l_settings = fh->v4l_settings; + + zr->v4l_sync_tail = zr->v4l_pend_tail; + if (!zr->v4l_memgrab_active && + zr->v4l_pend_head != zr->v4l_pend_tail) { + zr36057_set_memgrab(zr, 1); + } break; - case VIDIOC_S_STD: - { - int norm = -1, res = 0; - v4l2_std_id *std = arg; - - dprintk(3, KERN_DEBUG "%s: VIDIOC_S_STD - norm=0x%llx\n", - ZR_DEVNAME(zr), (unsigned long long)*std); - - if ((*std & V4L2_STD_PAL) && !(*std & ~V4L2_STD_PAL)) - norm = VIDEO_MODE_PAL; - else if ((*std & V4L2_STD_NTSC) && !(*std & ~V4L2_STD_NTSC)) - norm = VIDEO_MODE_NTSC; - else if ((*std & V4L2_STD_SECAM) && !(*std & ~V4L2_STD_SECAM)) - norm = VIDEO_MODE_SECAM; - else if (*std == V4L2_STD_ALL) - norm = VIDEO_MODE_AUTO; - else { - dprintk(1, - KERN_ERR - "%s: VIDIOC_S_STD - invalid norm 0x%llx\n", - ZR_DEVNAME(zr), (unsigned long long)*std); - return -EINVAL; + case ZORAN_MAP_MODE_JPG_REC: + case ZORAN_MAP_MODE_JPG_PLAY: + /* what is the codec mode right now? */ + if (zr->jpg_buffers.active != ZORAN_ACTIVE || + fh->jpg_buffers.active != ZORAN_ACTIVE) { + res = -EBUSY; + goto strmon_unlock_and_return; } - mutex_lock(&zr->resource_lock); - if ((res = zoran_set_norm(zr, norm))) - goto sstd_unlock_and_return; + zr->jpg_buffers.active = fh->jpg_buffers.active = ZORAN_LOCKED; - res = wait_grab_pending(zr); - sstd_unlock_and_return: - mutex_unlock(&zr->resource_lock); - return res; - } + if (zr->jpg_que_head != zr->jpg_que_tail) { + /* Start the jpeg codec when the first frame is queued */ + jpeg_start(zr); + } break; - case VIDIOC_ENUMINPUT: - { - struct v4l2_input *inp = arg; - int status; - - dprintk(3, KERN_DEBUG "%s: VIDIOC_ENUMINPUT - index=%d\n", - ZR_DEVNAME(zr), inp->index); + default: + dprintk(1, + KERN_ERR + "%s: VIDIOC_STREAMON - invalid map mode %d\n", + ZR_DEVNAME(zr), fh->map_mode); + res = -EINVAL; + break; + } +strmon_unlock_and_return: + mutex_unlock(&zr->resource_lock); - if (inp->index < 0 || inp->index >= zr->card.inputs) - return -EINVAL; - else { - int id = inp->index; - memset(inp, 0, sizeof(*inp)); - inp->index = id; - } + return res; +} - strncpy(inp->name, zr->card.input[inp->index].name, - sizeof(inp->name) - 1); - inp->type = V4L2_INPUT_TYPE_CAMERA; - inp->std = V4L2_STD_ALL; +static int zoran_streamoff(struct file *file, void *__fh, enum v4l2_buf_type type) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; + int i, res = 0; - /* Get status of video decoder */ - mutex_lock(&zr->resource_lock); - decoder_command(zr, DECODER_GET_STATUS, &status); - mutex_unlock(&zr->resource_lock); + mutex_lock(&zr->resource_lock); - if (!(status & DECODER_STATUS_GOOD)) { - inp->status |= V4L2_IN_ST_NO_POWER; - inp->status |= V4L2_IN_ST_NO_SIGNAL; + switch (fh->map_mode) { + case ZORAN_MAP_MODE_RAW: /* raw capture */ + if (fh->v4l_buffers.active == ZORAN_FREE && + zr->v4l_buffers.active != ZORAN_FREE) { + res = -EPERM; /* stay off other's settings! */ + goto strmoff_unlock_and_return; } - if (!(status & DECODER_STATUS_COLOR)) - inp->status |= V4L2_IN_ST_NO_COLOR; - - return 0; - } - break; + if (zr->v4l_buffers.active == ZORAN_FREE) + goto strmoff_unlock_and_return; - case VIDIOC_G_INPUT: - { - int *input = arg; + /* unload capture */ + if (zr->v4l_memgrab_active) { + unsigned long flags; - dprintk(3, KERN_DEBUG "%s: VIDIOC_G_INPUT\n", ZR_DEVNAME(zr)); + spin_lock_irqsave(&zr->spinlock, flags); + zr36057_set_memgrab(zr, 0); + spin_unlock_irqrestore(&zr->spinlock, flags); + } - mutex_lock(&zr->resource_lock); - *input = zr->input; - mutex_unlock(&zr->resource_lock); + for (i = 0; i < fh->v4l_buffers.num_buffers; i++) + zr->v4l_buffers.buffer[i].state = BUZ_STATE_USER; + fh->v4l_buffers = zr->v4l_buffers; - return 0; - } - break; + zr->v4l_buffers.active = fh->v4l_buffers.active = ZORAN_FREE; - case VIDIOC_S_INPUT: - { - int *input = arg, res = 0; + zr->v4l_grab_seq = 0; + zr->v4l_pend_head = zr->v4l_pend_tail = 0; + zr->v4l_sync_tail = 0; - dprintk(3, KERN_DEBUG "%s: VIDIOC_S_INPUT - input=%d\n", - ZR_DEVNAME(zr), *input); + break; - mutex_lock(&zr->resource_lock); - if ((res = zoran_set_input(zr, *input))) - goto sinput_unlock_and_return; + case ZORAN_MAP_MODE_JPG_REC: + case ZORAN_MAP_MODE_JPG_PLAY: + if (fh->jpg_buffers.active == ZORAN_FREE && + zr->jpg_buffers.active != ZORAN_FREE) { + res = -EPERM; /* stay off other's settings! */ + goto strmoff_unlock_and_return; + } + if (zr->jpg_buffers.active == ZORAN_FREE) + goto strmoff_unlock_and_return; - /* Make sure the changes come into effect */ - res = wait_grab_pending(zr); - sinput_unlock_and_return: - mutex_unlock(&zr->resource_lock); - return res; - } + res = jpg_qbuf(file, -1, + (fh->map_mode == ZORAN_MAP_MODE_JPG_REC) ? + BUZ_MODE_MOTION_COMPRESS : + BUZ_MODE_MOTION_DECOMPRESS); + if (res) + goto strmoff_unlock_and_return; + break; + default: + dprintk(1, KERN_ERR + "%s: VIDIOC_STREAMOFF - invalid map mode %d\n", + ZR_DEVNAME(zr), fh->map_mode); + res = -EINVAL; break; + } +strmoff_unlock_and_return: + mutex_unlock(&zr->resource_lock); - case VIDIOC_ENUMOUTPUT: - { - struct v4l2_output *outp = arg; + return res; +} - dprintk(3, KERN_DEBUG "%s: VIDIOC_ENUMOUTPUT - index=%d\n", - ZR_DEVNAME(zr), outp->index); +static int zoran_queryctrl(struct file *file, void *__fh, + struct v4l2_queryctrl *ctrl) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; - if (outp->index != 0) - return -EINVAL; + /* we only support hue/saturation/contrast/brightness */ + if (ctrl->id < V4L2_CID_BRIGHTNESS || + ctrl->id > V4L2_CID_HUE) + return -EINVAL; - memset(outp, 0, sizeof(*outp)); - outp->index = 0; - outp->type = V4L2_OUTPUT_TYPE_ANALOGVGAOVERLAY; - strncpy(outp->name, "Autodetect", sizeof(outp->name)-1); + decoder_call(zr, core, queryctrl, ctrl); - return 0; - } - break; + return 0; +} - case VIDIOC_G_OUTPUT: - { - int *output = arg; +static int zoran_g_ctrl(struct file *file, void *__fh, struct v4l2_control *ctrl) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; - dprintk(3, KERN_DEBUG "%s: VIDIOC_G_OUTPUT\n", ZR_DEVNAME(zr)); + /* we only support hue/saturation/contrast/brightness */ + if (ctrl->id < V4L2_CID_BRIGHTNESS || + ctrl->id > V4L2_CID_HUE) + return -EINVAL; - *output = 0; + mutex_lock(&zr->resource_lock); + decoder_call(zr, core, g_ctrl, ctrl); + mutex_unlock(&zr->resource_lock); - return 0; - } - break; + return 0; +} - case VIDIOC_S_OUTPUT: - { - int *output = arg; +static int zoran_s_ctrl(struct file *file, void *__fh, struct v4l2_control *ctrl) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; - dprintk(3, KERN_DEBUG "%s: VIDIOC_S_OUTPUT - output=%d\n", - ZR_DEVNAME(zr), *output); + /* we only support hue/saturation/contrast/brightness */ + if (ctrl->id < V4L2_CID_BRIGHTNESS || + ctrl->id > V4L2_CID_HUE) + return -EINVAL; - if (*output != 0) - return -EINVAL; + mutex_lock(&zr->resource_lock); + decoder_call(zr, core, s_ctrl, ctrl); + mutex_unlock(&zr->resource_lock); - return 0; - } - break; + return 0; +} - /* cropping (sub-frame capture) */ - case VIDIOC_CROPCAP: - { - struct v4l2_cropcap *cropcap = arg; - int type = cropcap->type, res = 0; +static int zoran_g_std(struct file *file, void *__fh, v4l2_std_id *std) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; + + mutex_lock(&zr->resource_lock); + *std = zr->norm; + mutex_unlock(&zr->resource_lock); + return 0; +} - dprintk(3, KERN_ERR "%s: VIDIOC_CROPCAP - type=%d\n", - ZR_DEVNAME(zr), cropcap->type); +static int zoran_s_std(struct file *file, void *__fh, v4l2_std_id *std) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; + int res = 0; - memset(cropcap, 0, sizeof(*cropcap)); - cropcap->type = type; + mutex_lock(&zr->resource_lock); + res = zoran_set_norm(zr, *std); + if (res) + goto sstd_unlock_and_return; - mutex_lock(&zr->resource_lock); + res = wait_grab_pending(zr); +sstd_unlock_and_return: + mutex_unlock(&zr->resource_lock); + return res; +} - if (cropcap->type != V4L2_BUF_TYPE_VIDEO_OUTPUT && - (cropcap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || - fh->map_mode == ZORAN_MAP_MODE_RAW)) { - dprintk(1, - KERN_ERR - "%s: VIDIOC_CROPCAP - subcapture only supported for compressed capture\n", - ZR_DEVNAME(zr)); - res = -EINVAL; - goto cropcap_unlock_and_return; - } +static int zoran_enum_input(struct file *file, void *__fh, + struct v4l2_input *inp) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; - cropcap->bounds.top = cropcap->bounds.left = 0; - cropcap->bounds.width = BUZ_MAX_WIDTH; - cropcap->bounds.height = BUZ_MAX_HEIGHT; - cropcap->defrect.top = cropcap->defrect.left = 0; - cropcap->defrect.width = BUZ_MIN_WIDTH; - cropcap->defrect.height = BUZ_MIN_HEIGHT; - cropcap_unlock_and_return: - mutex_unlock(&zr->resource_lock); - return res; + if (inp->index < 0 || inp->index >= zr->card.inputs) + return -EINVAL; + else { + int id = inp->index; + memset(inp, 0, sizeof(*inp)); + inp->index = id; } - break; - case VIDIOC_G_CROP: - { - struct v4l2_crop *crop = arg; - int type = crop->type, res = 0; + strncpy(inp->name, zr->card.input[inp->index].name, + sizeof(inp->name) - 1); + inp->type = V4L2_INPUT_TYPE_CAMERA; + inp->std = V4L2_STD_ALL; - dprintk(3, KERN_ERR "%s: VIDIOC_G_CROP - type=%d\n", - ZR_DEVNAME(zr), crop->type); - - memset(crop, 0, sizeof(*crop)); - crop->type = type; + /* Get status of video decoder */ + mutex_lock(&zr->resource_lock); + decoder_call(zr, video, g_input_status, &inp->status); + mutex_unlock(&zr->resource_lock); + return 0; +} - mutex_lock(&zr->resource_lock); +static int zoran_g_input(struct file *file, void *__fh, unsigned int *input) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; - if (crop->type != V4L2_BUF_TYPE_VIDEO_OUTPUT && - (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || - fh->map_mode == ZORAN_MAP_MODE_RAW)) { - dprintk(1, - KERN_ERR - "%s: VIDIOC_G_CROP - subcapture only supported for compressed capture\n", - ZR_DEVNAME(zr)); - res = -EINVAL; - goto gcrop_unlock_and_return; - } + mutex_lock(&zr->resource_lock); + *input = zr->input; + mutex_unlock(&zr->resource_lock); - crop->c.top = fh->jpg_settings.img_y; - crop->c.left = fh->jpg_settings.img_x; - crop->c.width = fh->jpg_settings.img_width; - crop->c.height = fh->jpg_settings.img_height; + return 0; +} - gcrop_unlock_and_return: - mutex_unlock(&zr->resource_lock); +static int zoran_s_input(struct file *file, void *__fh, unsigned int input) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; + int res; - return res; - } - break; + mutex_lock(&zr->resource_lock); + res = zoran_set_input(zr, input); + if (res) + goto sinput_unlock_and_return; - case VIDIOC_S_CROP: - { - struct v4l2_crop *crop = arg; - int res = 0; + /* Make sure the changes come into effect */ + res = wait_grab_pending(zr); +sinput_unlock_and_return: + mutex_unlock(&zr->resource_lock); + return res; +} - settings = fh->jpg_settings; +static int zoran_enum_output(struct file *file, void *__fh, + struct v4l2_output *outp) +{ + if (outp->index != 0) + return -EINVAL; - dprintk(3, - KERN_ERR - "%s: VIDIOC_S_CROP - type=%d, x=%d,y=%d,w=%d,h=%d\n", - ZR_DEVNAME(zr), crop->type, crop->c.left, crop->c.top, - crop->c.width, crop->c.height); + memset(outp, 0, sizeof(*outp)); + outp->index = 0; + outp->type = V4L2_OUTPUT_TYPE_ANALOGVGAOVERLAY; + strncpy(outp->name, "Autodetect", sizeof(outp->name)-1); - mutex_lock(&zr->resource_lock); + return 0; +} - if (fh->jpg_buffers.allocated || fh->v4l_buffers.allocated) { - dprintk(1, - KERN_ERR - "%s: VIDIOC_S_CROP - cannot change settings while active\n", - ZR_DEVNAME(zr)); - res = -EBUSY; - goto scrop_unlock_and_return; - } +static int zoran_g_output(struct file *file, void *__fh, unsigned int *output) +{ + *output = 0; - if (crop->type != V4L2_BUF_TYPE_VIDEO_OUTPUT && - (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || - fh->map_mode == ZORAN_MAP_MODE_RAW)) { - dprintk(1, - KERN_ERR - "%s: VIDIOC_G_CROP - subcapture only supported for compressed capture\n", - ZR_DEVNAME(zr)); - res = -EINVAL; - goto scrop_unlock_and_return; - } + return 0; +} - /* move into a form that we understand */ - settings.img_x = crop->c.left; - settings.img_y = crop->c.top; - settings.img_width = crop->c.width; - settings.img_height = crop->c.height; +static int zoran_s_output(struct file *file, void *__fh, unsigned int output) +{ + if (output != 0) + return -EINVAL; - /* check validity */ - if ((res = zoran_check_jpg_settings(zr, &settings))) - goto scrop_unlock_and_return; + return 0; +} - /* accept */ - fh->jpg_settings = settings; +/* cropping (sub-frame capture) */ +static int zoran_cropcap(struct file *file, void *__fh, + struct v4l2_cropcap *cropcap) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; + int type = cropcap->type, res = 0; - scrop_unlock_and_return: - mutex_unlock(&zr->resource_lock); - return res; - } - break; + memset(cropcap, 0, sizeof(*cropcap)); + cropcap->type = type; - case VIDIOC_G_JPEGCOMP: - { - struct v4l2_jpegcompression *params = arg; + mutex_lock(&zr->resource_lock); - dprintk(3, KERN_DEBUG "%s: VIDIOC_G_JPEGCOMP\n", + if (cropcap->type != V4L2_BUF_TYPE_VIDEO_OUTPUT && + (cropcap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || + fh->map_mode == ZORAN_MAP_MODE_RAW)) { + dprintk(1, KERN_ERR + "%s: VIDIOC_CROPCAP - subcapture only supported for compressed capture\n", ZR_DEVNAME(zr)); + res = -EINVAL; + goto cropcap_unlock_and_return; + } - memset(params, 0, sizeof(*params)); + cropcap->bounds.top = cropcap->bounds.left = 0; + cropcap->bounds.width = BUZ_MAX_WIDTH; + cropcap->bounds.height = BUZ_MAX_HEIGHT; + cropcap->defrect.top = cropcap->defrect.left = 0; + cropcap->defrect.width = BUZ_MIN_WIDTH; + cropcap->defrect.height = BUZ_MIN_HEIGHT; +cropcap_unlock_and_return: + mutex_unlock(&zr->resource_lock); + return res; +} - mutex_lock(&zr->resource_lock); +static int zoran_g_crop(struct file *file, void *__fh, struct v4l2_crop *crop) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; + int type = crop->type, res = 0; - params->quality = fh->jpg_settings.jpg_comp.quality; - params->APPn = fh->jpg_settings.jpg_comp.APPn; - memcpy(params->APP_data, - fh->jpg_settings.jpg_comp.APP_data, - fh->jpg_settings.jpg_comp.APP_len); - params->APP_len = fh->jpg_settings.jpg_comp.APP_len; - memcpy(params->COM_data, - fh->jpg_settings.jpg_comp.COM_data, - fh->jpg_settings.jpg_comp.COM_len); - params->COM_len = fh->jpg_settings.jpg_comp.COM_len; - params->jpeg_markers = - fh->jpg_settings.jpg_comp.jpeg_markers; + memset(crop, 0, sizeof(*crop)); + crop->type = type; - mutex_unlock(&zr->resource_lock); + mutex_lock(&zr->resource_lock); - return 0; + if (crop->type != V4L2_BUF_TYPE_VIDEO_OUTPUT && + (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || + fh->map_mode == ZORAN_MAP_MODE_RAW)) { + dprintk(1, + KERN_ERR + "%s: VIDIOC_G_CROP - subcapture only supported for compressed capture\n", + ZR_DEVNAME(zr)); + res = -EINVAL; + goto gcrop_unlock_and_return; } - break; - case VIDIOC_S_JPEGCOMP: - { - struct v4l2_jpegcompression *params = arg; - int res = 0; - - settings = fh->jpg_settings; + crop->c.top = fh->jpg_settings.img_y; + crop->c.left = fh->jpg_settings.img_x; + crop->c.width = fh->jpg_settings.img_width; + crop->c.height = fh->jpg_settings.img_height; - dprintk(3, - KERN_DEBUG - "%s: VIDIOC_S_JPEGCOMP - quality=%d, APPN=%d, APP_len=%d, COM_len=%d\n", - ZR_DEVNAME(zr), params->quality, params->APPn, - params->APP_len, params->COM_len); +gcrop_unlock_and_return: + mutex_unlock(&zr->resource_lock); - settings.jpg_comp = *params; + return res; +} - mutex_lock(&zr->resource_lock); +static int zoran_s_crop(struct file *file, void *__fh, struct v4l2_crop *crop) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; + int res = 0; + struct zoran_jpg_settings settings; - if (fh->v4l_buffers.active != ZORAN_FREE || - fh->jpg_buffers.active != ZORAN_FREE) { - dprintk(1, - KERN_WARNING - "%s: VIDIOC_S_JPEGCOMP called while in playback/capture mode\n", - ZR_DEVNAME(zr)); - res = -EBUSY; - goto sjpegc_unlock_and_return; - } + settings = fh->jpg_settings; - if ((res = zoran_check_jpg_settings(zr, &settings))) - goto sjpegc_unlock_and_return; - if (!fh->jpg_buffers.allocated) - fh->jpg_buffers.buffer_size = - zoran_v4l2_calc_bufsize(&fh->jpg_settings); - fh->jpg_settings.jpg_comp = *params = settings.jpg_comp; - sjpegc_unlock_and_return: - mutex_unlock(&zr->resource_lock); + mutex_lock(&zr->resource_lock); - return 0; + if (fh->jpg_buffers.allocated || fh->v4l_buffers.allocated) { + dprintk(1, KERN_ERR + "%s: VIDIOC_S_CROP - cannot change settings while active\n", + ZR_DEVNAME(zr)); + res = -EBUSY; + goto scrop_unlock_and_return; } - break; - case VIDIOC_QUERYSTD: /* why is this useful? */ - { - v4l2_std_id *std = arg; - - dprintk(3, - KERN_DEBUG "%s: VIDIOC_QUERY_STD - std=0x%llx\n", - ZR_DEVNAME(zr), (unsigned long long)*std); - - if (*std == V4L2_STD_ALL || *std == V4L2_STD_NTSC || - *std == V4L2_STD_PAL || (*std == V4L2_STD_SECAM && - zr->card.norms == 3)) { - return 0; - } - - return -EINVAL; + if (crop->type != V4L2_BUF_TYPE_VIDEO_OUTPUT && + (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || + fh->map_mode == ZORAN_MAP_MODE_RAW)) { + dprintk(1, KERN_ERR + "%s: VIDIOC_G_CROP - subcapture only supported for compressed capture\n", + ZR_DEVNAME(zr)); + res = -EINVAL; + goto scrop_unlock_and_return; } - break; - case VIDIOC_TRY_FMT: - { - struct v4l2_format *fmt = arg; - int res = 0; + /* move into a form that we understand */ + settings.img_x = crop->c.left; + settings.img_y = crop->c.top; + settings.img_width = crop->c.width; + settings.img_height = crop->c.height; - dprintk(3, KERN_DEBUG "%s: VIDIOC_TRY_FMT - type=%d\n", - ZR_DEVNAME(zr), fmt->type); + /* check validity */ + res = zoran_check_jpg_settings(zr, &settings, 0); + if (res) + goto scrop_unlock_and_return; - switch (fmt->type) { - case V4L2_BUF_TYPE_VIDEO_OVERLAY: - mutex_lock(&zr->resource_lock); + /* accept */ + fh->jpg_settings = settings; - if (fmt->fmt.win.w.width > BUZ_MAX_WIDTH) - fmt->fmt.win.w.width = BUZ_MAX_WIDTH; - if (fmt->fmt.win.w.width < BUZ_MIN_WIDTH) - fmt->fmt.win.w.width = BUZ_MIN_WIDTH; - if (fmt->fmt.win.w.height > BUZ_MAX_HEIGHT) - fmt->fmt.win.w.height = BUZ_MAX_HEIGHT; - if (fmt->fmt.win.w.height < BUZ_MIN_HEIGHT) - fmt->fmt.win.w.height = BUZ_MIN_HEIGHT; +scrop_unlock_and_return: + mutex_unlock(&zr->resource_lock); + return res; +} - mutex_unlock(&zr->resource_lock); - break; +static int zoran_g_jpegcomp(struct file *file, void *__fh, + struct v4l2_jpegcompression *params) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; + memset(params, 0, sizeof(*params)); - case V4L2_BUF_TYPE_VIDEO_CAPTURE: - case V4L2_BUF_TYPE_VIDEO_OUTPUT: - if (fmt->fmt.pix.bytesperline > 0) - return -EINVAL; + mutex_lock(&zr->resource_lock); - mutex_lock(&zr->resource_lock); - - if (fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_MJPEG) { - settings = fh->jpg_settings; - - /* we actually need to set 'real' parameters now */ - if ((fmt->fmt.pix.height * 2) > - BUZ_MAX_HEIGHT) - settings.TmpDcm = 1; - else - settings.TmpDcm = 2; - settings.decimation = 0; - if (fmt->fmt.pix.height <= - fh->jpg_settings.img_height / 2) - settings.VerDcm = 2; - else - settings.VerDcm = 1; - if (fmt->fmt.pix.width <= - fh->jpg_settings.img_width / 4) - settings.HorDcm = 4; - else if (fmt->fmt.pix.width <= - fh->jpg_settings.img_width / 2) - settings.HorDcm = 2; - else - settings.HorDcm = 1; - if (settings.TmpDcm == 1) - settings.field_per_buff = 2; - else - settings.field_per_buff = 1; - - /* check */ - if ((res = - zoran_check_jpg_settings(zr, - &settings))) - goto tryfmt_unlock_and_return; - - /* tell the user what we actually did */ - fmt->fmt.pix.width = - settings.img_width / settings.HorDcm; - fmt->fmt.pix.height = - settings.img_height * 2 / - (settings.TmpDcm * settings.VerDcm); - if (settings.TmpDcm == 1) - fmt->fmt.pix.field = - (fh->jpg_settings. - odd_even ? V4L2_FIELD_SEQ_TB : - V4L2_FIELD_SEQ_BT); - else - fmt->fmt.pix.field = - (fh->jpg_settings. - odd_even ? V4L2_FIELD_TOP : - V4L2_FIELD_BOTTOM); - - fmt->fmt.pix.sizeimage = - zoran_v4l2_calc_bufsize(&settings); - } else if (fmt->type == - V4L2_BUF_TYPE_VIDEO_CAPTURE) { - int i; - - for (i = 0; i < NUM_FORMATS; i++) - if (zoran_formats[i].fourcc == - fmt->fmt.pix.pixelformat) - break; - if (i == NUM_FORMATS) { - res = -EINVAL; - goto tryfmt_unlock_and_return; - } + params->quality = fh->jpg_settings.jpg_comp.quality; + params->APPn = fh->jpg_settings.jpg_comp.APPn; + memcpy(params->APP_data, + fh->jpg_settings.jpg_comp.APP_data, + fh->jpg_settings.jpg_comp.APP_len); + params->APP_len = fh->jpg_settings.jpg_comp.APP_len; + memcpy(params->COM_data, + fh->jpg_settings.jpg_comp.COM_data, + fh->jpg_settings.jpg_comp.COM_len); + params->COM_len = fh->jpg_settings.jpg_comp.COM_len; + params->jpeg_markers = + fh->jpg_settings.jpg_comp.jpeg_markers; - if (fmt->fmt.pix.width > BUZ_MAX_WIDTH) - fmt->fmt.pix.width = BUZ_MAX_WIDTH; - if (fmt->fmt.pix.width < BUZ_MIN_WIDTH) - fmt->fmt.pix.width = BUZ_MIN_WIDTH; - if (fmt->fmt.pix.height > BUZ_MAX_HEIGHT) - fmt->fmt.pix.height = - BUZ_MAX_HEIGHT; - if (fmt->fmt.pix.height < BUZ_MIN_HEIGHT) - fmt->fmt.pix.height = - BUZ_MIN_HEIGHT; - } else { - res = -EINVAL; - goto tryfmt_unlock_and_return; - } - tryfmt_unlock_and_return: - mutex_unlock(&zr->resource_lock); + mutex_unlock(&zr->resource_lock); - return res; - break; + return 0; +} - default: - return -EINVAL; - } +static int zoran_s_jpegcomp(struct file *file, void *__fh, + struct v4l2_jpegcompression *params) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; + int res = 0; + struct zoran_jpg_settings settings; - return 0; - } - break; + settings = fh->jpg_settings; - default: - dprintk(1, KERN_DEBUG "%s: UNKNOWN ioctl cmd: 0x%x\n", - ZR_DEVNAME(zr), cmd); - return -ENOIOCTLCMD; - break; + settings.jpg_comp = *params; + mutex_lock(&zr->resource_lock); + + if (fh->v4l_buffers.active != ZORAN_FREE || + fh->jpg_buffers.active != ZORAN_FREE) { + dprintk(1, KERN_WARNING + "%s: VIDIOC_S_JPEGCOMP called while in playback/capture mode\n", + ZR_DEVNAME(zr)); + res = -EBUSY; + goto sjpegc_unlock_and_return; } - return 0; -} + res = zoran_check_jpg_settings(zr, &settings, 0); + if (res) + goto sjpegc_unlock_and_return; + if (!fh->jpg_buffers.allocated) + fh->jpg_buffers.buffer_size = + zoran_v4l2_calc_bufsize(&fh->jpg_settings); + fh->jpg_settings.jpg_comp = *params = settings.jpg_comp; +sjpegc_unlock_and_return: + mutex_unlock(&zr->resource_lock); -static long -zoran_ioctl(struct file *file, - unsigned int cmd, - unsigned long arg) -{ - return video_usercopy(file, cmd, arg, zoran_do_ioctl); + return res; } static unsigned int @@ -4365,10 +3261,7 @@ zoran_vm_close (struct vm_area_struct *vma) fh->jpg_buffers.active = ZORAN_FREE; } - //jpg_fbuffer_free(file); - fh->jpg_buffers.allocated = 0; - fh->jpg_buffers.ready_to_be_freed = 1; - + jpg_fbuffer_free(file); mutex_unlock(&zr->resource_lock); } @@ -4405,10 +3298,7 @@ zoran_vm_close (struct vm_area_struct *vma) ZORAN_FREE; spin_unlock_irqrestore(&zr->spinlock, flags); } - //v4l_fbuffer_free(file); - fh->v4l_buffers.allocated = 0; - fh->v4l_buffers.ready_to_be_freed = 1; - + v4l_fbuffer_free(file); mutex_unlock(&zr->resource_lock); } @@ -4647,11 +3537,56 @@ zoran_mmap (struct file *file, return 0; } +static const struct v4l2_ioctl_ops zoran_ioctl_ops = { + .vidioc_querycap = zoran_querycap, + .vidioc_cropcap = zoran_cropcap, + .vidioc_s_crop = zoran_s_crop, + .vidioc_g_crop = zoran_g_crop, + .vidioc_enum_input = zoran_enum_input, + .vidioc_g_input = zoran_g_input, + .vidioc_s_input = zoran_s_input, + .vidioc_enum_output = zoran_enum_output, + .vidioc_g_output = zoran_g_output, + .vidioc_s_output = zoran_s_output, + .vidioc_g_fbuf = zoran_g_fbuf, + .vidioc_s_fbuf = zoran_s_fbuf, + .vidioc_g_std = zoran_g_std, + .vidioc_s_std = zoran_s_std, + .vidioc_g_jpegcomp = zoran_g_jpegcomp, + .vidioc_s_jpegcomp = zoran_s_jpegcomp, + .vidioc_overlay = zoran_overlay, + .vidioc_reqbufs = zoran_reqbufs, + .vidioc_querybuf = zoran_querybuf, + .vidioc_qbuf = zoran_qbuf, + .vidioc_dqbuf = zoran_dqbuf, + .vidioc_streamon = zoran_streamon, + .vidioc_streamoff = zoran_streamoff, + .vidioc_enum_fmt_vid_cap = zoran_enum_fmt_vid_cap, + .vidioc_enum_fmt_vid_out = zoran_enum_fmt_vid_out, + .vidioc_enum_fmt_vid_overlay = zoran_enum_fmt_vid_overlay, + .vidioc_g_fmt_vid_cap = zoran_g_fmt_vid_cap, + .vidioc_g_fmt_vid_out = zoran_g_fmt_vid_out, + .vidioc_g_fmt_vid_overlay = zoran_g_fmt_vid_overlay, + .vidioc_s_fmt_vid_cap = zoran_s_fmt_vid_cap, + .vidioc_s_fmt_vid_out = zoran_s_fmt_vid_out, + .vidioc_s_fmt_vid_overlay = zoran_s_fmt_vid_overlay, + .vidioc_try_fmt_vid_cap = zoran_try_fmt_vid_cap, + .vidioc_try_fmt_vid_out = zoran_try_fmt_vid_out, + .vidioc_try_fmt_vid_overlay = zoran_try_fmt_vid_overlay, + .vidioc_queryctrl = zoran_queryctrl, + .vidioc_s_ctrl = zoran_s_ctrl, + .vidioc_g_ctrl = zoran_g_ctrl, +#ifdef CONFIG_VIDEO_V4L1_COMPAT + .vidioc_default = zoran_default, + .vidiocgmbuf = zoran_vidiocgmbuf, +#endif +}; + static const struct v4l2_file_operations zoran_fops = { .owner = THIS_MODULE, .open = zoran_open, .release = zoran_close, - .ioctl = zoran_ioctl, + .ioctl = video_ioctl2, .read = zoran_read, .write = zoran_write, .mmap = zoran_mmap, @@ -4661,7 +3596,9 @@ static const struct v4l2_file_operations zoran_fops = { struct video_device zoran_template __devinitdata = { .name = ZORAN_NAME, .fops = &zoran_fops, + .ioctl_ops = &zoran_ioctl_ops, .release = &zoran_vdev_release, + .tvnorms = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM, .minor = -1 }; diff --git a/linux/drivers/media/video/zoran/zoran_procfs.c b/linux/drivers/media/video/zoran/zoran_procfs.c index 961950a21..89c49a5cf 100644 --- a/linux/drivers/media/video/zoran/zoran_procfs.c +++ b/linux/drivers/media/video/zoran/zoran_procfs.c @@ -37,7 +37,7 @@ #include <linux/i2c.h> #include <linux/i2c-algo-bit.h> #include "compat.h" -#include <linux/videodev.h> +#include <linux/videodev2.h> #include <linux/spinlock.h> #include <linux/sem.h> #include <linux/seq_file.h> diff --git a/linux/drivers/media/video/zoran/zr36016.c b/linux/drivers/media/video/zoran/zr36016.c index 693a648e9..7d8d5b195 100644 --- a/linux/drivers/media/video/zoran/zr36016.c +++ b/linux/drivers/media/video/zoran/zr36016.c @@ -34,16 +34,11 @@ #include <linux/types.h> #include <linux/wait.h> -/* includes for structures and defines regarding video - #include<linux/videodev.h> */ - /* I/O commands, error codes */ #include <asm/io.h> -//#include<errno.h> /* v4l API */ #include "compat.h" -#include <linux/videodev.h> /* headerfile of this module */ #include"zr36016.h" diff --git a/linux/drivers/media/video/zoran/zr36050.c b/linux/drivers/media/video/zoran/zr36050.c index cf8b271a1..639dd87c6 100644 --- a/linux/drivers/media/video/zoran/zr36050.c +++ b/linux/drivers/media/video/zoran/zr36050.c @@ -34,12 +34,8 @@ #include <linux/types.h> #include <linux/wait.h> -/* includes for structures and defines regarding video - #include<linux/videodev.h> */ - /* I/O commands, error codes */ #include <asm/io.h> -//#include<errno.h> /* headerfile of this module */ #include "zr36050.h" diff --git a/linux/drivers/media/video/zoran/zr36060.c b/linux/drivers/media/video/zoran/zr36060.c index 8e74054d5..008746ff7 100644 --- a/linux/drivers/media/video/zoran/zr36060.c +++ b/linux/drivers/media/video/zoran/zr36060.c @@ -34,12 +34,8 @@ #include <linux/types.h> #include <linux/wait.h> -/* includes for structures and defines regarding video - #include<linux/videodev.h> */ - /* I/O commands, error codes */ #include <asm/io.h> -//#include<errno.h> /* headerfile of this module */ #include "zr36060.h" |