pac7302.c revision 37b372e5ebe187037e01885151a0afb546a38520
11408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth/* 21408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth * Pixart PAC7302 library 31408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth * Copyright (C) 2005 Thomas Kaiser thomas@kaiser-linux.li 41408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth * 51408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth * V4L2 by Jean-Francois Moine <http://moinejf.free.fr> 61408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth * 71408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth * Separated from Pixart PAC7311 library by M�rton N�meth <nm127@freemail.hu> 81408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth * 91408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth * This program is free software; you can redistribute it and/or modify 101408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth * it under the terms of the GNU General Public License as published by 111408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth * the Free Software Foundation; either version 2 of the License, or 121408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth * any later version. 131408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth * 141408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth * This program is distributed in the hope that it will be useful, 151408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth * but WITHOUT ANY WARRANTY; without even the implied warranty of 161408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 171408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth * GNU General Public License for more details. 181408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth * 191408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth * You should have received a copy of the GNU General Public License 201408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth * along with this program; if not, write to the Free Software 211408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 221408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth */ 231408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 241408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth/* Some documentation about various registers as determined by trial and error. 251408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth When the register addresses differ between the 7202 and the 7311 the 2 261408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth different addresses are written as 7302addr/7311addr, when one of the 2 271408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth addresses is a - sign that register description is not valid for the 281408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth matching IC. 291408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 301408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth Register page 1: 311408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 321408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth Address Description 331408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth -/0x08 Unknown compressor related, must always be 8 except when not 341408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth in 640x480 resolution and page 4 reg 2 <= 3 then set it to 9 ! 351408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth -/0x1b Auto white balance related, bit 0 is AWB enable (inverted) 361408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth bits 345 seem to toggle per color gains on/off (inverted) 371408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x78 Global control, bit 6 controls the LED (inverted) 381408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth -/0x80 JPEG compression ratio ? Best not touched 391408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 401408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth Register page 3/4: 411408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 421408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth Address Description 431408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x02 Clock divider 2-63, fps =~ 60 / val. Must be a multiple of 3 on 441408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth the 7302, so one of 3, 6, 9, ..., except when between 6 and 12? 451408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth -/0x0f Master gain 1-245, low value = high gain 461408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x10/- Master gain 0-31 471408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth -/0x10 Another gain 0-15, limited influence (1-2x gain I guess) 481408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x21 Bitfield: 0-1 unused, 2-3 vflip/hflip, 4-5 unknown, 6-7 unused 491408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth -/0x27 Seems to toggle various gains on / off, Setting bit 7 seems to 501408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth completely disable the analog amplification block. Set to 0x68 511408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth for max gain, 0x14 for minimal gain. 52265a8098e75e156985abfaac250ee4f2b407f863Márton Németh 53265a8098e75e156985abfaac250ee4f2b407f863Márton Németh The registers are accessed in the following functions: 54265a8098e75e156985abfaac250ee4f2b407f863Márton Németh 55265a8098e75e156985abfaac250ee4f2b407f863Márton Németh Page | Register | Function 56265a8098e75e156985abfaac250ee4f2b407f863Márton Németh -----+------------+--------------------------------------------------- 57265a8098e75e156985abfaac250ee4f2b407f863Márton Németh 0 | 0x0f..0x20 | setcolors() 58265a8098e75e156985abfaac250ee4f2b407f863Márton Németh 0 | 0xa2..0xab | setbrightcont() 59265a8098e75e156985abfaac250ee4f2b407f863Márton Németh 0 | 0xc5 | setredbalance() 6023fbee6f88d59b4edca0855242d55e5b7cfc2401Marton Nemeth 0 | 0xc6 | setwhitebalance() 61265a8098e75e156985abfaac250ee4f2b407f863Márton Németh 0 | 0xc7 | setbluebalance() 62265a8098e75e156985abfaac250ee4f2b407f863Márton Németh 0 | 0xdc | setbrightcont(), setcolors() 63265a8098e75e156985abfaac250ee4f2b407f863Márton Németh 3 | 0x02 | setexposure() 64265a8098e75e156985abfaac250ee4f2b407f863Márton Németh 3 | 0x10 | setgain() 65265a8098e75e156985abfaac250ee4f2b407f863Márton Németh 3 | 0x11 | setcolors(), setgain(), setexposure(), sethvflip() 66265a8098e75e156985abfaac250ee4f2b407f863Márton Németh 3 | 0x21 | sethvflip() 671408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth*/ 681408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 691408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth#define MODULE_NAME "pac7302" 701408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 716763cc0e54e95eea356e15f9cd9a2f7b5ebeb7e8Márton Németh#include <media/v4l2-chip-ident.h> 721408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth#include "gspca.h" 731408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 741408b8472910e894b290205b4baed5b14b8f45afMarton NemethMODULE_AUTHOR("Thomas Kaiser thomas@kaiser-linux.li"); 751408b8472910e894b290205b4baed5b14b8f45afMarton NemethMODULE_DESCRIPTION("Pixart PAC7302"); 761408b8472910e894b290205b4baed5b14b8f45afMarton NemethMODULE_LICENSE("GPL"); 771408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 781408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth/* specific webcam descriptor for pac7302 */ 791408b8472910e894b290205b4baed5b14b8f45afMarton Nemethstruct sd { 801408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth struct gspca_dev gspca_dev; /* !! must be the first item */ 811408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 821408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth unsigned char brightness; 831408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth unsigned char contrast; 841408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth unsigned char colors; 8523fbee6f88d59b4edca0855242d55e5b7cfc2401Marton Nemeth unsigned char white_balance; 86265a8098e75e156985abfaac250ee4f2b407f863Márton Németh unsigned char red_balance; 87265a8098e75e156985abfaac250ee4f2b407f863Márton Németh unsigned char blue_balance; 881408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth unsigned char gain; 891408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth unsigned char exposure; 901408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth unsigned char autogain; 911408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth __u8 hflip; 921408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth __u8 vflip; 93fe2b6032513099b82cd19ef8da5050f02a18d3ecJean-Francois Moine u8 flags; 94fe2b6032513099b82cd19ef8da5050f02a18d3ecJean-Francois Moine#define FL_HFLIP 0x01 /* mirrored by default */ 95fe2b6032513099b82cd19ef8da5050f02a18d3ecJean-Francois Moine#define FL_VFLIP 0x02 /* vertical flipped by default */ 961408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 971408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth u8 sof_read; 981408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth u8 autogain_ignore_frames; 991408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 1001408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth atomic_t avg_lum; 1011408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth}; 1021408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 1031408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth/* V4L2 controls supported by the driver */ 1041408b8472910e894b290205b4baed5b14b8f45afMarton Nemethstatic int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); 1051408b8472910e894b290205b4baed5b14b8f45afMarton Nemethstatic int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); 1061408b8472910e894b290205b4baed5b14b8f45afMarton Nemethstatic int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); 1071408b8472910e894b290205b4baed5b14b8f45afMarton Nemethstatic int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); 1081408b8472910e894b290205b4baed5b14b8f45afMarton Nemethstatic int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val); 1091408b8472910e894b290205b4baed5b14b8f45afMarton Nemethstatic int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val); 11023fbee6f88d59b4edca0855242d55e5b7cfc2401Marton Nemethstatic int sd_setwhitebalance(struct gspca_dev *gspca_dev, __s32 val); 11123fbee6f88d59b4edca0855242d55e5b7cfc2401Marton Nemethstatic int sd_getwhitebalance(struct gspca_dev *gspca_dev, __s32 *val); 112265a8098e75e156985abfaac250ee4f2b407f863Márton Némethstatic int sd_setredbalance(struct gspca_dev *gspca_dev, __s32 val); 113265a8098e75e156985abfaac250ee4f2b407f863Márton Némethstatic int sd_getredbalance(struct gspca_dev *gspca_dev, __s32 *val); 114265a8098e75e156985abfaac250ee4f2b407f863Márton Némethstatic int sd_setbluebalance(struct gspca_dev *gspca_dev, __s32 val); 115265a8098e75e156985abfaac250ee4f2b407f863Márton Némethstatic int sd_getbluebalance(struct gspca_dev *gspca_dev, __s32 *val); 1161408b8472910e894b290205b4baed5b14b8f45afMarton Nemethstatic int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); 1171408b8472910e894b290205b4baed5b14b8f45afMarton Nemethstatic int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val); 1181408b8472910e894b290205b4baed5b14b8f45afMarton Nemethstatic int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val); 1191408b8472910e894b290205b4baed5b14b8f45afMarton Nemethstatic int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val); 1201408b8472910e894b290205b4baed5b14b8f45afMarton Nemethstatic int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val); 1211408b8472910e894b290205b4baed5b14b8f45afMarton Nemethstatic int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val); 1221408b8472910e894b290205b4baed5b14b8f45afMarton Nemethstatic int sd_setgain(struct gspca_dev *gspca_dev, __s32 val); 1231408b8472910e894b290205b4baed5b14b8f45afMarton Nemethstatic int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val); 1241408b8472910e894b290205b4baed5b14b8f45afMarton Nemethstatic int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val); 1251408b8472910e894b290205b4baed5b14b8f45afMarton Nemethstatic int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val); 1261408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 1271408b8472910e894b290205b4baed5b14b8f45afMarton Nemethstatic struct ctrl sd_ctrls[] = { 1281408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth/* This control is pac7302 only */ 1291408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth { 1301408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth { 1311408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .id = V4L2_CID_BRIGHTNESS, 1321408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .type = V4L2_CTRL_TYPE_INTEGER, 1331408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .name = "Brightness", 1341408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .minimum = 0, 1351408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth#define BRIGHTNESS_MAX 0x20 1361408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .maximum = BRIGHTNESS_MAX, 1371408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .step = 1, 1381408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth#define BRIGHTNESS_DEF 0x10 1391408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .default_value = BRIGHTNESS_DEF, 1401408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth }, 1411408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .set = sd_setbrightness, 1421408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .get = sd_getbrightness, 1431408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth }, 1441408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth/* This control is for both the 7302 and the 7311 */ 1451408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth { 1461408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth { 1471408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .id = V4L2_CID_CONTRAST, 1481408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .type = V4L2_CTRL_TYPE_INTEGER, 1491408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .name = "Contrast", 1501408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .minimum = 0, 1511408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth#define CONTRAST_MAX 255 1521408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .maximum = CONTRAST_MAX, 1531408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .step = 1, 1541408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth#define CONTRAST_DEF 127 1551408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .default_value = CONTRAST_DEF, 1561408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth }, 1571408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .set = sd_setcontrast, 1581408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .get = sd_getcontrast, 1591408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth }, 1601408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth/* This control is pac7302 only */ 1611408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth { 1621408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth { 1631408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .id = V4L2_CID_SATURATION, 1641408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .type = V4L2_CTRL_TYPE_INTEGER, 1651408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .name = "Saturation", 1661408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .minimum = 0, 1671408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth#define COLOR_MAX 255 1681408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .maximum = COLOR_MAX, 1691408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .step = 1, 1701408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth#define COLOR_DEF 127 1711408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .default_value = COLOR_DEF, 1721408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth }, 1731408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .set = sd_setcolors, 1741408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .get = sd_getcolors, 1751408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth }, 176265a8098e75e156985abfaac250ee4f2b407f863Márton Németh { 177265a8098e75e156985abfaac250ee4f2b407f863Márton Németh { 17823fbee6f88d59b4edca0855242d55e5b7cfc2401Marton Nemeth .id = V4L2_CID_WHITE_BALANCE_TEMPERATURE, 17923fbee6f88d59b4edca0855242d55e5b7cfc2401Marton Nemeth .type = V4L2_CTRL_TYPE_INTEGER, 18023fbee6f88d59b4edca0855242d55e5b7cfc2401Marton Nemeth .name = "White Balance", 18123fbee6f88d59b4edca0855242d55e5b7cfc2401Marton Nemeth .minimum = 0, 18223fbee6f88d59b4edca0855242d55e5b7cfc2401Marton Nemeth .maximum = 255, 18323fbee6f88d59b4edca0855242d55e5b7cfc2401Marton Nemeth .step = 1, 18423fbee6f88d59b4edca0855242d55e5b7cfc2401Marton Nemeth#define WHITEBALANCE_DEF 4 18523fbee6f88d59b4edca0855242d55e5b7cfc2401Marton Nemeth .default_value = WHITEBALANCE_DEF, 18623fbee6f88d59b4edca0855242d55e5b7cfc2401Marton Nemeth }, 18723fbee6f88d59b4edca0855242d55e5b7cfc2401Marton Nemeth .set = sd_setwhitebalance, 18823fbee6f88d59b4edca0855242d55e5b7cfc2401Marton Nemeth .get = sd_getwhitebalance, 18923fbee6f88d59b4edca0855242d55e5b7cfc2401Marton Nemeth }, 19023fbee6f88d59b4edca0855242d55e5b7cfc2401Marton Nemeth { 19123fbee6f88d59b4edca0855242d55e5b7cfc2401Marton Nemeth { 192265a8098e75e156985abfaac250ee4f2b407f863Márton Németh .id = V4L2_CID_RED_BALANCE, 193265a8098e75e156985abfaac250ee4f2b407f863Márton Németh .type = V4L2_CTRL_TYPE_INTEGER, 194265a8098e75e156985abfaac250ee4f2b407f863Márton Németh .name = "Red", 195265a8098e75e156985abfaac250ee4f2b407f863Márton Németh .minimum = 0, 196265a8098e75e156985abfaac250ee4f2b407f863Márton Németh .maximum = 3, 197265a8098e75e156985abfaac250ee4f2b407f863Márton Németh .step = 1, 198265a8098e75e156985abfaac250ee4f2b407f863Márton Németh#define REDBALANCE_DEF 1 199265a8098e75e156985abfaac250ee4f2b407f863Márton Németh .default_value = REDBALANCE_DEF, 200265a8098e75e156985abfaac250ee4f2b407f863Márton Németh }, 201265a8098e75e156985abfaac250ee4f2b407f863Márton Németh .set = sd_setredbalance, 202265a8098e75e156985abfaac250ee4f2b407f863Márton Németh .get = sd_getredbalance, 203265a8098e75e156985abfaac250ee4f2b407f863Márton Németh }, 204265a8098e75e156985abfaac250ee4f2b407f863Márton Németh { 205265a8098e75e156985abfaac250ee4f2b407f863Márton Németh { 206265a8098e75e156985abfaac250ee4f2b407f863Márton Németh .id = V4L2_CID_BLUE_BALANCE, 207265a8098e75e156985abfaac250ee4f2b407f863Márton Németh .type = V4L2_CTRL_TYPE_INTEGER, 208265a8098e75e156985abfaac250ee4f2b407f863Márton Németh .name = "Blue", 209265a8098e75e156985abfaac250ee4f2b407f863Márton Németh .minimum = 0, 210265a8098e75e156985abfaac250ee4f2b407f863Márton Németh .maximum = 3, 211265a8098e75e156985abfaac250ee4f2b407f863Márton Németh .step = 1, 212265a8098e75e156985abfaac250ee4f2b407f863Márton Németh#define BLUEBALANCE_DEF 1 213265a8098e75e156985abfaac250ee4f2b407f863Márton Németh .default_value = BLUEBALANCE_DEF, 214265a8098e75e156985abfaac250ee4f2b407f863Márton Németh }, 215265a8098e75e156985abfaac250ee4f2b407f863Márton Németh .set = sd_setbluebalance, 216265a8098e75e156985abfaac250ee4f2b407f863Márton Németh .get = sd_getbluebalance, 217265a8098e75e156985abfaac250ee4f2b407f863Márton Németh }, 2181408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth/* All controls below are for both the 7302 and the 7311 */ 2191408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth { 2201408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth { 2211408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .id = V4L2_CID_GAIN, 2221408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .type = V4L2_CTRL_TYPE_INTEGER, 2231408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .name = "Gain", 2241408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .minimum = 0, 2251408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth#define GAIN_MAX 255 2261408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .maximum = GAIN_MAX, 2271408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .step = 1, 2281408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth#define GAIN_DEF 127 2291408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth#define GAIN_KNEE 255 /* Gain seems to cause little noise on the pac73xx */ 2301408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .default_value = GAIN_DEF, 2311408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth }, 2321408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .set = sd_setgain, 2331408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .get = sd_getgain, 2341408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth }, 2351408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth { 2361408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth { 2371408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .id = V4L2_CID_EXPOSURE, 2381408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .type = V4L2_CTRL_TYPE_INTEGER, 2391408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .name = "Exposure", 2401408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .minimum = 0, 2411408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth#define EXPOSURE_MAX 255 2421408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .maximum = EXPOSURE_MAX, 2431408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .step = 1, 2441408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth#define EXPOSURE_DEF 16 /* 32 ms / 30 fps */ 2451408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth#define EXPOSURE_KNEE 50 /* 100 ms / 10 fps */ 2461408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .default_value = EXPOSURE_DEF, 2471408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth }, 2481408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .set = sd_setexposure, 2491408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .get = sd_getexposure, 2501408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth }, 2511408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth { 2521408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth { 2531408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .id = V4L2_CID_AUTOGAIN, 2541408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .type = V4L2_CTRL_TYPE_BOOLEAN, 2551408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .name = "Auto Gain", 2561408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .minimum = 0, 2571408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .maximum = 1, 2581408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .step = 1, 2591408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth#define AUTOGAIN_DEF 1 2601408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .default_value = AUTOGAIN_DEF, 2611408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth }, 2621408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .set = sd_setautogain, 2631408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .get = sd_getautogain, 2641408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth }, 2651408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth { 2661408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth { 2671408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .id = V4L2_CID_HFLIP, 2681408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .type = V4L2_CTRL_TYPE_BOOLEAN, 2691408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .name = "Mirror", 2701408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .minimum = 0, 2711408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .maximum = 1, 2721408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .step = 1, 2731408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth#define HFLIP_DEF 0 2741408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .default_value = HFLIP_DEF, 2751408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth }, 2761408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .set = sd_sethflip, 2771408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .get = sd_gethflip, 2781408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth }, 2791408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth { 2801408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth { 2811408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .id = V4L2_CID_VFLIP, 2821408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .type = V4L2_CTRL_TYPE_BOOLEAN, 2831408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .name = "Vflip", 2841408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .minimum = 0, 2851408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .maximum = 1, 2861408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .step = 1, 2871408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth#define VFLIP_DEF 0 2881408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .default_value = VFLIP_DEF, 2891408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth }, 2901408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .set = sd_setvflip, 2911408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .get = sd_getvflip, 2921408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth }, 2931408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth}; 2941408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 2951408b8472910e894b290205b4baed5b14b8f45afMarton Nemethstatic const struct v4l2_pix_format vga_mode[] = { 2961408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth {640, 480, V4L2_PIX_FMT_PJPG, V4L2_FIELD_NONE, 2971408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .bytesperline = 640, 2981408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .sizeimage = 640 * 480 * 3 / 8 + 590, 2991408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .colorspace = V4L2_COLORSPACE_JPEG, 3001408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .priv = 0}, 3011408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth}; 3021408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 3031408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth#define LOAD_PAGE3 255 3041408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth#define LOAD_PAGE4 254 3051408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth#define END_OF_SEQUENCE 0 3061408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 3071408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth/* pac 7302 */ 3081408b8472910e894b290205b4baed5b14b8f45afMarton Nemethstatic const __u8 init_7302[] = { 3091408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth/* index,value */ 3101408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0xff, 0x01, /* page 1 */ 3111408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x78, 0x00, /* deactivate */ 3121408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0xff, 0x01, 3131408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x78, 0x40, /* led off */ 3141408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth}; 3151408b8472910e894b290205b4baed5b14b8f45afMarton Nemethstatic const __u8 start_7302[] = { 3161408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth/* index, len, [value]* */ 3171408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0xff, 1, 0x00, /* page 0 */ 3181408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x00, 12, 0x01, 0x40, 0x40, 0x40, 0x01, 0xe0, 0x02, 0x80, 3191408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x00, 0x00, 0x00, 0x00, 3201408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x0d, 24, 0x03, 0x01, 0x00, 0xb5, 0x07, 0xcb, 0x00, 0x00, 3211408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x07, 0xc8, 0x00, 0xea, 0x07, 0xcf, 0x07, 0xf7, 3221408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x07, 0x7e, 0x01, 0x0b, 0x00, 0x00, 0x00, 0x11, 3231408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x26, 2, 0xaa, 0xaa, 3241408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x2e, 1, 0x31, 3251408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x38, 1, 0x01, 3261408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x3a, 3, 0x14, 0xff, 0x5a, 3271408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x43, 11, 0x00, 0x0a, 0x18, 0x11, 0x01, 0x2c, 0x88, 0x11, 3281408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x00, 0x54, 0x11, 3291408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x55, 1, 0x00, 3301408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x62, 4, 0x10, 0x1e, 0x1e, 0x18, 3311408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x6b, 1, 0x00, 3321408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x6e, 3, 0x08, 0x06, 0x00, 3331408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x72, 3, 0x00, 0xff, 0x00, 3341408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x7d, 23, 0x01, 0x01, 0x58, 0x46, 0x50, 0x3c, 0x50, 0x3c, 3351408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x54, 0x46, 0x54, 0x56, 0x52, 0x50, 0x52, 0x50, 3361408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x56, 0x64, 0xa4, 0x00, 0xda, 0x00, 0x00, 3371408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0xa2, 10, 0x22, 0x2c, 0x3c, 0x54, 0x69, 0x7c, 0x9c, 0xb9, 3381408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0xd2, 0xeb, 3391408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0xaf, 1, 0x02, 3401408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0xb5, 2, 0x08, 0x08, 3411408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0xb8, 2, 0x08, 0x88, 3421408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0xc4, 4, 0xae, 0x01, 0x04, 0x01, 3431408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0xcc, 1, 0x00, 3441408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0xd1, 11, 0x01, 0x30, 0x49, 0x5e, 0x6f, 0x7f, 0x8e, 0xa9, 3451408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0xc1, 0xd7, 0xec, 3461408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0xdc, 1, 0x01, 3471408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0xff, 1, 0x01, /* page 1 */ 3481408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x12, 3, 0x02, 0x00, 0x01, 3491408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x3e, 2, 0x00, 0x00, 3501408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x76, 5, 0x01, 0x20, 0x40, 0x00, 0xf2, 3511408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x7c, 1, 0x00, 3521408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x7f, 10, 0x4b, 0x0f, 0x01, 0x2c, 0x02, 0x58, 0x03, 0x20, 3531408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x02, 0x00, 3541408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x96, 5, 0x01, 0x10, 0x04, 0x01, 0x04, 3551408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0xc8, 14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 3561408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x07, 0x00, 0x01, 0x07, 0x04, 0x01, 3571408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0xd8, 1, 0x01, 3581408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0xdb, 2, 0x00, 0x01, 3591408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0xde, 7, 0x00, 0x01, 0x04, 0x04, 0x00, 0x00, 0x00, 3601408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0xe6, 4, 0x00, 0x00, 0x00, 0x01, 3611408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0xeb, 1, 0x00, 3621408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0xff, 1, 0x02, /* page 2 */ 3631408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x22, 1, 0x00, 3641408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0xff, 1, 0x03, /* page 3 */ 3651408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0, LOAD_PAGE3, /* load the page 3 */ 3661408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x11, 1, 0x01, 3671408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0xff, 1, 0x02, /* page 2 */ 3681408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x13, 1, 0x00, 3691408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x22, 4, 0x1f, 0xa4, 0xf0, 0x96, 3701408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x27, 2, 0x14, 0x0c, 3711408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x2a, 5, 0xc8, 0x00, 0x18, 0x12, 0x22, 3721408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x64, 8, 0x00, 0x00, 0xf0, 0x01, 0x14, 0x44, 0x44, 0x44, 3731408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x6e, 1, 0x08, 3741408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0xff, 1, 0x01, /* page 1 */ 3751408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x78, 1, 0x00, 3761408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0, END_OF_SEQUENCE /* end of sequence */ 3771408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth}; 3781408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 3791408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth#define SKIP 0xaa 3801408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth/* page 3 - the value SKIP says skip the index - see reg_w_page() */ 3811408b8472910e894b290205b4baed5b14b8f45afMarton Nemethstatic const __u8 page3_7302[] = { 3821408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x90, 0x40, 0x03, 0x50, 0xc2, 0x01, 0x14, 0x16, 3831408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x14, 0x12, 0x00, 0x00, 0x00, 0x02, 0x33, 0x00, 3841408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x0f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 3851408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x00, 0x00, 0x00, 0x47, 0x01, 0xb3, 0x01, 0x00, 3861408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x00, 0x08, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x21, 3871408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x00, 0x00, 0x00, 0x54, 0xf4, 0x02, 0x52, 0x54, 3881408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0xa4, 0xb8, 0xe0, 0x2a, 0xf6, 0x00, 0x00, 0x00, 3891408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 3901408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x00, 0xfc, 0x00, 0xf2, 0x1f, 0x04, 0x00, 0x00, 3911408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x00, 0x00, 0x00, 0xc0, 0xc0, 0x10, 0x00, 0x00, 3921408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 3931408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x00, 0x40, 0xff, 0x03, 0x19, 0x00, 0x00, 0x00, 3941408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 3951408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0xc8, 0xc8, 3961408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0xc8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 3971408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x08, 0x10, 0x24, 0x40, 0x00, 0x00, 0x00, 0x00, 3981408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x01, 0x00, 0x02, 0x47, 0x00, 0x00, 0x00, 0x00, 3991408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 4001408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x00, 0x02, 0xfa, 0x00, 0x64, 0x5a, 0x28, 0x00, 4011408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x00 4021408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth}; 4031408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 404b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Némethstatic int reg_w_buf(struct gspca_dev *gspca_dev, 4051408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth __u8 index, 4061408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth const char *buffer, int len) 4071408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth{ 4084f7309e27865b88df7b0b0ad59e0376dba1806afMarton Nemeth int ret; 4094f7309e27865b88df7b0b0ad59e0376dba1806afMarton Nemeth 4101408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth memcpy(gspca_dev->usb_buf, buffer, len); 4114f7309e27865b88df7b0b0ad59e0376dba1806afMarton Nemeth ret = usb_control_msg(gspca_dev->dev, 4121408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth usb_sndctrlpipe(gspca_dev->dev, 0), 4131408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 1, /* request */ 4141408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 4151408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0, /* value */ 4161408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth index, gspca_dev->usb_buf, len, 4171408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 500); 4184f7309e27865b88df7b0b0ad59e0376dba1806afMarton Nemeth if (ret < 0) 4194f7309e27865b88df7b0b0ad59e0376dba1806afMarton Nemeth PDEBUG(D_ERR, "reg_w_buf(): " 4204f7309e27865b88df7b0b0ad59e0376dba1806afMarton Nemeth "Failed to write registers to index 0x%x, error %i", 4214f7309e27865b88df7b0b0ad59e0376dba1806afMarton Nemeth index, ret); 422b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Németh return ret; 4231408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth} 4241408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 4251408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 426b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Némethstatic int reg_w(struct gspca_dev *gspca_dev, 4271408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth __u8 index, 4281408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth __u8 value) 4291408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth{ 4304f7309e27865b88df7b0b0ad59e0376dba1806afMarton Nemeth int ret; 4314f7309e27865b88df7b0b0ad59e0376dba1806afMarton Nemeth 4321408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth gspca_dev->usb_buf[0] = value; 4334f7309e27865b88df7b0b0ad59e0376dba1806afMarton Nemeth ret = usb_control_msg(gspca_dev->dev, 4341408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth usb_sndctrlpipe(gspca_dev->dev, 0), 4351408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0, /* request */ 4361408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 4371408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0, index, gspca_dev->usb_buf, 1, 4381408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 500); 4394f7309e27865b88df7b0b0ad59e0376dba1806afMarton Nemeth if (ret < 0) 4404f7309e27865b88df7b0b0ad59e0376dba1806afMarton Nemeth PDEBUG(D_ERR, "reg_w(): " 4414f7309e27865b88df7b0b0ad59e0376dba1806afMarton Nemeth "Failed to write register to index 0x%x, value 0x%x, error %i", 4424f7309e27865b88df7b0b0ad59e0376dba1806afMarton Nemeth index, value, ret); 443b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Németh return ret; 4441408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth} 4451408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 446b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Némethstatic int reg_w_seq(struct gspca_dev *gspca_dev, 4471408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth const __u8 *seq, int len) 4481408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth{ 449b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Németh int ret = 0; 4501408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth while (--len >= 0) { 451b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Németh if (0 <= ret) 452b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Németh ret = reg_w(gspca_dev, seq[0], seq[1]); 4531408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth seq += 2; 4541408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth } 455b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Németh return ret; 4561408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth} 4571408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 4581408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth/* load the beginning of a page */ 459b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Némethstatic int reg_w_page(struct gspca_dev *gspca_dev, 4601408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth const __u8 *page, int len) 4611408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth{ 4621408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth int index; 463b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Németh int ret = 0; 4641408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 4651408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth for (index = 0; index < len; index++) { 4661408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth if (page[index] == SKIP) /* skip this index */ 4671408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth continue; 4681408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth gspca_dev->usb_buf[0] = page[index]; 4694f7309e27865b88df7b0b0ad59e0376dba1806afMarton Nemeth ret = usb_control_msg(gspca_dev->dev, 4701408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth usb_sndctrlpipe(gspca_dev->dev, 0), 4711408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0, /* request */ 4721408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 4731408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0, index, gspca_dev->usb_buf, 1, 4741408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 500); 475b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Németh if (ret < 0) { 4764f7309e27865b88df7b0b0ad59e0376dba1806afMarton Nemeth PDEBUG(D_ERR, "reg_w_page(): " 4774f7309e27865b88df7b0b0ad59e0376dba1806afMarton Nemeth "Failed to write register to index 0x%x, " 4784f7309e27865b88df7b0b0ad59e0376dba1806afMarton Nemeth "value 0x%x, error %i", 4794f7309e27865b88df7b0b0ad59e0376dba1806afMarton Nemeth index, page[index], ret); 480b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Németh break; 481b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Németh } 4821408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth } 483b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Németh return ret; 4841408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth} 4851408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 4861408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth/* output a variable sequence */ 487b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Némethstatic int reg_w_var(struct gspca_dev *gspca_dev, 4881408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth const __u8 *seq, 4891408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth const __u8 *page3, unsigned int page3_len, 4901408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth const __u8 *page4, unsigned int page4_len) 4911408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth{ 4921408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth int index, len; 493b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Németh int ret = 0; 4941408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 4951408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth for (;;) { 4961408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth index = *seq++; 4971408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth len = *seq++; 4981408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth switch (len) { 4991408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth case END_OF_SEQUENCE: 500b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Németh return ret; 5011408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth case LOAD_PAGE4: 502b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Németh ret = reg_w_page(gspca_dev, page4, page4_len); 5031408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth break; 5041408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth case LOAD_PAGE3: 505b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Németh ret = reg_w_page(gspca_dev, page3, page3_len); 5061408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth break; 5071408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth default: 5081408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth if (len > USB_BUF_SZ) { 5091408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth PDEBUG(D_ERR|D_STREAM, 5101408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth "Incorrect variable sequence"); 511b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Németh return -EINVAL; 5121408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth } 5131408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth while (len > 0) { 5141408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth if (len < 8) { 515b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Németh ret = reg_w_buf(gspca_dev, 516b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Németh index, seq, len); 517b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Németh if (ret < 0) 518b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Németh return ret; 5191408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth seq += len; 5201408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth break; 5211408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth } 522b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Németh ret = reg_w_buf(gspca_dev, index, seq, 8); 5231408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth seq += 8; 5241408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth index += 8; 5251408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth len -= 8; 5261408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth } 5271408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth } 528b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Németh if (ret < 0) 529b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Németh return ret; 5301408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth } 5311408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth /* not reached */ 5321408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth} 5331408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 5341408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth/* this function is called at probe time for pac7302 */ 5351408b8472910e894b290205b4baed5b14b8f45afMarton Nemethstatic int sd_config(struct gspca_dev *gspca_dev, 5361408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth const struct usb_device_id *id) 5371408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth{ 5381408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth struct sd *sd = (struct sd *) gspca_dev; 5391408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth struct cam *cam; 5401408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 5411408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth cam = &gspca_dev->cam; 5421408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 5431408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth PDEBUG(D_CONF, "Find Sensor PAC7302"); 5441408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth cam->cam_mode = vga_mode; /* only 640x480 */ 5451408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth cam->nmodes = ARRAY_SIZE(vga_mode); 5461408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 5471408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth sd->brightness = BRIGHTNESS_DEF; 5481408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth sd->contrast = CONTRAST_DEF; 5491408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth sd->colors = COLOR_DEF; 55023fbee6f88d59b4edca0855242d55e5b7cfc2401Marton Nemeth sd->white_balance = WHITEBALANCE_DEF; 551265a8098e75e156985abfaac250ee4f2b407f863Márton Németh sd->red_balance = REDBALANCE_DEF; 552265a8098e75e156985abfaac250ee4f2b407f863Márton Németh sd->blue_balance = BLUEBALANCE_DEF; 5531408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth sd->gain = GAIN_DEF; 5541408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth sd->exposure = EXPOSURE_DEF; 5551408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth sd->autogain = AUTOGAIN_DEF; 5561408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth sd->hflip = HFLIP_DEF; 5571408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth sd->vflip = VFLIP_DEF; 558fe2b6032513099b82cd19ef8da5050f02a18d3ecJean-Francois Moine sd->flags = id->driver_info; 5591408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth return 0; 5601408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth} 5611408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 5621408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth/* This function is used by pac7302 only */ 563b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Némethstatic int setbrightcont(struct gspca_dev *gspca_dev) 5641408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth{ 5651408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth struct sd *sd = (struct sd *) gspca_dev; 5661408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth int i, v; 567b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Németh int ret; 5681408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth static const __u8 max[10] = 5691408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth {0x29, 0x33, 0x42, 0x5a, 0x6e, 0x80, 0x9f, 0xbb, 5701408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0xd4, 0xec}; 5711408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth static const __u8 delta[10] = 5721408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth {0x35, 0x33, 0x33, 0x2f, 0x2a, 0x25, 0x1e, 0x17, 5731408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x11, 0x0b}; 5741408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 575b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Németh ret = reg_w(gspca_dev, 0xff, 0x00); /* page 0 */ 5761408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth for (i = 0; i < 10; i++) { 5771408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth v = max[i]; 5781408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth v += (sd->brightness - BRIGHTNESS_MAX) 5791408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth * 150 / BRIGHTNESS_MAX; /* 200 ? */ 5801408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth v -= delta[i] * sd->contrast / CONTRAST_MAX; 5811408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth if (v < 0) 5821408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth v = 0; 5831408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth else if (v > 0xff) 5841408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth v = 0xff; 585b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Németh if (0 <= ret) 586b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Németh ret = reg_w(gspca_dev, 0xa2 + i, v); 5871408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth } 588b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Németh if (0 <= ret) 589b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Németh ret = reg_w(gspca_dev, 0xdc, 0x01); 590b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Németh return ret; 5911408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth} 5921408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 5931408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth/* This function is used by pac7302 only */ 594b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Némethstatic int setcolors(struct gspca_dev *gspca_dev) 5951408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth{ 5961408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth struct sd *sd = (struct sd *) gspca_dev; 5971408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth int i, v; 598b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Németh int ret; 5991408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth static const int a[9] = 6001408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth {217, -212, 0, -101, 170, -67, -38, -315, 355}; 6011408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth static const int b[9] = 6021408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth {19, 106, 0, 19, 106, 1, 19, 106, 1}; 6031408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 604b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Németh ret = reg_w(gspca_dev, 0xff, 0x03); /* page 3 */ 605b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Németh if (0 <= ret) 606b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Németh ret = reg_w(gspca_dev, 0x11, 0x01); 607b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Németh if (0 <= ret) 608b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Németh ret = reg_w(gspca_dev, 0xff, 0x00); /* page 0 */ 6091408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth for (i = 0; i < 9; i++) { 6101408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth v = a[i] * sd->colors / COLOR_MAX + b[i]; 611b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Németh if (0 <= ret) 612b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Németh ret = reg_w(gspca_dev, 0x0f + 2 * i, (v >> 8) & 0x07); 613b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Németh if (0 <= ret) 614b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Németh ret = reg_w(gspca_dev, 0x0f + 2 * i + 1, v); 6151408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth } 616b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Németh if (0 <= ret) 617b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Németh ret = reg_w(gspca_dev, 0xdc, 0x01); 6181408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth PDEBUG(D_CONF|D_STREAM, "color: %i", sd->colors); 619b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Németh return ret; 6201408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth} 6211408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 62223fbee6f88d59b4edca0855242d55e5b7cfc2401Marton Nemethstatic int setwhitebalance(struct gspca_dev *gspca_dev) 62323fbee6f88d59b4edca0855242d55e5b7cfc2401Marton Nemeth{ 62423fbee6f88d59b4edca0855242d55e5b7cfc2401Marton Nemeth struct sd *sd = (struct sd *) gspca_dev; 62523fbee6f88d59b4edca0855242d55e5b7cfc2401Marton Nemeth int ret; 62623fbee6f88d59b4edca0855242d55e5b7cfc2401Marton Nemeth 62723fbee6f88d59b4edca0855242d55e5b7cfc2401Marton Nemeth ret = reg_w(gspca_dev, 0xff, 0x00); /* page 0 */ 62823fbee6f88d59b4edca0855242d55e5b7cfc2401Marton Nemeth if (0 <= ret) 62923fbee6f88d59b4edca0855242d55e5b7cfc2401Marton Nemeth ret = reg_w(gspca_dev, 0xc6, sd->white_balance); 63023fbee6f88d59b4edca0855242d55e5b7cfc2401Marton Nemeth 63123fbee6f88d59b4edca0855242d55e5b7cfc2401Marton Nemeth if (0 <= ret) 63223fbee6f88d59b4edca0855242d55e5b7cfc2401Marton Nemeth ret = reg_w(gspca_dev, 0xdc, 0x01); 63323fbee6f88d59b4edca0855242d55e5b7cfc2401Marton Nemeth PDEBUG(D_CONF|D_STREAM, "white_balance: %i", sd->white_balance); 63423fbee6f88d59b4edca0855242d55e5b7cfc2401Marton Nemeth return ret; 63523fbee6f88d59b4edca0855242d55e5b7cfc2401Marton Nemeth} 63623fbee6f88d59b4edca0855242d55e5b7cfc2401Marton Nemeth 637265a8098e75e156985abfaac250ee4f2b407f863Márton Némethstatic int setredbalance(struct gspca_dev *gspca_dev) 638265a8098e75e156985abfaac250ee4f2b407f863Márton Németh{ 639265a8098e75e156985abfaac250ee4f2b407f863Márton Németh struct sd *sd = (struct sd *) gspca_dev; 640265a8098e75e156985abfaac250ee4f2b407f863Márton Németh int ret; 641265a8098e75e156985abfaac250ee4f2b407f863Márton Németh 642265a8098e75e156985abfaac250ee4f2b407f863Márton Németh ret = reg_w(gspca_dev, 0xff, 0x00); /* page 0 */ 643265a8098e75e156985abfaac250ee4f2b407f863Márton Németh if (0 <= ret) 644265a8098e75e156985abfaac250ee4f2b407f863Márton Németh ret = reg_w(gspca_dev, 0xc5, sd->red_balance); 645265a8098e75e156985abfaac250ee4f2b407f863Márton Németh 646265a8098e75e156985abfaac250ee4f2b407f863Márton Németh if (0 <= ret) 647265a8098e75e156985abfaac250ee4f2b407f863Márton Németh ret = reg_w(gspca_dev, 0xdc, 0x01); 648265a8098e75e156985abfaac250ee4f2b407f863Márton Németh PDEBUG(D_CONF|D_STREAM, "red_balance: %i", sd->red_balance); 649265a8098e75e156985abfaac250ee4f2b407f863Márton Németh return ret; 650265a8098e75e156985abfaac250ee4f2b407f863Márton Németh} 651265a8098e75e156985abfaac250ee4f2b407f863Márton Németh 652265a8098e75e156985abfaac250ee4f2b407f863Márton Némethstatic int setbluebalance(struct gspca_dev *gspca_dev) 653265a8098e75e156985abfaac250ee4f2b407f863Márton Németh{ 654265a8098e75e156985abfaac250ee4f2b407f863Márton Németh struct sd *sd = (struct sd *) gspca_dev; 655265a8098e75e156985abfaac250ee4f2b407f863Márton Németh int ret; 656265a8098e75e156985abfaac250ee4f2b407f863Márton Németh 657265a8098e75e156985abfaac250ee4f2b407f863Márton Németh ret = reg_w(gspca_dev, 0xff, 0x00); /* page 0 */ 658265a8098e75e156985abfaac250ee4f2b407f863Márton Németh if (0 <= ret) 659265a8098e75e156985abfaac250ee4f2b407f863Márton Németh ret = reg_w(gspca_dev, 0xc7, sd->blue_balance); 660265a8098e75e156985abfaac250ee4f2b407f863Márton Németh 661265a8098e75e156985abfaac250ee4f2b407f863Márton Németh if (0 <= ret) 662265a8098e75e156985abfaac250ee4f2b407f863Márton Németh ret = reg_w(gspca_dev, 0xdc, 0x01); 663265a8098e75e156985abfaac250ee4f2b407f863Márton Németh PDEBUG(D_CONF|D_STREAM, "blue_balance: %i", sd->blue_balance); 664265a8098e75e156985abfaac250ee4f2b407f863Márton Németh return ret; 665265a8098e75e156985abfaac250ee4f2b407f863Márton Németh} 666265a8098e75e156985abfaac250ee4f2b407f863Márton Németh 667b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Némethstatic int setgain(struct gspca_dev *gspca_dev) 6681408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth{ 6691408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth struct sd *sd = (struct sd *) gspca_dev; 670b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Németh int ret; 6711408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 672b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Németh ret = reg_w(gspca_dev, 0xff, 0x03); /* page 3 */ 673b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Németh if (0 <= ret) 674b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Németh ret = reg_w(gspca_dev, 0x10, sd->gain >> 3); 6751408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 6761408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth /* load registers to sensor (Bit 0, auto clear) */ 677b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Németh if (0 <= ret) 678b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Németh ret = reg_w(gspca_dev, 0x11, 0x01); 679b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Németh return ret; 6801408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth} 6811408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 682b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Némethstatic int setexposure(struct gspca_dev *gspca_dev) 6831408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth{ 6841408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth struct sd *sd = (struct sd *) gspca_dev; 685b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Németh int ret; 6861408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth __u8 reg; 6871408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 6881408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth /* register 2 of frame 3/4 contains the clock divider configuring the 6891408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth no fps according to the formula: 60 / reg. sd->exposure is the 6901408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth desired exposure time in ms. */ 6911408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth reg = 120 * sd->exposure / 1000; 6921408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth if (reg < 2) 6931408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth reg = 2; 6941408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth else if (reg > 63) 6951408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth reg = 63; 6961408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 6971408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth /* On the pac7302 reg2 MUST be a multiple of 3, so round it to 6981408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth the nearest multiple of 3, except when between 6 and 12? */ 6991408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth if (reg < 6 || reg > 12) 7001408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth reg = ((reg + 1) / 3) * 3; 701b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Németh ret = reg_w(gspca_dev, 0xff, 0x03); /* page 3 */ 702b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Németh if (0 <= ret) 703b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Németh ret = reg_w(gspca_dev, 0x02, reg); 7041408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 7051408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth /* load registers to sensor (Bit 0, auto clear) */ 706b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Németh if (0 <= ret) 707b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Németh ret = reg_w(gspca_dev, 0x11, 0x01); 708b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Németh return ret; 7091408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth} 7101408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 711b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Némethstatic int sethvflip(struct gspca_dev *gspca_dev) 7121408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth{ 7131408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth struct sd *sd = (struct sd *) gspca_dev; 714b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Németh int ret; 715fe2b6032513099b82cd19ef8da5050f02a18d3ecJean-Francois Moine u8 data, hflip, vflip; 716fe2b6032513099b82cd19ef8da5050f02a18d3ecJean-Francois Moine 717fe2b6032513099b82cd19ef8da5050f02a18d3ecJean-Francois Moine hflip = sd->hflip; 718fe2b6032513099b82cd19ef8da5050f02a18d3ecJean-Francois Moine if (sd->flags & FL_HFLIP) 719fe2b6032513099b82cd19ef8da5050f02a18d3ecJean-Francois Moine hflip = !hflip; 720fe2b6032513099b82cd19ef8da5050f02a18d3ecJean-Francois Moine vflip = sd->vflip; 721fe2b6032513099b82cd19ef8da5050f02a18d3ecJean-Francois Moine if (sd->flags & FL_VFLIP) 722fe2b6032513099b82cd19ef8da5050f02a18d3ecJean-Francois Moine vflip = !vflip; 7231408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 724b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Németh ret = reg_w(gspca_dev, 0xff, 0x03); /* page 3 */ 725fe2b6032513099b82cd19ef8da5050f02a18d3ecJean-Francois Moine data = (hflip ? 0x08 : 0x00) | (vflip ? 0x04 : 0x00); 726b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Németh if (0 <= ret) 727b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Németh ret = reg_w(gspca_dev, 0x21, data); 7281408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth /* load registers to sensor (Bit 0, auto clear) */ 729b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Németh if (0 <= ret) 730b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Németh ret = reg_w(gspca_dev, 0x11, 0x01); 731b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Németh return ret; 7321408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth} 7331408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 7341408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth/* this function is called at probe and resume time for pac7302 */ 7351408b8472910e894b290205b4baed5b14b8f45afMarton Nemethstatic int sd_init(struct gspca_dev *gspca_dev) 7361408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth{ 737b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Németh return reg_w_seq(gspca_dev, init_7302, sizeof(init_7302)/2); 7381408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth} 7391408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 7401408b8472910e894b290205b4baed5b14b8f45afMarton Nemethstatic int sd_start(struct gspca_dev *gspca_dev) 7411408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth{ 7421408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth struct sd *sd = (struct sd *) gspca_dev; 743b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Németh int ret = 0; 7441408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 7451408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth sd->sof_read = 0; 7461408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 747b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Németh ret = reg_w_var(gspca_dev, start_7302, 7481408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth page3_7302, sizeof(page3_7302), 7491408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth NULL, 0); 750b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Németh if (0 <= ret) 751b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Németh ret = setbrightcont(gspca_dev); 752b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Németh if (0 <= ret) 753b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Németh ret = setcolors(gspca_dev); 754b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Németh if (0 <= ret) 75523fbee6f88d59b4edca0855242d55e5b7cfc2401Marton Nemeth ret = setwhitebalance(gspca_dev); 75623fbee6f88d59b4edca0855242d55e5b7cfc2401Marton Nemeth if (0 <= ret) 757265a8098e75e156985abfaac250ee4f2b407f863Márton Németh ret = setredbalance(gspca_dev); 758265a8098e75e156985abfaac250ee4f2b407f863Márton Németh if (0 <= ret) 759265a8098e75e156985abfaac250ee4f2b407f863Márton Németh ret = setbluebalance(gspca_dev); 760265a8098e75e156985abfaac250ee4f2b407f863Márton Németh if (0 <= ret) 761012880be6e1c8503e2901f8de90cc1e711334989Marton Nemeth ret = setgain(gspca_dev); 762b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Németh if (0 <= ret) 763012880be6e1c8503e2901f8de90cc1e711334989Marton Nemeth ret = setexposure(gspca_dev); 764b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Németh if (0 <= ret) 765012880be6e1c8503e2901f8de90cc1e711334989Marton Nemeth ret = sethvflip(gspca_dev); 7661408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 7671408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth /* only resolution 640x480 is supported for pac7302 */ 7681408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 7691408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth sd->sof_read = 0; 7701408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth sd->autogain_ignore_frames = 0; 7711408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth atomic_set(&sd->avg_lum, -1); 7721408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 7731408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth /* start stream */ 774b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Németh if (0 <= ret) 775b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Németh ret = reg_w(gspca_dev, 0xff, 0x01); 776b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Németh if (0 <= ret) 777b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Németh ret = reg_w(gspca_dev, 0x78, 0x01); 7781408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 779b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Németh return ret; 7801408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth} 7811408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 7821408b8472910e894b290205b4baed5b14b8f45afMarton Nemethstatic void sd_stopN(struct gspca_dev *gspca_dev) 7831408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth{ 784b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Németh int ret; 785b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Németh 78667c98f72e132e191ff4db0ac7bd81ea94fa5c667Márton Németh /* stop stream */ 787b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Németh ret = reg_w(gspca_dev, 0xff, 0x01); 788b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Németh if (0 <= ret) 789b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Németh ret = reg_w(gspca_dev, 0x78, 0x00); 7901408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth} 7911408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 7921408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth/* called on streamoff with alt 0 and on disconnect for pac7302 */ 7931408b8472910e894b290205b4baed5b14b8f45afMarton Nemethstatic void sd_stop0(struct gspca_dev *gspca_dev) 7941408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth{ 795b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Németh int ret; 796b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Németh 7971408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth if (!gspca_dev->present) 7981408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth return; 799b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Németh ret = reg_w(gspca_dev, 0xff, 0x01); 800b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Németh if (0 <= ret) 801b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4Márton Németh ret = reg_w(gspca_dev, 0x78, 0x40); 8021408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth} 8031408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 8041408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth/* Include pac common sof detection functions */ 8051408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth#include "pac_common.h" 8061408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 8071408b8472910e894b290205b4baed5b14b8f45afMarton Nemethstatic void do_autogain(struct gspca_dev *gspca_dev) 8081408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth{ 8091408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth struct sd *sd = (struct sd *) gspca_dev; 8101408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth int avg_lum = atomic_read(&sd->avg_lum); 8111408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth int desired_lum, deadzone; 8121408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 8131408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth if (avg_lum == -1) 8141408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth return; 8151408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 8161408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth desired_lum = 270 + sd->brightness * 4; 8171408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth /* Hack hack, with the 7202 the first exposure step is 8181408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth pretty large, so if we're about to make the first 8191408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth exposure increase make the deadzone large to avoid 8201408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth oscilating */ 8211408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth if (desired_lum > avg_lum && sd->gain == GAIN_DEF && 8221408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth sd->exposure > EXPOSURE_DEF && 8231408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth sd->exposure < 42) 8241408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth deadzone = 90; 8251408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth else 8261408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth deadzone = 30; 8271408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 8281408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth if (sd->autogain_ignore_frames > 0) 8291408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth sd->autogain_ignore_frames--; 8301408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth else if (gspca_auto_gain_n_exposure(gspca_dev, avg_lum, desired_lum, 8311408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth deadzone, GAIN_KNEE, EXPOSURE_KNEE)) 8321408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth sd->autogain_ignore_frames = PAC_AUTOGAIN_IGNORE_FRAMES; 8331408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth} 8341408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 8351408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth/* JPEG header, part 1 */ 8361408b8472910e894b290205b4baed5b14b8f45afMarton Nemethstatic const unsigned char pac_jpeg_header1[] = { 8371408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0xff, 0xd8, /* SOI: Start of Image */ 8381408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 8391408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0xff, 0xc0, /* SOF0: Start of Frame (Baseline DCT) */ 8401408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x00, 0x11, /* length = 17 bytes (including this length field) */ 8411408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x08 /* Precision: 8 */ 8421408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth /* 2 bytes is placed here: number of image lines */ 8431408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth /* 2 bytes is placed here: samples per line */ 8441408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth}; 8451408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 8461408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth/* JPEG header, continued */ 8471408b8472910e894b290205b4baed5b14b8f45afMarton Nemethstatic const unsigned char pac_jpeg_header2[] = { 8481408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x03, /* Number of image components: 3 */ 8491408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x01, 0x21, 0x00, /* ID=1, Subsampling 1x1, Quantization table: 0 */ 8501408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x02, 0x11, 0x01, /* ID=2, Subsampling 2x1, Quantization table: 1 */ 8511408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x03, 0x11, 0x01, /* ID=3, Subsampling 2x1, Quantization table: 1 */ 8521408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 8531408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0xff, 0xda, /* SOS: Start Of Scan */ 8541408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x00, 0x0c, /* length = 12 bytes (including this length field) */ 8551408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x03, /* number of components: 3 */ 8561408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x01, 0x00, /* selector 1, table 0x00 */ 8571408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x02, 0x11, /* selector 2, table 0x11 */ 8581408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x03, 0x11, /* selector 3, table 0x11 */ 8591408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x00, 0x3f, /* Spectral selection: 0 .. 63 */ 8601408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 0x00 /* Successive approximation: 0 */ 8611408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth}; 8621408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 8631408b8472910e894b290205b4baed5b14b8f45afMarton Nemethstatic void pac_start_frame(struct gspca_dev *gspca_dev, 8641408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth struct gspca_frame *frame, 8651408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth __u16 lines, __u16 samples_per_line) 8661408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth{ 8671408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth unsigned char tmpbuf[4]; 8681408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 86976dd272b56cd1c7fa013ef5d7eb28c4d319e322bJean-Francois Moine gspca_frame_add(gspca_dev, FIRST_PACKET, 8701408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth pac_jpeg_header1, sizeof(pac_jpeg_header1)); 8711408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 8721408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth tmpbuf[0] = lines >> 8; 8731408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth tmpbuf[1] = lines & 0xff; 8741408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth tmpbuf[2] = samples_per_line >> 8; 8751408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth tmpbuf[3] = samples_per_line & 0xff; 8761408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 87776dd272b56cd1c7fa013ef5d7eb28c4d319e322bJean-Francois Moine gspca_frame_add(gspca_dev, INTER_PACKET, 8781408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth tmpbuf, sizeof(tmpbuf)); 87976dd272b56cd1c7fa013ef5d7eb28c4d319e322bJean-Francois Moine gspca_frame_add(gspca_dev, INTER_PACKET, 8801408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth pac_jpeg_header2, sizeof(pac_jpeg_header2)); 8811408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth} 8821408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 8831408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth/* this function is run at interrupt level */ 8841408b8472910e894b290205b4baed5b14b8f45afMarton Nemethstatic void sd_pkt_scan(struct gspca_dev *gspca_dev, 88576dd272b56cd1c7fa013ef5d7eb28c4d319e322bJean-Francois Moine u8 *data, /* isoc packet */ 8861408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth int len) /* iso packet length */ 8871408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth{ 8881408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth struct sd *sd = (struct sd *) gspca_dev; 88976dd272b56cd1c7fa013ef5d7eb28c4d319e322bJean-Francois Moine struct gspca_frame *frame; 8901408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth unsigned char *sof; 8911408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 8921408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth sof = pac_find_sof(&sd->sof_read, data, len); 8931408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth if (sof) { 8941408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth int n, lum_offset, footer_length; 8951408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 89676dd272b56cd1c7fa013ef5d7eb28c4d319e322bJean-Francois Moine frame = gspca_get_i_frame(gspca_dev); 89776dd272b56cd1c7fa013ef5d7eb28c4d319e322bJean-Francois Moine if (frame == NULL) { 89876dd272b56cd1c7fa013ef5d7eb28c4d319e322bJean-Francois Moine gspca_dev->last_packet_type = DISCARD_PACKET; 89976dd272b56cd1c7fa013ef5d7eb28c4d319e322bJean-Francois Moine return; 90076dd272b56cd1c7fa013ef5d7eb28c4d319e322bJean-Francois Moine } 90176dd272b56cd1c7fa013ef5d7eb28c4d319e322bJean-Francois Moine 9021408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth /* 6 bytes after the FF D9 EOF marker a number of lumination 9031408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth bytes are send corresponding to different parts of the 9041408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth image, the 14th and 15th byte after the EOF seem to 9051408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth correspond to the center of the image */ 9061408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth lum_offset = 61 + sizeof pac_sof_marker; 9071408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth footer_length = 74; 9081408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 9091408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth /* Finish decoding current frame */ 9101408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth n = (sof - data) - (footer_length + sizeof pac_sof_marker); 9111408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth if (n < 0) { 9121408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth frame->data_end += n; 9131408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth n = 0; 9141408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth } 91576dd272b56cd1c7fa013ef5d7eb28c4d319e322bJean-Francois Moine gspca_frame_add(gspca_dev, INTER_PACKET, 9161408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth data, n); 9171408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth if (gspca_dev->last_packet_type != DISCARD_PACKET && 9181408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth frame->data_end[-2] == 0xff && 9191408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth frame->data_end[-1] == 0xd9) 92076dd272b56cd1c7fa013ef5d7eb28c4d319e322bJean-Francois Moine gspca_frame_add(gspca_dev, LAST_PACKET, 9211408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth NULL, 0); 9221408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 9231408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth n = sof - data; 9241408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth len -= n; 9251408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth data = sof; 9261408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 9271408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth /* Get average lumination */ 9281408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth if (gspca_dev->last_packet_type == LAST_PACKET && 9291408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth n >= lum_offset) 9301408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth atomic_set(&sd->avg_lum, data[-lum_offset] + 9311408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth data[-lum_offset + 1]); 9321408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth else 9331408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth atomic_set(&sd->avg_lum, -1); 9341408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 9351408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth /* Start the new frame with the jpeg header */ 9361408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth /* The PAC7302 has the image rotated 90 degrees */ 9371408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth pac_start_frame(gspca_dev, frame, 9381408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth gspca_dev->width, gspca_dev->height); 9391408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth } 94076dd272b56cd1c7fa013ef5d7eb28c4d319e322bJean-Francois Moine gspca_frame_add(gspca_dev, INTER_PACKET, data, len); 9411408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth} 9421408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 9431408b8472910e894b290205b4baed5b14b8f45afMarton Nemethstatic int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) 9441408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth{ 9451408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth struct sd *sd = (struct sd *) gspca_dev; 9461408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 9471408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth sd->brightness = val; 9481408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth if (gspca_dev->streaming) 9491408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth setbrightcont(gspca_dev); 9501408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth return 0; 9511408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth} 9521408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 9531408b8472910e894b290205b4baed5b14b8f45afMarton Nemethstatic int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) 9541408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth{ 9551408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth struct sd *sd = (struct sd *) gspca_dev; 9561408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 9571408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth *val = sd->brightness; 9581408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth return 0; 9591408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth} 9601408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 9611408b8472910e894b290205b4baed5b14b8f45afMarton Nemethstatic int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) 9621408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth{ 9631408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth struct sd *sd = (struct sd *) gspca_dev; 9641408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 9651408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth sd->contrast = val; 9661408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth if (gspca_dev->streaming) { 9671408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth setbrightcont(gspca_dev); 9681408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth } 9691408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth return 0; 9701408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth} 9711408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 9721408b8472910e894b290205b4baed5b14b8f45afMarton Nemethstatic int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) 9731408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth{ 9741408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth struct sd *sd = (struct sd *) gspca_dev; 9751408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 9761408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth *val = sd->contrast; 9771408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth return 0; 9781408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth} 9791408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 9801408b8472910e894b290205b4baed5b14b8f45afMarton Nemethstatic int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val) 9811408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth{ 9821408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth struct sd *sd = (struct sd *) gspca_dev; 9831408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 9841408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth sd->colors = val; 9851408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth if (gspca_dev->streaming) 9861408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth setcolors(gspca_dev); 9871408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth return 0; 9881408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth} 9891408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 9901408b8472910e894b290205b4baed5b14b8f45afMarton Nemethstatic int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val) 9911408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth{ 9921408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth struct sd *sd = (struct sd *) gspca_dev; 9931408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 9941408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth *val = sd->colors; 9951408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth return 0; 9961408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth} 9971408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 99823fbee6f88d59b4edca0855242d55e5b7cfc2401Marton Nemethstatic int sd_setwhitebalance(struct gspca_dev *gspca_dev, __s32 val) 99923fbee6f88d59b4edca0855242d55e5b7cfc2401Marton Nemeth{ 100023fbee6f88d59b4edca0855242d55e5b7cfc2401Marton Nemeth struct sd *sd = (struct sd *) gspca_dev; 100123fbee6f88d59b4edca0855242d55e5b7cfc2401Marton Nemeth int ret = 0; 100223fbee6f88d59b4edca0855242d55e5b7cfc2401Marton Nemeth 100323fbee6f88d59b4edca0855242d55e5b7cfc2401Marton Nemeth sd->white_balance = val; 100423fbee6f88d59b4edca0855242d55e5b7cfc2401Marton Nemeth if (gspca_dev->streaming) 100523fbee6f88d59b4edca0855242d55e5b7cfc2401Marton Nemeth ret = setwhitebalance(gspca_dev); 100623fbee6f88d59b4edca0855242d55e5b7cfc2401Marton Nemeth if (0 <= ret) 100723fbee6f88d59b4edca0855242d55e5b7cfc2401Marton Nemeth ret = 0; 100823fbee6f88d59b4edca0855242d55e5b7cfc2401Marton Nemeth return ret; 100923fbee6f88d59b4edca0855242d55e5b7cfc2401Marton Nemeth} 101023fbee6f88d59b4edca0855242d55e5b7cfc2401Marton Nemeth 101123fbee6f88d59b4edca0855242d55e5b7cfc2401Marton Nemethstatic int sd_getwhitebalance(struct gspca_dev *gspca_dev, __s32 *val) 101223fbee6f88d59b4edca0855242d55e5b7cfc2401Marton Nemeth{ 101323fbee6f88d59b4edca0855242d55e5b7cfc2401Marton Nemeth struct sd *sd = (struct sd *) gspca_dev; 101423fbee6f88d59b4edca0855242d55e5b7cfc2401Marton Nemeth 101523fbee6f88d59b4edca0855242d55e5b7cfc2401Marton Nemeth *val = sd->white_balance; 101623fbee6f88d59b4edca0855242d55e5b7cfc2401Marton Nemeth return 0; 101723fbee6f88d59b4edca0855242d55e5b7cfc2401Marton Nemeth} 101823fbee6f88d59b4edca0855242d55e5b7cfc2401Marton Nemeth 1019265a8098e75e156985abfaac250ee4f2b407f863Márton Némethstatic int sd_setredbalance(struct gspca_dev *gspca_dev, __s32 val) 1020265a8098e75e156985abfaac250ee4f2b407f863Márton Németh{ 1021265a8098e75e156985abfaac250ee4f2b407f863Márton Németh struct sd *sd = (struct sd *) gspca_dev; 1022265a8098e75e156985abfaac250ee4f2b407f863Márton Németh int ret = 0; 1023265a8098e75e156985abfaac250ee4f2b407f863Márton Németh 1024265a8098e75e156985abfaac250ee4f2b407f863Márton Németh sd->red_balance = val; 1025265a8098e75e156985abfaac250ee4f2b407f863Márton Németh if (gspca_dev->streaming) 1026265a8098e75e156985abfaac250ee4f2b407f863Márton Németh ret = setredbalance(gspca_dev); 1027265a8098e75e156985abfaac250ee4f2b407f863Márton Németh if (0 <= ret) 1028265a8098e75e156985abfaac250ee4f2b407f863Márton Németh ret = 0; 1029265a8098e75e156985abfaac250ee4f2b407f863Márton Németh return ret; 1030265a8098e75e156985abfaac250ee4f2b407f863Márton Németh} 1031265a8098e75e156985abfaac250ee4f2b407f863Márton Németh 1032265a8098e75e156985abfaac250ee4f2b407f863Márton Némethstatic int sd_getredbalance(struct gspca_dev *gspca_dev, __s32 *val) 1033265a8098e75e156985abfaac250ee4f2b407f863Márton Németh{ 1034265a8098e75e156985abfaac250ee4f2b407f863Márton Németh struct sd *sd = (struct sd *) gspca_dev; 1035265a8098e75e156985abfaac250ee4f2b407f863Márton Németh 1036265a8098e75e156985abfaac250ee4f2b407f863Márton Németh *val = sd->red_balance; 1037265a8098e75e156985abfaac250ee4f2b407f863Márton Németh return 0; 1038265a8098e75e156985abfaac250ee4f2b407f863Márton Németh} 1039265a8098e75e156985abfaac250ee4f2b407f863Márton Németh 1040265a8098e75e156985abfaac250ee4f2b407f863Márton Némethstatic int sd_setbluebalance(struct gspca_dev *gspca_dev, __s32 val) 1041265a8098e75e156985abfaac250ee4f2b407f863Márton Németh{ 1042265a8098e75e156985abfaac250ee4f2b407f863Márton Németh struct sd *sd = (struct sd *) gspca_dev; 1043265a8098e75e156985abfaac250ee4f2b407f863Márton Németh int ret = 0; 1044265a8098e75e156985abfaac250ee4f2b407f863Márton Németh 1045265a8098e75e156985abfaac250ee4f2b407f863Márton Németh sd->blue_balance = val; 1046265a8098e75e156985abfaac250ee4f2b407f863Márton Németh if (gspca_dev->streaming) 1047265a8098e75e156985abfaac250ee4f2b407f863Márton Németh ret = setbluebalance(gspca_dev); 1048265a8098e75e156985abfaac250ee4f2b407f863Márton Németh if (0 <= ret) 1049265a8098e75e156985abfaac250ee4f2b407f863Márton Németh ret = 0; 1050265a8098e75e156985abfaac250ee4f2b407f863Márton Németh return ret; 1051265a8098e75e156985abfaac250ee4f2b407f863Márton Németh} 1052265a8098e75e156985abfaac250ee4f2b407f863Márton Németh 1053265a8098e75e156985abfaac250ee4f2b407f863Márton Némethstatic int sd_getbluebalance(struct gspca_dev *gspca_dev, __s32 *val) 1054265a8098e75e156985abfaac250ee4f2b407f863Márton Németh{ 1055265a8098e75e156985abfaac250ee4f2b407f863Márton Németh struct sd *sd = (struct sd *) gspca_dev; 1056265a8098e75e156985abfaac250ee4f2b407f863Márton Németh 1057265a8098e75e156985abfaac250ee4f2b407f863Márton Németh *val = sd->blue_balance; 1058265a8098e75e156985abfaac250ee4f2b407f863Márton Németh return 0; 1059265a8098e75e156985abfaac250ee4f2b407f863Márton Németh} 1060265a8098e75e156985abfaac250ee4f2b407f863Márton Németh 10611408b8472910e894b290205b4baed5b14b8f45afMarton Nemethstatic int sd_setgain(struct gspca_dev *gspca_dev, __s32 val) 10621408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth{ 10631408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth struct sd *sd = (struct sd *) gspca_dev; 10641408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 10651408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth sd->gain = val; 10661408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth if (gspca_dev->streaming) 10671408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth setgain(gspca_dev); 10681408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth return 0; 10691408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth} 10701408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 10711408b8472910e894b290205b4baed5b14b8f45afMarton Nemethstatic int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val) 10721408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth{ 10731408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth struct sd *sd = (struct sd *) gspca_dev; 10741408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 10751408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth *val = sd->gain; 10761408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth return 0; 10771408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth} 10781408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 10791408b8472910e894b290205b4baed5b14b8f45afMarton Nemethstatic int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val) 10801408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth{ 10811408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth struct sd *sd = (struct sd *) gspca_dev; 10821408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 10831408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth sd->exposure = val; 10841408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth if (gspca_dev->streaming) 10851408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth setexposure(gspca_dev); 10861408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth return 0; 10871408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth} 10881408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 10891408b8472910e894b290205b4baed5b14b8f45afMarton Nemethstatic int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val) 10901408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth{ 10911408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth struct sd *sd = (struct sd *) gspca_dev; 10921408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 10931408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth *val = sd->exposure; 10941408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth return 0; 10951408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth} 10961408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 10971408b8472910e894b290205b4baed5b14b8f45afMarton Nemethstatic int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val) 10981408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth{ 10991408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth struct sd *sd = (struct sd *) gspca_dev; 11001408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 11011408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth sd->autogain = val; 11021408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth /* when switching to autogain set defaults to make sure 11031408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth we are on a valid point of the autogain gain / 11041408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth exposure knee graph, and give this change time to 11051408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth take effect before doing autogain. */ 11061408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth if (sd->autogain) { 11071408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth sd->exposure = EXPOSURE_DEF; 11081408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth sd->gain = GAIN_DEF; 11091408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth if (gspca_dev->streaming) { 11101408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth sd->autogain_ignore_frames = 11111408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth PAC_AUTOGAIN_IGNORE_FRAMES; 11121408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth setexposure(gspca_dev); 11131408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth setgain(gspca_dev); 11141408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth } 11151408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth } 11161408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 11171408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth return 0; 11181408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth} 11191408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 11201408b8472910e894b290205b4baed5b14b8f45afMarton Nemethstatic int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val) 11211408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth{ 11221408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth struct sd *sd = (struct sd *) gspca_dev; 11231408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 11241408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth *val = sd->autogain; 11251408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth return 0; 11261408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth} 11271408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 11281408b8472910e894b290205b4baed5b14b8f45afMarton Nemethstatic int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val) 11291408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth{ 11301408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth struct sd *sd = (struct sd *) gspca_dev; 11311408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 11321408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth sd->hflip = val; 11331408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth if (gspca_dev->streaming) 11341408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth sethvflip(gspca_dev); 11351408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth return 0; 11361408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth} 11371408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 11381408b8472910e894b290205b4baed5b14b8f45afMarton Nemethstatic int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val) 11391408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth{ 11401408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth struct sd *sd = (struct sd *) gspca_dev; 11411408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 11421408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth *val = sd->hflip; 11431408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth return 0; 11441408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth} 11451408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 11461408b8472910e894b290205b4baed5b14b8f45afMarton Nemethstatic int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val) 11471408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth{ 11481408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth struct sd *sd = (struct sd *) gspca_dev; 11491408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 11501408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth sd->vflip = val; 11511408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth if (gspca_dev->streaming) 11521408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth sethvflip(gspca_dev); 11531408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth return 0; 11541408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth} 11551408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 11561408b8472910e894b290205b4baed5b14b8f45afMarton Nemethstatic int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val) 11571408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth{ 11581408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth struct sd *sd = (struct sd *) gspca_dev; 11591408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 11601408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth *val = sd->vflip; 11611408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth return 0; 11621408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth} 11631408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 11646763cc0e54e95eea356e15f9cd9a2f7b5ebeb7e8Márton Németh#ifdef CONFIG_VIDEO_ADV_DEBUG 11656763cc0e54e95eea356e15f9cd9a2f7b5ebeb7e8Márton Némethstatic int sd_dbg_s_register(struct gspca_dev *gspca_dev, 11666763cc0e54e95eea356e15f9cd9a2f7b5ebeb7e8Márton Németh struct v4l2_dbg_register *reg) 11676763cc0e54e95eea356e15f9cd9a2f7b5ebeb7e8Márton Németh{ 11686763cc0e54e95eea356e15f9cd9a2f7b5ebeb7e8Márton Németh int ret = -EINVAL; 11696763cc0e54e95eea356e15f9cd9a2f7b5ebeb7e8Márton Németh __u8 index; 11706763cc0e54e95eea356e15f9cd9a2f7b5ebeb7e8Márton Németh __u8 value; 11716763cc0e54e95eea356e15f9cd9a2f7b5ebeb7e8Márton Németh 11726763cc0e54e95eea356e15f9cd9a2f7b5ebeb7e8Márton Németh /* reg->reg: bit0..15: reserved for register index (wIndex is 16bit 11736763cc0e54e95eea356e15f9cd9a2f7b5ebeb7e8Márton Németh long on the USB bus) 11746763cc0e54e95eea356e15f9cd9a2f7b5ebeb7e8Márton Németh */ 11756763cc0e54e95eea356e15f9cd9a2f7b5ebeb7e8Márton Németh if (reg->match.type == V4L2_CHIP_MATCH_HOST && 11766763cc0e54e95eea356e15f9cd9a2f7b5ebeb7e8Márton Németh reg->match.addr == 0 && 11776763cc0e54e95eea356e15f9cd9a2f7b5ebeb7e8Márton Németh (reg->reg < 0x000000ff) && 11786763cc0e54e95eea356e15f9cd9a2f7b5ebeb7e8Márton Németh (reg->val <= 0x000000ff) 11796763cc0e54e95eea356e15f9cd9a2f7b5ebeb7e8Márton Németh ) { 11806763cc0e54e95eea356e15f9cd9a2f7b5ebeb7e8Márton Németh /* Currently writing to page 0 is only supported. */ 11816763cc0e54e95eea356e15f9cd9a2f7b5ebeb7e8Márton Németh /* reg_w() only supports 8bit index */ 11826763cc0e54e95eea356e15f9cd9a2f7b5ebeb7e8Márton Németh index = reg->reg & 0x000000ff; 11836763cc0e54e95eea356e15f9cd9a2f7b5ebeb7e8Márton Németh value = reg->val & 0x000000ff; 11846763cc0e54e95eea356e15f9cd9a2f7b5ebeb7e8Márton Németh 11856763cc0e54e95eea356e15f9cd9a2f7b5ebeb7e8Márton Németh /* Note that there shall be no access to other page 11866763cc0e54e95eea356e15f9cd9a2f7b5ebeb7e8Márton Németh by any other function between the page swith and 11876763cc0e54e95eea356e15f9cd9a2f7b5ebeb7e8Márton Németh the actual register write */ 11886763cc0e54e95eea356e15f9cd9a2f7b5ebeb7e8Márton Németh ret = reg_w(gspca_dev, 0xff, 0x00); /* page 0 */ 11896763cc0e54e95eea356e15f9cd9a2f7b5ebeb7e8Márton Németh if (0 <= ret) 11906763cc0e54e95eea356e15f9cd9a2f7b5ebeb7e8Márton Németh ret = reg_w(gspca_dev, index, value); 11916763cc0e54e95eea356e15f9cd9a2f7b5ebeb7e8Márton Németh 11926763cc0e54e95eea356e15f9cd9a2f7b5ebeb7e8Márton Németh if (0 <= ret) 11936763cc0e54e95eea356e15f9cd9a2f7b5ebeb7e8Márton Németh ret = reg_w(gspca_dev, 0xdc, 0x01); 11946763cc0e54e95eea356e15f9cd9a2f7b5ebeb7e8Márton Németh } 11956763cc0e54e95eea356e15f9cd9a2f7b5ebeb7e8Márton Németh return ret; 11966763cc0e54e95eea356e15f9cd9a2f7b5ebeb7e8Márton Németh} 11976763cc0e54e95eea356e15f9cd9a2f7b5ebeb7e8Márton Németh 11986763cc0e54e95eea356e15f9cd9a2f7b5ebeb7e8Márton Némethstatic int sd_chip_ident(struct gspca_dev *gspca_dev, 11996763cc0e54e95eea356e15f9cd9a2f7b5ebeb7e8Márton Németh struct v4l2_dbg_chip_ident *chip) 12006763cc0e54e95eea356e15f9cd9a2f7b5ebeb7e8Márton Németh{ 12016763cc0e54e95eea356e15f9cd9a2f7b5ebeb7e8Márton Németh int ret = -EINVAL; 12026763cc0e54e95eea356e15f9cd9a2f7b5ebeb7e8Márton Németh 12036763cc0e54e95eea356e15f9cd9a2f7b5ebeb7e8Márton Németh if (chip->match.type == V4L2_CHIP_MATCH_HOST && 12046763cc0e54e95eea356e15f9cd9a2f7b5ebeb7e8Márton Németh chip->match.addr == 0) { 12056763cc0e54e95eea356e15f9cd9a2f7b5ebeb7e8Márton Németh chip->revision = 0; 12066763cc0e54e95eea356e15f9cd9a2f7b5ebeb7e8Márton Németh chip->ident = V4L2_IDENT_UNKNOWN; 12076763cc0e54e95eea356e15f9cd9a2f7b5ebeb7e8Márton Németh ret = 0; 12086763cc0e54e95eea356e15f9cd9a2f7b5ebeb7e8Márton Németh } 12096763cc0e54e95eea356e15f9cd9a2f7b5ebeb7e8Márton Németh return ret; 12106763cc0e54e95eea356e15f9cd9a2f7b5ebeb7e8Márton Németh} 12116763cc0e54e95eea356e15f9cd9a2f7b5ebeb7e8Márton Németh#endif 12126763cc0e54e95eea356e15f9cd9a2f7b5ebeb7e8Márton Németh 12131408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth/* sub-driver description for pac7302 */ 12141408b8472910e894b290205b4baed5b14b8f45afMarton Nemethstatic struct sd_desc sd_desc = { 12151408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .name = MODULE_NAME, 12161408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .ctrls = sd_ctrls, 12171408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .nctrls = ARRAY_SIZE(sd_ctrls), 12181408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .config = sd_config, 12191408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .init = sd_init, 12201408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .start = sd_start, 12211408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .stopN = sd_stopN, 12221408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .stop0 = sd_stop0, 12231408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .pkt_scan = sd_pkt_scan, 12241408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .dq_callback = do_autogain, 12256763cc0e54e95eea356e15f9cd9a2f7b5ebeb7e8Márton Németh#ifdef CONFIG_VIDEO_ADV_DEBUG 12266763cc0e54e95eea356e15f9cd9a2f7b5ebeb7e8Márton Németh .set_register = sd_dbg_s_register, 12276763cc0e54e95eea356e15f9cd9a2f7b5ebeb7e8Márton Németh .get_chip_ident = sd_chip_ident, 12286763cc0e54e95eea356e15f9cd9a2f7b5ebeb7e8Márton Németh#endif 12291408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth}; 12301408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 12311408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth/* -- module initialisation -- */ 123237b372e5ebe187037e01885151a0afb546a38520Márton Némethstatic const struct usb_device_id device_table[] __devinitconst = { 12331408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth {USB_DEVICE(0x06f8, 0x3009)}, 12341408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth {USB_DEVICE(0x093a, 0x2620)}, 12351408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth {USB_DEVICE(0x093a, 0x2621)}, 1236fe2b6032513099b82cd19ef8da5050f02a18d3ecJean-Francois Moine {USB_DEVICE(0x093a, 0x2622), .driver_info = FL_VFLIP}, 1237fe2b6032513099b82cd19ef8da5050f02a18d3ecJean-Francois Moine {USB_DEVICE(0x093a, 0x2624), .driver_info = FL_VFLIP}, 12381408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth {USB_DEVICE(0x093a, 0x2626)}, 12391408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth {USB_DEVICE(0x093a, 0x2628)}, 1240c4322bfca8907109689eb6b244258bf52277f7dcJean-Francois Moine {USB_DEVICE(0x093a, 0x2629), .driver_info = FL_VFLIP}, 12411408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth {USB_DEVICE(0x093a, 0x262a)}, 12421408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth {USB_DEVICE(0x093a, 0x262c)}, 12431408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth {} 12441408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth}; 12451408b8472910e894b290205b4baed5b14b8f45afMarton NemethMODULE_DEVICE_TABLE(usb, device_table); 12461408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 12471408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth/* -- device connect -- */ 124837b372e5ebe187037e01885151a0afb546a38520Márton Némethstatic int __devinit sd_probe(struct usb_interface *intf, 12491408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth const struct usb_device_id *id) 12501408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth{ 12511408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), 12521408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth THIS_MODULE); 12531408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth} 12541408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 12551408b8472910e894b290205b4baed5b14b8f45afMarton Nemethstatic struct usb_driver sd_driver = { 12561408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .name = MODULE_NAME, 12571408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .id_table = device_table, 12581408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .probe = sd_probe, 12591408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .disconnect = gspca_disconnect, 12601408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth#ifdef CONFIG_PM 12611408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .suspend = gspca_suspend, 12621408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth .resume = gspca_resume, 12631408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth#endif 12641408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth}; 12651408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 12661408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth/* -- module insert / remove -- */ 12671408b8472910e894b290205b4baed5b14b8f45afMarton Nemethstatic int __init sd_mod_init(void) 12681408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth{ 12691408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth int ret; 12701408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth ret = usb_register(&sd_driver); 12711408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth if (ret < 0) 12721408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth return ret; 12731408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth PDEBUG(D_PROBE, "registered"); 12741408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth return 0; 12751408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth} 12761408b8472910e894b290205b4baed5b14b8f45afMarton Nemethstatic void __exit sd_mod_exit(void) 12771408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth{ 12781408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth usb_deregister(&sd_driver); 12791408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth PDEBUG(D_PROBE, "deregistered"); 12801408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth} 12811408b8472910e894b290205b4baed5b14b8f45afMarton Nemeth 12821408b8472910e894b290205b4baed5b14b8f45afMarton Nemethmodule_init(sd_mod_init); 12831408b8472910e894b290205b4baed5b14b8f45afMarton Nemethmodule_exit(sd_mod_exit); 1284