Commit 9ee6d78c authored by Luc Saillard's avatar Luc Saillard Committed by Mauro Carvalho Chehab

V4L/DVB (5547): Add ENUM_FRAMESIZES and ENUM_FRAMEINTERVALS ioctls

This patch add support for the VIDIOC_ENUM_FRAMESIZES and
VIDIOC_ENUM_FRAMEINTERVALS ioctl.
* check if the maximum native framesize for raw mode is correct
* raw mode framerates for all three chipset types
Signed-off-by: default avatarGregor Jasny <gjasny@web.de>
Signed-off-by: default avatarLuc Saillard <luc@saillard.org>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@infradead.org>
parent 1de69238
...@@ -140,6 +140,8 @@ static const char *size2name[PSZ_MAX] = ...@@ -140,6 +140,8 @@ static const char *size2name[PSZ_MAX] =
An alternate value of 0 means this mode is not available at all. An alternate value of 0 means this mode is not available at all.
*/ */
#define PWC_FPS_MAX_NALA 8
struct Nala_table_entry { struct Nala_table_entry {
char alternate; /* USB alternate setting */ char alternate; /* USB alternate setting */
int compressed; /* Compressed yes/no */ int compressed; /* Compressed yes/no */
...@@ -147,7 +149,9 @@ struct Nala_table_entry { ...@@ -147,7 +149,9 @@ struct Nala_table_entry {
unsigned char mode[3]; /* precomputed mode table */ unsigned char mode[3]; /* precomputed mode table */
}; };
static struct Nala_table_entry Nala_table[PSZ_MAX][8] = static unsigned int Nala_fps_vector[PWC_FPS_MAX_NALA] = { 4, 5, 7, 10, 12, 15, 20, 24 };
static struct Nala_table_entry Nala_table[PSZ_MAX][PWC_FPS_MAX_NALA] =
{ {
#include "pwc-nala.h" #include "pwc-nala.h"
}; };
...@@ -423,6 +427,59 @@ int pwc_set_video_mode(struct pwc_device *pdev, int width, int height, int frame ...@@ -423,6 +427,59 @@ int pwc_set_video_mode(struct pwc_device *pdev, int width, int height, int frame
return 0; return 0;
} }
static unsigned int pwc_get_fps_Nala(struct pwc_device *pdev, unsigned int index, unsigned int size)
{
unsigned int i;
for (i = 0; i < PWC_FPS_MAX_NALA; i++) {
if (Nala_table[size][i].alternate) {
if (index--==0) return Nala_fps_vector[i];
}
}
return 0;
}
static unsigned int pwc_get_fps_Kiara(struct pwc_device *pdev, unsigned int index, unsigned int size)
{
unsigned int i;
for (i = 0; i < PWC_FPS_MAX_KIARA; i++) {
if (Kiara_table[size][i][3].alternate) {
if (index--==0) return Kiara_fps_vector[i];
}
}
return 0;
}
static unsigned int pwc_get_fps_Timon(struct pwc_device *pdev, unsigned int index, unsigned int size)
{
unsigned int i;
for (i=0; i < PWC_FPS_MAX_TIMON; i++) {
if (Timon_table[size][i][3].alternate) {
if (index--==0) return Timon_fps_vector[i];
}
}
return 0;
}
unsigned int pwc_get_fps(struct pwc_device *pdev, unsigned int index, unsigned int size)
{
unsigned int ret;
if (DEVICE_USE_CODEC1(pdev->type)) {
ret = pwc_get_fps_Nala(pdev, index, size);
} else if (DEVICE_USE_CODEC3(pdev->type)) {
ret = pwc_get_fps_Kiara(pdev, index, size);
} else {
ret = pwc_get_fps_Timon(pdev, index, size);
}
return ret;
}
#define BLACK_Y 0 #define BLACK_Y 0
#define BLACK_U 128 #define BLACK_U 128
#define BLACK_V 128 #define BLACK_V 128
...@@ -1343,7 +1400,7 @@ int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg) ...@@ -1343,7 +1400,7 @@ int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg)
ret = pwc_read_red_gain(pdev, &ARGR(wb).read_red); ret = pwc_read_red_gain(pdev, &ARGR(wb).read_red);
if (ret < 0) if (ret < 0)
break; break;
ret =pwc_read_blue_gain(pdev, &ARGR(wb).read_blue); ret = pwc_read_blue_gain(pdev, &ARGR(wb).read_blue);
if (ret < 0) if (ret < 0)
break; break;
} }
......
...@@ -1493,7 +1493,7 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id ...@@ -1493,7 +1493,7 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
case 0x0329: case 0x0329:
PWC_INFO("Philips SPC 900NC USB webcam detected.\n"); PWC_INFO("Philips SPC 900NC USB webcam detected.\n");
name = "Philips SPC 900NC webcam"; name = "Philips SPC 900NC webcam";
type_id = 720; type_id = 740;
break; break;
default: default:
return -ENODEV; return -ENODEV;
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
#define PWC_IOCTL_H #define PWC_IOCTL_H
/* (C) 2001-2004 Nemosoft Unv. /* (C) 2001-2004 Nemosoft Unv.
(C) 2004 Luc Saillard (luc@saillard.org) (C) 2004-2006 Luc Saillard (luc@saillard.org)
NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
driver and thus may have bugs that are not present in the original version. driver and thus may have bugs that are not present in the original version.
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/ */
/* This is pwc-ioctl.h belonging to PWC 8.12.1 /* This is pwc-ioctl.h belonging to PWC 10.0.10
It contains structures and defines to communicate from user space It contains structures and defines to communicate from user space
directly to the driver. directly to the driver.
*/ */
...@@ -51,6 +51,9 @@ ...@@ -51,6 +51,9 @@
... the function ... the function
*/ */
#include <linux/types.h>
#include <linux/version.h>
/* Enumeration of image sizes */ /* Enumeration of image sizes */
#define PSZ_SQCIF 0x00 #define PSZ_SQCIF 0x00
...@@ -65,6 +68,8 @@ ...@@ -65,6 +68,8 @@
/* The frame rate is encoded in the video_window.flags parameter using /* The frame rate is encoded in the video_window.flags parameter using
the upper 16 bits, since some flags are defined nowadays. The following the upper 16 bits, since some flags are defined nowadays. The following
defines provide a mask and shift to filter out this value. defines provide a mask and shift to filter out this value.
This value can also be passing using the private flag when using v4l2 and
VIDIOC_S_FMT ioctl.
In 'Snapshot' mode the camera freezes its automatic exposure and colour In 'Snapshot' mode the camera freezes its automatic exposure and colour
balance controls. balance controls.
...@@ -73,6 +78,8 @@ ...@@ -73,6 +78,8 @@
#define PWC_FPS_MASK 0x00FF0000 #define PWC_FPS_MASK 0x00FF0000
#define PWC_FPS_FRMASK 0x003F0000 #define PWC_FPS_FRMASK 0x003F0000
#define PWC_FPS_SNAPSHOT 0x00400000 #define PWC_FPS_SNAPSHOT 0x00400000
#define PWC_QLT_MASK 0x03000000
#define PWC_QLT_SHIFT 24
/* structure for transferring x & y coordinates */ /* structure for transferring x & y coordinates */
...@@ -289,4 +296,29 @@ struct pwc_table_init_buffer { ...@@ -289,4 +296,29 @@ struct pwc_table_init_buffer {
}; };
#define VIDIOCPWCGVIDTABLE _IOR('v', 216, struct pwc_table_init_buffer) #define VIDIOCPWCGVIDTABLE _IOR('v', 216, struct pwc_table_init_buffer)
/*
* This is private command used when communicating with v4l2.
* In the future all private ioctl will be remove/replace to
* use interface offer by v4l2.
*/
#define V4L2_CID_PRIVATE_SAVE_USER (V4L2_CID_PRIVATE_BASE + 0)
#define V4L2_CID_PRIVATE_RESTORE_USER (V4L2_CID_PRIVATE_BASE + 1)
#define V4L2_CID_PRIVATE_RESTORE_FACTORY (V4L2_CID_PRIVATE_BASE + 2)
#define V4L2_CID_PRIVATE_COLOUR_MODE (V4L2_CID_PRIVATE_BASE + 3)
#define V4L2_CID_PRIVATE_AUTOCONTOUR (V4L2_CID_PRIVATE_BASE + 4)
#define V4L2_CID_PRIVATE_CONTOUR (V4L2_CID_PRIVATE_BASE + 5)
#define V4L2_CID_PRIVATE_BACKLIGHT (V4L2_CID_PRIVATE_BASE + 6)
#define V4L2_CID_PRIVATE_FLICKERLESS (V4L2_CID_PRIVATE_BASE + 7)
#define V4L2_CID_PRIVATE_NOISE_REDUCTION (V4L2_CID_PRIVATE_BASE + 8)
struct pwc_raw_frame {
__le16 type; /* type of the webcam */
__le16 vbandlength; /* Size of 4lines compressed (used by the decompressor) */
__u8 cmd[4]; /* the four byte of the command (in case of nala,
only the first 3 bytes is filled) */
__u8 rawframe[0]; /* frame_size = H/4*vbandlength */
} __attribute__ ((packed));
#endif #endif
...@@ -42,6 +42,8 @@ ...@@ -42,6 +42,8 @@
#include "pwc-kiara.h" #include "pwc-kiara.h"
#include "pwc-uncompress.h" #include "pwc-uncompress.h"
const unsigned int Kiara_fps_vector[PWC_FPS_MAX_KIARA] = { 5, 10, 15, 20, 25, 30 };
const struct Kiara_table_entry Kiara_table[PSZ_MAX][6][4] = const struct Kiara_table_entry Kiara_table[PSZ_MAX][6][4] =
{ {
/* SQCIF */ /* SQCIF */
......
...@@ -29,6 +29,8 @@ ...@@ -29,6 +29,8 @@
#include <media/pwc-ioctl.h> #include <media/pwc-ioctl.h>
#define PWC_FPS_MAX_KIARA 6
struct Kiara_table_entry struct Kiara_table_entry
{ {
char alternate; /* USB alternate interface */ char alternate; /* USB alternate interface */
...@@ -37,8 +39,9 @@ struct Kiara_table_entry ...@@ -37,8 +39,9 @@ struct Kiara_table_entry
unsigned char mode[12]; /* precomputed mode settings for cam */ unsigned char mode[12]; /* precomputed mode settings for cam */
}; };
extern const struct Kiara_table_entry Kiara_table[PSZ_MAX][6][4]; extern const struct Kiara_table_entry Kiara_table[PSZ_MAX][PWC_FPS_MAX_KIARA][4];
extern const unsigned int KiaraRomTable[8][2][16][8]; extern const unsigned int KiaraRomTable[8][2][16][8];
extern const unsigned int Kiara_fps_vector[PWC_FPS_MAX_KIARA];
#endif #endif
......
...@@ -40,7 +40,9 @@ ...@@ -40,7 +40,9 @@
#include "pwc-timon.h" #include "pwc-timon.h"
const struct Timon_table_entry Timon_table[PSZ_MAX][6][4] = const unsigned int Timon_fps_vector[PWC_FPS_MAX_TIMON] = { 5, 10, 15, 20, 25, 30 };
const struct Timon_table_entry Timon_table[PSZ_MAX][PWC_FPS_MAX_TIMON][4] =
{ {
/* SQCIF */ /* SQCIF */
{ {
......
...@@ -44,6 +44,8 @@ ...@@ -44,6 +44,8 @@
#include <media/pwc-ioctl.h> #include <media/pwc-ioctl.h>
#define PWC_FPS_MAX_TIMON 6
struct Timon_table_entry struct Timon_table_entry
{ {
char alternate; /* USB alternate interface */ char alternate; /* USB alternate interface */
...@@ -52,9 +54,9 @@ struct Timon_table_entry ...@@ -52,9 +54,9 @@ struct Timon_table_entry
unsigned char mode[13]; /* precomputed mode settings for cam */ unsigned char mode[13]; /* precomputed mode settings for cam */
}; };
extern const struct Timon_table_entry Timon_table[PSZ_MAX][6][4]; extern const struct Timon_table_entry Timon_table[PSZ_MAX][PWC_FPS_MAX_TIMON][4];
extern const unsigned int TimonRomTable [16][2][16][8]; extern const unsigned int TimonRomTable [16][2][16][8];
extern const unsigned int Timon_fps_vector[PWC_FPS_MAX_TIMON];
#endif #endif
......
...@@ -1193,6 +1193,64 @@ int pwc_video_do_ioctl(struct inode *inode, struct file *file, ...@@ -1193,6 +1193,64 @@ int pwc_video_do_ioctl(struct inode *inode, struct file *file,
return 0; return 0;
} }
case VIDIOC_ENUM_FRAMESIZES:
{
struct v4l2_frmsizeenum *fsize = arg;
unsigned int i = 0, index = fsize->index;
if (fsize->pixel_format == V4L2_PIX_FMT_YUV420) {
for (i = 0; i < PSZ_MAX; i++) {
if (pdev->image_mask & (1UL << i)) {
if (!index--) {
fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
fsize->discrete.width = pwc_image_sizes[i].x;
fsize->discrete.height = pwc_image_sizes[i].y;
return 0;
}
}
}
} else if (fsize->index == 0 &&
((fsize->pixel_format == V4L2_PIX_FMT_PWC1 && DEVICE_USE_CODEC1(pdev->type)) ||
(fsize->pixel_format == V4L2_PIX_FMT_PWC2 && DEVICE_USE_CODEC23(pdev->type)))) {
fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
fsize->discrete.width = pdev->abs_max.x;
fsize->discrete.height = pdev->abs_max.y;
return 0;
}
return -EINVAL;
}
case VIDIOC_ENUM_FRAMEINTERVALS:
{
struct v4l2_frmivalenum *fival = arg;
int size = -1;
unsigned int i;
for (i = 0; i < PSZ_MAX; i++) {
if (pwc_image_sizes[i].x == fival->width &&
pwc_image_sizes[i].y == fival->height) {
size = i;
break;
}
}
/* TODO: Support raw format */
if (size < 0 || fival->pixel_format != V4L2_PIX_FMT_YUV420) {
return -EINVAL;
}
i = pwc_get_fps(pdev, fival->index, size);
if (!i)
return -EINVAL;
fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
fival->discrete.numerator = 1;
fival->discrete.denominator = i;
return 0;
}
default: default:
return pwc_ioctl(pdev, cmd, arg); return pwc_ioctl(pdev, cmd, arg);
} /* ..switch */ } /* ..switch */
......
...@@ -44,7 +44,7 @@ ...@@ -44,7 +44,7 @@
#define PWC_MINOR 0 #define PWC_MINOR 0
#define PWC_EXTRAMINOR 12 #define PWC_EXTRAMINOR 12
#define PWC_VERSION_CODE KERNEL_VERSION(PWC_MAJOR,PWC_MINOR,PWC_EXTRAMINOR) #define PWC_VERSION_CODE KERNEL_VERSION(PWC_MAJOR,PWC_MINOR,PWC_EXTRAMINOR)
#define PWC_VERSION "10.0.12" #define PWC_VERSION "10.0.13"
#define PWC_NAME "pwc" #define PWC_NAME "pwc"
#define PFX PWC_NAME ": " #define PFX PWC_NAME ": "
...@@ -85,7 +85,7 @@ ...@@ -85,7 +85,7 @@
#define PWC_INFO(fmt, args...) printk(KERN_INFO PFX fmt, ##args) #define PWC_INFO(fmt, args...) printk(KERN_INFO PFX fmt, ##args)
#define PWC_TRACE(fmt, args...) PWC_DEBUG(TRACE, fmt, ##args) #define PWC_TRACE(fmt, args...) PWC_DEBUG(TRACE, fmt, ##args)
#else /* if ! CONFIG_PWC_DEBUG */ #else /* if ! CONFIG_USB_PWC_DEBUG */
#define PWC_ERROR(fmt, args...) printk(KERN_ERR PFX fmt, ##args) #define PWC_ERROR(fmt, args...) printk(KERN_ERR PFX fmt, ##args)
#define PWC_WARNING(fmt, args...) printk(KERN_WARNING PFX fmt, ##args) #define PWC_WARNING(fmt, args...) printk(KERN_WARNING PFX fmt, ##args)
...@@ -287,6 +287,7 @@ void pwc_construct(struct pwc_device *pdev); ...@@ -287,6 +287,7 @@ void pwc_construct(struct pwc_device *pdev);
/** Functions in pwc-ctrl.c */ /** Functions in pwc-ctrl.c */
/* Request a certain video mode. Returns < 0 if not possible */ /* Request a certain video mode. Returns < 0 if not possible */
extern int pwc_set_video_mode(struct pwc_device *pdev, int width, int height, int frames, int compression, int snapshot); extern int pwc_set_video_mode(struct pwc_device *pdev, int width, int height, int frames, int compression, int snapshot);
extern unsigned int pwc_get_fps(struct pwc_device *pdev, unsigned int index, unsigned int size);
/* Calculate the number of bytes per image (not frame) */ /* Calculate the number of bytes per image (not frame) */
extern int pwc_mpt_reset(struct pwc_device *pdev, int flags); extern int pwc_mpt_reset(struct pwc_device *pdev, int flags);
extern int pwc_mpt_set_angle(struct pwc_device *pdev, int pan, int tilt); extern int pwc_mpt_set_angle(struct pwc_device *pdev, int pan, int tilt);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment