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