Resguardo inicial

This commit is contained in:
lastdragon
2026-09-06 12:53:21 -06:00
parent 662efe3c2a
commit ad2088d178
94853 changed files with 43200404 additions and 0 deletions
+49
View File
@@ -0,0 +1,49 @@
# SPDX-License-Identifier: GPL-2.0-only
config USB_PWC
tristate "USB Philips Cameras"
depends on VIDEO_DEV
select VIDEOBUF2_VMALLOC
help
Say Y or M here if you want to use one of these Philips & OEM
webcams:
* Philips PCA645, PCA646
* Philips PCVC675, PCVC680, PCVC690
* Philips PCVC720/40, PCVC730, PCVC740, PCVC750
* Philips SPC900NC
* Askey VC010
* Logitech QuickCam Pro 3000, 4000, 'Zoom', 'Notebook Pro'
and 'Orbit'/'Sphere'
* Samsung MPC-C10, MPC-C30
* Creative Webcam 5, Pro Ex
* SOTEC Afina Eye
* Visionite VCS-UC300, VCS-UM100
The PCA635, PCVC665 and PCVC720/20 are not supported by this driver
and never will be, but the 665 and 720/20 are supported by other
drivers.
Some newer logitech webcams are not handled by this driver but by the
Usb Video Class driver (linux-uvc).
The built-in microphone is enabled by selecting USB Audio support.
To compile this driver as a module, choose M here: the
module will be called pwc.
config USB_PWC_DEBUG
bool "USB Philips Cameras verbose debug"
depends on USB_PWC
help
Say Y here in order to have the pwc driver generate verbose debugging
messages.
A special module options 'trace' is used to control the verbosity.
config USB_PWC_INPUT_EVDEV
bool "USB Philips Cameras input events device support"
default y
depends on USB_PWC && (USB_PWC=INPUT || INPUT=y)
help
This option makes USB Philips cameras register the snapshot button as
an input device to report button events.
If you are in doubt, say Y.
@@ -0,0 +1,5 @@
# SPDX-License-Identifier: GPL-2.0-only
pwc-objs += pwc-if.o pwc-misc.o pwc-ctrl.o pwc-v4l.o pwc-uncompress.o
pwc-objs += pwc-dec1.o pwc-dec23.o pwc-kiara.o pwc-timon.o
obj-$(CONFIG_USB_PWC) += pwc.o
@@ -0,0 +1,544 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/* Driver for Philips webcam
Functions that send various control messages to the webcam, including
video modes.
(C) 1999-2003 Nemosoft Unv.
(C) 2004-2006 Luc Saillard (luc@saillard.org)
(C) 2011 Hans de Goede <hdegoede@redhat.com>
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.
Please send bug reports and support requests to <luc@saillard.org>.
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.
Please send bug reports and support requests to <luc@saillard.org>.
The decompression routines have been implemented by reverse-engineering the
Nemosoft binary pwcx module. Caveat emptor.
*/
/*
Changes
2001/08/03 Alvarado Added methods for changing white balance and
red/green gains
*/
/* Control functions for the cam; brightness, contrast, video mode, etc. */
#ifdef __KERNEL__
#include <linux/uaccess.h>
#endif
#include <asm/errno.h>
#include "pwc.h"
#include "pwc-kiara.h"
#include "pwc-timon.h"
#include "pwc-dec1.h"
#include "pwc-dec23.h"
/* Selectors for status controls used only in this file */
#define GET_STATUS_B00 0x0B00
#define SENSOR_TYPE_FORMATTER1 0x0C00
#define GET_STATUS_3000 0x3000
#define READ_RAW_Y_MEAN_FORMATTER 0x3100
#define SET_POWER_SAVE_MODE_FORMATTER 0x3200
#define MIRROR_IMAGE_FORMATTER 0x3300
#define LED_FORMATTER 0x3400
#define LOWLIGHT 0x3500
#define GET_STATUS_3600 0x3600
#define SENSOR_TYPE_FORMATTER2 0x3700
#define GET_STATUS_3800 0x3800
#define GET_STATUS_4000 0x4000
#define GET_STATUS_4100 0x4100 /* Get */
#define CTL_STATUS_4200 0x4200 /* [GS] 1 */
/* Formatters for the Video Endpoint controls [GS]ET_EP_STREAM_CTL */
#define VIDEO_OUTPUT_CONTROL_FORMATTER 0x0100
static const char *size2name[PSZ_MAX] =
{
"subQCIF",
"QSIF",
"QCIF",
"SIF",
"CIF",
"VGA",
};
/********/
/* Entries for the Nala (645/646) camera; the Nala doesn't have compression
preferences, so you either get compressed or non-compressed streams.
An alternate value of 0 means this mode is not available at all.
*/
#define PWC_FPS_MAX_NALA 8
struct Nala_table_entry {
char alternate; /* USB alternate setting */
int compressed; /* Compressed yes/no */
unsigned char mode[3]; /* precomputed mode table */
};
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"
};
/****************************************************************************/
static int recv_control_msg(struct pwc_device *pdev,
u8 request, u16 value, int recv_count)
{
int rc;
rc = usb_control_msg(pdev->udev, usb_rcvctrlpipe(pdev->udev, 0),
request,
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
value, pdev->vcinterface,
pdev->ctrl_buf, recv_count, USB_CTRL_GET_TIMEOUT);
if (rc < 0)
PWC_ERROR("recv_control_msg error %d req %02x val %04x\n",
rc, request, value);
return rc;
}
static inline int send_video_command(struct pwc_device *pdev,
int index, const unsigned char *buf, int buflen)
{
int rc;
memcpy(pdev->ctrl_buf, buf, buflen);
rc = usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0),
SET_EP_STREAM_CTL,
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
VIDEO_OUTPUT_CONTROL_FORMATTER, index,
pdev->ctrl_buf, buflen, USB_CTRL_SET_TIMEOUT);
if (rc >= 0)
memcpy(pdev->cmd_buf, buf, buflen);
else
PWC_ERROR("send_video_command error %d\n", rc);
return rc;
}
int send_control_msg(struct pwc_device *pdev,
u8 request, u16 value, void *buf, int buflen)
{
return usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0),
request,
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
value, pdev->vcinterface,
buf, buflen, USB_CTRL_SET_TIMEOUT);
}
static int set_video_mode_Nala(struct pwc_device *pdev, int size, int pixfmt,
int frames, int *compression, int send_to_cam)
{
int fps, ret = 0;
struct Nala_table_entry *pEntry;
int frames2frames[31] =
{ /* closest match of framerate */
0, 0, 0, 0, 4, /* 0-4 */
5, 5, 7, 7, 10, /* 5-9 */
10, 10, 12, 12, 15, /* 10-14 */
15, 15, 15, 20, 20, /* 15-19 */
20, 20, 20, 24, 24, /* 20-24 */
24, 24, 24, 24, 24, /* 25-29 */
24 /* 30 */
};
int frames2table[31] =
{ 0, 0, 0, 0, 0, /* 0-4 */
1, 1, 1, 2, 2, /* 5-9 */
3, 3, 4, 4, 4, /* 10-14 */
5, 5, 5, 5, 5, /* 15-19 */
6, 6, 6, 6, 7, /* 20-24 */
7, 7, 7, 7, 7, /* 25-29 */
7 /* 30 */
};
if (size < 0 || size > PSZ_CIF)
return -EINVAL;
if (frames < 4)
frames = 4;
else if (size > PSZ_QCIF && frames > 15)
frames = 15;
else if (frames > 25)
frames = 25;
frames = frames2frames[frames];
fps = frames2table[frames];
pEntry = &Nala_table[size][fps];
if (pEntry->alternate == 0)
return -EINVAL;
if (send_to_cam)
ret = send_video_command(pdev, pdev->vendpoint,
pEntry->mode, 3);
if (ret < 0)
return ret;
if (pEntry->compressed && pixfmt == V4L2_PIX_FMT_YUV420)
pwc_dec1_init(pdev, pEntry->mode);
/* Set various parameters */
pdev->pixfmt = pixfmt;
pdev->vframes = frames;
pdev->valternate = pEntry->alternate;
pdev->width = pwc_image_sizes[size][0];
pdev->height = pwc_image_sizes[size][1];
pdev->frame_size = (pdev->width * pdev->height * 3) / 2;
if (pEntry->compressed) {
if (pdev->release < 5) { /* 4 fold compression */
pdev->vbandlength = 528;
pdev->frame_size /= 4;
}
else {
pdev->vbandlength = 704;
pdev->frame_size /= 3;
}
}
else
pdev->vbandlength = 0;
/* Let pwc-if.c:isoc_init know we don't support higher compression */
*compression = 3;
return 0;
}
static int set_video_mode_Timon(struct pwc_device *pdev, int size, int pixfmt,
int frames, int *compression, int send_to_cam)
{
const struct Timon_table_entry *pChoose;
int fps, ret = 0;
if (size >= PSZ_MAX || *compression < 0 || *compression > 3)
return -EINVAL;
if (frames < 5)
frames = 5;
else if (size == PSZ_VGA && frames > 15)
frames = 15;
else if (frames > 30)
frames = 30;
fps = (frames / 5) - 1;
/* Find a supported framerate with progressively higher compression */
do {
pChoose = &Timon_table[size][fps][*compression];
if (pChoose->alternate != 0)
break;
(*compression)++;
} while (*compression <= 3);
if (pChoose->alternate == 0)
return -ENOENT; /* Not supported. */
if (send_to_cam)
ret = send_video_command(pdev, pdev->vendpoint,
pChoose->mode, 13);
if (ret < 0)
return ret;
if (pChoose->bandlength > 0 && pixfmt == V4L2_PIX_FMT_YUV420)
pwc_dec23_init(pdev, pChoose->mode);
/* Set various parameters */
pdev->pixfmt = pixfmt;
pdev->vframes = (fps + 1) * 5;
pdev->valternate = pChoose->alternate;
pdev->width = pwc_image_sizes[size][0];
pdev->height = pwc_image_sizes[size][1];
pdev->vbandlength = pChoose->bandlength;
if (pChoose->bandlength > 0)
pdev->frame_size = (pChoose->bandlength * pdev->height) / 4;
else
pdev->frame_size = (pdev->width * pdev->height * 12) / 8;
return 0;
}
static int set_video_mode_Kiara(struct pwc_device *pdev, int size, int pixfmt,
int frames, int *compression, int send_to_cam)
{
const struct Kiara_table_entry *pChoose;
int fps, ret = 0;
if (size >= PSZ_MAX || *compression < 0 || *compression > 3)
return -EINVAL;
if (frames < 5)
frames = 5;
else if (size == PSZ_VGA && frames > 15)
frames = 15;
else if (frames > 30)
frames = 30;
fps = (frames / 5) - 1;
/* Find a supported framerate with progressively higher compression */
do {
pChoose = &Kiara_table[size][fps][*compression];
if (pChoose->alternate != 0)
break;
(*compression)++;
} while (*compression <= 3);
if (pChoose->alternate == 0)
return -ENOENT; /* Not supported. */
/* Firmware bug: video endpoint is 5, but commands are sent to endpoint 4 */
if (send_to_cam)
ret = send_video_command(pdev, 4, pChoose->mode, 12);
if (ret < 0)
return ret;
if (pChoose->bandlength > 0 && pixfmt == V4L2_PIX_FMT_YUV420)
pwc_dec23_init(pdev, pChoose->mode);
/* All set and go */
pdev->pixfmt = pixfmt;
pdev->vframes = (fps + 1) * 5;
pdev->valternate = pChoose->alternate;
pdev->width = pwc_image_sizes[size][0];
pdev->height = pwc_image_sizes[size][1];
pdev->vbandlength = pChoose->bandlength;
if (pdev->vbandlength > 0)
pdev->frame_size = (pdev->vbandlength * pdev->height) / 4;
else
pdev->frame_size = (pdev->width * pdev->height * 12) / 8;
PWC_TRACE("frame_size=%d, vframes=%d, vsize=%d, vbandlength=%d\n",
pdev->frame_size, pdev->vframes, size, pdev->vbandlength);
return 0;
}
int pwc_set_video_mode(struct pwc_device *pdev, int width, int height,
int pixfmt, int frames, int *compression, int send_to_cam)
{
int ret, size;
PWC_DEBUG_FLOW("set_video_mode(%dx%d @ %d, pixfmt %08x).\n",
width, height, frames, pixfmt);
size = pwc_get_size(pdev, width, height);
PWC_TRACE("decode_size = %d.\n", size);
if (DEVICE_USE_CODEC1(pdev->type)) {
ret = set_video_mode_Nala(pdev, size, pixfmt, frames,
compression, send_to_cam);
} else if (DEVICE_USE_CODEC3(pdev->type)) {
ret = set_video_mode_Kiara(pdev, size, pixfmt, frames,
compression, send_to_cam);
} else {
ret = set_video_mode_Timon(pdev, size, pixfmt, frames,
compression, send_to_cam);
}
if (ret < 0) {
PWC_ERROR("Failed to set video mode %s@%d fps; return code = %d\n", size2name[size], frames, ret);
return ret;
}
pdev->frame_total_size = pdev->frame_size + pdev->frame_header_size + pdev->frame_trailer_size;
PWC_DEBUG_SIZE("Set resolution to %dx%d\n", pdev->width, pdev->height);
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;
}
int pwc_get_u8_ctrl(struct pwc_device *pdev, u8 request, u16 value, int *data)
{
int ret;
ret = recv_control_msg(pdev, request, value, 1);
if (ret < 0)
return ret;
*data = pdev->ctrl_buf[0];
return 0;
}
int pwc_set_u8_ctrl(struct pwc_device *pdev, u8 request, u16 value, u8 data)
{
int ret;
pdev->ctrl_buf[0] = data;
ret = send_control_msg(pdev, request, value, pdev->ctrl_buf, 1);
if (ret < 0)
return ret;
return 0;
}
int pwc_get_s8_ctrl(struct pwc_device *pdev, u8 request, u16 value, int *data)
{
int ret;
ret = recv_control_msg(pdev, request, value, 1);
if (ret < 0)
return ret;
*data = ((s8 *)pdev->ctrl_buf)[0];
return 0;
}
int pwc_get_u16_ctrl(struct pwc_device *pdev, u8 request, u16 value, int *data)
{
int ret;
ret = recv_control_msg(pdev, request, value, 2);
if (ret < 0)
return ret;
*data = (pdev->ctrl_buf[1] << 8) | pdev->ctrl_buf[0];
return 0;
}
int pwc_set_u16_ctrl(struct pwc_device *pdev, u8 request, u16 value, u16 data)
{
int ret;
pdev->ctrl_buf[0] = data & 0xff;
pdev->ctrl_buf[1] = data >> 8;
ret = send_control_msg(pdev, request, value, pdev->ctrl_buf, 2);
if (ret < 0)
return ret;
return 0;
}
int pwc_button_ctrl(struct pwc_device *pdev, u16 value)
{
int ret;
ret = send_control_msg(pdev, SET_STATUS_CTL, value, NULL, 0);
if (ret < 0)
return ret;
return 0;
}
/* POWER */
void pwc_camera_power(struct pwc_device *pdev, int power)
{
int r;
if (!pdev->power_save)
return;
if (pdev->type < 675 || (pdev->type < 730 && pdev->release < 6))
return; /* Not supported by Nala or Timon < release 6 */
if (power)
pdev->ctrl_buf[0] = 0x00; /* active */
else
pdev->ctrl_buf[0] = 0xFF; /* power save */
r = send_control_msg(pdev, SET_STATUS_CTL,
SET_POWER_SAVE_MODE_FORMATTER, pdev->ctrl_buf, 1);
if (r < 0)
PWC_ERROR("Failed to power %s camera (%d)\n",
power ? "on" : "off", r);
}
int pwc_set_leds(struct pwc_device *pdev, int on_value, int off_value)
{
int r;
if (pdev->type < 730)
return 0;
on_value /= 100;
off_value /= 100;
if (on_value < 0)
on_value = 0;
if (on_value > 0xff)
on_value = 0xff;
if (off_value < 0)
off_value = 0;
if (off_value > 0xff)
off_value = 0xff;
pdev->ctrl_buf[0] = on_value;
pdev->ctrl_buf[1] = off_value;
r = send_control_msg(pdev,
SET_STATUS_CTL, LED_FORMATTER, pdev->ctrl_buf, 2);
if (r < 0)
PWC_ERROR("Failed to set LED on/off time (%d)\n", r);
return r;
}
#ifdef CONFIG_USB_PWC_DEBUG
int pwc_get_cmos_sensor(struct pwc_device *pdev, int *sensor)
{
int ret, request;
if (pdev->type < 675)
request = SENSOR_TYPE_FORMATTER1;
else if (pdev->type < 730)
return -1; /* The Vesta series doesn't have this call */
else
request = SENSOR_TYPE_FORMATTER2;
ret = recv_control_msg(pdev, GET_STATUS_CTL, request, 1);
if (ret < 0)
return ret;
if (pdev->type < 675)
*sensor = pdev->ctrl_buf[0] | 0x100;
else
*sensor = pdev->ctrl_buf[0];
return 0;
}
#endif
@@ -0,0 +1,20 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/* Linux driver for Philips webcam
Decompression for chipset version 1
(C) 2004-2006 Luc Saillard (luc@saillard.org)
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.
Please send bug reports and support requests to <luc@saillard.org>.
The decompression routines have been implemented by reverse-engineering the
Nemosoft binary pwcx module. Caveat emptor.
*/
#include "pwc.h"
void pwc_dec1_init(struct pwc_device *pdev, const unsigned char *cmd)
{
struct pwc_dec1_private *pdec = &pdev->dec1;
pdec->version = pdev->release;
}
@@ -0,0 +1,27 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/* Linux driver for Philips webcam
(C) 2004-2006 Luc Saillard (luc@saillard.org)
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.
Please send bug reports and support requests to <luc@saillard.org>.
The decompression routines have been implemented by reverse-engineering the
Nemosoft binary pwcx module. Caveat emptor.
*/
#ifndef PWC_DEC1_H
#define PWC_DEC1_H
#include <linux/mutex.h>
struct pwc_device;
struct pwc_dec1_private
{
int version;
};
void pwc_dec1_init(struct pwc_device *pdev, const unsigned char *cmd);
#endif
@@ -0,0 +1,678 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/* Linux driver for Philips webcam
Decompression for chipset version 2 et 3
(C) 2004-2006 Luc Saillard (luc@saillard.org)
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.
Please send bug reports and support requests to <luc@saillard.org>.
The decompression routines have been implemented by reverse-engineering the
Nemosoft binary pwcx module. Caveat emptor.
*/
#include "pwc-timon.h"
#include "pwc-kiara.h"
#include "pwc-dec23.h"
#include <linux/string.h>
#include <linux/slab.h>
/*
* USE_LOOKUP_TABLE_TO_CLAMP
* 0: use a C version of this tests: { a<0?0:(a>255?255:a) }
* 1: use a faster lookup table for cpu with a big cache (intel)
*/
#define USE_LOOKUP_TABLE_TO_CLAMP 1
/*
* UNROLL_LOOP_FOR_COPYING_BLOCK
* 0: use a loop for a smaller code (but little slower)
* 1: when unrolling the loop, gcc produces some faster code (perhaps only
* valid for intel processor class). Activating this option, automatically
* activate USE_LOOKUP_TABLE_TO_CLAMP
*/
#define UNROLL_LOOP_FOR_COPY 1
#if UNROLL_LOOP_FOR_COPY
# undef USE_LOOKUP_TABLE_TO_CLAMP
# define USE_LOOKUP_TABLE_TO_CLAMP 1
#endif
static void build_subblock_pattern(struct pwc_dec23_private *pdec)
{
static const unsigned int initial_values[12] = {
-0x526500, -0x221200, 0x221200, 0x526500,
-0x3de200, 0x3de200,
-0x6db480, -0x2d5d00, 0x2d5d00, 0x6db480,
-0x12c200, 0x12c200
};
static const unsigned int values_derivated[12] = {
0xa4ca, 0x4424, -0x4424, -0xa4ca,
0x7bc4, -0x7bc4,
0xdb69, 0x5aba, -0x5aba, -0xdb69,
0x2584, -0x2584
};
unsigned int temp_values[12];
int i, j;
memcpy(temp_values, initial_values, sizeof(initial_values));
for (i = 0; i < 256; i++) {
for (j = 0; j < 12; j++) {
pdec->table_subblock[i][j] = temp_values[j];
temp_values[j] += values_derivated[j];
}
}
}
static void build_bit_powermask_table(struct pwc_dec23_private *pdec)
{
unsigned char *p;
unsigned int bit, byte, mask, val;
unsigned int bitpower = 1;
for (bit = 0; bit < 8; bit++) {
mask = bitpower - 1;
p = pdec->table_bitpowermask[bit];
for (byte = 0; byte < 256; byte++) {
val = (byte & mask);
if (byte & bitpower)
val = -val;
*p++ = val;
}
bitpower<<=1;
}
}
static void build_table_color(const unsigned int romtable[16][8],
unsigned char p0004[16][1024],
unsigned char p8004[16][256])
{
int compression_mode, j, k, bit, pw;
unsigned char *p0, *p8;
const unsigned int *r;
/* We have 16 compressions tables */
for (compression_mode = 0; compression_mode < 16; compression_mode++) {
p0 = p0004[compression_mode];
p8 = p8004[compression_mode];
r = romtable[compression_mode];
for (j = 0; j < 8; j++, r++, p0 += 128) {
for (k = 0; k < 16; k++) {
if (k == 0)
bit = 1;
else if (k >= 1 && k < 3)
bit = (r[0] >> 15) & 7;
else if (k >= 3 && k < 6)
bit = (r[0] >> 12) & 7;
else if (k >= 6 && k < 10)
bit = (r[0] >> 9) & 7;
else if (k >= 10 && k < 13)
bit = (r[0] >> 6) & 7;
else if (k >= 13 && k < 15)
bit = (r[0] >> 3) & 7;
else
bit = (r[0]) & 7;
if (k == 0)
*p8++ = 8;
else
*p8++ = j - bit;
*p8++ = bit;
pw = 1 << bit;
p0[k + 0x00] = (1 * pw) + 0x80;
p0[k + 0x10] = (2 * pw) + 0x80;
p0[k + 0x20] = (3 * pw) + 0x80;
p0[k + 0x30] = (4 * pw) + 0x80;
p0[k + 0x40] = (-1 * pw) + 0x80;
p0[k + 0x50] = (-2 * pw) + 0x80;
p0[k + 0x60] = (-3 * pw) + 0x80;
p0[k + 0x70] = (-4 * pw) + 0x80;
} /* end of for (k=0; k<16; k++, p8++) */
} /* end of for (j=0; j<8; j++ , table++) */
} /* end of foreach compression_mode */
}
/*
*
*/
static void fill_table_dc00_d800(struct pwc_dec23_private *pdec)
{
#define SCALEBITS 15
#define ONE_HALF (1UL << (SCALEBITS - 1))
int i;
unsigned int offset1 = ONE_HALF;
unsigned int offset2 = 0x0000;
for (i=0; i<256; i++) {
pdec->table_dc00[i] = offset1 & ~(ONE_HALF);
pdec->table_d800[i] = offset2;
offset1 += 0x7bc4;
offset2 += 0x7bc4;
}
}
/*
* To decode the stream:
* if look_bits(2) == 0: # op == 2 in the lookup table
* skip_bits(2)
* end of the stream
* elif look_bits(3) == 7: # op == 1 in the lookup table
* skip_bits(3)
* yyyy = get_bits(4)
* xxxx = get_bits(8)
* else: # op == 0 in the lookup table
* skip_bits(x)
*
* For speedup processing, we build a lookup table and we takes the first 6 bits.
*
* struct {
* unsigned char op; // operation to execute
* unsigned char bits; // bits use to perform operation
* unsigned char offset1; // offset to add to access in the table_0004 % 16
* unsigned char offset2; // offset to add to access in the table_0004
* }
*
* How to build this table ?
* op == 2 when (i%4)==0
* op == 1 when (i%8)==7
* op == 0 otherwise
*
*/
static const unsigned char hash_table_ops[64*4] = {
0x02, 0x00, 0x00, 0x00,
0x00, 0x03, 0x01, 0x00,
0x00, 0x04, 0x01, 0x10,
0x00, 0x06, 0x01, 0x30,
0x02, 0x00, 0x00, 0x00,
0x00, 0x03, 0x01, 0x40,
0x00, 0x05, 0x01, 0x20,
0x01, 0x00, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00,
0x00, 0x03, 0x01, 0x00,
0x00, 0x04, 0x01, 0x50,
0x00, 0x05, 0x02, 0x00,
0x02, 0x00, 0x00, 0x00,
0x00, 0x03, 0x01, 0x40,
0x00, 0x05, 0x03, 0x00,
0x01, 0x00, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00,
0x00, 0x03, 0x01, 0x00,
0x00, 0x04, 0x01, 0x10,
0x00, 0x06, 0x02, 0x10,
0x02, 0x00, 0x00, 0x00,
0x00, 0x03, 0x01, 0x40,
0x00, 0x05, 0x01, 0x60,
0x01, 0x00, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00,
0x00, 0x03, 0x01, 0x00,
0x00, 0x04, 0x01, 0x50,
0x00, 0x05, 0x02, 0x40,
0x02, 0x00, 0x00, 0x00,
0x00, 0x03, 0x01, 0x40,
0x00, 0x05, 0x03, 0x40,
0x01, 0x00, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00,
0x00, 0x03, 0x01, 0x00,
0x00, 0x04, 0x01, 0x10,
0x00, 0x06, 0x01, 0x70,
0x02, 0x00, 0x00, 0x00,
0x00, 0x03, 0x01, 0x40,
0x00, 0x05, 0x01, 0x20,
0x01, 0x00, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00,
0x00, 0x03, 0x01, 0x00,
0x00, 0x04, 0x01, 0x50,
0x00, 0x05, 0x02, 0x00,
0x02, 0x00, 0x00, 0x00,
0x00, 0x03, 0x01, 0x40,
0x00, 0x05, 0x03, 0x00,
0x01, 0x00, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00,
0x00, 0x03, 0x01, 0x00,
0x00, 0x04, 0x01, 0x10,
0x00, 0x06, 0x02, 0x50,
0x02, 0x00, 0x00, 0x00,
0x00, 0x03, 0x01, 0x40,
0x00, 0x05, 0x01, 0x60,
0x01, 0x00, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00,
0x00, 0x03, 0x01, 0x00,
0x00, 0x04, 0x01, 0x50,
0x00, 0x05, 0x02, 0x40,
0x02, 0x00, 0x00, 0x00,
0x00, 0x03, 0x01, 0x40,
0x00, 0x05, 0x03, 0x40,
0x01, 0x00, 0x00, 0x00
};
/*
*
*/
static const unsigned int MulIdx[16][16] = {
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,},
{0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3,},
{0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3,},
{4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4,},
{6, 7, 8, 9, 7, 10, 11, 8, 8, 11, 10, 7, 9, 8, 7, 6,},
{4, 5, 5, 4, 4, 5, 5, 4, 4, 5, 5, 4, 4, 5, 5, 4,},
{1, 3, 0, 2, 1, 3, 0, 2, 1, 3, 0, 2, 1, 3, 0, 2,},
{0, 3, 3, 0, 1, 2, 2, 1, 2, 1, 1, 2, 3, 0, 0, 3,},
{0, 1, 2, 3, 3, 2, 1, 0, 3, 2, 1, 0, 0, 1, 2, 3,},
{1, 1, 1, 1, 3, 3, 3, 3, 0, 0, 0, 0, 2, 2, 2, 2,},
{7, 10, 11, 8, 9, 8, 7, 6, 6, 7, 8, 9, 8, 11, 10, 7,},
{4, 5, 5, 4, 5, 4, 4, 5, 5, 4, 4, 5, 4, 5, 5, 4,},
{7, 9, 6, 8, 10, 8, 7, 11, 11, 7, 8, 10, 8, 6, 9, 7,},
{1, 3, 0, 2, 2, 0, 3, 1, 2, 0, 3, 1, 1, 3, 0, 2,},
{1, 2, 2, 1, 3, 0, 0, 3, 0, 3, 3, 0, 2, 1, 1, 2,},
{10, 8, 7, 11, 8, 6, 9, 7, 7, 9, 6, 8, 11, 7, 8, 10}
};
#if USE_LOOKUP_TABLE_TO_CLAMP
#define MAX_OUTER_CROP_VALUE (512)
static unsigned char pwc_crop_table[256 + 2*MAX_OUTER_CROP_VALUE];
#define CLAMP(x) (pwc_crop_table[MAX_OUTER_CROP_VALUE+(x)])
#else
#define CLAMP(x) ((x)>255?255:((x)<0?0:x))
#endif
/* If the type or the command change, we rebuild the lookup table */
void pwc_dec23_init(struct pwc_device *pdev, const unsigned char *cmd)
{
int flags, version, shift, i;
struct pwc_dec23_private *pdec = &pdev->dec23;
mutex_init(&pdec->lock);
if (pdec->last_cmd_valid && pdec->last_cmd == cmd[2])
return;
if (DEVICE_USE_CODEC3(pdev->type)) {
flags = cmd[2] & 0x18;
if (flags == 8)
pdec->nbits = 7; /* More bits, mean more bits to encode the stream, but better quality */
else if (flags == 0x10)
pdec->nbits = 8;
else
pdec->nbits = 6;
version = cmd[2] >> 5;
build_table_color(KiaraRomTable[version][0], pdec->table_0004_pass1, pdec->table_8004_pass1);
build_table_color(KiaraRomTable[version][1], pdec->table_0004_pass2, pdec->table_8004_pass2);
} else {
flags = cmd[2] & 6;
if (flags == 2)
pdec->nbits = 7;
else if (flags == 4)
pdec->nbits = 8;
else
pdec->nbits = 6;
version = cmd[2] >> 3;
build_table_color(TimonRomTable[version][0], pdec->table_0004_pass1, pdec->table_8004_pass1);
build_table_color(TimonRomTable[version][1], pdec->table_0004_pass2, pdec->table_8004_pass2);
}
/* Information can be coded on a variable number of bits but never less than 8 */
shift = 8 - pdec->nbits;
pdec->scalebits = SCALEBITS - shift;
pdec->nbitsmask = 0xFF >> shift;
fill_table_dc00_d800(pdec);
build_subblock_pattern(pdec);
build_bit_powermask_table(pdec);
#if USE_LOOKUP_TABLE_TO_CLAMP
/* Build the static table to clamp value [0-255] */
for (i=0;i<MAX_OUTER_CROP_VALUE;i++)
pwc_crop_table[i] = 0;
for (i=0; i<256; i++)
pwc_crop_table[MAX_OUTER_CROP_VALUE+i] = i;
for (i=0; i<MAX_OUTER_CROP_VALUE; i++)
pwc_crop_table[MAX_OUTER_CROP_VALUE+256+i] = 255;
#endif
pdec->last_cmd = cmd[2];
pdec->last_cmd_valid = 1;
}
/*
* Copy the 4x4 image block to Y plane buffer
*/
static void copy_image_block_Y(const int *src, unsigned char *dst, unsigned int bytes_per_line, unsigned int scalebits)
{
#if UNROLL_LOOP_FOR_COPY
const unsigned char *cm = pwc_crop_table+MAX_OUTER_CROP_VALUE;
const int *c = src;
unsigned char *d = dst;
*d++ = cm[c[0] >> scalebits];
*d++ = cm[c[1] >> scalebits];
*d++ = cm[c[2] >> scalebits];
*d++ = cm[c[3] >> scalebits];
d = dst + bytes_per_line;
*d++ = cm[c[4] >> scalebits];
*d++ = cm[c[5] >> scalebits];
*d++ = cm[c[6] >> scalebits];
*d++ = cm[c[7] >> scalebits];
d = dst + bytes_per_line*2;
*d++ = cm[c[8] >> scalebits];
*d++ = cm[c[9] >> scalebits];
*d++ = cm[c[10] >> scalebits];
*d++ = cm[c[11] >> scalebits];
d = dst + bytes_per_line*3;
*d++ = cm[c[12] >> scalebits];
*d++ = cm[c[13] >> scalebits];
*d++ = cm[c[14] >> scalebits];
*d++ = cm[c[15] >> scalebits];
#else
int i;
const int *c = src;
unsigned char *d = dst;
for (i = 0; i < 4; i++, c++)
*d++ = CLAMP((*c) >> scalebits);
d = dst + bytes_per_line;
for (i = 0; i < 4; i++, c++)
*d++ = CLAMP((*c) >> scalebits);
d = dst + bytes_per_line*2;
for (i = 0; i < 4; i++, c++)
*d++ = CLAMP((*c) >> scalebits);
d = dst + bytes_per_line*3;
for (i = 0; i < 4; i++, c++)
*d++ = CLAMP((*c) >> scalebits);
#endif
}
/*
* Copy the 4x4 image block to a CrCb plane buffer
*
*/
static void copy_image_block_CrCb(const int *src, unsigned char *dst, unsigned int bytes_per_line, unsigned int scalebits)
{
#if UNROLL_LOOP_FOR_COPY
/* Unroll all loops */
const unsigned char *cm = pwc_crop_table+MAX_OUTER_CROP_VALUE;
const int *c = src;
unsigned char *d = dst;
*d++ = cm[c[0] >> scalebits];
*d++ = cm[c[4] >> scalebits];
*d++ = cm[c[1] >> scalebits];
*d++ = cm[c[5] >> scalebits];
*d++ = cm[c[2] >> scalebits];
*d++ = cm[c[6] >> scalebits];
*d++ = cm[c[3] >> scalebits];
*d++ = cm[c[7] >> scalebits];
d = dst + bytes_per_line;
*d++ = cm[c[12] >> scalebits];
*d++ = cm[c[8] >> scalebits];
*d++ = cm[c[13] >> scalebits];
*d++ = cm[c[9] >> scalebits];
*d++ = cm[c[14] >> scalebits];
*d++ = cm[c[10] >> scalebits];
*d++ = cm[c[15] >> scalebits];
*d++ = cm[c[11] >> scalebits];
#else
int i;
const int *c1 = src;
const int *c2 = src + 4;
unsigned char *d = dst;
for (i = 0; i < 4; i++, c1++, c2++) {
*d++ = CLAMP((*c1) >> scalebits);
*d++ = CLAMP((*c2) >> scalebits);
}
c1 = src + 12;
d = dst + bytes_per_line;
for (i = 0; i < 4; i++, c1++, c2++) {
*d++ = CLAMP((*c1) >> scalebits);
*d++ = CLAMP((*c2) >> scalebits);
}
#endif
}
/*
* To manage the stream, we keep bits in a 32 bits register.
* fill_nbits(n): fill the reservoir with at least n bits
* skip_bits(n): discard n bits from the reservoir
* get_bits(n): fill the reservoir, returns the first n bits and discard the
* bits from the reservoir.
* __get_nbits(n): faster version of get_bits(n), but asumes that the reservoir
* contains at least n bits. bits returned is discarded.
*/
#define fill_nbits(pdec, nbits_wanted) do { \
while (pdec->nbits_in_reservoir<(nbits_wanted)) \
{ \
pdec->reservoir |= (*(pdec->stream)++) << (pdec->nbits_in_reservoir); \
pdec->nbits_in_reservoir += 8; \
} \
} while(0);
#define skip_nbits(pdec, nbits_to_skip) do { \
pdec->reservoir >>= (nbits_to_skip); \
pdec->nbits_in_reservoir -= (nbits_to_skip); \
} while(0);
#define get_nbits(pdec, nbits_wanted, result) do { \
fill_nbits(pdec, nbits_wanted); \
result = (pdec->reservoir) & ((1U<<(nbits_wanted))-1); \
skip_nbits(pdec, nbits_wanted); \
} while(0);
#define __get_nbits(pdec, nbits_wanted, result) do { \
result = (pdec->reservoir) & ((1U<<(nbits_wanted))-1); \
skip_nbits(pdec, nbits_wanted); \
} while(0);
#define look_nbits(pdec, nbits_wanted) \
((pdec->reservoir) & ((1U<<(nbits_wanted))-1))
/*
* Decode a 4x4 pixel block
*/
static void decode_block(struct pwc_dec23_private *pdec,
const unsigned char *ptable0004,
const unsigned char *ptable8004)
{
unsigned int primary_color;
unsigned int channel_v, offset1, op;
int i;
fill_nbits(pdec, 16);
__get_nbits(pdec, pdec->nbits, primary_color);
if (look_nbits(pdec,2) == 0) {
skip_nbits(pdec, 2);
/* Very simple, the color is the same for all pixels of the square */
for (i = 0; i < 16; i++)
pdec->temp_colors[i] = pdec->table_dc00[primary_color];
return;
}
/* This block is encoded with small pattern */
for (i = 0; i < 16; i++)
pdec->temp_colors[i] = pdec->table_d800[primary_color];
__get_nbits(pdec, 3, channel_v);
channel_v = ((channel_v & 1) << 2) | (channel_v & 2) | ((channel_v & 4) >> 2);
ptable0004 += (channel_v * 128);
ptable8004 += (channel_v * 32);
offset1 = 0;
do
{
unsigned int htable_idx, rows = 0;
const unsigned int *block;
/* [ zzzz y x x ]
* xx == 00 :=> end of the block def, remove the two bits from the stream
* yxx == 111
* yxx == any other value
*
*/
fill_nbits(pdec, 16);
htable_idx = look_nbits(pdec, 6);
op = hash_table_ops[htable_idx * 4];
if (op == 2) {
skip_nbits(pdec, 2);
} else if (op == 1) {
/* 15bits [ xxxx xxxx yyyy 111 ]
* yyy => offset in the table8004
* xxx => offset in the tabled004 (tree)
*/
unsigned int mask, shift;
unsigned int nbits, col1;
unsigned int yyyy;
skip_nbits(pdec, 3);
/* offset1 += yyyy */
__get_nbits(pdec, 4, yyyy);
offset1 += 1 + yyyy;
offset1 &= 0x0F;
nbits = ptable8004[offset1 * 2];
/* col1 = xxxx xxxx */
__get_nbits(pdec, nbits+1, col1);
/* Bit mask table */
mask = pdec->table_bitpowermask[nbits][col1];
shift = ptable8004[offset1 * 2 + 1];
rows = ((mask << shift) + 0x80) & 0xFF;
block = pdec->table_subblock[rows];
for (i = 0; i < 16; i++)
pdec->temp_colors[i] += block[MulIdx[offset1][i]];
} else {
/* op == 0
* offset1 is coded on 3 bits
*/
unsigned int shift;
offset1 += hash_table_ops [htable_idx * 4 + 2];
offset1 &= 0x0F;
rows = ptable0004[offset1 + hash_table_ops [htable_idx * 4 + 3]];
block = pdec->table_subblock[rows];
for (i = 0; i < 16; i++)
pdec->temp_colors[i] += block[MulIdx[offset1][i]];
shift = hash_table_ops[htable_idx * 4 + 1];
skip_nbits(pdec, shift);
}
} while (op != 2);
}
static void DecompressBand23(struct pwc_dec23_private *pdec,
const unsigned char *rawyuv,
unsigned char *planar_y,
unsigned char *planar_u,
unsigned char *planar_v,
unsigned int compressed_image_width,
unsigned int real_image_width)
{
int compression_index, nblocks;
const unsigned char *ptable0004;
const unsigned char *ptable8004;
pdec->reservoir = 0;
pdec->nbits_in_reservoir = 0;
pdec->stream = rawyuv + 1; /* The first byte of the stream is skipped */
get_nbits(pdec, 4, compression_index);
/* pass 1: uncompress Y component */
nblocks = compressed_image_width / 4;
ptable0004 = pdec->table_0004_pass1[compression_index];
ptable8004 = pdec->table_8004_pass1[compression_index];
/* Each block decode a square of 4x4 */
while (nblocks) {
decode_block(pdec, ptable0004, ptable8004);
copy_image_block_Y(pdec->temp_colors, planar_y, real_image_width, pdec->scalebits);
planar_y += 4;
nblocks--;
}
/* pass 2: uncompress UV component */
nblocks = compressed_image_width / 8;
ptable0004 = pdec->table_0004_pass2[compression_index];
ptable8004 = pdec->table_8004_pass2[compression_index];
/* Each block decode a square of 4x4 */
while (nblocks) {
decode_block(pdec, ptable0004, ptable8004);
copy_image_block_CrCb(pdec->temp_colors, planar_u, real_image_width/2, pdec->scalebits);
decode_block(pdec, ptable0004, ptable8004);
copy_image_block_CrCb(pdec->temp_colors, planar_v, real_image_width/2, pdec->scalebits);
planar_v += 8;
planar_u += 8;
nblocks -= 2;
}
}
/**
* pwc_dec23_decompress - Uncompress a pwc23 buffer.
* @pdev: pointer to pwc device's internal struct
* @src: raw data
* @dst: image output
*/
void pwc_dec23_decompress(struct pwc_device *pdev,
const void *src,
void *dst)
{
int bandlines_left, bytes_per_block;
struct pwc_dec23_private *pdec = &pdev->dec23;
/* YUV420P image format */
unsigned char *pout_planar_y;
unsigned char *pout_planar_u;
unsigned char *pout_planar_v;
unsigned int plane_size;
mutex_lock(&pdec->lock);
bandlines_left = pdev->height / 4;
bytes_per_block = pdev->width * 4;
plane_size = pdev->height * pdev->width;
pout_planar_y = dst;
pout_planar_u = dst + plane_size;
pout_planar_v = dst + plane_size + plane_size / 4;
while (bandlines_left--) {
DecompressBand23(pdec, src,
pout_planar_y, pout_planar_u, pout_planar_v,
pdev->width, pdev->width);
src += pdev->vbandlength;
pout_planar_y += bytes_per_block;
pout_planar_u += pdev->width;
pout_planar_v += pdev->width;
}
mutex_unlock(&pdec->lock);
}
@@ -0,0 +1,49 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/* Linux driver for Philips webcam
(C) 2004-2006 Luc Saillard (luc@saillard.org)
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.
Please send bug reports and support requests to <luc@saillard.org>.
The decompression routines have been implemented by reverse-engineering the
Nemosoft binary pwcx module. Caveat emptor.
*/
#ifndef PWC_DEC23_H
#define PWC_DEC23_H
struct pwc_device;
struct pwc_dec23_private
{
struct mutex lock;
unsigned char last_cmd, last_cmd_valid;
unsigned int scalebits;
unsigned int nbitsmask, nbits; /* Number of bits of a color in the compressed stream */
unsigned int reservoir;
unsigned int nbits_in_reservoir;
const unsigned char *stream;
int temp_colors[16];
unsigned char table_0004_pass1[16][1024];
unsigned char table_0004_pass2[16][1024];
unsigned char table_8004_pass1[16][256];
unsigned char table_8004_pass2[16][256];
unsigned int table_subblock[256][12];
unsigned char table_bitpowermask[8][256];
unsigned int table_d800[256];
unsigned int table_dc00[256];
};
void pwc_dec23_init(struct pwc_device *pdev, const unsigned char *cmd);
void pwc_dec23_decompress(struct pwc_device *pdev,
const void *src,
void *dst);
#endif
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,880 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/* Linux driver for Philips webcam
(C) 2004-2006 Luc Saillard (luc@saillard.org)
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.
Please send bug reports and support requests to <luc@saillard.org>.
The decompression routines have been implemented by reverse-engineering the
Nemosoft binary pwcx module. Caveat emptor.
*/
/* This tables contains entries for the 730/740/750 (Kiara) camera, with
4 different qualities (no compression, low, medium, high).
It lists the bandwidth requirements for said mode by its alternate interface
number. An alternate of 0 means that the mode is unavailable.
There are 6 * 4 * 4 entries:
6 different resolutions subqcif, qsif, qcif, sif, cif, vga
6 framerates: 5, 10, 15, 20, 25, 30
4 compression modi: none, low, medium, high
When an uncompressed mode is not available, the next available compressed mode
will be chosen (unless the decompressor is absent). Sometimes there are only
1 or 2 compressed modes available; in that case entries are duplicated.
*/
#include "pwc-kiara.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] =
{
/* SQCIF */
{
/* 5 fps */
{
{0, },
{0, },
{0, },
{0, },
},
/* 10 fps */
{
{0, },
{0, },
{0, },
{0, },
},
/* 15 fps */
{
{0, },
{0, },
{0, },
{0, },
},
/* 20 fps */
{
{0, },
{0, },
{0, },
{0, },
},
/* 25 fps */
{
{0, },
{0, },
{0, },
{0, },
},
/* 30 fps */
{
{0, },
{0, },
{0, },
{0, },
},
},
/* QSIF */
{
/* 5 fps */
{
{1, 146, 0, {0x1D, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x92, 0x00, 0x80}},
{1, 146, 0, {0x1D, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x92, 0x00, 0x80}},
{1, 146, 0, {0x1D, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x92, 0x00, 0x80}},
{1, 146, 0, {0x1D, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x92, 0x00, 0x80}},
},
/* 10 fps */
{
{2, 291, 0, {0x1C, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x23, 0x01, 0x80}},
{1, 192, 630, {0x14, 0xF4, 0x30, 0x13, 0xA9, 0x12, 0xE1, 0x17, 0x08, 0xC0, 0x00, 0x80}},
{1, 192, 630, {0x14, 0xF4, 0x30, 0x13, 0xA9, 0x12, 0xE1, 0x17, 0x08, 0xC0, 0x00, 0x80}},
{1, 192, 630, {0x14, 0xF4, 0x30, 0x13, 0xA9, 0x12, 0xE1, 0x17, 0x08, 0xC0, 0x00, 0x80}},
},
/* 15 fps */
{
{3, 437, 0, {0x1B, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0xB5, 0x01, 0x80}},
{2, 292, 640, {0x13, 0xF4, 0x30, 0x13, 0xF7, 0x13, 0x2F, 0x13, 0x20, 0x24, 0x01, 0x80}},
{2, 292, 640, {0x13, 0xF4, 0x30, 0x13, 0xF7, 0x13, 0x2F, 0x13, 0x20, 0x24, 0x01, 0x80}},
{1, 192, 420, {0x13, 0xF4, 0x30, 0x0D, 0x1B, 0x0C, 0x53, 0x1E, 0x18, 0xC0, 0x00, 0x80}},
},
/* 20 fps */
{
{4, 589, 0, {0x1A, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x4D, 0x02, 0x80}},
{3, 448, 730, {0x12, 0xF4, 0x30, 0x16, 0xC9, 0x16, 0x01, 0x0E, 0x18, 0xC0, 0x01, 0x80}},
{2, 292, 476, {0x12, 0xF4, 0x30, 0x0E, 0xD8, 0x0E, 0x10, 0x19, 0x18, 0x24, 0x01, 0x80}},
{1, 192, 312, {0x12, 0xF4, 0x50, 0x09, 0xB3, 0x08, 0xEB, 0x1E, 0x18, 0xC0, 0x00, 0x80}},
},
/* 25 fps */
{
{5, 703, 0, {0x19, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0xBF, 0x02, 0x80}},
{3, 447, 610, {0x11, 0xF4, 0x30, 0x13, 0x0B, 0x12, 0x43, 0x14, 0x28, 0xBF, 0x01, 0x80}},
{2, 292, 398, {0x11, 0xF4, 0x50, 0x0C, 0x6C, 0x0B, 0xA4, 0x1E, 0x28, 0x24, 0x01, 0x80}},
{1, 193, 262, {0x11, 0xF4, 0x50, 0x08, 0x23, 0x07, 0x5B, 0x1E, 0x28, 0xC1, 0x00, 0x80}},
},
/* 30 fps */
{
{8, 874, 0, {0x18, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x6A, 0x03, 0x80}},
{5, 704, 730, {0x10, 0xF4, 0x30, 0x16, 0xC9, 0x16, 0x01, 0x0E, 0x28, 0xC0, 0x02, 0x80}},
{3, 448, 492, {0x10, 0xF4, 0x30, 0x0F, 0x5D, 0x0E, 0x95, 0x15, 0x28, 0xC0, 0x01, 0x80}},
{2, 292, 320, {0x10, 0xF4, 0x50, 0x09, 0xFB, 0x09, 0x33, 0x1E, 0x28, 0x24, 0x01, 0x80}},
},
},
/* QCIF */
{
/* 5 fps */
{
{0, },
{0, },
{0, },
{0, },
},
/* 10 fps */
{
{0, },
{0, },
{0, },
{0, },
},
/* 15 fps */
{
{0, },
{0, },
{0, },
{0, },
},
/* 20 fps */
{
{0, },
{0, },
{0, },
{0, },
},
/* 25 fps */
{
{0, },
{0, },
{0, },
{0, },
},
/* 30 fps */
{
{0, },
{0, },
{0, },
{0, },
},
},
/* SIF */
{
/* 5 fps */
{
{4, 582, 0, {0x0D, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x46, 0x02, 0x80}},
{3, 387, 1276, {0x05, 0xF4, 0x30, 0x27, 0xD8, 0x26, 0x48, 0x03, 0x10, 0x83, 0x01, 0x80}},
{2, 291, 960, {0x05, 0xF4, 0x30, 0x1D, 0xF2, 0x1C, 0x62, 0x04, 0x10, 0x23, 0x01, 0x80}},
{1, 191, 630, {0x05, 0xF4, 0x50, 0x13, 0xA9, 0x12, 0x19, 0x05, 0x18, 0xBF, 0x00, 0x80}},
},
/* 10 fps */
{
{0, },
{6, 775, 1278, {0x04, 0xF4, 0x30, 0x27, 0xE8, 0x26, 0x58, 0x05, 0x30, 0x07, 0x03, 0x80}},
{3, 447, 736, {0x04, 0xF4, 0x30, 0x16, 0xFB, 0x15, 0x6B, 0x05, 0x28, 0xBF, 0x01, 0x80}},
{2, 292, 480, {0x04, 0xF4, 0x70, 0x0E, 0xF9, 0x0D, 0x69, 0x09, 0x28, 0x24, 0x01, 0x80}},
},
/* 15 fps */
{
{0, },
{9, 955, 1050, {0x03, 0xF4, 0x30, 0x20, 0xCF, 0x1F, 0x3F, 0x06, 0x48, 0xBB, 0x03, 0x80}},
{4, 592, 650, {0x03, 0xF4, 0x30, 0x14, 0x44, 0x12, 0xB4, 0x08, 0x30, 0x50, 0x02, 0x80}},
{3, 448, 492, {0x03, 0xF4, 0x50, 0x0F, 0x52, 0x0D, 0xC2, 0x09, 0x38, 0xC0, 0x01, 0x80}},
},
/* 20 fps */
{
{0, },
{9, 958, 782, {0x02, 0xF4, 0x30, 0x18, 0x6A, 0x16, 0xDA, 0x0B, 0x58, 0xBE, 0x03, 0x80}},
{5, 703, 574, {0x02, 0xF4, 0x50, 0x11, 0xE7, 0x10, 0x57, 0x0B, 0x40, 0xBF, 0x02, 0x80}},
{3, 446, 364, {0x02, 0xF4, 0x90, 0x0B, 0x5C, 0x09, 0xCC, 0x0E, 0x38, 0xBE, 0x01, 0x80}},
},
/* 25 fps */
{
{0, },
{9, 958, 654, {0x01, 0xF4, 0x30, 0x14, 0x66, 0x12, 0xD6, 0x0B, 0x50, 0xBE, 0x03, 0x80}},
{6, 776, 530, {0x01, 0xF4, 0x50, 0x10, 0x8C, 0x0E, 0xFC, 0x0C, 0x48, 0x08, 0x03, 0x80}},
{4, 592, 404, {0x01, 0xF4, 0x70, 0x0C, 0x96, 0x0B, 0x06, 0x0B, 0x48, 0x50, 0x02, 0x80}},
},
/* 30 fps */
{
{0, },
{9, 957, 526, {0x00, 0xF4, 0x50, 0x10, 0x68, 0x0E, 0xD8, 0x0D, 0x58, 0xBD, 0x03, 0x80}},
{6, 775, 426, {0x00, 0xF4, 0x70, 0x0D, 0x48, 0x0B, 0xB8, 0x0F, 0x50, 0x07, 0x03, 0x80}},
{4, 590, 324, {0x00, 0x7A, 0x88, 0x0A, 0x1C, 0x08, 0xB4, 0x0E, 0x50, 0x4E, 0x02, 0x80}},
},
},
/* CIF */
{
/* 5 fps */
{
{0, },
{0, },
{0, },
{0, },
},
/* 10 fps */
{
{0, },
{0, },
{0, },
{0, },
},
/* 15 fps */
{
{0, },
{0, },
{0, },
{0, },
},
/* 20 fps */
{
{0, },
{0, },
{0, },
{0, },
},
/* 25 fps */
{
{0, },
{0, },
{0, },
{0, },
},
/* 30 fps */
{
{0, },
{0, },
{0, },
{0, },
},
},
/* VGA */
{
/* 5 fps */
{
{0, },
{6, 773, 1272, {0x25, 0xF4, 0x30, 0x27, 0xB6, 0x24, 0x96, 0x02, 0x30, 0x05, 0x03, 0x80}},
{4, 592, 976, {0x25, 0xF4, 0x50, 0x1E, 0x78, 0x1B, 0x58, 0x03, 0x30, 0x50, 0x02, 0x80}},
{3, 448, 738, {0x25, 0xF4, 0x90, 0x17, 0x0C, 0x13, 0xEC, 0x04, 0x30, 0xC0, 0x01, 0x80}},
},
/* 10 fps */
{
{0, },
{9, 956, 788, {0x24, 0xF4, 0x70, 0x18, 0x9C, 0x15, 0x7C, 0x03, 0x48, 0xBC, 0x03, 0x80}},
{6, 776, 640, {0x24, 0xF4, 0xB0, 0x13, 0xFC, 0x11, 0x2C, 0x04, 0x48, 0x08, 0x03, 0x80}},
{4, 592, 488, {0x24, 0x7A, 0xE8, 0x0F, 0x3C, 0x0C, 0x6C, 0x06, 0x48, 0x50, 0x02, 0x80}},
},
/* 15 fps */
{
{0, },
{9, 957, 526, {0x23, 0x7A, 0xE8, 0x10, 0x68, 0x0D, 0x98, 0x06, 0x58, 0xBD, 0x03, 0x80}},
{9, 957, 526, {0x23, 0x7A, 0xE8, 0x10, 0x68, 0x0D, 0x98, 0x06, 0x58, 0xBD, 0x03, 0x80}},
{8, 895, 492, {0x23, 0x7A, 0xE8, 0x0F, 0x5D, 0x0C, 0x8D, 0x06, 0x58, 0x7F, 0x03, 0x80}},
},
/* 20 fps */
{
{0, },
{0, },
{0, },
{0, },
},
/* 25 fps */
{
{0, },
{0, },
{0, },
{0, },
},
/* 30 fps */
{
{0, },
{0, },
{0, },
{0, },
},
},
};
/*
* Rom table for kiara chips
*
* 32 roms tables (one for each resolution ?)
* 2 tables per roms (one for each passes) (Y, and U&V)
* 128 bytes per passes
*/
const unsigned int KiaraRomTable [8][2][16][8] =
{
{ /* version 0 */
{ /* version 0, passes 0 */
{0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000001,0x00000001},
{0x00000000,0x00000000,0x00000009,0x00000009,
0x00000009,0x00000009,0x00000009,0x00000009},
{0x00000000,0x00000000,0x00000009,0x00000049,
0x00000049,0x00000049,0x00000049,0x00000049},
{0x00000000,0x00000000,0x00000049,0x00000049,
0x00000049,0x00000249,0x0000024a,0x00000049},
{0x00000000,0x00000000,0x00000049,0x00000049,
0x00000249,0x00000249,0x0000024a,0x0000024a},
{0x00000000,0x00000000,0x00000049,0x00000249,
0x00000249,0x0000124a,0x0000024a,0x0000024a},
{0x00000000,0x00000000,0x00000049,0x00000249,
0x0000124a,0x00009252,0x00001252,0x00001252},
{0x00000000,0x00000000,0x00000249,0x00000249,
0x00009252,0x00009292,0x00009292,0x00009292},
{0x00000000,0x00000000,0x00000249,0x00001249,
0x00009292,0x00009292,0x00009493,0x000124db},
{0x00000000,0x00000000,0x00000249,0x0000924a,
0x00009492,0x0000a49b,0x0000a49b,0x000124db},
{0x00000000,0x00000000,0x00001249,0x00009252,
0x0000a493,0x000124db,0x000124db,0x000126dc},
{0x00000000,0x00000000,0x00001249,0x00009493,
0x000124db,0x000126dc,0x000136e4,0x000126dc},
{0x00000000,0x00000000,0x00009292,0x0000a49b,
0x000124db,0x000136e4,0x000136e4,0x000136e4},
{0x00000000,0x00000000,0x00009292,0x0000a49b,
0x000126dc,0x0001b724,0x0001b92d,0x0001b925},
{0x00000000,0x00000000,0x00009492,0x000124db,
0x000136e4,0x0001b925,0x0001c96e,0x0001c92d},
{0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000}
},
{ /* version 0, passes 1 */
{0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000},
{0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000},
{0x00000000,0x00000000,0x00000001,0x00000009,
0x00000009,0x00000009,0x00000009,0x00000001},
{0x00000000,0x00000000,0x00000009,0x00000009,
0x00000049,0x00000049,0x00000049,0x00000049},
{0x00000000,0x00000000,0x00000049,0x00000049,
0x00000049,0x00000049,0x0000024a,0x0000024a},
{0x00000000,0x00000000,0x00000049,0x00000049,
0x00000249,0x00000249,0x0000024a,0x0000024a},
{0x00000000,0x00000000,0x00000049,0x00000249,
0x00000249,0x00000249,0x0000024a,0x00001252},
{0x00000000,0x00000000,0x00000049,0x00001249,
0x0000124a,0x0000124a,0x00001252,0x00009292},
{0x00000000,0x00000000,0x00000249,0x00001249,
0x00009252,0x00009252,0x00009292,0x00009493},
{0x00000000,0x00000000,0x00000249,0x0000924a,
0x00009292,0x00009292,0x00009292,0x00009493},
{0x00000000,0x00000000,0x00000249,0x00009292,
0x00009492,0x00009493,0x0000a49b,0x00009493},
{0x00000000,0x00000000,0x00001249,0x00009292,
0x0000a493,0x000124db,0x000126dc,0x000126dc},
{0x00000000,0x00000000,0x0000924a,0x00009493,
0x0000a493,0x000126dc,0x000136e4,0x000136e4},
{0x00000000,0x00000000,0x00009252,0x00009493,
0x000126dc,0x000126dc,0x000136e4,0x000136e4},
{0x00000000,0x00000000,0x00009292,0x0000a49b,
0x000136e4,0x000136e4,0x0001b725,0x0001b724},
{0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000}
}
},
{ /* version 1 */
{ /* version 1, passes 0 */
{0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000001},
{0x00000000,0x00000000,0x00000009,0x00000009,
0x00000009,0x00000009,0x00000009,0x00000009},
{0x00000000,0x00000000,0x00000049,0x00000049,
0x00000049,0x00000049,0x00000049,0x00000049},
{0x00000000,0x00000000,0x00000049,0x00000049,
0x00000049,0x00000249,0x0000024a,0x0000024a},
{0x00000000,0x00000000,0x00000049,0x00000249,
0x00000249,0x00000249,0x0000024a,0x00001252},
{0x00000000,0x00000000,0x00000249,0x00000249,
0x00000249,0x0000124a,0x00001252,0x00001252},
{0x00000000,0x00000000,0x00000249,0x00000249,
0x0000124a,0x0000124a,0x00009292,0x00009292},
{0x00000000,0x00000000,0x00000249,0x00001249,
0x0000124a,0x00009252,0x00009292,0x00009292},
{0x00000000,0x00000000,0x00000249,0x00001249,
0x00009252,0x00009292,0x00009292,0x00009292},
{0x00000000,0x00000000,0x00000249,0x00001249,
0x00009252,0x00009292,0x00009493,0x00009493},
{0x00000000,0x00000000,0x00000249,0x0000924a,
0x00009252,0x00009493,0x00009493,0x00009493},
{0x00000000,0x00000000,0x00000249,0x0000924a,
0x00009292,0x00009493,0x00009493,0x00009493},
{0x00000000,0x00000000,0x00000249,0x00009252,
0x00009492,0x00009493,0x0000a49b,0x0000a49b},
{0x00000000,0x00000000,0x00001249,0x00009292,
0x00009492,0x000124db,0x000124db,0x000124db},
{0x00000000,0x00000000,0x0000924a,0x00009493,
0x0000a493,0x000126dc,0x000126dc,0x000126dc},
{0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000}
},
{ /* version 1, passes 1 */
{0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000},
{0x00000000,0x00000000,0x00000049,0x00000009,
0x00000049,0x00000009,0x00000001,0x00000000},
{0x00000000,0x00000000,0x00000049,0x00000049,
0x00000049,0x00000049,0x00000049,0x00000000},
{0x00000000,0x00000000,0x00000249,0x00000049,
0x00000249,0x00000049,0x0000024a,0x00000001},
{0x00000000,0x00000000,0x00000249,0x00000249,
0x00000249,0x00000249,0x0000024a,0x00000001},
{0x00000000,0x00000000,0x00000249,0x00000249,
0x00000249,0x00000249,0x0000024a,0x00000001},
{0x00000000,0x00000000,0x00000249,0x00000249,
0x00000249,0x00000249,0x0000024a,0x00000009},
{0x00000000,0x00000000,0x00000249,0x00000249,
0x0000124a,0x0000124a,0x0000024a,0x00000009},
{0x00000000,0x00000000,0x00000249,0x00000249,
0x0000124a,0x0000124a,0x0000024a,0x00000009},
{0x00000000,0x00000000,0x00001249,0x00001249,
0x0000124a,0x00009252,0x00001252,0x00000049},
{0x00000000,0x00000000,0x00001249,0x00001249,
0x0000124a,0x00009292,0x00001252,0x00000049},
{0x00000000,0x00000000,0x00001249,0x00001249,
0x0000124a,0x00009292,0x00001252,0x00000049},
{0x00000000,0x00000000,0x00001249,0x00001249,
0x00009252,0x00009292,0x00001252,0x0000024a},
{0x00000000,0x00000000,0x00001249,0x00001249,
0x00009292,0x00009292,0x00001252,0x0000024a},
{0x00000000,0x00000000,0x0000924a,0x0000924a,
0x00009492,0x00009493,0x00009292,0x00001252},
{0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000}
}
},
{ /* version 2 */
{ /* version 2, passes 0 */
{0x00000000,0x00000000,0x00000049,0x00000049,
0x00000049,0x00000049,0x0000024a,0x0000024a},
{0x00000000,0x00000000,0x00000249,0x00000249,
0x00000249,0x0000124a,0x00001252,0x00009292},
{0x00000000,0x00000000,0x00000249,0x00000249,
0x0000124a,0x00009252,0x00009292,0x00009292},
{0x00000000,0x00000000,0x00000249,0x00001249,
0x0000124a,0x00009292,0x00009493,0x00009493},
{0x00000000,0x00000000,0x00000249,0x00001249,
0x00009252,0x00009493,0x00009493,0x0000a49b},
{0x00000000,0x00000000,0x00000249,0x0000924a,
0x00009292,0x00009493,0x0000a49b,0x0000a49b},
{0x00000000,0x00000000,0x00001249,0x0000924a,
0x00009292,0x00009493,0x0000a49b,0x000124db},
{0x00000000,0x00000000,0x00001249,0x00009252,
0x00009492,0x0000a49b,0x0000a49b,0x000124db},
{0x00000000,0x00000000,0x00001249,0x00009292,
0x00009492,0x000124db,0x000124db,0x000126dc},
{0x00000000,0x00000000,0x00001249,0x00009292,
0x0000a493,0x000124db,0x000126dc,0x000126dc},
{0x00000000,0x00000000,0x00001249,0x00009493,
0x0000a493,0x000124db,0x000126dc,0x000136e4},
{0x00000000,0x00000000,0x00001249,0x00009493,
0x0000a493,0x000126dc,0x000136e4,0x000136e4},
{0x00000000,0x00000000,0x0000924a,0x00009493,
0x0001249b,0x000126dc,0x000136e4,0x000136e4},
{0x00000000,0x00000000,0x0000924a,0x0000a49b,
0x000124db,0x000136e4,0x000136e4,0x0001b724},
{0x00000000,0x00000000,0x00009252,0x000124db,
0x000126dc,0x0001b724,0x0001b725,0x0001b925},
{0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000}
},
{ /* version 2, passes 1 */
{0x00000000,0x00000000,0x00000049,0x00000049,
0x00000049,0x00000049,0x00000049,0x00000049},
{0x00000000,0x00000000,0x00000249,0x00000249,
0x00000249,0x00000249,0x0000024a,0x00000049},
{0x00000000,0x00000000,0x00001249,0x00000249,
0x0000124a,0x0000124a,0x00001252,0x00000049},
{0x00000000,0x00000000,0x00001249,0x00001249,
0x0000124a,0x0000124a,0x00009292,0x0000024a},
{0x00000000,0x00000000,0x00001249,0x00001249,
0x00009252,0x00009292,0x00009292,0x0000024a},
{0x00000000,0x00000000,0x00001249,0x00001249,
0x00009252,0x00009292,0x0000a49b,0x0000024a},
{0x00000000,0x00000000,0x00001249,0x00001249,
0x00009292,0x00009493,0x0000a49b,0x00001252},
{0x00000000,0x00000000,0x00001249,0x00001249,
0x00009292,0x00009493,0x0000a49b,0x00001252},
{0x00000000,0x00000000,0x00001249,0x0000924a,
0x00009492,0x0000a49b,0x0000a49b,0x00001252},
{0x00000000,0x00000000,0x00001249,0x00009252,
0x00009492,0x0000a49b,0x0000a49b,0x00009292},
{0x00000000,0x00000000,0x00001249,0x00009292,
0x00009492,0x0000a49b,0x0000a49b,0x00009292},
{0x00000000,0x00000000,0x00001249,0x00009493,
0x0000a493,0x0000a49b,0x0000a49b,0x00009292},
{0x00000000,0x00000000,0x00001249,0x00009493,
0x0000a493,0x0000a49b,0x0000a49b,0x00009493},
{0x00000000,0x00000000,0x0000924a,0x00009493,
0x0000a493,0x000124db,0x0000a49b,0x00009493},
{0x00000000,0x00000000,0x00009252,0x0000a49b,
0x0001249b,0x000126dc,0x000124db,0x0000a49b},
{0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000}
}
},
{ /* version 3 */
{ /* version 3, passes 0 */
{0x00000000,0x00000000,0x00000249,0x00000249,
0x0000124a,0x0000124a,0x00009292,0x00009292},
{0x00000000,0x00000000,0x00001249,0x00001249,
0x00009292,0x00009493,0x0000a49b,0x0000a49b},
{0x00000000,0x00000000,0x00001249,0x0000924a,
0x00009492,0x0000a49b,0x0000a49b,0x000124db},
{0x00000000,0x00000000,0x00001249,0x00009292,
0x00009492,0x000124db,0x000126dc,0x000126dc},
{0x00000000,0x00000000,0x00001249,0x00009493,
0x0000a493,0x000124db,0x000126dc,0x000126dc},
{0x00000000,0x00000000,0x00001249,0x00009493,
0x0000a493,0x000126dc,0x000136e4,0x000136e4},
{0x00000000,0x00000000,0x00001249,0x00009493,
0x0000a493,0x000126dc,0x000136e4,0x0001b724},
{0x00000000,0x00000000,0x00001249,0x00009493,
0x0001249b,0x000126dc,0x000136e4,0x0001b724},
{0x00000000,0x00000000,0x0000924a,0x0000a49b,
0x0001249b,0x000126dc,0x000136e4,0x0001b724},
{0x00000000,0x00000000,0x0000924a,0x0000a49b,
0x0001249b,0x000136e4,0x0001b725,0x0001b724},
{0x00000000,0x00000000,0x0000924a,0x0000a49b,
0x000124db,0x000136e4,0x0001b725,0x0001b925},
{0x00000000,0x00000000,0x00009292,0x0000a49b,
0x000126dc,0x000136e4,0x0001b92d,0x0001b925},
{0x00000000,0x00000000,0x00009292,0x0000a49b,
0x000126dc,0x0001b724,0x0001b92d,0x0001c92d},
{0x00000000,0x00000000,0x00009492,0x000124db,
0x000126dc,0x0001b724,0x0001c96e,0x0001c92d},
{0x00000000,0x00000000,0x0000a492,0x000126db,
0x000136e4,0x0001b925,0x00025bb6,0x00024b77},
{0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000}
},
{ /* version 3, passes 1 */
{0x00000000,0x00000000,0x00001249,0x00000249,
0x0000124a,0x0000124a,0x00001252,0x00001252},
{0x00000000,0x00000000,0x00001249,0x00001249,
0x00009252,0x00009292,0x00009292,0x00001252},
{0x00000000,0x00000000,0x00001249,0x0000924a,
0x00009492,0x00009493,0x0000a49b,0x00001252},
{0x00000000,0x00000000,0x00001249,0x00009252,
0x00009492,0x0000a49b,0x0000a49b,0x00009292},
{0x00000000,0x00000000,0x00001249,0x00009292,
0x00009492,0x0000a49b,0x0000a49b,0x00009292},
{0x00000000,0x00000000,0x00001249,0x00009493,
0x0000a493,0x0000a49b,0x000126dc,0x00009292},
{0x00000000,0x00000000,0x0000924a,0x00009493,
0x0000a493,0x0000a49b,0x000126dc,0x00009493},
{0x00000000,0x00000000,0x0000924a,0x00009493,
0x0000a493,0x0000a49b,0x000126dc,0x00009493},
{0x00000000,0x00000000,0x0000924a,0x00009493,
0x0000a493,0x000124db,0x000126dc,0x00009493},
{0x00000000,0x00000000,0x0000924a,0x00009493,
0x0000a493,0x000124db,0x000126dc,0x0000a49b},
{0x00000000,0x00000000,0x0000924a,0x0000a49b,
0x0000a493,0x000124db,0x000126dc,0x0000a49b},
{0x00000000,0x00000000,0x0000924a,0x0000a49b,
0x0001249b,0x000126dc,0x000126dc,0x0000a49b},
{0x00000000,0x00000000,0x0000924a,0x0000a49b,
0x000124db,0x000136e4,0x000126dc,0x000124db},
{0x00000000,0x00000000,0x00009492,0x0000a49b,
0x000136e4,0x000136e4,0x000126dc,0x000124db},
{0x00000000,0x00000000,0x0000a492,0x000124db,
0x0001b724,0x0001b724,0x000136e4,0x000126dc},
{0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000}
}
},
{ /* version 4 */
{ /* version 4, passes 0 */
{0x00000000,0x00000000,0x00000049,0x00000049,
0x00000049,0x00000049,0x00000049,0x00000049},
{0x00000000,0x00000000,0x00000249,0x00000049,
0x00000249,0x00000249,0x0000024a,0x00000049},
{0x00000000,0x00000000,0x00000249,0x00000249,
0x0000124a,0x00009252,0x00001252,0x0000024a},
{0x00000000,0x00000000,0x00001249,0x00001249,
0x00009252,0x00009292,0x00009493,0x00001252},
{0x00000000,0x00000000,0x00001249,0x0000924a,
0x00009292,0x00009493,0x00009493,0x00001252},
{0x00000000,0x00000000,0x00001249,0x00009292,
0x00009492,0x0000a49b,0x0000a49b,0x00009292},
{0x00000000,0x00000000,0x00001249,0x00009493,
0x0000a493,0x000124db,0x000124db,0x00009493},
{0x00000000,0x00000000,0x0000924a,0x00009493,
0x0000a493,0x000124db,0x000126dc,0x0000a49b},
{0x00000000,0x00000000,0x0000924a,0x00009493,
0x0000a493,0x000124db,0x000126dc,0x0000a49b},
{0x00000000,0x00000000,0x0000924a,0x00009493,
0x0001249b,0x000126dc,0x000126dc,0x000124db},
{0x00000000,0x00000000,0x00009252,0x00009493,
0x000124db,0x000136e4,0x000136e4,0x000126dc},
{0x00000000,0x00000000,0x00009252,0x0000a49b,
0x000124db,0x000136e4,0x000136e4,0x000126dc},
{0x00000000,0x00000000,0x00009292,0x0000a49b,
0x000126dc,0x000136e4,0x000136e4,0x000136e4},
{0x00000000,0x00000000,0x00009492,0x0000a49b,
0x000126dc,0x0001b724,0x0001b725,0x0001b724},
{0x00000000,0x00000000,0x0000a492,0x000124db,
0x000136e4,0x0001b925,0x0001b92d,0x0001b925},
{0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000}
},
{ /* version 4, passes 1 */
{0x00000000,0x00000000,0x00000249,0x00000049,
0x00000009,0x00000009,0x00000009,0x00000009},
{0x00000000,0x00000000,0x00000249,0x00000249,
0x00000049,0x00000049,0x00000009,0x00000009},
{0x00000000,0x00000000,0x00001249,0x00001249,
0x0000124a,0x00000249,0x00000049,0x00000049},
{0x00000000,0x00000000,0x00001249,0x00001249,
0x0000124a,0x0000124a,0x00000049,0x00000049},
{0x00000000,0x00000000,0x00001249,0x00001249,
0x00009252,0x0000124a,0x0000024a,0x0000024a},
{0x00000000,0x00000000,0x00001249,0x0000924a,
0x00009252,0x0000124a,0x0000024a,0x0000024a},
{0x00000000,0x00000000,0x00001249,0x00009292,
0x00009492,0x00009252,0x00001252,0x00001252},
{0x00000000,0x00000000,0x00001249,0x00009493,
0x0000a493,0x00009292,0x00009292,0x00001252},
{0x00000000,0x00000000,0x0000924a,0x00009493,
0x0000a493,0x00009292,0x00009292,0x00009292},
{0x00000000,0x00000000,0x0000924a,0x00009493,
0x0000a493,0x00009493,0x00009493,0x00009292},
{0x00000000,0x00000000,0x0000924a,0x0000a49b,
0x0000a493,0x0000a49b,0x00009493,0x00009493},
{0x00000000,0x00000000,0x0000924a,0x0000a49b,
0x0000a493,0x0000a49b,0x0000a49b,0x00009493},
{0x00000000,0x00000000,0x0000924a,0x0000a49b,
0x0001249b,0x000124db,0x0000a49b,0x0000a49b},
{0x00000000,0x00000000,0x0000924a,0x0000a49b,
0x000136e4,0x000126dc,0x000124db,0x0000a49b},
{0x00000000,0x00000000,0x00009252,0x000124db,
0x0001b724,0x000136e4,0x000126dc,0x000124db},
{0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000}
}
},
{ /* version 5 */
{ /* version 5, passes 0 */
{0x00000000,0x00000000,0x00000249,0x00000249,
0x00000249,0x00000249,0x00001252,0x00001252},
{0x00000000,0x00000000,0x00001249,0x00001249,
0x00009252,0x00009292,0x00009292,0x00001252},
{0x00000000,0x00000000,0x00001249,0x0000924a,
0x00009492,0x0000a49b,0x0000a49b,0x00009292},
{0x00000000,0x00000000,0x00001249,0x00009493,
0x0000a493,0x0000a49b,0x000124db,0x00009493},
{0x00000000,0x00000000,0x00001249,0x00009493,
0x0000a493,0x000124db,0x000126dc,0x00009493},
{0x00000000,0x00000000,0x0000924a,0x00009493,
0x0000a493,0x000126dc,0x000126dc,0x0000a49b},
{0x00000000,0x00000000,0x0000924a,0x0000a49b,
0x0001249b,0x000126dc,0x000136e4,0x000124db},
{0x00000000,0x00000000,0x0000924a,0x0000a49b,
0x000126dc,0x000136e4,0x000136e4,0x000126dc},
{0x00000000,0x00000000,0x00009292,0x0000a49b,
0x000126dc,0x000136e4,0x000136e4,0x000126dc},
{0x00000000,0x00000000,0x00009292,0x0000a49b,
0x000126dc,0x0001b724,0x0001b725,0x000136e4},
{0x00000000,0x00000000,0x00009292,0x0000a49b,
0x000136e4,0x0001b724,0x0001b92d,0x0001b724},
{0x00000000,0x00000000,0x00009492,0x0000a49b,
0x000136e4,0x0001b724,0x0001b92d,0x0001b724},
{0x00000000,0x00000000,0x00009492,0x000124db,
0x000136e4,0x0001b925,0x0001c96e,0x0001b925},
{0x00000000,0x00000000,0x00009492,0x000124db,
0x0001b724,0x0001b925,0x0001c96e,0x0001c92d},
{0x00000000,0x00000000,0x0000a492,0x000126db,
0x0001c924,0x0002496d,0x00025bb6,0x00024b77},
{0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000}
},
{ /* version 5, passes 1 */
{0x00000000,0x00000000,0x00001249,0x00000249,
0x00000249,0x00000249,0x0000024a,0x0000024a},
{0x00000000,0x00000000,0x00001249,0x00001249,
0x0000124a,0x0000124a,0x0000024a,0x0000024a},
{0x00000000,0x00000000,0x00001249,0x0000924a,
0x00009252,0x00009252,0x0000024a,0x0000024a},
{0x00000000,0x00000000,0x00001249,0x00009292,
0x00009492,0x0000a49b,0x00001252,0x00001252},
{0x00000000,0x00000000,0x0000924a,0x00009493,
0x0000a493,0x0000a49b,0x00001252,0x00001252},
{0x00000000,0x00000000,0x0000924a,0x00009493,
0x0000a493,0x0000a49b,0x00009292,0x00001252},
{0x00000000,0x00000000,0x0000924a,0x0000a49b,
0x0000a493,0x0000a49b,0x00009292,0x00009292},
{0x00000000,0x00000000,0x0000924a,0x0000a49b,
0x0000a493,0x0000a49b,0x00009493,0x00009292},
{0x00000000,0x00000000,0x0000924a,0x0000a49b,
0x0001249b,0x000124db,0x00009493,0x00009292},
{0x00000000,0x00000000,0x0000924a,0x0000a49b,
0x0001249b,0x000124db,0x00009493,0x00009493},
{0x00000000,0x00000000,0x0000924a,0x0000a49b,
0x000124db,0x000124db,0x0000a49b,0x00009493},
{0x00000000,0x00000000,0x0000924a,0x000124db,
0x000126dc,0x000126dc,0x0000a49b,0x00009493},
{0x00000000,0x00000000,0x0000924a,0x000124db,
0x000136e4,0x000126dc,0x000124db,0x0000a49b},
{0x00000000,0x00000000,0x00009292,0x000124db,
0x000136e4,0x000126dc,0x000124db,0x0000a49b},
{0x00000000,0x00000000,0x00009492,0x000126db,
0x0001b724,0x000136e4,0x000126dc,0x000124db},
{0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000}
}
},
{ /* version 6 */
{ /* version 6, passes 0 */
{0x00000000,0x00000000,0x00001249,0x00001249,
0x00009252,0x00009292,0x00009493,0x00009493},
{0x00000000,0x00000000,0x00001249,0x00009292,
0x0000a493,0x0000a49b,0x0000a49b,0x00009493},
{0x00000000,0x00000000,0x00001249,0x00009493,
0x0000a493,0x000124db,0x000124db,0x0000a49b},
{0x00000000,0x00000000,0x0000924a,0x00009493,
0x0000a493,0x000126dc,0x000126dc,0x0000a49b},
{0x00000000,0x00000000,0x0000924a,0x0000a49b,
0x0001249b,0x000126dc,0x000136e4,0x000124db},
{0x00000000,0x00000000,0x0000924a,0x0000a49b,
0x000126dc,0x000136e4,0x000136e4,0x000126dc},
{0x00000000,0x00000000,0x00009292,0x0000a49b,
0x000126dc,0x0001b724,0x0001b725,0x000126dc},
{0x00000000,0x00000000,0x00009292,0x0000a49b,
0x000136e4,0x0001b724,0x0001b92d,0x000136e4},
{0x00000000,0x00000000,0x00009492,0x0000a49b,
0x000136e4,0x0001b724,0x0001b92d,0x0001b724},
{0x00000000,0x00000000,0x00009492,0x000124db,
0x000136e4,0x0001b724,0x0001b92d,0x0001b724},
{0x00000000,0x00000000,0x00009492,0x000124db,
0x000136e4,0x0001b925,0x0001b92d,0x0001b925},
{0x00000000,0x00000000,0x00009492,0x000124db,
0x0001b724,0x0001b925,0x0001c96e,0x0001c92d},
{0x00000000,0x00000000,0x0000a492,0x000124db,
0x0001b724,0x0001c92d,0x0001c96e,0x0001c92d},
{0x00000000,0x00000000,0x0000a492,0x000124db,
0x0001b724,0x0001c92d,0x00024b76,0x0002496e},
{0x00000000,0x00000000,0x00012492,0x000126db,
0x0001c924,0x00024b6d,0x0002ddb6,0x00025bbf},
{0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000}
},
{ /* version 6, passes 1 */
{0x00000000,0x00000000,0x00001249,0x00001249,
0x0000124a,0x0000124a,0x00001252,0x00001252},
{0x00000000,0x00000000,0x00001249,0x00009292,
0x00009492,0x00009252,0x00001252,0x00001252},
{0x00000000,0x00000000,0x0000924a,0x00009493,
0x0000a493,0x00009292,0x00001252,0x00001252},
{0x00000000,0x00000000,0x0000924a,0x0000a49b,
0x0000a493,0x0000a49b,0x00009292,0x00009292},
{0x00000000,0x00000000,0x0000924a,0x0000a49b,
0x0000a493,0x0000a49b,0x00009292,0x00009292},
{0x00000000,0x00000000,0x0000924a,0x0000a49b,
0x0001249b,0x0000a49b,0x00009493,0x00009292},
{0x00000000,0x00000000,0x0000924a,0x0000a49b,
0x000124db,0x000124db,0x00009493,0x00009493},
{0x00000000,0x00000000,0x0000924a,0x0000a49b,
0x000124db,0x000124db,0x0000a49b,0x00009493},
{0x00000000,0x00000000,0x0000924a,0x000124db,
0x000126dc,0x000124db,0x0000a49b,0x00009493},
{0x00000000,0x00000000,0x0000924a,0x000124db,
0x000126dc,0x000126dc,0x0000a49b,0x0000a49b},
{0x00000000,0x00000000,0x0000924a,0x000124db,
0x000136e4,0x000126dc,0x000124db,0x0000a49b},
{0x00000000,0x00000000,0x00009492,0x000126db,
0x000136e4,0x000126dc,0x000124db,0x0000a49b},
{0x00000000,0x00000000,0x00009492,0x000126db,
0x0001b724,0x000136e4,0x000126dc,0x000124db},
{0x00000000,0x00000000,0x00009492,0x000126db,
0x0001b724,0x000136e4,0x000126dc,0x000124db},
{0x00000000,0x00000000,0x0000a492,0x000136db,
0x0001c924,0x0001b724,0x000136e4,0x000126dc},
{0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000}
}
},
{ /* version 7 */
{ /* version 7, passes 0 */
{0x00000000,0x00000000,0x00001249,0x00001249,
0x00009252,0x00009292,0x00009493,0x00009493},
{0x00000000,0x00000000,0x00001249,0x00009493,
0x0000a493,0x000124db,0x000126dc,0x00009493},
{0x00000000,0x00000000,0x00001249,0x0000a49b,
0x0001249b,0x000126dc,0x000126dc,0x0000a49b},
{0x00000000,0x00000000,0x0000924a,0x0000a49b,
0x0001249b,0x000126dc,0x000136e4,0x0000a49b},
{0x00000000,0x00000000,0x0000924a,0x0000a49b,
0x000126dc,0x000136e4,0x0001b725,0x000124db},
{0x00000000,0x00000000,0x00009292,0x0000a49b,
0x000136e4,0x0001b724,0x0001b725,0x000126dc},
{0x00000000,0x00000000,0x00009292,0x000124db,
0x000136e4,0x0001b724,0x0001b725,0x000126dc},
{0x00000000,0x00000000,0x00009492,0x000124db,
0x000136e4,0x0001b724,0x0001c96e,0x000136e4},
{0x00000000,0x00000000,0x00009492,0x000124db,
0x000136e4,0x0001c92d,0x0001c96e,0x0001b724},
{0x00000000,0x00000000,0x0000a492,0x000124db,
0x000136e4,0x0001c92d,0x0001c96e,0x0001b724},
{0x00000000,0x00000000,0x0000a492,0x000124db,
0x0001b724,0x0001c92d,0x0001c96e,0x0001b925},
{0x00000000,0x00000000,0x0000a492,0x000126db,
0x0001b724,0x0001c92d,0x00024b76,0x0001c92d},
{0x00000000,0x00000000,0x0000a492,0x000126db,
0x0001b924,0x0001c92d,0x00024b76,0x0001c92d},
{0x00000000,0x00000000,0x0000a492,0x000126db,
0x0001b924,0x0001c92d,0x00024b76,0x0002496e},
{0x00000000,0x00000000,0x00012492,0x000136db,
0x00024924,0x00024b6d,0x0002ddb6,0x00025bbf},
{0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000}
},
{ /* version 7, passes 1 */
{0x00000000,0x00000000,0x00001249,0x00001249,
0x0000124a,0x0000124a,0x00001252,0x00001252},
{0x00000000,0x00000000,0x0000924a,0x00009493,
0x00009492,0x00009292,0x00001252,0x00001252},
{0x00000000,0x00000000,0x0000924a,0x0000a49b,
0x0000a493,0x0000a49b,0x00001252,0x00001252},
{0x00000000,0x00000000,0x0000924a,0x0000a49b,
0x0000a493,0x0000a49b,0x00009292,0x00009292},
{0x00000000,0x00000000,0x0000924a,0x0000a49b,
0x0000a493,0x0000a49b,0x00009292,0x00009292},
{0x00000000,0x00000000,0x0000924a,0x0000a49b,
0x000126dc,0x0000a49b,0x00009493,0x00009292},
{0x00000000,0x00000000,0x0000924a,0x000124db,
0x000126dc,0x000124db,0x00009493,0x00009493},
{0x00000000,0x00000000,0x0000924a,0x000124db,
0x000136e4,0x000124db,0x0000a49b,0x00009493},
{0x00000000,0x00000000,0x0000924a,0x000136db,
0x0001b724,0x000124db,0x0000a49b,0x00009493},
{0x00000000,0x00000000,0x0000924a,0x000136db,
0x0001b724,0x000126dc,0x0000a49b,0x0000a49b},
{0x00000000,0x00000000,0x00009292,0x000136db,
0x0001b724,0x000126dc,0x000124db,0x0000a49b},
{0x00000000,0x00000000,0x00009492,0x000136db,
0x0001b724,0x000126dc,0x000124db,0x0000a49b},
{0x00000000,0x00000000,0x0000a492,0x000136db,
0x0001b724,0x000136e4,0x000126dc,0x000124db},
{0x00000000,0x00000000,0x0000a492,0x000136db,
0x0001b724,0x000136e4,0x000126dc,0x000124db},
{0x00000000,0x00000000,0x00012492,0x0001b6db,
0x0001c924,0x0001b724,0x000136e4,0x000126dc},
{0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000}
}
}
};
@@ -0,0 +1,36 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/* Linux driver for Philips webcam
(C) 2004-2006 Luc Saillard (luc@saillard.org)
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.
Please send bug reports and support requests to <luc@saillard.org>.
The decompression routines have been implemented by reverse-engineering the
Nemosoft binary pwcx module. Caveat emptor.
*/
/* Entries for the Kiara (730/740/750) camera */
#ifndef PWC_KIARA_H
#define PWC_KIARA_H
#include "pwc.h"
#define PWC_FPS_MAX_KIARA 6
struct Kiara_table_entry
{
char alternate; /* USB alternate interface */
unsigned short packetsize; /* Normal packet size */
unsigned short bandlength; /* Bandlength when decompressing */
unsigned char mode[12]; /* precomputed mode settings for cam */
};
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 Kiara_fps_vector[PWC_FPS_MAX_KIARA];
#endif
@@ -0,0 +1,81 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/* Linux driver for Philips webcam
Various miscellaneous functions and tables.
(C) 1999-2003 Nemosoft Unv.
(C) 2004-2006 Luc Saillard (luc@saillard.org)
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.
Please send bug reports and support requests to <luc@saillard.org>.
The decompression routines have been implemented by reverse-engineering the
Nemosoft binary pwcx module. Caveat emptor.
*/
#include "pwc.h"
const int pwc_image_sizes[PSZ_MAX][2] =
{
{ 128, 96 }, /* sqcif */
{ 160, 120 }, /* qsif */
{ 176, 144 }, /* qcif */
{ 320, 240 }, /* sif */
{ 352, 288 }, /* cif */
{ 640, 480 }, /* vga */
};
/* x,y -> PSZ_ */
int pwc_get_size(struct pwc_device *pdev, int width, int height)
{
int i;
/* Find the largest size supported by the camera that fits into the
requested size. */
for (i = PSZ_MAX - 1; i >= 0; i--) {
if (!(pdev->image_mask & (1 << i)))
continue;
if (pwc_image_sizes[i][0] <= width &&
pwc_image_sizes[i][1] <= height)
return i;
}
/* No mode found, return the smallest mode we have */
for (i = 0; i < PSZ_MAX; i++) {
if (pdev->image_mask & (1 << i))
return i;
}
/* Never reached there always is at least one supported mode */
return 0;
}
/* initialize variables depending on type and decompressor */
void pwc_construct(struct pwc_device *pdev)
{
if (DEVICE_USE_CODEC1(pdev->type)) {
pdev->image_mask = 1 << PSZ_SQCIF | 1 << PSZ_QCIF | 1 << PSZ_CIF;
pdev->vcinterface = 2;
pdev->vendpoint = 4;
pdev->frame_header_size = 0;
pdev->frame_trailer_size = 0;
} else if (DEVICE_USE_CODEC3(pdev->type)) {
pdev->image_mask = 1 << PSZ_QSIF | 1 << PSZ_SIF | 1 << PSZ_VGA;
pdev->vcinterface = 3;
pdev->vendpoint = 5;
pdev->frame_header_size = TOUCAM_HEADER_SIZE;
pdev->frame_trailer_size = TOUCAM_TRAILER_SIZE;
} else /* if (DEVICE_USE_CODEC2(pdev->type)) */ {
pdev->image_mask = 1 << PSZ_SQCIF | 1 << PSZ_QSIF | 1 << PSZ_QCIF | 1 << PSZ_SIF | 1 << PSZ_CIF | 1 << PSZ_VGA;
pdev->vcinterface = 3;
pdev->vendpoint = 4;
pdev->frame_header_size = 0;
pdev->frame_trailer_size = 0;
}
}
@@ -0,0 +1,67 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* SQCIF */
{
{0, 0, {0x04, 0x01, 0x03}},
{8, 0, {0x05, 0x01, 0x03}},
{7, 0, {0x08, 0x01, 0x03}},
{7, 0, {0x0A, 0x01, 0x03}},
{6, 0, {0x0C, 0x01, 0x03}},
{5, 0, {0x0F, 0x01, 0x03}},
{4, 0, {0x14, 0x01, 0x03}},
{3, 0, {0x18, 0x01, 0x03}},
},
/* QSIF */
{
{0},
{0},
{0},
{0},
{0},
{0},
{0},
{0},
},
/* QCIF */
{
{0, 0, {0x04, 0x01, 0x02}},
{8, 0, {0x05, 0x01, 0x02}},
{7, 0, {0x08, 0x01, 0x02}},
{6, 0, {0x0A, 0x01, 0x02}},
{5, 0, {0x0C, 0x01, 0x02}},
{4, 0, {0x0F, 0x01, 0x02}},
{1, 0, {0x14, 0x01, 0x02}},
{1, 0, {0x18, 0x01, 0x02}},
},
/* SIF */
{
{0},
{0},
{0},
{0},
{0},
{0},
{0},
{0},
},
/* CIF */
{
{4, 0, {0x04, 0x01, 0x01}},
{7, 1, {0x05, 0x03, 0x01}},
{6, 1, {0x08, 0x03, 0x01}},
{4, 1, {0x0A, 0x03, 0x01}},
{3, 1, {0x0C, 0x03, 0x01}},
{2, 1, {0x0F, 0x03, 0x01}},
{0},
{0},
},
/* VGA */
{
{0},
{0},
{0},
{0},
{0},
{0},
{0},
{0},
},
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,51 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/* Linux driver for Philips webcam
(C) 2004-2006 Luc Saillard (luc@saillard.org)
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.
Please send bug reports and support requests to <luc@saillard.org>.
The decompression routines have been implemented by reverse-engineering the
Nemosoft binary pwcx module. Caveat emptor.
*/
/* This tables contains entries for the 675/680/690 (Timon) camera, with
4 different qualities (no compression, low, medium, high).
It lists the bandwidth requirements for said mode by its alternate interface
number. An alternate of 0 means that the mode is unavailable.
There are 6 * 4 * 4 entries:
6 different resolutions subqcif, qsif, qcif, sif, cif, vga
6 framerates: 5, 10, 15, 20, 25, 30
4 compression modi: none, low, medium, high
When an uncompressed mode is not available, the next available compressed mode
will be chosen (unless the decompressor is absent). Sometimes there are only
1 or 2 compressed modes available; in that case entries are duplicated.
*/
#ifndef PWC_TIMON_H
#define PWC_TIMON_H
#include "pwc.h"
#define PWC_FPS_MAX_TIMON 6
struct Timon_table_entry
{
char alternate; /* USB alternate interface */
unsigned short packetsize; /* Normal packet size */
unsigned short bandlength; /* Bandlength when decompressing */
unsigned char mode[13]; /* precomputed mode settings for cam */
};
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 Timon_fps_vector[PWC_FPS_MAX_TIMON];
#endif
@@ -0,0 +1,92 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/* Linux driver for Philips webcam
Decompression frontend.
(C) 1999-2003 Nemosoft Unv.
(C) 2004-2006 Luc Saillard (luc@saillard.org)
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.
Please send bug reports and support requests to <luc@saillard.org>.
The decompression routines have been implemented by reverse-engineering the
Nemosoft binary pwcx module. Caveat emptor.
*/
#include <asm/current.h>
#include <asm/types.h>
#include "pwc.h"
#include "pwc-dec1.h"
#include "pwc-dec23.h"
int pwc_decompress(struct pwc_device *pdev, struct pwc_frame_buf *fbuf)
{
int n, line, col;
void *yuv, *image;
u16 *src;
u16 *dsty, *dstu, *dstv;
image = vb2_plane_vaddr(&fbuf->vb.vb2_buf, 0);
yuv = fbuf->data + pdev->frame_header_size; /* Skip header */
/* Raw format; that's easy... */
if (pdev->pixfmt != V4L2_PIX_FMT_YUV420)
{
struct pwc_raw_frame *raw_frame = image;
raw_frame->type = cpu_to_le16(pdev->type);
raw_frame->vbandlength = cpu_to_le16(pdev->vbandlength);
/* cmd_buf is always 4 bytes, but sometimes, only the
* first 3 bytes is filled (Nala case). We can
* determine this using the type of the webcam */
memcpy(raw_frame->cmd, pdev->cmd_buf, 4);
memcpy(raw_frame->rawframe, yuv, pdev->frame_size);
vb2_set_plane_payload(&fbuf->vb.vb2_buf, 0,
struct_size(raw_frame, rawframe, pdev->frame_size));
return 0;
}
vb2_set_plane_payload(&fbuf->vb.vb2_buf, 0,
pdev->width * pdev->height * 3 / 2);
if (pdev->vbandlength == 0) {
/* Uncompressed mode.
*
* We do some byte shuffling here to go from the
* native format to YUV420P.
*/
src = (u16 *)yuv;
n = pdev->width * pdev->height;
dsty = (u16 *)(image);
dstu = (u16 *)(image + n);
dstv = (u16 *)(image + n + n / 4);
for (line = 0; line < pdev->height; line++) {
for (col = 0; col < pdev->width; col += 4) {
*dsty++ = *src++;
*dsty++ = *src++;
if (line & 1)
*dstv++ = *src++;
else
*dstu++ = *src++;
}
}
return 0;
}
/*
* Compressed;
* the decompressor routines will write the data in planar format
* immediately.
*/
if (DEVICE_USE_CODEC1(pdev->type)) {
/* TODO & FIXME */
PWC_ERROR("This chipset is not supported for now\n");
return -ENXIO; /* No such device or address: missing decompressor */
} else {
pwc_dec23_decompress(pdev, yuv, image);
}
return 0;
}
File diff suppressed because it is too large Load Diff
+383
View File
@@ -0,0 +1,383 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/* (C) 1999-2003 Nemosoft Unv.
(C) 2004-2006 Luc Saillard (luc@saillard.org)
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.
Please send bug reports and support requests to <luc@saillard.org>.
The decompression routines have been implemented by reverse-engineering the
Nemosoft binary pwcx module. Caveat emptor.
*/
#ifndef PWC_H
#define PWC_H
#include <linux/module.h>
#include <linux/usb.h>
#include <linux/spinlock.h>
#include <linux/wait.h>
#include <linux/mutex.h>
#include <linux/mm.h>
#include <linux/slab.h>
#include <asm/errno.h>
#include <linux/videodev2.h>
#include <media/v4l2-common.h>
#include <media/v4l2-device.h>
#include <media/v4l2-ioctl.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-fh.h>
#include <media/v4l2-event.h>
#include <media/videobuf2-v4l2.h>
#include <media/videobuf2-vmalloc.h>
#ifdef CONFIG_USB_PWC_INPUT_EVDEV
#include <linux/input.h>
#endif
#include "pwc-dec1.h"
#include "pwc-dec23.h"
/* Version block */
#define PWC_VERSION "10.0.15"
#define PWC_NAME "pwc"
#define PFX PWC_NAME ": "
/* Trace certain actions in the driver */
#define PWC_DEBUG_LEVEL_MODULE BIT(0)
#define PWC_DEBUG_LEVEL_PROBE BIT(1)
#define PWC_DEBUG_LEVEL_OPEN BIT(2)
#define PWC_DEBUG_LEVEL_READ BIT(3)
#define PWC_DEBUG_LEVEL_MEMORY BIT(4)
#define PWC_DEBUG_LEVEL_FLOW BIT(5)
#define PWC_DEBUG_LEVEL_SIZE BIT(6)
#define PWC_DEBUG_LEVEL_IOCTL BIT(7)
#define PWC_DEBUG_LEVEL_TRACE BIT(8)
#define PWC_DEBUG_MODULE(fmt, args...) PWC_DEBUG(MODULE, fmt, ##args)
#define PWC_DEBUG_PROBE(fmt, args...) PWC_DEBUG(PROBE, fmt, ##args)
#define PWC_DEBUG_OPEN(fmt, args...) PWC_DEBUG(OPEN, fmt, ##args)
#define PWC_DEBUG_READ(fmt, args...) PWC_DEBUG(READ, fmt, ##args)
#define PWC_DEBUG_MEMORY(fmt, args...) PWC_DEBUG(MEMORY, fmt, ##args)
#define PWC_DEBUG_FLOW(fmt, args...) PWC_DEBUG(FLOW, fmt, ##args)
#define PWC_DEBUG_SIZE(fmt, args...) PWC_DEBUG(SIZE, fmt, ##args)
#define PWC_DEBUG_IOCTL(fmt, args...) PWC_DEBUG(IOCTL, fmt, ##args)
#define PWC_DEBUG_TRACE(fmt, args...) PWC_DEBUG(TRACE, fmt, ##args)
#ifdef CONFIG_USB_PWC_DEBUG
#define PWC_DEBUG_LEVEL (PWC_DEBUG_LEVEL_MODULE)
#define PWC_DEBUG(level, fmt, args...) do {\
if ((PWC_DEBUG_LEVEL_ ##level) & pwc_trace) \
printk(KERN_DEBUG PFX fmt, ##args); \
} while (0)
#define PWC_ERROR(fmt, args...) printk(KERN_ERR PFX fmt, ##args)
#define PWC_WARNING(fmt, args...) printk(KERN_WARNING PFX fmt, ##args)
#define PWC_INFO(fmt, args...) printk(KERN_INFO PFX fmt, ##args)
#define PWC_TRACE(fmt, args...) PWC_DEBUG(TRACE, fmt, ##args)
#else /* if ! CONFIG_USB_PWC_DEBUG */
#define PWC_ERROR(fmt, args...) printk(KERN_ERR PFX fmt, ##args)
#define PWC_WARNING(fmt, args...) printk(KERN_WARNING PFX fmt, ##args)
#define PWC_INFO(fmt, args...) printk(KERN_INFO PFX fmt, ##args)
#define PWC_TRACE(fmt, args...) do { } while(0)
#define PWC_DEBUG(level, fmt, args...) do { } while(0)
#define pwc_trace 0
#endif
/* Defines for ToUCam cameras */
#define TOUCAM_HEADER_SIZE 8
#define TOUCAM_TRAILER_SIZE 4
#define FEATURE_MOTOR_PANTILT 0x0001
#define FEATURE_CODEC1 0x0002
#define FEATURE_CODEC2 0x0004
#define MAX_WIDTH 640
#define MAX_HEIGHT 480
/* Ignore errors in the first N frames, to allow for startup delays */
#define FRAME_LOWMARK 5
/* Size and number of buffers for the ISO pipe. */
#define MAX_ISO_BUFS 3
#define ISO_FRAMES_PER_DESC 10
#define ISO_MAX_FRAME_SIZE 960
#define ISO_BUFFER_SIZE (ISO_FRAMES_PER_DESC * ISO_MAX_FRAME_SIZE)
/* Maximum size after decompression is 640x480 YUV data, 1.5 * 640 * 480 */
#define PWC_FRAME_SIZE (460800 + TOUCAM_HEADER_SIZE + TOUCAM_TRAILER_SIZE)
/* Absolute minimum and maximum number of buffers available for mmap() */
#define MIN_FRAMES 2
#define MAX_FRAMES 16
/* Some macros to quickly find the type of a webcam */
#define DEVICE_USE_CODEC1(x) ((x)<675)
#define DEVICE_USE_CODEC2(x) ((x)>=675 && (x)<700)
#define DEVICE_USE_CODEC3(x) ((x)>=700)
#define DEVICE_USE_CODEC23(x) ((x)>=675)
/* Request types: video */
#define SET_LUM_CTL 0x01
#define GET_LUM_CTL 0x02
#define SET_CHROM_CTL 0x03
#define GET_CHROM_CTL 0x04
#define SET_STATUS_CTL 0x05
#define GET_STATUS_CTL 0x06
#define SET_EP_STREAM_CTL 0x07
#define GET_EP_STREAM_CTL 0x08
#define GET_XX_CTL 0x09
#define SET_XX_CTL 0x0A
#define GET_XY_CTL 0x0B
#define SET_XY_CTL 0x0C
#define SET_MPT_CTL 0x0D
#define GET_MPT_CTL 0x0E
/* Selectors for the Luminance controls [GS]ET_LUM_CTL */
#define AGC_MODE_FORMATTER 0x2000
#define PRESET_AGC_FORMATTER 0x2100
#define SHUTTER_MODE_FORMATTER 0x2200
#define PRESET_SHUTTER_FORMATTER 0x2300
#define PRESET_CONTOUR_FORMATTER 0x2400
#define AUTO_CONTOUR_FORMATTER 0x2500
#define BACK_LIGHT_COMPENSATION_FORMATTER 0x2600
#define CONTRAST_FORMATTER 0x2700
#define DYNAMIC_NOISE_CONTROL_FORMATTER 0x2800
#define FLICKERLESS_MODE_FORMATTER 0x2900
#define AE_CONTROL_SPEED 0x2A00
#define BRIGHTNESS_FORMATTER 0x2B00
#define GAMMA_FORMATTER 0x2C00
/* Selectors for the Chrominance controls [GS]ET_CHROM_CTL */
#define WB_MODE_FORMATTER 0x1000
#define AWB_CONTROL_SPEED_FORMATTER 0x1100
#define AWB_CONTROL_DELAY_FORMATTER 0x1200
#define PRESET_MANUAL_RED_GAIN_FORMATTER 0x1300
#define PRESET_MANUAL_BLUE_GAIN_FORMATTER 0x1400
#define COLOUR_MODE_FORMATTER 0x1500
#define SATURATION_MODE_FORMATTER1 0x1600
#define SATURATION_MODE_FORMATTER2 0x1700
/* Selectors for the Status controls [GS]ET_STATUS_CTL */
#define SAVE_USER_DEFAULTS_FORMATTER 0x0200
#define RESTORE_USER_DEFAULTS_FORMATTER 0x0300
#define RESTORE_FACTORY_DEFAULTS_FORMATTER 0x0400
#define READ_AGC_FORMATTER 0x0500
#define READ_SHUTTER_FORMATTER 0x0600
#define READ_RED_GAIN_FORMATTER 0x0700
#define READ_BLUE_GAIN_FORMATTER 0x0800
/* Formatters for the motorized pan & tilt [GS]ET_MPT_CTL */
#define PT_RELATIVE_CONTROL_FORMATTER 0x01
#define PT_RESET_CONTROL_FORMATTER 0x02
#define PT_STATUS_FORMATTER 0x03
/* Enumeration of image sizes */
#define PSZ_SQCIF 0x00
#define PSZ_QSIF 0x01
#define PSZ_QCIF 0x02
#define PSZ_SIF 0x03
#define PSZ_CIF 0x04
#define PSZ_VGA 0x05
#define PSZ_MAX 6
struct pwc_raw_frame {
__le16 type; /* type of the webcam */
__le16 vbandlength; /* Size of 4 lines 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[]; /* frame_size = H / 4 * vbandlength */
} __packed;
/* intermediate buffers with raw data from the USB cam */
struct pwc_frame_buf
{
/* common v4l buffer stuff -- must be first */
struct vb2_v4l2_buffer vb;
struct list_head list;
void *data;
int filled; /* number of bytes filled */
};
struct pwc_device
{
struct video_device vdev;
struct v4l2_device v4l2_dev;
/* videobuf2 queue and queued buffers list */
struct vb2_queue vb_queue;
struct list_head queued_bufs;
spinlock_t queued_bufs_lock; /* Protects queued_bufs */
/* If taking both locks vb_queue_lock must always be locked first! */
struct mutex v4l2_lock; /* Protects everything else */
struct mutex vb_queue_lock; /* Protects vb_queue and capt_file */
/* Pointer to our usb_device, will be NULL after unplug */
struct usb_device *udev; /* Both mutexes most be hold when setting! */
/* type of cam (645, 646, 675, 680, 690, 720, 730, 740, 750) */
int type;
int release; /* release number */
int features; /* feature bits */
/*** Video data ***/
int vendpoint; /* video isoc endpoint */
int vcinterface; /* video control interface */
int valternate; /* alternate interface needed */
int vframes; /* frames-per-second */
int pixfmt; /* pixelformat: V4L2_PIX_FMT_YUV420 or _PWCX */
int vframe_count; /* received frames */
int vmax_packet_size; /* USB maxpacket size */
int vlast_packet_size; /* for frame synchronisation */
int visoc_errors; /* number of contiguous ISOC errors */
int vbandlength; /* compressed band length; 0 is uncompressed */
char vsync; /* used by isoc handler */
char vmirror; /* for ToUCaM series */
char power_save; /* Do powersaving for this cam */
unsigned char cmd_buf[13];
unsigned char *ctrl_buf;
struct urb *urbs[MAX_ISO_BUFS];
/*
* Frame currently being filled, this only gets touched by the
* isoc urb complete handler, and by stream start / stop since
* start / stop touch it before / after starting / killing the urbs
* no locking is needed around this
*/
struct pwc_frame_buf *fill_buf;
int frame_header_size, frame_trailer_size;
int frame_size;
int frame_total_size; /* including header & trailer */
int drop_frames;
union { /* private data for decompression engine */
struct pwc_dec1_private dec1;
struct pwc_dec23_private dec23;
};
/*
* We have an 'image' and a 'view', where 'image' is the fixed-size img
* as delivered by the camera, and 'view' is the size requested by the
* program. The camera image is centered in this viewport, laced with
* a gray or black border. view_min <= image <= view <= view_max;
*/
int image_mask; /* supported sizes */
int width, height; /* current resolution */
#ifdef CONFIG_USB_PWC_INPUT_EVDEV
struct input_dev *button_dev; /* webcam snapshot button input */
char button_phys[64];
#endif
/* controls */
struct v4l2_ctrl_handler ctrl_handler;
u16 saturation_fmt;
struct v4l2_ctrl *brightness;
struct v4l2_ctrl *contrast;
struct v4l2_ctrl *saturation;
struct v4l2_ctrl *gamma;
struct {
/* awb / red-blue balance cluster */
struct v4l2_ctrl *auto_white_balance;
struct v4l2_ctrl *red_balance;
struct v4l2_ctrl *blue_balance;
/* usb ctrl transfers are slow, so we cache things */
int color_bal_valid;
unsigned long last_color_bal_update; /* In jiffies */
s32 last_red_balance;
s32 last_blue_balance;
};
struct {
/* autogain / gain cluster */
struct v4l2_ctrl *autogain;
struct v4l2_ctrl *gain;
int gain_valid;
unsigned long last_gain_update; /* In jiffies */
s32 last_gain;
};
struct {
/* exposure_auto / exposure cluster */
struct v4l2_ctrl *exposure_auto;
struct v4l2_ctrl *exposure;
int exposure_valid;
unsigned long last_exposure_update; /* In jiffies */
s32 last_exposure;
};
struct v4l2_ctrl *colorfx;
struct {
/* autocontour/contour cluster */
struct v4l2_ctrl *autocontour;
struct v4l2_ctrl *contour;
};
struct v4l2_ctrl *backlight;
struct v4l2_ctrl *flicker;
struct v4l2_ctrl *noise_reduction;
struct v4l2_ctrl *save_user;
struct v4l2_ctrl *restore_user;
struct v4l2_ctrl *restore_factory;
struct v4l2_ctrl *awb_speed;
struct v4l2_ctrl *awb_delay;
struct {
/* motor control cluster */
struct v4l2_ctrl *motor_pan;
struct v4l2_ctrl *motor_tilt;
struct v4l2_ctrl *motor_pan_reset;
struct v4l2_ctrl *motor_tilt_reset;
};
/* CODEC3 models have both gain and exposure controlled by autogain */
struct v4l2_ctrl *autogain_expo_cluster[3];
};
/* Global variables */
#ifdef CONFIG_USB_PWC_DEBUG
extern int pwc_trace;
#endif
/** Functions in pwc-misc.c */
/* sizes in pixels */
extern const int pwc_image_sizes[PSZ_MAX][2];
int pwc_get_size(struct pwc_device *pdev, int width, int height);
void pwc_construct(struct pwc_device *pdev);
/** Functions in pwc-ctrl.c */
/* 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 pixfmt, int frames, int *compression, int send_to_cam);
extern unsigned int pwc_get_fps(struct pwc_device *pdev, unsigned int index, unsigned int size);
extern int pwc_set_leds(struct pwc_device *pdev, int on_value, int off_value);
extern int pwc_get_cmos_sensor(struct pwc_device *pdev, int *sensor);
extern int send_control_msg(struct pwc_device *pdev,
u8 request, u16 value, void *buf, int buflen);
/* Control get / set helpers */
int pwc_get_u8_ctrl(struct pwc_device *pdev, u8 request, u16 value, int *data);
int pwc_set_u8_ctrl(struct pwc_device *pdev, u8 request, u16 value, u8 data);
int pwc_get_s8_ctrl(struct pwc_device *pdev, u8 request, u16 value, int *data);
#define pwc_set_s8_ctrl pwc_set_u8_ctrl
int pwc_get_u16_ctrl(struct pwc_device *pdev, u8 request, u16 value, int *dat);
int pwc_set_u16_ctrl(struct pwc_device *pdev, u8 request, u16 value, u16 data);
int pwc_button_ctrl(struct pwc_device *pdev, u16 value);
int pwc_init_controls(struct pwc_device *pdev);
/* Power down or up the camera; not supported by all models */
extern void pwc_camera_power(struct pwc_device *pdev, int power);
extern const struct v4l2_ioctl_ops pwc_ioctl_ops;
/** pwc-uncompress.c */
/* Expand frame to image, possibly including decompression. Uses read_frame and fill_image */
int pwc_decompress(struct pwc_device *pdev, struct pwc_frame_buf *fbuf);
#endif