11408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth/* 2ae251e6b18cff8c1bd1d825f8862b083a33be421Jean-François Moine * Pixart PAC7302 driver 31408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth * 4ae251e6b18cff8c1bd1d825f8862b083a33be421Jean-François Moine * Copyright (C) 2008-2012 Jean-Francois Moine <http://moinejf.free.fr> 5ae251e6b18cff8c1bd1d825f8862b083a33be421Jean-François Moine * Copyright (C) 2005 Thomas Kaiser thomas@kaiser-linux.li 61408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth * 7cc2f82c22f3f954f0858642bd782f48e8ccbf058Jean-Francois Moine * Separated from Pixart PAC7311 library by Márton Németh 8aed6f1b5fe4e95cf8a9fc149e25041aa8cc7c78aMárton Németh * Camera button input handling by Márton Németh <nm127@freemail.hu> 9aed6f1b5fe4e95cf8a9fc149e25041aa8cc7c78aMárton Németh * Copyright (C) 2009-2010 Márton Németh <nm127@freemail.hu> 101408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth * 111408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth * This program is free software; you can redistribute it and/or modify 121408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth * it under the terms of the GNU General Public License as published by 131408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth * the Free Software Foundation; either version 2 of the License, or 141408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth * any later version. 151408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth * 161408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth * This program is distributed in the hope that it will be useful, 171408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth * but WITHOUT ANY WARRANTY; without even the implied warranty of 181408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 191408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth * GNU General Public License for more details. 201408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth * 211408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth * You should have received a copy of the GNU General Public License 221408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth * along with this program; if not, write to the Free Software 231408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 241408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth */ 251408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 261408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth/* Some documentation about various registers as determined by trial and error. 271408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 281408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth Register page 1: 291408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 301408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth Address Description 311408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x78 Global control, bit 6 controls the LED (inverted) 321408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 335fb2dde28122e74bbab9dae3cc04bcbc8c08b332Hans de Goede Register page 3: 341408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 351408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth Address Description 365fb2dde28122e74bbab9dae3cc04bcbc8c08b332Hans de Goede 0x02 Clock divider 3-63, fps = 90 / val. Must be a multiple of 3 on 371408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth the 7302, so one of 3, 6, 9, ..., except when between 6 and 12? 385fb2dde28122e74bbab9dae3cc04bcbc8c08b332Hans de Goede 0x03 Variable framerate ctrl reg2==3: 0 -> ~30 fps, 255 -> ~22fps 395fb2dde28122e74bbab9dae3cc04bcbc8c08b332Hans de Goede 0x04 Another var framerate ctrl reg2==3, reg3==0: 0 -> ~30 fps, 405fb2dde28122e74bbab9dae3cc04bcbc8c08b332Hans de Goede 63 -> ~27 fps, the 2 msb's must always be 1 !! 415fb2dde28122e74bbab9dae3cc04bcbc8c08b332Hans de Goede 0x05 Another var framerate ctrl reg2==3, reg3==0, reg4==0xc0: 425fb2dde28122e74bbab9dae3cc04bcbc8c08b332Hans de Goede 1 -> ~30 fps, 2 -> ~20 fps 435fb2dde28122e74bbab9dae3cc04bcbc8c08b332Hans de Goede 0x0e Exposure bits 0-7, 0-448, 0 = use full frame time 445fb2dde28122e74bbab9dae3cc04bcbc8c08b332Hans de Goede 0x0f Exposure bit 8, 0-448, 448 = no exposure at all 455fb2dde28122e74bbab9dae3cc04bcbc8c08b332Hans de Goede 0x10 Master gain 0-31 461408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x21 Bitfield: 0-1 unused, 2-3 vflip/hflip, 4-5 unknown, 6-7 unused 47265a8098e75e156985abfaac250ee4f2b407f863Márton Németh 48265a8098e75e156985abfaac250ee4f2b407f863Márton Németh The registers are accessed in the following functions: 49265a8098e75e156985abfaac250ee4f2b407f863Márton Németh 50265a8098e75e156985abfaac250ee4f2b407f863Márton Németh Page | Register | Function 51265a8098e75e156985abfaac250ee4f2b407f863Márton Németh -----+------------+--------------------------------------------------- 52265a8098e75e156985abfaac250ee4f2b407f863Márton Németh 0 | 0x0f..0x20 | setcolors() 53265a8098e75e156985abfaac250ee4f2b407f863Márton Németh 0 | 0xa2..0xab | setbrightcont() 54265a8098e75e156985abfaac250ee4f2b407f863Márton Németh 0 | 0xc5 | setredbalance() 5523fbee6f88d59b4edca0855242d55e5b7cfc2401Marton Nemeth 0 | 0xc6 | setwhitebalance() 56265a8098e75e156985abfaac250ee4f2b407f863Márton Németh 0 | 0xc7 | setbluebalance() 57265a8098e75e156985abfaac250ee4f2b407f863Márton Németh 0 | 0xdc | setbrightcont(), setcolors() 58265a8098e75e156985abfaac250ee4f2b407f863Márton Németh 3 | 0x02 | setexposure() 59265a8098e75e156985abfaac250ee4f2b407f863Márton Németh 3 | 0x10 | setgain() 60265a8098e75e156985abfaac250ee4f2b407f863Márton Németh 3 | 0x11 | setcolors(), setgain(), setexposure(), sethvflip() 61265a8098e75e156985abfaac250ee4f2b407f863Márton Németh 3 | 0x21 | sethvflip() 621408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth*/ 631408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 64133a9fe949862d9ed8411fb423739f4cee08232dJoe Perches#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 65133a9fe949862d9ed8411fb423739f4cee08232dJoe Perches 66aed6f1b5fe4e95cf8a9fc149e25041aa8cc7c78aMárton Németh#include <linux/input.h> 676763cc0e54e95eea356e15f9cd9a2f7b5ebeb7e8Márton Németh#include <media/v4l2-chip-ident.h> 681408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth#include "gspca.h" 69ac399cd313f13d5208567c01ff70a476605804b7Jean-François Moine/* Include pac common sof detection functions */ 70ac399cd313f13d5208567c01ff70a476605804b7Jean-François Moine#include "pac_common.h" 711408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 72ae251e6b18cff8c1bd1d825f8862b083a33be421Jean-François MoineMODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>, " 73ae251e6b18cff8c1bd1d825f8862b083a33be421Jean-François Moine "Thomas Kaiser thomas@kaiser-linux.li"); 741408b8472910e894b290205b4baed5b14b8f45afMarton NemethMODULE_DESCRIPTION("Pixart PAC7302"); 751408b8472910e894b290205b4baed5b14b8f45afMarton NemethMODULE_LICENSE("GPL"); 761408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 77aa5b7925f19f9bb586136fef55188deaf094805dJean-François Moineenum e_ctrl { 78aa5b7925f19f9bb586136fef55188deaf094805dJean-François Moine BRIGHTNESS, 79aa5b7925f19f9bb586136fef55188deaf094805dJean-François Moine CONTRAST, 80aa5b7925f19f9bb586136fef55188deaf094805dJean-François Moine COLORS, 81aa5b7925f19f9bb586136fef55188deaf094805dJean-François Moine WHITE_BALANCE, 82aa5b7925f19f9bb586136fef55188deaf094805dJean-François Moine RED_BALANCE, 83aa5b7925f19f9bb586136fef55188deaf094805dJean-François Moine BLUE_BALANCE, 84aa5b7925f19f9bb586136fef55188deaf094805dJean-François Moine GAIN, 85aa5b7925f19f9bb586136fef55188deaf094805dJean-François Moine AUTOGAIN, 86aa5b7925f19f9bb586136fef55188deaf094805dJean-François Moine EXPOSURE, 87aa5b7925f19f9bb586136fef55188deaf094805dJean-François Moine VFLIP, 88aa5b7925f19f9bb586136fef55188deaf094805dJean-François Moine HFLIP, 89aa5b7925f19f9bb586136fef55188deaf094805dJean-François Moine NCTRLS /* number of controls */ 90aa5b7925f19f9bb586136fef55188deaf094805dJean-François Moine}; 91aa5b7925f19f9bb586136fef55188deaf094805dJean-François Moine 921408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth/* specific webcam descriptor for pac7302 */ 931408b8472910e894b290205b4baed5b14b8f45afMarton Nemethstruct sd { 941408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth struct gspca_dev gspca_dev; /* !! must be the first item */ 951408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 96aa5b7925f19f9bb586136fef55188deaf094805dJean-François Moine struct gspca_ctrl ctrls[NCTRLS]; 97aa5b7925f19f9bb586136fef55188deaf094805dJean-François Moine 98fe2b6032513099b82cd19ef8da5050f02a18d3ecJean-Francois Moine u8 flags; 99fe2b6032513099b82cd19ef8da5050f02a18d3ecJean-Francois Moine#define FL_HFLIP 0x01 /* mirrored by default */ 100fe2b6032513099b82cd19ef8da5050f02a18d3ecJean-Francois Moine#define FL_VFLIP 0x02 /* vertical flipped by default */ 1011408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 1021408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth u8 sof_read; 103ac399cd313f13d5208567c01ff70a476605804b7Jean-François Moine s8 autogain_ignore_frames; 1041408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 1051408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth atomic_t avg_lum; 1061408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth}; 1071408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 1081408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth/* V4L2 controls supported by the driver */ 109aa5b7925f19f9bb586136fef55188deaf094805dJean-François Moinestatic void setbrightcont(struct gspca_dev *gspca_dev); 110aa5b7925f19f9bb586136fef55188deaf094805dJean-François Moinestatic void setcolors(struct gspca_dev *gspca_dev); 111aa5b7925f19f9bb586136fef55188deaf094805dJean-François Moinestatic void setwhitebalance(struct gspca_dev *gspca_dev); 112aa5b7925f19f9bb586136fef55188deaf094805dJean-François Moinestatic void setredbalance(struct gspca_dev *gspca_dev); 113aa5b7925f19f9bb586136fef55188deaf094805dJean-François Moinestatic void setbluebalance(struct gspca_dev *gspca_dev); 114aa5b7925f19f9bb586136fef55188deaf094805dJean-François Moinestatic void setgain(struct gspca_dev *gspca_dev); 115aa5b7925f19f9bb586136fef55188deaf094805dJean-François Moinestatic void setexposure(struct gspca_dev *gspca_dev); 116ac399cd313f13d5208567c01ff70a476605804b7Jean-François Moinestatic void setautogain(struct gspca_dev *gspca_dev); 117aa5b7925f19f9bb586136fef55188deaf094805dJean-François Moinestatic void sethvflip(struct gspca_dev *gspca_dev); 1181408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 1197e64dc4c4d6f5c8935fac25c7fc7aa83f9880ed7Marton Nemethstatic const struct ctrl sd_ctrls[] = { 120aa5b7925f19f9bb586136fef55188deaf094805dJean-François Moine[BRIGHTNESS] = { 1211408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth { 1221408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .id = V4L2_CID_BRIGHTNESS, 1231408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .type = V4L2_CTRL_TYPE_INTEGER, 1241408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .name = "Brightness", 1251408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .minimum = 0, 1261408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth#define BRIGHTNESS_MAX 0x20 1271408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .maximum = BRIGHTNESS_MAX, 1281408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .step = 1, 129aa5b7925f19f9bb586136fef55188deaf094805dJean-François Moine .default_value = 0x10, 1301408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth }, 131aa5b7925f19f9bb586136fef55188deaf094805dJean-François Moine .set_control = setbrightcont 1321408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth }, 133aa5b7925f19f9bb586136fef55188deaf094805dJean-François Moine[CONTRAST] = { 1341408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth { 1351408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .id = V4L2_CID_CONTRAST, 1361408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .type = V4L2_CTRL_TYPE_INTEGER, 1371408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .name = "Contrast", 1381408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .minimum = 0, 1391408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth#define CONTRAST_MAX 255 1401408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .maximum = CONTRAST_MAX, 1411408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .step = 1, 142aa5b7925f19f9bb586136fef55188deaf094805dJean-François Moine .default_value = 127, 1431408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth }, 144aa5b7925f19f9bb586136fef55188deaf094805dJean-François Moine .set_control = setbrightcont 1451408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth }, 146aa5b7925f19f9bb586136fef55188deaf094805dJean-François Moine[COLORS] = { 1471408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth { 1481408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .id = V4L2_CID_SATURATION, 1491408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .type = V4L2_CTRL_TYPE_INTEGER, 1501408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .name = "Saturation", 1511408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .minimum = 0, 1521408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth#define COLOR_MAX 255 1531408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .maximum = COLOR_MAX, 1541408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .step = 1, 155aa5b7925f19f9bb586136fef55188deaf094805dJean-François Moine .default_value = 127 1561408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth }, 157aa5b7925f19f9bb586136fef55188deaf094805dJean-François Moine .set_control = setcolors 1581408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth }, 159aa5b7925f19f9bb586136fef55188deaf094805dJean-François Moine[WHITE_BALANCE] = { 160265a8098e75e156985abfaac250ee4f2b407f863Márton Németh { 16123fbee6f88d59b4edca0855242d55e5b7cfc2401Marton Nemeth .id = V4L2_CID_WHITE_BALANCE_TEMPERATURE, 16223fbee6f88d59b4edca0855242d55e5b7cfc2401Marton Nemeth .type = V4L2_CTRL_TYPE_INTEGER, 16323fbee6f88d59b4edca0855242d55e5b7cfc2401Marton Nemeth .name = "White Balance", 16423fbee6f88d59b4edca0855242d55e5b7cfc2401Marton Nemeth .minimum = 0, 16523fbee6f88d59b4edca0855242d55e5b7cfc2401Marton Nemeth .maximum = 255, 16623fbee6f88d59b4edca0855242d55e5b7cfc2401Marton Nemeth .step = 1, 167aa5b7925f19f9bb586136fef55188deaf094805dJean-François Moine .default_value = 4, 16823fbee6f88d59b4edca0855242d55e5b7cfc2401Marton Nemeth }, 169aa5b7925f19f9bb586136fef55188deaf094805dJean-François Moine .set_control = setwhitebalance 17023fbee6f88d59b4edca0855242d55e5b7cfc2401Marton Nemeth }, 171aa5b7925f19f9bb586136fef55188deaf094805dJean-François Moine[RED_BALANCE] = { 17223fbee6f88d59b4edca0855242d55e5b7cfc2401Marton Nemeth { 173265a8098e75e156985abfaac250ee4f2b407f863Márton Németh .id = V4L2_CID_RED_BALANCE, 174265a8098e75e156985abfaac250ee4f2b407f863Márton Németh .type = V4L2_CTRL_TYPE_INTEGER, 175265a8098e75e156985abfaac250ee4f2b407f863Márton Németh .name = "Red", 176265a8098e75e156985abfaac250ee4f2b407f863Márton Németh .minimum = 0, 177265a8098e75e156985abfaac250ee4f2b407f863Márton Németh .maximum = 3, 178265a8098e75e156985abfaac250ee4f2b407f863Márton Németh .step = 1, 179aa5b7925f19f9bb586136fef55188deaf094805dJean-François Moine .default_value = 1, 180265a8098e75e156985abfaac250ee4f2b407f863Márton Németh }, 181aa5b7925f19f9bb586136fef55188deaf094805dJean-François Moine .set_control = setredbalance 182265a8098e75e156985abfaac250ee4f2b407f863Márton Németh }, 183aa5b7925f19f9bb586136fef55188deaf094805dJean-François Moine[BLUE_BALANCE] = { 184265a8098e75e156985abfaac250ee4f2b407f863Márton Németh { 185265a8098e75e156985abfaac250ee4f2b407f863Márton Németh .id = V4L2_CID_BLUE_BALANCE, 186265a8098e75e156985abfaac250ee4f2b407f863Márton Németh .type = V4L2_CTRL_TYPE_INTEGER, 187265a8098e75e156985abfaac250ee4f2b407f863Márton Németh .name = "Blue", 188265a8098e75e156985abfaac250ee4f2b407f863Márton Németh .minimum = 0, 189265a8098e75e156985abfaac250ee4f2b407f863Márton Németh .maximum = 3, 190265a8098e75e156985abfaac250ee4f2b407f863Márton Németh .step = 1, 191aa5b7925f19f9bb586136fef55188deaf094805dJean-François Moine .default_value = 1, 192265a8098e75e156985abfaac250ee4f2b407f863Márton Németh }, 193aa5b7925f19f9bb586136fef55188deaf094805dJean-François Moine .set_control = setbluebalance 194265a8098e75e156985abfaac250ee4f2b407f863Márton Németh }, 195aa5b7925f19f9bb586136fef55188deaf094805dJean-François Moine[GAIN] = { 1961408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth { 1971408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .id = V4L2_CID_GAIN, 1981408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .type = V4L2_CTRL_TYPE_INTEGER, 1991408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .name = "Gain", 2001408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .minimum = 0, 201aa5b7925f19f9bb586136fef55188deaf094805dJean-François Moine .maximum = 255, 2021408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .step = 1, 2031408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth#define GAIN_DEF 127 2041408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth#define GAIN_KNEE 255 /* Gain seems to cause little noise on the pac73xx */ 2051408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .default_value = GAIN_DEF, 2061408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth }, 207aa5b7925f19f9bb586136fef55188deaf094805dJean-François Moine .set_control = setgain 2081408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth }, 209aa5b7925f19f9bb586136fef55188deaf094805dJean-François Moine[EXPOSURE] = { 2101408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth { 2111408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .id = V4L2_CID_EXPOSURE, 2121408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .type = V4L2_CTRL_TYPE_INTEGER, 2131408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .name = "Exposure", 2141408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .minimum = 0, 2155fb2dde28122e74bbab9dae3cc04bcbc8c08b332Hans de Goede .maximum = 1023, 2161408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .step = 1, 2175fb2dde28122e74bbab9dae3cc04bcbc8c08b332Hans de Goede#define EXPOSURE_DEF 66 /* 33 ms / 30 fps */ 2185fb2dde28122e74bbab9dae3cc04bcbc8c08b332Hans de Goede#define EXPOSURE_KNEE 133 /* 66 ms / 15 fps */ 2191408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .default_value = EXPOSURE_DEF, 2201408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth }, 221aa5b7925f19f9bb586136fef55188deaf094805dJean-François Moine .set_control = setexposure 2221408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth }, 223aa5b7925f19f9bb586136fef55188deaf094805dJean-François Moine[AUTOGAIN] = { 2241408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth { 2251408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .id = V4L2_CID_AUTOGAIN, 2261408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .type = V4L2_CTRL_TYPE_BOOLEAN, 2271408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .name = "Auto Gain", 2281408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .minimum = 0, 2291408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .maximum = 1, 2301408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .step = 1, 2311408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth#define AUTOGAIN_DEF 1 2321408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .default_value = AUTOGAIN_DEF, 2331408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth }, 234ac399cd313f13d5208567c01ff70a476605804b7Jean-François Moine .set_control = setautogain, 2351408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth }, 236aa5b7925f19f9bb586136fef55188deaf094805dJean-François Moine[HFLIP] = { 2371408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth { 2381408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .id = V4L2_CID_HFLIP, 2391408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .type = V4L2_CTRL_TYPE_BOOLEAN, 2401408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .name = "Mirror", 2411408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .minimum = 0, 2421408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .maximum = 1, 2431408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .step = 1, 244aa5b7925f19f9bb586136fef55188deaf094805dJean-François Moine .default_value = 0, 2451408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth }, 246aa5b7925f19f9bb586136fef55188deaf094805dJean-François Moine .set_control = sethvflip, 2471408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth }, 248aa5b7925f19f9bb586136fef55188deaf094805dJean-François Moine[VFLIP] = { 2491408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth { 2501408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .id = V4L2_CID_VFLIP, 2511408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .type = V4L2_CTRL_TYPE_BOOLEAN, 2521408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .name = "Vflip", 2531408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .minimum = 0, 2541408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .maximum = 1, 2551408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .step = 1, 256aa5b7925f19f9bb586136fef55188deaf094805dJean-François Moine .default_value = 0, 2571408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth }, 258aa5b7925f19f9bb586136fef55188deaf094805dJean-François Moine .set_control = sethvflip 2591408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth }, 2601408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth}; 2611408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 2621408b8472910e894b290205b4baed5b14b8f45afMarton Nemethstatic const struct v4l2_pix_format vga_mode[] = { 2631408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth {640, 480, V4L2_PIX_FMT_PJPG, V4L2_FIELD_NONE, 2641408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .bytesperline = 640, 2651408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .sizeimage = 640 * 480 * 3 / 8 + 590, 2661408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .colorspace = V4L2_COLORSPACE_JPEG, 267ae251e6b18cff8c1bd1d825f8862b083a33be421Jean-François Moine }, 2681408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth}; 2691408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 2701408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth#define LOAD_PAGE3 255 2711408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth#define END_OF_SEQUENCE 0 2721408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 2731408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth/* pac 7302 */ 274ae251e6b18cff8c1bd1d825f8862b083a33be421Jean-François Moinestatic const u8 init_7302[] = { 2751408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth/* index,value */ 2761408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0xff, 0x01, /* page 1 */ 2771408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x78, 0x00, /* deactivate */ 2781408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0xff, 0x01, 2791408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x78, 0x40, /* led off */ 2801408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth}; 281ae251e6b18cff8c1bd1d825f8862b083a33be421Jean-François Moinestatic const u8 start_7302[] = { 2821408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth/* index, len, [value]* */ 2831408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0xff, 1, 0x00, /* page 0 */ 2841408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x00, 12, 0x01, 0x40, 0x40, 0x40, 0x01, 0xe0, 0x02, 0x80, 2851408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x00, 0x00, 0x00, 0x00, 2861408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x0d, 24, 0x03, 0x01, 0x00, 0xb5, 0x07, 0xcb, 0x00, 0x00, 2871408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x07, 0xc8, 0x00, 0xea, 0x07, 0xcf, 0x07, 0xf7, 2881408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x07, 0x7e, 0x01, 0x0b, 0x00, 0x00, 0x00, 0x11, 2891408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x26, 2, 0xaa, 0xaa, 2901408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x2e, 1, 0x31, 2911408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x38, 1, 0x01, 2921408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x3a, 3, 0x14, 0xff, 0x5a, 2931408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x43, 11, 0x00, 0x0a, 0x18, 0x11, 0x01, 0x2c, 0x88, 0x11, 2941408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x00, 0x54, 0x11, 2951408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x55, 1, 0x00, 296ae251e6b18cff8c1bd1d825f8862b083a33be421Jean-François Moine 0x62, 4, 0x10, 0x1e, 0x1e, 0x18, 2971408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x6b, 1, 0x00, 2981408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x6e, 3, 0x08, 0x06, 0x00, 2991408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x72, 3, 0x00, 0xff, 0x00, 3001408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x7d, 23, 0x01, 0x01, 0x58, 0x46, 0x50, 0x3c, 0x50, 0x3c, 3011408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x54, 0x46, 0x54, 0x56, 0x52, 0x50, 0x52, 0x50, 3021408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x56, 0x64, 0xa4, 0x00, 0xda, 0x00, 0x00, 3031408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0xa2, 10, 0x22, 0x2c, 0x3c, 0x54, 0x69, 0x7c, 0x9c, 0xb9, 3041408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0xd2, 0xeb, 3051408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0xaf, 1, 0x02, 3061408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0xb5, 2, 0x08, 0x08, 3071408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0xb8, 2, 0x08, 0x88, 3081408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0xc4, 4, 0xae, 0x01, 0x04, 0x01, 3091408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0xcc, 1, 0x00, 3101408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0xd1, 11, 0x01, 0x30, 0x49, 0x5e, 0x6f, 0x7f, 0x8e, 0xa9, 3111408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0xc1, 0xd7, 0xec, 3121408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0xdc, 1, 0x01, 3131408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0xff, 1, 0x01, /* page 1 */ 3141408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x12, 3, 0x02, 0x00, 0x01, 3151408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x3e, 2, 0x00, 0x00, 3161408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x76, 5, 0x01, 0x20, 0x40, 0x00, 0xf2, 3171408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x7c, 1, 0x00, 3181408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x7f, 10, 0x4b, 0x0f, 0x01, 0x2c, 0x02, 0x58, 0x03, 0x20, 3191408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x02, 0x00, 3201408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x96, 5, 0x01, 0x10, 0x04, 0x01, 0x04, 3211408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0xc8, 14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 3221408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x07, 0x00, 0x01, 0x07, 0x04, 0x01, 3231408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0xd8, 1, 0x01, 3241408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0xdb, 2, 0x00, 0x01, 3251408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0xde, 7, 0x00, 0x01, 0x04, 0x04, 0x00, 0x00, 0x00, 3261408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0xe6, 4, 0x00, 0x00, 0x00, 0x01, 3271408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0xeb, 1, 0x00, 3281408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0xff, 1, 0x02, /* page 2 */ 3291408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x22, 1, 0x00, 3301408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0xff, 1, 0x03, /* page 3 */ 3311408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0, LOAD_PAGE3, /* load the page 3 */ 3321408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x11, 1, 0x01, 3331408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0xff, 1, 0x02, /* page 2 */ 3341408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x13, 1, 0x00, 3351408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x22, 4, 0x1f, 0xa4, 0xf0, 0x96, 3361408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x27, 2, 0x14, 0x0c, 3371408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x2a, 5, 0xc8, 0x00, 0x18, 0x12, 0x22, 3381408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x64, 8, 0x00, 0x00, 0xf0, 0x01, 0x14, 0x44, 0x44, 0x44, 3391408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x6e, 1, 0x08, 3401408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0xff, 1, 0x01, /* page 1 */ 3411408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x78, 1, 0x00, 3421408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0, END_OF_SEQUENCE /* end of sequence */ 3431408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth}; 3441408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 3451408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth#define SKIP 0xaa 3461408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth/* page 3 - the value SKIP says skip the index - see reg_w_page() */ 347ae251e6b18cff8c1bd1d825f8862b083a33be421Jean-François Moinestatic const u8 page3_7302[] = { 3485fb2dde28122e74bbab9dae3cc04bcbc8c08b332Hans de Goede 0x90, 0x40, 0x03, 0x00, 0xc0, 0x01, 0x14, 0x16, 3491408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x14, 0x12, 0x00, 0x00, 0x00, 0x02, 0x33, 0x00, 3501408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x0f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 3511408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x00, 0x00, 0x00, 0x47, 0x01, 0xb3, 0x01, 0x00, 3521408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x00, 0x08, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x21, 3531408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x00, 0x00, 0x00, 0x54, 0xf4, 0x02, 0x52, 0x54, 3541408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0xa4, 0xb8, 0xe0, 0x2a, 0xf6, 0x00, 0x00, 0x00, 3551408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 3561408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x00, 0xfc, 0x00, 0xf2, 0x1f, 0x04, 0x00, 0x00, 357cdf955cd8e45d8279c53b47a2c0e0c5decaaca86Jean-Francois Moine SKIP, 0x00, 0x00, 0xc0, 0xc0, 0x10, 0x00, 0x00, 3581408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 3591408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x00, 0x40, 0xff, 0x03, 0x19, 0x00, 0x00, 0x00, 3601408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 3611408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0xc8, 0xc8, 3621408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0xc8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 3631408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x08, 0x10, 0x24, 0x40, 0x00, 0x00, 0x00, 0x00, 3641408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x01, 0x00, 0x02, 0x47, 0x00, 0x00, 0x00, 0x00, 3651408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 3661408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x00, 0x02, 0xfa, 0x00, 0x64, 0x5a, 0x28, 0x00, 3671408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x00 3681408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth}; 3691408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 370be927befd091481f88c5806aa0585f25ab2ee3a1Jean-Francois Moinestatic void reg_w_buf(struct gspca_dev *gspca_dev, 371ae251e6b18cff8c1bd1d825f8862b083a33be421Jean-François Moine u8 index, 3720aeb5ec74b0a95f1699040f0262a6fd5507d6e8fJean-François Moine const u8 *buffer, int len) 3731408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth{ 3744f7309e27865b88df7b0b0ad59e0376dba1806afMarton Nemeth int ret; 3754f7309e27865b88df7b0b0ad59e0376dba1806afMarton Nemeth 376be927befd091481f88c5806aa0585f25ab2ee3a1Jean-Francois Moine if (gspca_dev->usb_err < 0) 377be927befd091481f88c5806aa0585f25ab2ee3a1Jean-Francois Moine return; 3781408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth memcpy(gspca_dev->usb_buf, buffer, len); 3794f7309e27865b88df7b0b0ad59e0376dba1806afMarton Nemeth ret = usb_control_msg(gspca_dev->dev, 3801408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth usb_sndctrlpipe(gspca_dev->dev, 0), 381a1317135d109f4b6dd89caa1a9b2b6c8d54b09cdJean-François Moine 0, /* request */ 3821408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 3831408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0, /* value */ 3841408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth index, gspca_dev->usb_buf, len, 3851408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 500); 386be927befd091481f88c5806aa0585f25ab2ee3a1Jean-Francois Moine if (ret < 0) { 387ae251e6b18cff8c1bd1d825f8862b083a33be421Jean-François Moine pr_err("reg_w_buf failed i: %02x error %d\n", 388133a9fe949862d9ed8411fb423739f4cee08232dJoe Perches index, ret); 389be927befd091481f88c5806aa0585f25ab2ee3a1Jean-Francois Moine gspca_dev->usb_err = ret; 390be927befd091481f88c5806aa0585f25ab2ee3a1Jean-Francois Moine } 3911408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth} 3921408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 3931408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 394be927befd091481f88c5806aa0585f25ab2ee3a1Jean-Francois Moinestatic void reg_w(struct gspca_dev *gspca_dev, 395ae251e6b18cff8c1bd1d825f8862b083a33be421Jean-François Moine u8 index, 396ae251e6b18cff8c1bd1d825f8862b083a33be421Jean-François Moine u8 value) 3971408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth{ 3984f7309e27865b88df7b0b0ad59e0376dba1806afMarton Nemeth int ret; 3994f7309e27865b88df7b0b0ad59e0376dba1806afMarton Nemeth 400be927befd091481f88c5806aa0585f25ab2ee3a1Jean-Francois Moine if (gspca_dev->usb_err < 0) 401be927befd091481f88c5806aa0585f25ab2ee3a1Jean-Francois Moine return; 4021408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth gspca_dev->usb_buf[0] = value; 4034f7309e27865b88df7b0b0ad59e0376dba1806afMarton Nemeth ret = usb_control_msg(gspca_dev->dev, 4041408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth usb_sndctrlpipe(gspca_dev->dev, 0), 4051408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0, /* request */ 4061408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 4071408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0, index, gspca_dev->usb_buf, 1, 4081408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 500); 409be927befd091481f88c5806aa0585f25ab2ee3a1Jean-Francois Moine if (ret < 0) { 410ae251e6b18cff8c1bd1d825f8862b083a33be421Jean-François Moine pr_err("reg_w() failed i: %02x v: %02x error %d\n", 411133a9fe949862d9ed8411fb423739f4cee08232dJoe Perches index, value, ret); 412be927befd091481f88c5806aa0585f25ab2ee3a1Jean-Francois Moine gspca_dev->usb_err = ret; 413be927befd091481f88c5806aa0585f25ab2ee3a1Jean-Francois Moine } 4141408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth} 4151408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 416be927befd091481f88c5806aa0585f25ab2ee3a1Jean-Francois Moinestatic void reg_w_seq(struct gspca_dev *gspca_dev, 417ae251e6b18cff8c1bd1d825f8862b083a33be421Jean-François Moine const u8 *seq, int len) 4181408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth{ 4191408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth while (--len >= 0) { 420be927befd091481f88c5806aa0585f25ab2ee3a1Jean-Francois Moine reg_w(gspca_dev, seq[0], seq[1]); 4211408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth seq += 2; 4221408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth } 4231408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth} 4241408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 4251408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth/* load the beginning of a page */ 426be927befd091481f88c5806aa0585f25ab2ee3a1Jean-Francois Moinestatic void reg_w_page(struct gspca_dev *gspca_dev, 427ae251e6b18cff8c1bd1d825f8862b083a33be421Jean-François Moine const u8 *page, int len) 4281408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth{ 4291408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth int index; 430b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Németh int ret = 0; 4311408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 432be927befd091481f88c5806aa0585f25ab2ee3a1Jean-Francois Moine if (gspca_dev->usb_err < 0) 433be927befd091481f88c5806aa0585f25ab2ee3a1Jean-Francois Moine return; 4341408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth for (index = 0; index < len; index++) { 4351408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth if (page[index] == SKIP) /* skip this index */ 4361408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth continue; 4371408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth gspca_dev->usb_buf[0] = page[index]; 4384f7309e27865b88df7b0b0ad59e0376dba1806afMarton Nemeth ret = usb_control_msg(gspca_dev->dev, 4391408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth usb_sndctrlpipe(gspca_dev->dev, 0), 4401408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0, /* request */ 4411408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 4421408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0, index, gspca_dev->usb_buf, 1, 4431408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 500); 444b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Németh if (ret < 0) { 445ae251e6b18cff8c1bd1d825f8862b083a33be421Jean-François Moine pr_err("reg_w_page() failed i: %02x v: %02x error %d\n", 446133a9fe949862d9ed8411fb423739f4cee08232dJoe Perches index, page[index], ret); 447be927befd091481f88c5806aa0585f25ab2ee3a1Jean-Francois Moine gspca_dev->usb_err = ret; 448b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Németh break; 449b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Németh } 4501408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth } 4511408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth} 4521408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 4531408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth/* output a variable sequence */ 454be927befd091481f88c5806aa0585f25ab2ee3a1Jean-Francois Moinestatic void reg_w_var(struct gspca_dev *gspca_dev, 455ae251e6b18cff8c1bd1d825f8862b083a33be421Jean-François Moine const u8 *seq, 456ae251e6b18cff8c1bd1d825f8862b083a33be421Jean-François Moine const u8 *page3, unsigned int page3_len) 4571408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth{ 4581408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth int index, len; 4591408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 4601408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth for (;;) { 4611408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth index = *seq++; 4621408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth len = *seq++; 4631408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth switch (len) { 4641408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth case END_OF_SEQUENCE: 465be927befd091481f88c5806aa0585f25ab2ee3a1Jean-Francois Moine return; 4661408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth case LOAD_PAGE3: 467be927befd091481f88c5806aa0585f25ab2ee3a1Jean-Francois Moine reg_w_page(gspca_dev, page3, page3_len); 4681408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth break; 4691408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth default: 470ae251e6b18cff8c1bd1d825f8862b083a33be421Jean-François Moine#ifdef GSPCA_DEBUG 4711408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth if (len > USB_BUF_SZ) { 4721408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth PDEBUG(D_ERR|D_STREAM, 4731408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth "Incorrect variable sequence"); 474be927befd091481f88c5806aa0585f25ab2ee3a1Jean-Francois Moine return; 4751408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth } 476ae251e6b18cff8c1bd1d825f8862b083a33be421Jean-François Moine#endif 4771408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth while (len > 0) { 4781408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth if (len < 8) { 479be927befd091481f88c5806aa0585f25ab2ee3a1Jean-Francois Moine reg_w_buf(gspca_dev, 480b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Németh index, seq, len); 4811408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth seq += len; 4821408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth break; 4831408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth } 484be927befd091481f88c5806aa0585f25ab2ee3a1Jean-Francois Moine reg_w_buf(gspca_dev, index, seq, 8); 4851408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth seq += 8; 4861408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth index += 8; 4871408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth len -= 8; 4881408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth } 4891408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth } 4901408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth } 4911408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth /* not reached */ 4921408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth} 4931408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 4941408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth/* this function is called at probe time for pac7302 */ 4951408b8472910e894b290205b4baed5b14b8f45afMarton Nemethstatic int sd_config(struct gspca_dev *gspca_dev, 4961408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth const struct usb_device_id *id) 4971408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth{ 4981408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth struct sd *sd = (struct sd *) gspca_dev; 4991408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth struct cam *cam; 5001408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 5011408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth cam = &gspca_dev->cam; 5021408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 5031408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth cam->cam_mode = vga_mode; /* only 640x480 */ 5041408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth cam->nmodes = ARRAY_SIZE(vga_mode); 5051408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 506aa5b7925f19f9bb586136fef55188deaf094805dJean-François Moine gspca_dev->cam.ctrls = sd->ctrls; 507aa5b7925f19f9bb586136fef55188deaf094805dJean-François Moine 508fe2b6032513099b82cd19ef8da5050f02a18d3ecJean-Francois Moine sd->flags = id->driver_info; 5091408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth return 0; 5101408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth} 5111408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 5121408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth/* This function is used by pac7302 only */ 513be927befd091481f88c5806aa0585f25ab2ee3a1Jean-Francois Moinestatic void setbrightcont(struct gspca_dev *gspca_dev) 5141408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth{ 5151408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth struct sd *sd = (struct sd *) gspca_dev; 5161408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth int i, v; 517ae251e6b18cff8c1bd1d825f8862b083a33be421Jean-François Moine static const u8 max[10] = 5181408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth {0x29, 0x33, 0x42, 0x5a, 0x6e, 0x80, 0x9f, 0xbb, 5191408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0xd4, 0xec}; 520ae251e6b18cff8c1bd1d825f8862b083a33be421Jean-François Moine static const u8 delta[10] = 5211408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth {0x35, 0x33, 0x33, 0x2f, 0x2a, 0x25, 0x1e, 0x17, 5221408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x11, 0x0b}; 5231408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 524be927befd091481f88c5806aa0585f25ab2ee3a1Jean-Francois Moine reg_w(gspca_dev, 0xff, 0x00); /* page 0 */ 5251408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth for (i = 0; i < 10; i++) { 5261408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth v = max[i]; 527aa5b7925f19f9bb586136fef55188deaf094805dJean-François Moine v += (sd->ctrls[BRIGHTNESS].val - BRIGHTNESS_MAX) 5281408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth * 150 / BRIGHTNESS_MAX; /* 200 ? */ 529aa5b7925f19f9bb586136fef55188deaf094805dJean-François Moine v -= delta[i] * sd->ctrls[CONTRAST].val / CONTRAST_MAX; 5301408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth if (v < 0) 5311408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth v = 0; 5321408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth else if (v > 0xff) 5331408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth v = 0xff; 534be927befd091481f88c5806aa0585f25ab2ee3a1Jean-Francois Moine reg_w(gspca_dev, 0xa2 + i, v); 5351408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth } 536be927befd091481f88c5806aa0585f25ab2ee3a1Jean-Francois Moine reg_w(gspca_dev, 0xdc, 0x01); 5371408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth} 5381408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 5391408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth/* This function is used by pac7302 only */ 540be927befd091481f88c5806aa0585f25ab2ee3a1Jean-Francois Moinestatic void setcolors(struct gspca_dev *gspca_dev) 5411408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth{ 5421408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth struct sd *sd = (struct sd *) gspca_dev; 5431408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth int i, v; 5441408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth static const int a[9] = 5451408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth {217, -212, 0, -101, 170, -67, -38, -315, 355}; 5461408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth static const int b[9] = 5471408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth {19, 106, 0, 19, 106, 1, 19, 106, 1}; 5481408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 549be927befd091481f88c5806aa0585f25ab2ee3a1Jean-Francois Moine reg_w(gspca_dev, 0xff, 0x03); /* page 3 */ 550be927befd091481f88c5806aa0585f25ab2ee3a1Jean-Francois Moine reg_w(gspca_dev, 0x11, 0x01); 551be927befd091481f88c5806aa0585f25ab2ee3a1Jean-Francois Moine reg_w(gspca_dev, 0xff, 0x00); /* page 0 */ 5521408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth for (i = 0; i < 9; i++) { 553aa5b7925f19f9bb586136fef55188deaf094805dJean-François Moine v = a[i] * sd->ctrls[COLORS].val / COLOR_MAX + b[i]; 554be927befd091481f88c5806aa0585f25ab2ee3a1Jean-Francois Moine reg_w(gspca_dev, 0x0f + 2 * i, (v >> 8) & 0x07); 555be927befd091481f88c5806aa0585f25ab2ee3a1Jean-Francois Moine reg_w(gspca_dev, 0x0f + 2 * i + 1, v); 5561408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth } 557be927befd091481f88c5806aa0585f25ab2ee3a1Jean-Francois Moine reg_w(gspca_dev, 0xdc, 0x01); 5581408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth} 5591408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 560be927befd091481f88c5806aa0585f25ab2ee3a1Jean-Francois Moinestatic void setwhitebalance(struct gspca_dev *gspca_dev) 56123fbee6f88d59b4edca0855242d55e5b7cfc2401Marton Nemeth{ 56223fbee6f88d59b4edca0855242d55e5b7cfc2401Marton Nemeth struct sd *sd = (struct sd *) gspca_dev; 56323fbee6f88d59b4edca0855242d55e5b7cfc2401Marton Nemeth 564be927befd091481f88c5806aa0585f25ab2ee3a1Jean-Francois Moine reg_w(gspca_dev, 0xff, 0x00); /* page 0 */ 565aa5b7925f19f9bb586136fef55188deaf094805dJean-François Moine reg_w(gspca_dev, 0xc6, sd->ctrls[WHITE_BALANCE].val); 56623fbee6f88d59b4edca0855242d55e5b7cfc2401Marton Nemeth 567be927befd091481f88c5806aa0585f25ab2ee3a1Jean-Francois Moine reg_w(gspca_dev, 0xdc, 0x01); 56823fbee6f88d59b4edca0855242d55e5b7cfc2401Marton Nemeth} 56923fbee6f88d59b4edca0855242d55e5b7cfc2401Marton Nemeth 570be927befd091481f88c5806aa0585f25ab2ee3a1Jean-Francois Moinestatic void setredbalance(struct gspca_dev *gspca_dev) 571265a8098e75e156985abfaac250ee4f2b407f863Márton Németh{ 572265a8098e75e156985abfaac250ee4f2b407f863Márton Németh struct sd *sd = (struct sd *) gspca_dev; 573265a8098e75e156985abfaac250ee4f2b407f863Márton Németh 574be927befd091481f88c5806aa0585f25ab2ee3a1Jean-Francois Moine reg_w(gspca_dev, 0xff, 0x00); /* page 0 */ 575aa5b7925f19f9bb586136fef55188deaf094805dJean-François Moine reg_w(gspca_dev, 0xc5, sd->ctrls[RED_BALANCE].val); 576265a8098e75e156985abfaac250ee4f2b407f863Márton Németh 577be927befd091481f88c5806aa0585f25ab2ee3a1Jean-Francois Moine reg_w(gspca_dev, 0xdc, 0x01); 578265a8098e75e156985abfaac250ee4f2b407f863Márton Németh} 579265a8098e75e156985abfaac250ee4f2b407f863Márton Németh 580be927befd091481f88c5806aa0585f25ab2ee3a1Jean-Francois Moinestatic void setbluebalance(struct gspca_dev *gspca_dev) 581265a8098e75e156985abfaac250ee4f2b407f863Márton Németh{ 582265a8098e75e156985abfaac250ee4f2b407f863Márton Németh struct sd *sd = (struct sd *) gspca_dev; 583265a8098e75e156985abfaac250ee4f2b407f863Márton Németh 584be927befd091481f88c5806aa0585f25ab2ee3a1Jean-Francois Moine reg_w(gspca_dev, 0xff, 0x00); /* page 0 */ 585aa5b7925f19f9bb586136fef55188deaf094805dJean-François Moine reg_w(gspca_dev, 0xc7, sd->ctrls[BLUE_BALANCE].val); 586265a8098e75e156985abfaac250ee4f2b407f863Márton Németh 587be927befd091481f88c5806aa0585f25ab2ee3a1Jean-Francois Moine reg_w(gspca_dev, 0xdc, 0x01); 588265a8098e75e156985abfaac250ee4f2b407f863Márton Németh} 589265a8098e75e156985abfaac250ee4f2b407f863Márton Németh 590be927befd091481f88c5806aa0585f25ab2ee3a1Jean-Francois Moinestatic void setgain(struct gspca_dev *gspca_dev) 5911408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth{ 5921408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth struct sd *sd = (struct sd *) gspca_dev; 5931408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 594be927befd091481f88c5806aa0585f25ab2ee3a1Jean-Francois Moine reg_w(gspca_dev, 0xff, 0x03); /* page 3 */ 595aa5b7925f19f9bb586136fef55188deaf094805dJean-François Moine reg_w(gspca_dev, 0x10, sd->ctrls[GAIN].val >> 3); 5961408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 5971408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth /* load registers to sensor (Bit 0, auto clear) */ 598be927befd091481f88c5806aa0585f25ab2ee3a1Jean-Francois Moine reg_w(gspca_dev, 0x11, 0x01); 5991408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth} 6001408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 601be927befd091481f88c5806aa0585f25ab2ee3a1Jean-Francois Moinestatic void setexposure(struct gspca_dev *gspca_dev) 6021408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth{ 6031408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth struct sd *sd = (struct sd *) gspca_dev; 604ae251e6b18cff8c1bd1d825f8862b083a33be421Jean-François Moine u8 clockdiv; 605ae251e6b18cff8c1bd1d825f8862b083a33be421Jean-François Moine u16 exposure; 6065fb2dde28122e74bbab9dae3cc04bcbc8c08b332Hans de Goede 6075fb2dde28122e74bbab9dae3cc04bcbc8c08b332Hans de Goede /* register 2 of frame 3 contains the clock divider configuring the 6085fb2dde28122e74bbab9dae3cc04bcbc8c08b332Hans de Goede no fps according to the formula: 90 / reg. sd->exposure is the 6095fb2dde28122e74bbab9dae3cc04bcbc8c08b332Hans de Goede desired exposure time in 0.5 ms. */ 610aa5b7925f19f9bb586136fef55188deaf094805dJean-François Moine clockdiv = (90 * sd->ctrls[EXPOSURE].val + 1999) / 2000; 6115fb2dde28122e74bbab9dae3cc04bcbc8c08b332Hans de Goede 6125fb2dde28122e74bbab9dae3cc04bcbc8c08b332Hans de Goede /* Note clockdiv = 3 also works, but when running at 30 fps, depending 6135fb2dde28122e74bbab9dae3cc04bcbc8c08b332Hans de Goede on the scene being recorded, the camera switches to another 6145fb2dde28122e74bbab9dae3cc04bcbc8c08b332Hans de Goede quantization table for certain JPEG blocks, and we don't know how 6155fb2dde28122e74bbab9dae3cc04bcbc8c08b332Hans de Goede to decompress these blocks. So we cap the framerate at 15 fps */ 6165fb2dde28122e74bbab9dae3cc04bcbc8c08b332Hans de Goede if (clockdiv < 6) 6175fb2dde28122e74bbab9dae3cc04bcbc8c08b332Hans de Goede clockdiv = 6; 6185fb2dde28122e74bbab9dae3cc04bcbc8c08b332Hans de Goede else if (clockdiv > 63) 6195fb2dde28122e74bbab9dae3cc04bcbc8c08b332Hans de Goede clockdiv = 63; 6205fb2dde28122e74bbab9dae3cc04bcbc8c08b332Hans de Goede 6215fb2dde28122e74bbab9dae3cc04bcbc8c08b332Hans de Goede /* reg2 MUST be a multiple of 3, except when between 6 and 12? 6225fb2dde28122e74bbab9dae3cc04bcbc8c08b332Hans de Goede Always round up, otherwise we cannot get the desired frametime 6235fb2dde28122e74bbab9dae3cc04bcbc8c08b332Hans de Goede using the partial frame time exposure control */ 6245fb2dde28122e74bbab9dae3cc04bcbc8c08b332Hans de Goede if (clockdiv < 6 || clockdiv > 12) 6255fb2dde28122e74bbab9dae3cc04bcbc8c08b332Hans de Goede clockdiv = ((clockdiv + 2) / 3) * 3; 6265fb2dde28122e74bbab9dae3cc04bcbc8c08b332Hans de Goede 6275fb2dde28122e74bbab9dae3cc04bcbc8c08b332Hans de Goede /* frame exposure time in ms = 1000 * clockdiv / 90 -> 6285fb2dde28122e74bbab9dae3cc04bcbc8c08b332Hans de Goede exposure = (sd->exposure / 2) * 448 / (1000 * clockdiv / 90) */ 629aa5b7925f19f9bb586136fef55188deaf094805dJean-François Moine exposure = (sd->ctrls[EXPOSURE].val * 45 * 448) / (1000 * clockdiv); 6305fb2dde28122e74bbab9dae3cc04bcbc8c08b332Hans de Goede /* 0 = use full frametime, 448 = no exposure, reverse it */ 6315fb2dde28122e74bbab9dae3cc04bcbc8c08b332Hans de Goede exposure = 448 - exposure; 6325fb2dde28122e74bbab9dae3cc04bcbc8c08b332Hans de Goede 633be927befd091481f88c5806aa0585f25ab2ee3a1Jean-Francois Moine reg_w(gspca_dev, 0xff, 0x03); /* page 3 */ 6345fb2dde28122e74bbab9dae3cc04bcbc8c08b332Hans de Goede reg_w(gspca_dev, 0x02, clockdiv); 6355fb2dde28122e74bbab9dae3cc04bcbc8c08b332Hans de Goede reg_w(gspca_dev, 0x0e, exposure & 0xff); 6365fb2dde28122e74bbab9dae3cc04bcbc8c08b332Hans de Goede reg_w(gspca_dev, 0x0f, exposure >> 8); 6371408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 6381408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth /* load registers to sensor (Bit 0, auto clear) */ 639be927befd091481f88c5806aa0585f25ab2ee3a1Jean-Francois Moine reg_w(gspca_dev, 0x11, 0x01); 6401408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth} 6411408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 642ac399cd313f13d5208567c01ff70a476605804b7Jean-François Moinestatic void setautogain(struct gspca_dev *gspca_dev) 643ac399cd313f13d5208567c01ff70a476605804b7Jean-François Moine{ 644ac399cd313f13d5208567c01ff70a476605804b7Jean-François Moine struct sd *sd = (struct sd *) gspca_dev; 645ac399cd313f13d5208567c01ff70a476605804b7Jean-François Moine 646ac399cd313f13d5208567c01ff70a476605804b7Jean-François Moine /* when switching to autogain set defaults to make sure 647ac399cd313f13d5208567c01ff70a476605804b7Jean-François Moine we are on a valid point of the autogain gain / 648ac399cd313f13d5208567c01ff70a476605804b7Jean-François Moine exposure knee graph, and give this change time to 649ac399cd313f13d5208567c01ff70a476605804b7Jean-François Moine take effect before doing autogain. */ 650ac399cd313f13d5208567c01ff70a476605804b7Jean-François Moine if (sd->ctrls[AUTOGAIN].val) { 651ac399cd313f13d5208567c01ff70a476605804b7Jean-François Moine sd->ctrls[EXPOSURE].val = EXPOSURE_DEF; 652ac399cd313f13d5208567c01ff70a476605804b7Jean-François Moine sd->ctrls[GAIN].val = GAIN_DEF; 653ac399cd313f13d5208567c01ff70a476605804b7Jean-François Moine sd->autogain_ignore_frames = 654ac399cd313f13d5208567c01ff70a476605804b7Jean-François Moine PAC_AUTOGAIN_IGNORE_FRAMES; 655ac399cd313f13d5208567c01ff70a476605804b7Jean-François Moine } else { 656ac399cd313f13d5208567c01ff70a476605804b7Jean-François Moine sd->autogain_ignore_frames = -1; 657ac399cd313f13d5208567c01ff70a476605804b7Jean-François Moine } 658ac399cd313f13d5208567c01ff70a476605804b7Jean-François Moine setexposure(gspca_dev); 659ac399cd313f13d5208567c01ff70a476605804b7Jean-François Moine setgain(gspca_dev); 660ac399cd313f13d5208567c01ff70a476605804b7Jean-François Moine} 661ac399cd313f13d5208567c01ff70a476605804b7Jean-François Moine 662be927befd091481f88c5806aa0585f25ab2ee3a1Jean-Francois Moinestatic void sethvflip(struct gspca_dev *gspca_dev) 6631408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth{ 6641408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth struct sd *sd = (struct sd *) gspca_dev; 665fe2b6032513099b82cd19ef8da5050f02a18d3ecJean-Francois Moine u8 data, hflip, vflip; 666fe2b6032513099b82cd19ef8da5050f02a18d3ecJean-Francois Moine 667aa5b7925f19f9bb586136fef55188deaf094805dJean-François Moine hflip = sd->ctrls[HFLIP].val; 668fe2b6032513099b82cd19ef8da5050f02a18d3ecJean-Francois Moine if (sd->flags & FL_HFLIP) 669fe2b6032513099b82cd19ef8da5050f02a18d3ecJean-Francois Moine hflip = !hflip; 670aa5b7925f19f9bb586136fef55188deaf094805dJean-François Moine vflip = sd->ctrls[VFLIP].val; 671fe2b6032513099b82cd19ef8da5050f02a18d3ecJean-Francois Moine if (sd->flags & FL_VFLIP) 672fe2b6032513099b82cd19ef8da5050f02a18d3ecJean-Francois Moine vflip = !vflip; 6731408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 674be927befd091481f88c5806aa0585f25ab2ee3a1Jean-Francois Moine reg_w(gspca_dev, 0xff, 0x03); /* page 3 */ 675fe2b6032513099b82cd19ef8da5050f02a18d3ecJean-Francois Moine data = (hflip ? 0x08 : 0x00) | (vflip ? 0x04 : 0x00); 676be927befd091481f88c5806aa0585f25ab2ee3a1Jean-Francois Moine reg_w(gspca_dev, 0x21, data); 677be927befd091481f88c5806aa0585f25ab2ee3a1Jean-Francois Moine 6781408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth /* load registers to sensor (Bit 0, auto clear) */ 679be927befd091481f88c5806aa0585f25ab2ee3a1Jean-Francois Moine reg_w(gspca_dev, 0x11, 0x01); 6801408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth} 6811408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 6821408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth/* this function is called at probe and resume time for pac7302 */ 6831408b8472910e894b290205b4baed5b14b8f45afMarton Nemethstatic int sd_init(struct gspca_dev *gspca_dev) 6841408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth{ 685be927befd091481f88c5806aa0585f25ab2ee3a1Jean-Francois Moine reg_w_seq(gspca_dev, init_7302, sizeof(init_7302)/2); 686be927befd091481f88c5806aa0585f25ab2ee3a1Jean-Francois Moine return gspca_dev->usb_err; 6871408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth} 6881408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 6891408b8472910e894b290205b4baed5b14b8f45afMarton Nemethstatic int sd_start(struct gspca_dev *gspca_dev) 6901408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth{ 6911408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth struct sd *sd = (struct sd *) gspca_dev; 6921408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 693be927befd091481f88c5806aa0585f25ab2ee3a1Jean-Francois Moine reg_w_var(gspca_dev, start_7302, 69423a5de202bc385b69eb91a5db36699e9579ec03eJean-Francois Moine page3_7302, sizeof(page3_7302)); 695be927befd091481f88c5806aa0585f25ab2ee3a1Jean-Francois Moine setbrightcont(gspca_dev); 696be927befd091481f88c5806aa0585f25ab2ee3a1Jean-Francois Moine setcolors(gspca_dev); 697be927befd091481f88c5806aa0585f25ab2ee3a1Jean-Francois Moine setwhitebalance(gspca_dev); 698be927befd091481f88c5806aa0585f25ab2ee3a1Jean-Francois Moine setredbalance(gspca_dev); 699be927befd091481f88c5806aa0585f25ab2ee3a1Jean-Francois Moine setbluebalance(gspca_dev); 700ac399cd313f13d5208567c01ff70a476605804b7Jean-François Moine setautogain(gspca_dev); 701be927befd091481f88c5806aa0585f25ab2ee3a1Jean-Francois Moine sethvflip(gspca_dev); 7021408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 7031408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth /* only resolution 640x480 is supported for pac7302 */ 7041408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 7051408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth sd->sof_read = 0; 706ac399cd313f13d5208567c01ff70a476605804b7Jean-François Moine atomic_set(&sd->avg_lum, 270 + sd->ctrls[BRIGHTNESS].val); 7071408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 7081408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth /* start stream */ 709be927befd091481f88c5806aa0585f25ab2ee3a1Jean-Francois Moine reg_w(gspca_dev, 0xff, 0x01); 710be927befd091481f88c5806aa0585f25ab2ee3a1Jean-Francois Moine reg_w(gspca_dev, 0x78, 0x01); 7111408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 712be927befd091481f88c5806aa0585f25ab2ee3a1Jean-Francois Moine return gspca_dev->usb_err; 7131408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth} 7141408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 7151408b8472910e894b290205b4baed5b14b8f45afMarton Nemethstatic void sd_stopN(struct gspca_dev *gspca_dev) 7161408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth{ 717b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Németh 71867c98f72e132e191ff4db0ac7bd81ea94fa5c667Márton Németh /* stop stream */ 719be927befd091481f88c5806aa0585f25ab2ee3a1Jean-Francois Moine reg_w(gspca_dev, 0xff, 0x01); 720be927befd091481f88c5806aa0585f25ab2ee3a1Jean-Francois Moine reg_w(gspca_dev, 0x78, 0x00); 7211408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth} 7221408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 7231408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth/* called on streamoff with alt 0 and on disconnect for pac7302 */ 7241408b8472910e894b290205b4baed5b14b8f45afMarton Nemethstatic void sd_stop0(struct gspca_dev *gspca_dev) 7251408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth{ 7261408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth if (!gspca_dev->present) 7271408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth return; 728be927befd091481f88c5806aa0585f25ab2ee3a1Jean-Francois Moine reg_w(gspca_dev, 0xff, 0x01); 729be927befd091481f88c5806aa0585f25ab2ee3a1Jean-Francois Moine reg_w(gspca_dev, 0x78, 0x40); 7301408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth} 7311408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 732aa5b7925f19f9bb586136fef55188deaf094805dJean-François Moine/* !! coarse_grained_expo_autogain is not used !! */ 733aa5b7925f19f9bb586136fef55188deaf094805dJean-François Moine#define exp_too_low_cnt flags 734aa5b7925f19f9bb586136fef55188deaf094805dJean-François Moine#define exp_too_high_cnt sof_read 735aa5b7925f19f9bb586136fef55188deaf094805dJean-François Moine#include "autogain_functions.h" 736aa5b7925f19f9bb586136fef55188deaf094805dJean-François Moine 7371408b8472910e894b290205b4baed5b14b8f45afMarton Nemethstatic void do_autogain(struct gspca_dev *gspca_dev) 7381408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth{ 7391408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth struct sd *sd = (struct sd *) gspca_dev; 7401408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth int avg_lum = atomic_read(&sd->avg_lum); 7415fb2dde28122e74bbab9dae3cc04bcbc8c08b332Hans de Goede int desired_lum; 7425fb2dde28122e74bbab9dae3cc04bcbc8c08b332Hans de Goede const int deadzone = 30; 7431408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 744ac399cd313f13d5208567c01ff70a476605804b7Jean-François Moine if (sd->autogain_ignore_frames < 0) 7451408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth return; 7461408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 747ac399cd313f13d5208567c01ff70a476605804b7Jean-François Moine if (sd->autogain_ignore_frames > 0) { 7481408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth sd->autogain_ignore_frames--; 749ac399cd313f13d5208567c01ff70a476605804b7Jean-François Moine } else { 750ac399cd313f13d5208567c01ff70a476605804b7Jean-François Moine desired_lum = 270 + sd->ctrls[BRIGHTNESS].val; 751ac399cd313f13d5208567c01ff70a476605804b7Jean-François Moine 752ac399cd313f13d5208567c01ff70a476605804b7Jean-François Moine auto_gain_n_exposure(gspca_dev, avg_lum, desired_lum, 753ac399cd313f13d5208567c01ff70a476605804b7Jean-François Moine deadzone, GAIN_KNEE, EXPOSURE_KNEE); 7541408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth sd->autogain_ignore_frames = PAC_AUTOGAIN_IGNORE_FRAMES; 755ac399cd313f13d5208567c01ff70a476605804b7Jean-François Moine } 7561408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth} 7571408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 7587532e815995da3c83d28dc051ab62a03a7788ab4Jean-François Moine/* JPEG header */ 7597532e815995da3c83d28dc051ab62a03a7788ab4Jean-François Moinestatic const u8 jpeg_header[] = { 7607532e815995da3c83d28dc051ab62a03a7788ab4Jean-François Moine 0xff, 0xd8, /* SOI: Start of Image */ 7617532e815995da3c83d28dc051ab62a03a7788ab4Jean-François Moine 7627532e815995da3c83d28dc051ab62a03a7788ab4Jean-François Moine 0xff, 0xc0, /* SOF0: Start of Frame (Baseline DCT) */ 7637532e815995da3c83d28dc051ab62a03a7788ab4Jean-François Moine 0x00, 0x11, /* length = 17 bytes (including this length field) */ 7647532e815995da3c83d28dc051ab62a03a7788ab4Jean-François Moine 0x08, /* Precision: 8 */ 7657532e815995da3c83d28dc051ab62a03a7788ab4Jean-François Moine 0x02, 0x80, /* height = 640 (image rotated) */ 7667532e815995da3c83d28dc051ab62a03a7788ab4Jean-François Moine 0x01, 0xe0, /* width = 480 */ 7677532e815995da3c83d28dc051ab62a03a7788ab4Jean-François Moine 0x03, /* Number of image components: 3 */ 7687532e815995da3c83d28dc051ab62a03a7788ab4Jean-François Moine 0x01, 0x21, 0x00, /* ID=1, Subsampling 1x1, Quantization table: 0 */ 7697532e815995da3c83d28dc051ab62a03a7788ab4Jean-François Moine 0x02, 0x11, 0x01, /* ID=2, Subsampling 2x1, Quantization table: 1 */ 7707532e815995da3c83d28dc051ab62a03a7788ab4Jean-François Moine 0x03, 0x11, 0x01, /* ID=3, Subsampling 2x1, Quantization table: 1 */ 7717532e815995da3c83d28dc051ab62a03a7788ab4Jean-François Moine 7727532e815995da3c83d28dc051ab62a03a7788ab4Jean-François Moine 0xff, 0xda, /* SOS: Start Of Scan */ 7737532e815995da3c83d28dc051ab62a03a7788ab4Jean-François Moine 0x00, 0x0c, /* length = 12 bytes (including this length field) */ 7747532e815995da3c83d28dc051ab62a03a7788ab4Jean-François Moine 0x03, /* number of components: 3 */ 7757532e815995da3c83d28dc051ab62a03a7788ab4Jean-François Moine 0x01, 0x00, /* selector 1, table 0x00 */ 7767532e815995da3c83d28dc051ab62a03a7788ab4Jean-François Moine 0x02, 0x11, /* selector 2, table 0x11 */ 7777532e815995da3c83d28dc051ab62a03a7788ab4Jean-François Moine 0x03, 0x11, /* selector 3, table 0x11 */ 7787532e815995da3c83d28dc051ab62a03a7788ab4Jean-François Moine 0x00, 0x3f, /* Spectral selection: 0 .. 63 */ 7797532e815995da3c83d28dc051ab62a03a7788ab4Jean-François Moine 0x00 /* Successive approximation: 0 */ 7801408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth}; 7811408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 7821408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth/* this function is run at interrupt level */ 7831408b8472910e894b290205b4baed5b14b8f45afMarton Nemethstatic void sd_pkt_scan(struct gspca_dev *gspca_dev, 78476dd272b56cd1c7fa013ef5d7eb28c4d319e322bJean-Francois Moine u8 *data, /* isoc packet */ 7851408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth int len) /* iso packet length */ 7861408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth{ 7871408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth struct sd *sd = (struct sd *) gspca_dev; 788b192ca983746585e807259414f8d6f58cb28311fJean-François Moine u8 *image; 789ae251e6b18cff8c1bd1d825f8862b083a33be421Jean-François Moine u8 *sof; 7901408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 7911408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth sof = pac_find_sof(&sd->sof_read, data, len); 7921408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth if (sof) { 7931408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth int n, lum_offset, footer_length; 7941408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 7951408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth /* 6 bytes after the FF D9 EOF marker a number of lumination 7961408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth bytes are send corresponding to different parts of the 7971408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth image, the 14th and 15th byte after the EOF seem to 7981408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth correspond to the center of the image */ 7991408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth lum_offset = 61 + sizeof pac_sof_marker; 8001408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth footer_length = 74; 8011408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 8021408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth /* Finish decoding current frame */ 8031408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth n = (sof - data) - (footer_length + sizeof pac_sof_marker); 8041408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth if (n < 0) { 805b192ca983746585e807259414f8d6f58cb28311fJean-François Moine gspca_dev->image_len += n; 8061408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth n = 0; 807b192ca983746585e807259414f8d6f58cb28311fJean-François Moine } else { 808b192ca983746585e807259414f8d6f58cb28311fJean-François Moine gspca_frame_add(gspca_dev, INTER_PACKET, data, n); 8091408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth } 810f7059eaa285c0460569ffd26c43ae07e3f03cd6cJean-François Moine 811f7059eaa285c0460569ffd26c43ae07e3f03cd6cJean-François Moine image = gspca_dev->image; 812f7059eaa285c0460569ffd26c43ae07e3f03cd6cJean-François Moine if (image != NULL 813b192ca983746585e807259414f8d6f58cb28311fJean-François Moine && image[gspca_dev->image_len - 2] == 0xff 814b192ca983746585e807259414f8d6f58cb28311fJean-François Moine && image[gspca_dev->image_len - 1] == 0xd9) 815b192ca983746585e807259414f8d6f58cb28311fJean-François Moine gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0); 8161408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 8171408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth n = sof - data; 8181408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth len -= n; 8191408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth data = sof; 8201408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 8211408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth /* Get average lumination */ 8221408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth if (gspca_dev->last_packet_type == LAST_PACKET && 8231408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth n >= lum_offset) 8241408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth atomic_set(&sd->avg_lum, data[-lum_offset] + 8251408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth data[-lum_offset + 1]); 8261408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 8271408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth /* Start the new frame with the jpeg header */ 8281408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth /* The PAC7302 has the image rotated 90 degrees */ 8297532e815995da3c83d28dc051ab62a03a7788ab4Jean-François Moine gspca_frame_add(gspca_dev, FIRST_PACKET, 8307532e815995da3c83d28dc051ab62a03a7788ab4Jean-François Moine jpeg_header, sizeof jpeg_header); 8311408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth } 83276dd272b56cd1c7fa013ef5d7eb28c4d319e322bJean-Francois Moine gspca_frame_add(gspca_dev, INTER_PACKET, data, len); 8331408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth} 8341408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 8356763cc0e54e95eea356e15f9cd9a2f7b5ebeb7e8Márton Németh#ifdef CONFIG_VIDEO_ADV_DEBUG 8366763cc0e54e95eea356e15f9cd9a2f7b5ebeb7e8Márton Némethstatic int sd_dbg_s_register(struct gspca_dev *gspca_dev, 8376763cc0e54e95eea356e15f9cd9a2f7b5ebeb7e8Márton Németh struct v4l2_dbg_register *reg) 8386763cc0e54e95eea356e15f9cd9a2f7b5ebeb7e8Márton Németh{ 839ae251e6b18cff8c1bd1d825f8862b083a33be421Jean-François Moine u8 index; 840ae251e6b18cff8c1bd1d825f8862b083a33be421Jean-François Moine u8 value; 8416763cc0e54e95eea356e15f9cd9a2f7b5ebeb7e8Márton Németh 8426763cc0e54e95eea356e15f9cd9a2f7b5ebeb7e8Márton Németh /* reg->reg: bit0..15: reserved for register index (wIndex is 16bit 8436763cc0e54e95eea356e15f9cd9a2f7b5ebeb7e8Márton Németh long on the USB bus) 8446763cc0e54e95eea356e15f9cd9a2f7b5ebeb7e8Márton Németh */ 8456763cc0e54e95eea356e15f9cd9a2f7b5ebeb7e8Márton Németh if (reg->match.type == V4L2_CHIP_MATCH_HOST && 8466763cc0e54e95eea356e15f9cd9a2f7b5ebeb7e8Márton Németh reg->match.addr == 0 && 8476763cc0e54e95eea356e15f9cd9a2f7b5ebeb7e8Márton Németh (reg->reg < 0x000000ff) && 8486763cc0e54e95eea356e15f9cd9a2f7b5ebeb7e8Márton Németh (reg->val <= 0x000000ff) 8496763cc0e54e95eea356e15f9cd9a2f7b5ebeb7e8Márton Németh ) { 8506763cc0e54e95eea356e15f9cd9a2f7b5ebeb7e8Márton Németh /* Currently writing to page 0 is only supported. */ 8516763cc0e54e95eea356e15f9cd9a2f7b5ebeb7e8Márton Németh /* reg_w() only supports 8bit index */ 852ae251e6b18cff8c1bd1d825f8862b083a33be421Jean-François Moine index = reg->reg; 853ae251e6b18cff8c1bd1d825f8862b083a33be421Jean-François Moine value = reg->val; 8546763cc0e54e95eea356e15f9cd9a2f7b5ebeb7e8Márton Németh 8556763cc0e54e95eea356e15f9cd9a2f7b5ebeb7e8Márton Németh /* Note that there shall be no access to other page 8566763cc0e54e95eea356e15f9cd9a2f7b5ebeb7e8Márton Németh by any other function between the page swith and 8576763cc0e54e95eea356e15f9cd9a2f7b5ebeb7e8Márton Németh the actual register write */ 858be927befd091481f88c5806aa0585f25ab2ee3a1Jean-Francois Moine reg_w(gspca_dev, 0xff, 0x00); /* page 0 */ 859be927befd091481f88c5806aa0585f25ab2ee3a1Jean-Francois Moine reg_w(gspca_dev, index, value); 8606763cc0e54e95eea356e15f9cd9a2f7b5ebeb7e8Márton Németh 861be927befd091481f88c5806aa0585f25ab2ee3a1Jean-Francois Moine reg_w(gspca_dev, 0xdc, 0x01); 8626763cc0e54e95eea356e15f9cd9a2f7b5ebeb7e8Márton Németh } 863be927befd091481f88c5806aa0585f25ab2ee3a1Jean-Francois Moine return gspca_dev->usb_err; 8646763cc0e54e95eea356e15f9cd9a2f7b5ebeb7e8Márton Németh} 8656763cc0e54e95eea356e15f9cd9a2f7b5ebeb7e8Márton Németh 8666763cc0e54e95eea356e15f9cd9a2f7b5ebeb7e8Márton Némethstatic int sd_chip_ident(struct gspca_dev *gspca_dev, 8676763cc0e54e95eea356e15f9cd9a2f7b5ebeb7e8Márton Németh struct v4l2_dbg_chip_ident *chip) 8686763cc0e54e95eea356e15f9cd9a2f7b5ebeb7e8Márton Németh{ 8696763cc0e54e95eea356e15f9cd9a2f7b5ebeb7e8Márton Németh int ret = -EINVAL; 8706763cc0e54e95eea356e15f9cd9a2f7b5ebeb7e8Márton Németh 8716763cc0e54e95eea356e15f9cd9a2f7b5ebeb7e8Márton Németh if (chip->match.type == V4L2_CHIP_MATCH_HOST && 8726763cc0e54e95eea356e15f9cd9a2f7b5ebeb7e8Márton Németh chip->match.addr == 0) { 8736763cc0e54e95eea356e15f9cd9a2f7b5ebeb7e8Márton Németh chip->revision = 0; 8746763cc0e54e95eea356e15f9cd9a2f7b5ebeb7e8Márton Németh chip->ident = V4L2_IDENT_UNKNOWN; 8756763cc0e54e95eea356e15f9cd9a2f7b5ebeb7e8Márton Németh ret = 0; 8766763cc0e54e95eea356e15f9cd9a2f7b5ebeb7e8Márton Németh } 8776763cc0e54e95eea356e15f9cd9a2f7b5ebeb7e8Márton Németh return ret; 8786763cc0e54e95eea356e15f9cd9a2f7b5ebeb7e8Márton Németh} 8796763cc0e54e95eea356e15f9cd9a2f7b5ebeb7e8Márton Németh#endif 8806763cc0e54e95eea356e15f9cd9a2f7b5ebeb7e8Márton Németh 8812856643e2e18f306227ae1257b63fc713d426dc7Jean-François Moine#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) 882aed6f1b5fe4e95cf8a9fc149e25041aa8cc7c78aMárton Némethstatic int sd_int_pkt_scan(struct gspca_dev *gspca_dev, 883aed6f1b5fe4e95cf8a9fc149e25041aa8cc7c78aMárton Németh u8 *data, /* interrupt packet data */ 884aed6f1b5fe4e95cf8a9fc149e25041aa8cc7c78aMárton Németh int len) /* interrput packet length */ 885aed6f1b5fe4e95cf8a9fc149e25041aa8cc7c78aMárton Németh{ 886aed6f1b5fe4e95cf8a9fc149e25041aa8cc7c78aMárton Németh int ret = -EINVAL; 887aed6f1b5fe4e95cf8a9fc149e25041aa8cc7c78aMárton Németh u8 data0, data1; 888aed6f1b5fe4e95cf8a9fc149e25041aa8cc7c78aMárton Németh 889aed6f1b5fe4e95cf8a9fc149e25041aa8cc7c78aMárton Németh if (len == 2) { 890aed6f1b5fe4e95cf8a9fc149e25041aa8cc7c78aMárton Németh data0 = data[0]; 891aed6f1b5fe4e95cf8a9fc149e25041aa8cc7c78aMárton Németh data1 = data[1]; 892aed6f1b5fe4e95cf8a9fc149e25041aa8cc7c78aMárton Németh if ((data0 == 0x00 && data1 == 0x11) || 893aed6f1b5fe4e95cf8a9fc149e25041aa8cc7c78aMárton Németh (data0 == 0x22 && data1 == 0x33) || 894aed6f1b5fe4e95cf8a9fc149e25041aa8cc7c78aMárton Németh (data0 == 0x44 && data1 == 0x55) || 895aed6f1b5fe4e95cf8a9fc149e25041aa8cc7c78aMárton Németh (data0 == 0x66 && data1 == 0x77) || 896aed6f1b5fe4e95cf8a9fc149e25041aa8cc7c78aMárton Németh (data0 == 0x88 && data1 == 0x99) || 897aed6f1b5fe4e95cf8a9fc149e25041aa8cc7c78aMárton Németh (data0 == 0xaa && data1 == 0xbb) || 898aed6f1b5fe4e95cf8a9fc149e25041aa8cc7c78aMárton Németh (data0 == 0xcc && data1 == 0xdd) || 899aed6f1b5fe4e95cf8a9fc149e25041aa8cc7c78aMárton Németh (data0 == 0xee && data1 == 0xff)) { 900aed6f1b5fe4e95cf8a9fc149e25041aa8cc7c78aMárton Németh input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1); 901aed6f1b5fe4e95cf8a9fc149e25041aa8cc7c78aMárton Németh input_sync(gspca_dev->input_dev); 902aed6f1b5fe4e95cf8a9fc149e25041aa8cc7c78aMárton Németh input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0); 903aed6f1b5fe4e95cf8a9fc149e25041aa8cc7c78aMárton Németh input_sync(gspca_dev->input_dev); 904aed6f1b5fe4e95cf8a9fc149e25041aa8cc7c78aMárton Németh ret = 0; 905aed6f1b5fe4e95cf8a9fc149e25041aa8cc7c78aMárton Németh } 906aed6f1b5fe4e95cf8a9fc149e25041aa8cc7c78aMárton Németh } 907aed6f1b5fe4e95cf8a9fc149e25041aa8cc7c78aMárton Németh 908aed6f1b5fe4e95cf8a9fc149e25041aa8cc7c78aMárton Németh return ret; 909aed6f1b5fe4e95cf8a9fc149e25041aa8cc7c78aMárton Németh} 910aed6f1b5fe4e95cf8a9fc149e25041aa8cc7c78aMárton Németh#endif 911aed6f1b5fe4e95cf8a9fc149e25041aa8cc7c78aMárton Németh 9121408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth/* sub-driver description for pac7302 */ 913aabcdfb65be31d7f9486d1400fa217c8827dddd3Márton Némethstatic const struct sd_desc sd_desc = { 914ae251e6b18cff8c1bd1d825f8862b083a33be421Jean-François Moine .name = KBUILD_MODNAME, 9151408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .ctrls = sd_ctrls, 9161408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .nctrls = ARRAY_SIZE(sd_ctrls), 9171408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .config = sd_config, 9181408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .init = sd_init, 9191408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .start = sd_start, 9201408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .stopN = sd_stopN, 9211408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .stop0 = sd_stop0, 9221408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .pkt_scan = sd_pkt_scan, 9231408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .dq_callback = do_autogain, 9246763cc0e54e95eea356e15f9cd9a2f7b5ebeb7e8Márton Németh#ifdef CONFIG_VIDEO_ADV_DEBUG 9256763cc0e54e95eea356e15f9cd9a2f7b5ebeb7e8Márton Németh .set_register = sd_dbg_s_register, 9266763cc0e54e95eea356e15f9cd9a2f7b5ebeb7e8Márton Németh .get_chip_ident = sd_chip_ident, 9276763cc0e54e95eea356e15f9cd9a2f7b5ebeb7e8Márton Németh#endif 9282856643e2e18f306227ae1257b63fc713d426dc7Jean-François Moine#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) 929aed6f1b5fe4e95cf8a9fc149e25041aa8cc7c78aMárton Németh .int_pkt_scan = sd_int_pkt_scan, 930aed6f1b5fe4e95cf8a9fc149e25041aa8cc7c78aMárton Németh#endif 9311408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth}; 9321408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 9331408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth/* -- module initialisation -- */ 93495c967c167785eb991cf6b22fb854dd8d61d0ff8Jean-François Moinestatic const struct usb_device_id device_table[] = { 9351408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth {USB_DEVICE(0x06f8, 0x3009)}, 936dd32f98120e7a763b125a3d5f60799a97b0a2b51Jean-François Moine {USB_DEVICE(0x06f8, 0x301b)}, 9371408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth {USB_DEVICE(0x093a, 0x2620)}, 9381408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth {USB_DEVICE(0x093a, 0x2621)}, 939fe2b6032513099b82cd19ef8da5050f02a18d3ecJean-Francois Moine {USB_DEVICE(0x093a, 0x2622), .driver_info = FL_VFLIP}, 940fe2b6032513099b82cd19ef8da5050f02a18d3ecJean-Francois Moine {USB_DEVICE(0x093a, 0x2624), .driver_info = FL_VFLIP}, 9414e6aeefeb822c70d70de4d3b9970939e5de9c647Márton Németh {USB_DEVICE(0x093a, 0x2625)}, 9421408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth {USB_DEVICE(0x093a, 0x2626)}, 9431408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth {USB_DEVICE(0x093a, 0x2628)}, 944c4322bfca8907109689eb6b244258bf52277f7dcJean-Francois Moine {USB_DEVICE(0x093a, 0x2629), .driver_info = FL_VFLIP}, 9451408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth {USB_DEVICE(0x093a, 0x262a)}, 9461408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth {USB_DEVICE(0x093a, 0x262c)}, 9474d6454dbae935825e729f34dc7410bb1b22c7944Hans de Goede {USB_DEVICE(0x145f, 0x013c)}, 9481408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth {} 9491408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth}; 9501408b8472910e894b290205b4baed5b14b8f45afMarton NemethMODULE_DEVICE_TABLE(usb, device_table); 9511408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 9521408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth/* -- device connect -- */ 95395c967c167785eb991cf6b22fb854dd8d61d0ff8Jean-François Moinestatic int sd_probe(struct usb_interface *intf, 9541408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth const struct usb_device_id *id) 9551408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth{ 9561408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), 9571408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth THIS_MODULE); 9581408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth} 9591408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 9601408b8472910e894b290205b4baed5b14b8f45afMarton Nemethstatic struct usb_driver sd_driver = { 961ae251e6b18cff8c1bd1d825f8862b083a33be421Jean-François Moine .name = KBUILD_MODNAME, 9621408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .id_table = device_table, 9631408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .probe = sd_probe, 9641408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .disconnect = gspca_disconnect, 9651408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth#ifdef CONFIG_PM 9661408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .suspend = gspca_suspend, 9671408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .resume = gspca_resume, 9681408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth#endif 9691408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth}; 9701408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 971ecb3b2b35db49778b6d89e3ffd0c400776c20735Greg Kroah-Hartmanmodule_usb_driver(sd_driver); 972