18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * Pixart PAC207BCA / PAC73xx common functions
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * Copyright (C) 2008 Hans de Goede <j.w.r.degoede@hhs.nl>
68c2ecf20Sopenharmony_ci * Copyright (C) 2005 Thomas Kaiser thomas@kaiser-linux.li
78c2ecf20Sopenharmony_ci * Copyleft (C) 2005 Michel Xhaard mxhaard@magic.fr
88c2ecf20Sopenharmony_ci *
98c2ecf20Sopenharmony_ci * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
108c2ecf20Sopenharmony_ci */
118c2ecf20Sopenharmony_ci
128c2ecf20Sopenharmony_ci/* We calculate the autogain at the end of the transfer of a frame, at this
138c2ecf20Sopenharmony_ci   moment a frame with the old settings is being captured and transmitted. So
148c2ecf20Sopenharmony_ci   if we adjust the gain or exposure we must ignore at least the next frame for
158c2ecf20Sopenharmony_ci   the new settings to come into effect before doing any other adjustments. */
168c2ecf20Sopenharmony_ci#define PAC_AUTOGAIN_IGNORE_FRAMES	2
178c2ecf20Sopenharmony_ci
188c2ecf20Sopenharmony_cistatic const unsigned char pac_sof_marker[5] =
198c2ecf20Sopenharmony_ci		{ 0xff, 0xff, 0x00, 0xff, 0x96 };
208c2ecf20Sopenharmony_ci
218c2ecf20Sopenharmony_ci/*
228c2ecf20Sopenharmony_ci   The following state machine finds the SOF marker sequence
238c2ecf20Sopenharmony_ci   0xff, 0xff, 0x00, 0xff, 0x96 in a byte stream.
248c2ecf20Sopenharmony_ci
258c2ecf20Sopenharmony_ci	   +----------+
268c2ecf20Sopenharmony_ci	   | 0: START |<---------------\
278c2ecf20Sopenharmony_ci	   +----------+<-\             |
288c2ecf20Sopenharmony_ci	     |       \---/otherwise    |
298c2ecf20Sopenharmony_ci	     v 0xff                    |
308c2ecf20Sopenharmony_ci	   +----------+ otherwise      |
318c2ecf20Sopenharmony_ci	   |     1    |--------------->*
328c2ecf20Sopenharmony_ci	   |          |                ^
338c2ecf20Sopenharmony_ci	   +----------+                |
348c2ecf20Sopenharmony_ci	     |                         |
358c2ecf20Sopenharmony_ci	     v 0xff                    |
368c2ecf20Sopenharmony_ci	   +----------+<-\0xff         |
378c2ecf20Sopenharmony_ci	/->|          |--/             |
388c2ecf20Sopenharmony_ci	|  |     2    |--------------->*
398c2ecf20Sopenharmony_ci	|  |          | otherwise      ^
408c2ecf20Sopenharmony_ci	|  +----------+                |
418c2ecf20Sopenharmony_ci	|    |                         |
428c2ecf20Sopenharmony_ci	|    v 0x00                    |
438c2ecf20Sopenharmony_ci	|  +----------+                |
448c2ecf20Sopenharmony_ci	|  |     3    |                |
458c2ecf20Sopenharmony_ci	|  |          |--------------->*
468c2ecf20Sopenharmony_ci	|  +----------+ otherwise      ^
478c2ecf20Sopenharmony_ci	|    |                         |
488c2ecf20Sopenharmony_ci   0xff |    v 0xff                    |
498c2ecf20Sopenharmony_ci	|  +----------+                |
508c2ecf20Sopenharmony_ci	\--|     4    |                |
518c2ecf20Sopenharmony_ci	   |          |----------------/
528c2ecf20Sopenharmony_ci	   +----------+ otherwise
538c2ecf20Sopenharmony_ci	     |
548c2ecf20Sopenharmony_ci	     v 0x96
558c2ecf20Sopenharmony_ci	   +----------+
568c2ecf20Sopenharmony_ci	   |  FOUND   |
578c2ecf20Sopenharmony_ci	   +----------+
588c2ecf20Sopenharmony_ci*/
598c2ecf20Sopenharmony_ci
608c2ecf20Sopenharmony_cistatic unsigned char *pac_find_sof(struct gspca_dev *gspca_dev, u8 *sof_read,
618c2ecf20Sopenharmony_ci					unsigned char *m, int len)
628c2ecf20Sopenharmony_ci{
638c2ecf20Sopenharmony_ci	int i;
648c2ecf20Sopenharmony_ci
658c2ecf20Sopenharmony_ci	/* Search for the SOF marker (fixed part) in the header */
668c2ecf20Sopenharmony_ci	for (i = 0; i < len; i++) {
678c2ecf20Sopenharmony_ci		switch (*sof_read) {
688c2ecf20Sopenharmony_ci		case 0:
698c2ecf20Sopenharmony_ci			if (m[i] == 0xff)
708c2ecf20Sopenharmony_ci				*sof_read = 1;
718c2ecf20Sopenharmony_ci			break;
728c2ecf20Sopenharmony_ci		case 1:
738c2ecf20Sopenharmony_ci			if (m[i] == 0xff)
748c2ecf20Sopenharmony_ci				*sof_read = 2;
758c2ecf20Sopenharmony_ci			else
768c2ecf20Sopenharmony_ci				*sof_read = 0;
778c2ecf20Sopenharmony_ci			break;
788c2ecf20Sopenharmony_ci		case 2:
798c2ecf20Sopenharmony_ci			switch (m[i]) {
808c2ecf20Sopenharmony_ci			case 0x00:
818c2ecf20Sopenharmony_ci				*sof_read = 3;
828c2ecf20Sopenharmony_ci				break;
838c2ecf20Sopenharmony_ci			case 0xff:
848c2ecf20Sopenharmony_ci				/* stay in this state */
858c2ecf20Sopenharmony_ci				break;
868c2ecf20Sopenharmony_ci			default:
878c2ecf20Sopenharmony_ci				*sof_read = 0;
888c2ecf20Sopenharmony_ci			}
898c2ecf20Sopenharmony_ci			break;
908c2ecf20Sopenharmony_ci		case 3:
918c2ecf20Sopenharmony_ci			if (m[i] == 0xff)
928c2ecf20Sopenharmony_ci				*sof_read = 4;
938c2ecf20Sopenharmony_ci			else
948c2ecf20Sopenharmony_ci				*sof_read = 0;
958c2ecf20Sopenharmony_ci			break;
968c2ecf20Sopenharmony_ci		case 4:
978c2ecf20Sopenharmony_ci			switch (m[i]) {
988c2ecf20Sopenharmony_ci			case 0x96:
998c2ecf20Sopenharmony_ci				/* Pattern found */
1008c2ecf20Sopenharmony_ci				gspca_dbg(gspca_dev, D_FRAM,
1018c2ecf20Sopenharmony_ci					  "SOF found, bytes to analyze: %u - Frame starts at byte #%u\n",
1028c2ecf20Sopenharmony_ci					  len, i + 1);
1038c2ecf20Sopenharmony_ci				*sof_read = 0;
1048c2ecf20Sopenharmony_ci				return m + i + 1;
1058c2ecf20Sopenharmony_ci				break;
1068c2ecf20Sopenharmony_ci			case 0xff:
1078c2ecf20Sopenharmony_ci				*sof_read = 2;
1088c2ecf20Sopenharmony_ci				break;
1098c2ecf20Sopenharmony_ci			default:
1108c2ecf20Sopenharmony_ci				*sof_read = 0;
1118c2ecf20Sopenharmony_ci			}
1128c2ecf20Sopenharmony_ci			break;
1138c2ecf20Sopenharmony_ci		default:
1148c2ecf20Sopenharmony_ci			*sof_read = 0;
1158c2ecf20Sopenharmony_ci		}
1168c2ecf20Sopenharmony_ci	}
1178c2ecf20Sopenharmony_ci
1188c2ecf20Sopenharmony_ci	return NULL;
1198c2ecf20Sopenharmony_ci}
120