^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /* Linux driver for Philips webcam
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) Various miscellaneous functions and tables.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) (C) 1999-2003 Nemosoft Unv.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) (C) 2004-2006 Luc Saillard (luc@saillard.org)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) driver and thus may have bugs that are not present in the original version.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) Please send bug reports and support requests to <luc@saillard.org>.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) The decompression routines have been implemented by reverse-engineering the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) Nemosoft binary pwcx module. Caveat emptor.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include "pwc.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) const int pwc_image_sizes[PSZ_MAX][2] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) { 128, 96 }, /* sqcif */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) { 160, 120 }, /* qsif */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) { 176, 144 }, /* qcif */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) { 320, 240 }, /* sif */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) { 352, 288 }, /* cif */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) { 640, 480 }, /* vga */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) /* x,y -> PSZ_ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) int pwc_get_size(struct pwc_device *pdev, int width, int height)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) /* Find the largest size supported by the camera that fits into the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) requested size. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) for (i = PSZ_MAX - 1; i >= 0; i--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) if (!(pdev->image_mask & (1 << i)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) if (pwc_image_sizes[i][0] <= width &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) pwc_image_sizes[i][1] <= height)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) return i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) /* No mode found, return the smallest mode we have */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) for (i = 0; i < PSZ_MAX; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) if (pdev->image_mask & (1 << i))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) return i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) /* Never reached there always is at least one supported mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) /* initialize variables depending on type and decompressor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) void pwc_construct(struct pwc_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) if (DEVICE_USE_CODEC1(pdev->type)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) pdev->image_mask = 1 << PSZ_SQCIF | 1 << PSZ_QCIF | 1 << PSZ_CIF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) pdev->vcinterface = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) pdev->vendpoint = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) pdev->frame_header_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) pdev->frame_trailer_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) } else if (DEVICE_USE_CODEC3(pdev->type)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) pdev->image_mask = 1 << PSZ_QSIF | 1 << PSZ_SIF | 1 << PSZ_VGA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) pdev->vcinterface = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) pdev->vendpoint = 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) pdev->frame_header_size = TOUCAM_HEADER_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) pdev->frame_trailer_size = TOUCAM_TRAILER_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) } else /* if (DEVICE_USE_CODEC2(pdev->type)) */ {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) pdev->image_mask = 1 << PSZ_SQCIF | 1 << PSZ_QSIF | 1 << PSZ_QCIF | 1 << PSZ_SIF | 1 << PSZ_CIF | 1 << PSZ_VGA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) pdev->vcinterface = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) pdev->vendpoint = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) pdev->frame_header_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) pdev->frame_trailer_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) }