1*c942fddfSThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-or-later */ 2327c4abfSHans de Goede /* 3327c4abfSHans de Goede * Pixart PAC207BCA / PAC73xx common functions 4327c4abfSHans de Goede * 5327c4abfSHans de Goede * Copyright (C) 2008 Hans de Goede <j.w.r.degoede@hhs.nl> 6327c4abfSHans de Goede * Copyright (C) 2005 Thomas Kaiser thomas@kaiser-linux.li 7327c4abfSHans de Goede * Copyleft (C) 2005 Michel Xhaard mxhaard@magic.fr 8327c4abfSHans de Goede * 9327c4abfSHans de Goede * V4L2 by Jean-Francois Moine <http://moinejf.free.fr> 10327c4abfSHans de Goede */ 11327c4abfSHans de Goede 128a5b2e90SHans de Goede /* We calculate the autogain at the end of the transfer of a frame, at this 135fb2dde2SHans de Goede moment a frame with the old settings is being captured and transmitted. So 145fb2dde2SHans de Goede if we adjust the gain or exposure we must ignore at least the next frame for 155fb2dde2SHans de Goede the new settings to come into effect before doing any other adjustments. */ 165fb2dde2SHans de Goede #define PAC_AUTOGAIN_IGNORE_FRAMES 2 178a5b2e90SHans de Goede 18327c4abfSHans de Goede static const unsigned char pac_sof_marker[5] = 19327c4abfSHans de Goede { 0xff, 0xff, 0x00, 0xff, 0x96 }; 20327c4abfSHans de Goede 21e0d49e2dSMarton Nemeth /* 22e0d49e2dSMarton Nemeth The following state machine finds the SOF marker sequence 23e0d49e2dSMarton Nemeth 0xff, 0xff, 0x00, 0xff, 0x96 in a byte stream. 24e0d49e2dSMarton Nemeth 25e0d49e2dSMarton Nemeth +----------+ 26e0d49e2dSMarton Nemeth | 0: START |<---------------\ 27e0d49e2dSMarton Nemeth +----------+<-\ | 28e0d49e2dSMarton Nemeth | \---/otherwise | 29e0d49e2dSMarton Nemeth v 0xff | 30e0d49e2dSMarton Nemeth +----------+ otherwise | 31e0d49e2dSMarton Nemeth | 1 |--------------->* 32e0d49e2dSMarton Nemeth | | ^ 33e0d49e2dSMarton Nemeth +----------+ | 34e0d49e2dSMarton Nemeth | | 35e0d49e2dSMarton Nemeth v 0xff | 36e0d49e2dSMarton Nemeth +----------+<-\0xff | 37e0d49e2dSMarton Nemeth /->| |--/ | 38e0d49e2dSMarton Nemeth | | 2 |--------------->* 39e0d49e2dSMarton Nemeth | | | otherwise ^ 40e0d49e2dSMarton Nemeth | +----------+ | 41e0d49e2dSMarton Nemeth | | | 42e0d49e2dSMarton Nemeth | v 0x00 | 43e0d49e2dSMarton Nemeth | +----------+ | 44e0d49e2dSMarton Nemeth | | 3 | | 45e0d49e2dSMarton Nemeth | | |--------------->* 46e0d49e2dSMarton Nemeth | +----------+ otherwise ^ 47e0d49e2dSMarton Nemeth | | | 48e0d49e2dSMarton Nemeth 0xff | v 0xff | 49e0d49e2dSMarton Nemeth | +----------+ | 50e0d49e2dSMarton Nemeth \--| 4 | | 51e0d49e2dSMarton Nemeth | |----------------/ 52e0d49e2dSMarton Nemeth +----------+ otherwise 53e0d49e2dSMarton Nemeth | 54e0d49e2dSMarton Nemeth v 0x96 55e0d49e2dSMarton Nemeth +----------+ 56e0d49e2dSMarton Nemeth | FOUND | 57e0d49e2dSMarton Nemeth +----------+ 58e0d49e2dSMarton Nemeth */ 59e0d49e2dSMarton Nemeth 60c93396e1STheodore Kilgore static unsigned char *pac_find_sof(struct gspca_dev *gspca_dev, u8 *sof_read, 61327c4abfSHans de Goede unsigned char *m, int len) 62327c4abfSHans de Goede { 63327c4abfSHans de Goede int i; 64327c4abfSHans de Goede 65327c4abfSHans de Goede /* Search for the SOF marker (fixed part) in the header */ 66327c4abfSHans de Goede for (i = 0; i < len; i++) { 67a6b69e40SMarton Nemeth switch (*sof_read) { 68e0d49e2dSMarton Nemeth case 0: 69e0d49e2dSMarton Nemeth if (m[i] == 0xff) 70a6b69e40SMarton Nemeth *sof_read = 1; 71e0d49e2dSMarton Nemeth break; 72e0d49e2dSMarton Nemeth case 1: 73e0d49e2dSMarton Nemeth if (m[i] == 0xff) 74a6b69e40SMarton Nemeth *sof_read = 2; 75e0d49e2dSMarton Nemeth else 76a6b69e40SMarton Nemeth *sof_read = 0; 77e0d49e2dSMarton Nemeth break; 78e0d49e2dSMarton Nemeth case 2: 79e0d49e2dSMarton Nemeth switch (m[i]) { 80e0d49e2dSMarton Nemeth case 0x00: 81a6b69e40SMarton Nemeth *sof_read = 3; 82e0d49e2dSMarton Nemeth break; 83e0d49e2dSMarton Nemeth case 0xff: 84e0d49e2dSMarton Nemeth /* stay in this state */ 85e0d49e2dSMarton Nemeth break; 86e0d49e2dSMarton Nemeth default: 87a6b69e40SMarton Nemeth *sof_read = 0; 88e0d49e2dSMarton Nemeth } 89e0d49e2dSMarton Nemeth break; 90e0d49e2dSMarton Nemeth case 3: 91e0d49e2dSMarton Nemeth if (m[i] == 0xff) 92a6b69e40SMarton Nemeth *sof_read = 4; 93e0d49e2dSMarton Nemeth else 94a6b69e40SMarton Nemeth *sof_read = 0; 95e0d49e2dSMarton Nemeth break; 96e0d49e2dSMarton Nemeth case 4: 97e0d49e2dSMarton Nemeth switch (m[i]) { 98e0d49e2dSMarton Nemeth case 0x96: 99e0d49e2dSMarton Nemeth /* Pattern found */ 10037d5efb0SJoe Perches gspca_dbg(gspca_dev, D_FRAM, 10137d5efb0SJoe Perches "SOF found, bytes to analyze: %u - Frame starts at byte #%u\n", 102327c4abfSHans de Goede len, i + 1); 103a6b69e40SMarton Nemeth *sof_read = 0; 104327c4abfSHans de Goede return m + i + 1; 105e0d49e2dSMarton Nemeth break; 106e0d49e2dSMarton Nemeth case 0xff: 107a6b69e40SMarton Nemeth *sof_read = 2; 108e0d49e2dSMarton Nemeth break; 109e0d49e2dSMarton Nemeth default: 110a6b69e40SMarton Nemeth *sof_read = 0; 111327c4abfSHans de Goede } 112e0d49e2dSMarton Nemeth break; 113e0d49e2dSMarton Nemeth default: 114a6b69e40SMarton Nemeth *sof_read = 0; 115327c4abfSHans de Goede } 116327c4abfSHans de Goede } 117327c4abfSHans de Goede 118327c4abfSHans de Goede return NULL; 119327c4abfSHans de Goede } 120