xref: /openbmc/linux/drivers/media/usb/pwc/pwc-misc.c (revision 1a59d1b8)
11a59d1b8SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
20c0d06caSMauro Carvalho Chehab /* Linux driver for Philips webcam
30c0d06caSMauro Carvalho Chehab    Various miscellaneous functions and tables.
40c0d06caSMauro Carvalho Chehab    (C) 1999-2003 Nemosoft Unv.
50c0d06caSMauro Carvalho Chehab    (C) 2004-2006 Luc Saillard (luc@saillard.org)
60c0d06caSMauro Carvalho Chehab 
70c0d06caSMauro Carvalho Chehab    NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
80c0d06caSMauro Carvalho Chehab    driver and thus may have bugs that are not present in the original version.
90c0d06caSMauro Carvalho Chehab    Please send bug reports and support requests to <luc@saillard.org>.
100c0d06caSMauro Carvalho Chehab    The decompression routines have been implemented by reverse-engineering the
110c0d06caSMauro Carvalho Chehab    Nemosoft binary pwcx module. Caveat emptor.
120c0d06caSMauro Carvalho Chehab 
130c0d06caSMauro Carvalho Chehab */
140c0d06caSMauro Carvalho Chehab 
150c0d06caSMauro Carvalho Chehab 
160c0d06caSMauro Carvalho Chehab #include "pwc.h"
170c0d06caSMauro Carvalho Chehab 
180c0d06caSMauro Carvalho Chehab const int pwc_image_sizes[PSZ_MAX][2] =
190c0d06caSMauro Carvalho Chehab {
200c0d06caSMauro Carvalho Chehab 	{ 128,  96 }, /* sqcif */
210c0d06caSMauro Carvalho Chehab 	{ 160, 120 }, /* qsif */
220c0d06caSMauro Carvalho Chehab 	{ 176, 144 }, /* qcif */
230c0d06caSMauro Carvalho Chehab 	{ 320, 240 }, /* sif */
240c0d06caSMauro Carvalho Chehab 	{ 352, 288 }, /* cif */
250c0d06caSMauro Carvalho Chehab 	{ 640, 480 }, /* vga */
260c0d06caSMauro Carvalho Chehab };
270c0d06caSMauro Carvalho Chehab 
280c0d06caSMauro Carvalho Chehab /* x,y -> PSZ_ */
pwc_get_size(struct pwc_device * pdev,int width,int height)290c0d06caSMauro Carvalho Chehab int pwc_get_size(struct pwc_device *pdev, int width, int height)
300c0d06caSMauro Carvalho Chehab {
310c0d06caSMauro Carvalho Chehab 	int i;
320c0d06caSMauro Carvalho Chehab 
330c0d06caSMauro Carvalho Chehab 	/* Find the largest size supported by the camera that fits into the
340c0d06caSMauro Carvalho Chehab 	   requested size. */
350c0d06caSMauro Carvalho Chehab 	for (i = PSZ_MAX - 1; i >= 0; i--) {
360c0d06caSMauro Carvalho Chehab 		if (!(pdev->image_mask & (1 << i)))
370c0d06caSMauro Carvalho Chehab 			continue;
380c0d06caSMauro Carvalho Chehab 
390c0d06caSMauro Carvalho Chehab 		if (pwc_image_sizes[i][0] <= width &&
400c0d06caSMauro Carvalho Chehab 		    pwc_image_sizes[i][1] <= height)
410c0d06caSMauro Carvalho Chehab 			return i;
420c0d06caSMauro Carvalho Chehab 	}
430c0d06caSMauro Carvalho Chehab 
440c0d06caSMauro Carvalho Chehab 	/* No mode found, return the smallest mode we have */
450c0d06caSMauro Carvalho Chehab 	for (i = 0; i < PSZ_MAX; i++) {
460c0d06caSMauro Carvalho Chehab 		if (pdev->image_mask & (1 << i))
470c0d06caSMauro Carvalho Chehab 			return i;
480c0d06caSMauro Carvalho Chehab 	}
490c0d06caSMauro Carvalho Chehab 
500c0d06caSMauro Carvalho Chehab 	/* Never reached there always is at least one supported mode */
510c0d06caSMauro Carvalho Chehab 	return 0;
520c0d06caSMauro Carvalho Chehab }
530c0d06caSMauro Carvalho Chehab 
540c0d06caSMauro Carvalho Chehab /* initialize variables depending on type and decompressor */
pwc_construct(struct pwc_device * pdev)550c0d06caSMauro Carvalho Chehab void pwc_construct(struct pwc_device *pdev)
560c0d06caSMauro Carvalho Chehab {
570c0d06caSMauro Carvalho Chehab 	if (DEVICE_USE_CODEC1(pdev->type)) {
580c0d06caSMauro Carvalho Chehab 
590c0d06caSMauro Carvalho Chehab 		pdev->image_mask = 1 << PSZ_SQCIF | 1 << PSZ_QCIF | 1 << PSZ_CIF;
600c0d06caSMauro Carvalho Chehab 		pdev->vcinterface = 2;
610c0d06caSMauro Carvalho Chehab 		pdev->vendpoint = 4;
620c0d06caSMauro Carvalho Chehab 		pdev->frame_header_size = 0;
630c0d06caSMauro Carvalho Chehab 		pdev->frame_trailer_size = 0;
640c0d06caSMauro Carvalho Chehab 
650c0d06caSMauro Carvalho Chehab 	} else if (DEVICE_USE_CODEC3(pdev->type)) {
660c0d06caSMauro Carvalho Chehab 
670c0d06caSMauro Carvalho Chehab 		pdev->image_mask = 1 << PSZ_QSIF | 1 << PSZ_SIF | 1 << PSZ_VGA;
680c0d06caSMauro Carvalho Chehab 		pdev->vcinterface = 3;
690c0d06caSMauro Carvalho Chehab 		pdev->vendpoint = 5;
700c0d06caSMauro Carvalho Chehab 		pdev->frame_header_size = TOUCAM_HEADER_SIZE;
710c0d06caSMauro Carvalho Chehab 		pdev->frame_trailer_size = TOUCAM_TRAILER_SIZE;
720c0d06caSMauro Carvalho Chehab 
730c0d06caSMauro Carvalho Chehab 	} else /* if (DEVICE_USE_CODEC2(pdev->type)) */ {
740c0d06caSMauro Carvalho Chehab 
750c0d06caSMauro Carvalho Chehab 		pdev->image_mask = 1 << PSZ_SQCIF | 1 << PSZ_QSIF | 1 << PSZ_QCIF | 1 << PSZ_SIF | 1 << PSZ_CIF | 1 << PSZ_VGA;
760c0d06caSMauro Carvalho Chehab 		pdev->vcinterface = 3;
770c0d06caSMauro Carvalho Chehab 		pdev->vendpoint = 4;
780c0d06caSMauro Carvalho Chehab 		pdev->frame_header_size = 0;
790c0d06caSMauro Carvalho Chehab 		pdev->frame_trailer_size = 0;
800c0d06caSMauro Carvalho Chehab 	}
810c0d06caSMauro Carvalho Chehab }
82