18668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede/* 28668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede * Support for the sensor part which is integrated (I think) into the 38668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede * st6422 stv06xx alike bridge, as its integrated there are no i2c writes 48668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede * but instead direct bridge writes. 58668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede * 68668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede * Copyright (c) 2009 Hans de Goede <hdegoede@redhat.com> 78668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede * 88668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede * Strongly based on qc-usb-messenger, which is: 98668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede * Copyright (c) 2001 Jean-Fredric Clere, Nikolas Zimmermann, Georg Acher 108668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede * Mark Cave-Ayland, Carlo E Prelz, Dick Streefland 118668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede * Copyright (c) 2002, 2003 Tuukka Toivonen 128668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede * 138668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede * This program is free software; you can redistribute it and/or modify 148668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede * it under the terms of the GNU General Public License as published by 158668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede * the Free Software Foundation; either version 2 of the License, or 168668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede * (at your option) any later version. 178668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede * 188668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede * This program is distributed in the hope that it will be useful, 198668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede * but WITHOUT ANY WARRANTY; without even the implied warranty of 208668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 218668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede * GNU General Public License for more details. 228668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede * 238668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede * You should have received a copy of the GNU General Public License 248668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede * along with this program; if not, write to the Free Software 258668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 268668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede * 278668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede */ 288668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede 29133a9fe949862d9ed8411fb423739f4cee08232dJoe Perches#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 30133a9fe949862d9ed8411fb423739f4cee08232dJoe Perches 318668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede#include "stv06xx_st6422.h" 328668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede 3371e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moine/* controls */ 3471e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moineenum e_ctrl { 3571e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moine BRIGHTNESS, 3671e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moine CONTRAST, 3771e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moine GAIN, 3871e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moine EXPOSURE, 3971e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moine NCTRLS /* number of controls */ 4071e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moine}; 4171e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moine 4271e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moine/* sensor settings */ 4371e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moinestruct st6422_settings { 4471e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moine struct gspca_ctrl ctrls[NCTRLS]; 4571e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moine}; 4671e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moine 478668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goedestatic struct v4l2_pix_format st6422_mode[] = { 488668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede /* Note we actually get 124 lines of data, of which we skip the 4st 498668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede 4 as they are garbage */ 508668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede { 518668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede 162, 528668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede 120, 538668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede V4L2_PIX_FMT_SGRBG8, 548668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede V4L2_FIELD_NONE, 558668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede .sizeimage = 162 * 120, 568668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede .bytesperline = 162, 578668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede .colorspace = V4L2_COLORSPACE_SRGB, 588668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede .priv = 1 598668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede }, 608668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede /* Note we actually get 248 lines of data, of which we skip the 4st 618668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede 4 as they are garbage, and we tell the app it only gets the 628668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede first 240 of the 244 lines it actually gets, so that it ignores 638668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede the last 4. */ 648668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede { 658668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede 324, 668668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede 240, 678668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede V4L2_PIX_FMT_SGRBG8, 688668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede V4L2_FIELD_NONE, 698668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede .sizeimage = 324 * 244, 708668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede .bytesperline = 324, 718668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede .colorspace = V4L2_COLORSPACE_SRGB, 728668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede .priv = 0 738668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede }, 748668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede}; 758668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede 7671e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moine/* V4L2 controls supported by the driver */ 7771e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moinestatic void st6422_set_brightness(struct gspca_dev *gspca_dev); 7871e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moinestatic void st6422_set_contrast(struct gspca_dev *gspca_dev); 7971e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moinestatic void st6422_set_gain(struct gspca_dev *gspca_dev); 8071e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moinestatic void st6422_set_exposure(struct gspca_dev *gspca_dev); 8171e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moine 8271e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moinestatic const struct ctrl st6422_ctrl[NCTRLS] = { 8371e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moine[BRIGHTNESS] = { 848668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede { 858668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede .id = V4L2_CID_BRIGHTNESS, 868668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede .type = V4L2_CTRL_TYPE_INTEGER, 878668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede .name = "Brightness", 888668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede .minimum = 0, 898668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede .maximum = 31, 908668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede .step = 1, 918668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede .default_value = 3 928668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede }, 9371e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moine .set_control = st6422_set_brightness 948668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede }, 9571e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moine[CONTRAST] = { 968668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede { 978668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede .id = V4L2_CID_CONTRAST, 988668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede .type = V4L2_CTRL_TYPE_INTEGER, 998668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede .name = "Contrast", 1008668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede .minimum = 0, 1018668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede .maximum = 15, 1028668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede .step = 1, 1038668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede .default_value = 11 1048668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede }, 10571e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moine .set_control = st6422_set_contrast 1068668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede }, 10771e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moine[GAIN] = { 1088668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede { 1098668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede .id = V4L2_CID_GAIN, 1108668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede .type = V4L2_CTRL_TYPE_INTEGER, 1118668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede .name = "Gain", 1128668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede .minimum = 0, 1138668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede .maximum = 255, 1148668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede .step = 1, 1158668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede .default_value = 64 1168668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede }, 11771e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moine .set_control = st6422_set_gain 1188668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede }, 11971e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moine[EXPOSURE] = { 1208668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede { 1218668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede .id = V4L2_CID_EXPOSURE, 1228668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede .type = V4L2_CTRL_TYPE_INTEGER, 1238668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede .name = "Exposure", 1248668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede .minimum = 0, 12571e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moine#define EXPOSURE_MAX 1023 12671e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moine .maximum = EXPOSURE_MAX, 1278668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede .step = 1, 1288668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede .default_value = 256 1298668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede }, 13071e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moine .set_control = st6422_set_exposure 1318668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede }, 1328668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede}; 1338668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede 1348668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goedestatic int st6422_probe(struct sd *sd) 1358668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede{ 13671e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moine struct st6422_settings *sensor_settings; 1378668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede 1388668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede if (sd->bridge != BRIDGE_ST6422) 1398668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede return -ENODEV; 1408668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede 141133a9fe949862d9ed8411fb423739f4cee08232dJoe Perches pr_info("st6422 sensor detected\n"); 1428668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede 14371e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moine sensor_settings = kmalloc(sizeof *sensor_settings, GFP_KERNEL); 1448668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede if (!sensor_settings) 1458668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede return -ENOMEM; 1468668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede 1478668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede sd->gspca_dev.cam.cam_mode = st6422_mode; 1488668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede sd->gspca_dev.cam.nmodes = ARRAY_SIZE(st6422_mode); 14971e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moine sd->gspca_dev.cam.ctrls = sensor_settings->ctrls; 1508668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede sd->desc.ctrls = st6422_ctrl; 1518668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede sd->desc.nctrls = ARRAY_SIZE(st6422_ctrl); 1528668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede sd->sensor_priv = sensor_settings; 1538668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede 1548668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede return 0; 1558668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede} 1568668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede 1578668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goedestatic int st6422_init(struct sd *sd) 1588668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede{ 1598668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede int err = 0, i; 1608668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede 1618668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede const u16 st6422_bridge_init[][2] = { 1628668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede { STV_ISO_ENABLE, 0x00 }, /* disable capture */ 1638668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede { 0x1436, 0x00 }, 1648668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede { 0x1432, 0x03 }, /* 0x00-0x1F brightness */ 1651d00d6c1ff13607974fcd9469aa9466fcd253c3aJean-François Moine { 0x143a, 0xf9 }, /* 0x00-0x0F contrast */ 1668668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede { 0x0509, 0x38 }, /* R */ 1678668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede { 0x050a, 0x38 }, /* G */ 1688668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede { 0x050b, 0x38 }, /* B */ 1691d00d6c1ff13607974fcd9469aa9466fcd253c3aJean-François Moine { 0x050c, 0x2a }, 1708668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede { 0x050d, 0x01 }, 1718668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede 1728668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede 1738668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede { 0x1431, 0x00 }, /* 0x00-0x07 ??? */ 1748668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede { 0x1433, 0x34 }, /* 160x120, 0x00-0x01 night filter */ 1758668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede { 0x1438, 0x18 }, /* 640x480 */ 1768668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede/* 18 bayes */ 1778668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede/* 10 compressed? */ 1788668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede 1798668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede { 0x1439, 0x00 }, 180bf5c562a3e6f7fd4071284caa01f81b031aacc97Erik Andrén/* anti-noise? 0xa2 gives a perfect image */ 1818668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede 1828668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede { 0x143b, 0x05 }, 1838668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede { 0x143c, 0x00 }, /* 0x00-0x01 - ??? */ 1848668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede 1858668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede 1868668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede/* shutter time 0x0000-0x03FF */ 1878668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede/* low value give good picures on moving objects (but requires much light) */ 1888668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede/* high value gives good picures in darkness (but tends to be overexposed) */ 1898668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede { 0x143e, 0x01 }, 1908668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede { 0x143d, 0x00 }, 1918668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede 1928668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede { 0x1442, 0xe2 }, 1938668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede/* write: 1x1x xxxx */ 1948668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede/* read: 1x1x xxxx */ 1958668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede/* bit 5 == button pressed and hold if 0 */ 1968668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede/* write 0xe2,0xea */ 1978668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede 1988668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede/* 0x144a */ 1998668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede/* 0x00 init */ 2008668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede/* bit 7 == button has been pressed, but not handled */ 2018668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede 2028668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede/* interrupt */ 2038668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede/* if(urb->iso_frame_desc[i].status == 0x80) { */ 2048668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede/* if(urb->iso_frame_desc[i].status == 0x88) { */ 2058668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede 2068668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede { 0x1500, 0xd0 }, 2078668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede { 0x1500, 0xd0 }, 2088668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede { 0x1500, 0x50 }, /* 0x00 - 0xFF 0x80 == compr ? */ 2098668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede 2108668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede { 0x1501, 0xaf }, 211bf5c562a3e6f7fd4071284caa01f81b031aacc97Erik Andrén/* high val-> light area gets darker */ 212bf5c562a3e6f7fd4071284caa01f81b031aacc97Erik Andrén/* low val -> light area gets lighter */ 2138668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede { 0x1502, 0xc2 }, 214bf5c562a3e6f7fd4071284caa01f81b031aacc97Erik Andrén/* high val-> light area gets darker */ 215bf5c562a3e6f7fd4071284caa01f81b031aacc97Erik Andrén/* low val -> light area gets lighter */ 2168668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede { 0x1503, 0x45 }, 217bf5c562a3e6f7fd4071284caa01f81b031aacc97Erik Andrén/* high val-> light area gets darker */ 218bf5c562a3e6f7fd4071284caa01f81b031aacc97Erik Andrén/* low val -> light area gets lighter */ 2198668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede { 0x1505, 0x02 }, 2208668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede/* 2 : 324x248 80352 bytes */ 2218668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede/* 7 : 248x162 40176 bytes */ 2228668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede/* c+f: 162*124 20088 bytes */ 2238668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede 2248668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede { 0x150e, 0x8e }, 2258668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede { 0x150f, 0x37 }, 2268668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede { 0x15c0, 0x00 }, 2278668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede { 0x15c3, 0x08 }, /* 0x04/0x14 ... test pictures ??? */ 2288668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede 2298668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede 2308668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede { 0x143f, 0x01 }, /* commit settings */ 2318668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede 2328668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede }; 2338668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede 2348668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede for (i = 0; i < ARRAY_SIZE(st6422_bridge_init) && !err; i++) { 2358668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede err = stv06xx_write_bridge(sd, st6422_bridge_init[i][0], 2368668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede st6422_bridge_init[i][1]); 2378668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede } 2388668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede 2398668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede return err; 2408668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede} 2418668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede 2428668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goedestatic void st6422_disconnect(struct sd *sd) 2438668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede{ 2448668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede sd->sensor = NULL; 2458668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede kfree(sd->sensor_priv); 2468668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede} 2478668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede 24871e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moinestatic int setbrightness(struct sd *sd) 24971e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moine{ 25071e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moine struct st6422_settings *sensor_settings = sd->sensor_priv; 25171e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moine 25271e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moine /* val goes from 0 -> 31 */ 25371e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moine return stv06xx_write_bridge(sd, 0x1432, 25471e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moine sensor_settings->ctrls[BRIGHTNESS].val); 25571e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moine} 25671e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moine 25771e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moinestatic int setcontrast(struct sd *sd) 25871e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moine{ 25971e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moine struct st6422_settings *sensor_settings = sd->sensor_priv; 26071e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moine 26171e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moine /* Val goes from 0 -> 15 */ 26271e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moine return stv06xx_write_bridge(sd, 0x143a, 26371e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moine sensor_settings->ctrls[CONTRAST].val | 0xf0); 26471e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moine} 26571e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moine 26671e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moinestatic int setgain(struct sd *sd) 2678668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede{ 26871e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moine struct st6422_settings *sensor_settings = sd->sensor_priv; 26971e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moine u8 gain; 270c0b33bdc5b8d9c1120dece660480d4dd86b817eeHans de Goede int err; 2718668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede 27271e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moine gain = sensor_settings->ctrls[GAIN].val; 2738668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede 27471e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moine /* Set red, green, blue, gain */ 27571e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moine err = stv06xx_write_bridge(sd, 0x0509, gain); 2768668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede if (err < 0) 2778668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede return err; 2788668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede 27971e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moine err = stv06xx_write_bridge(sd, 0x050a, gain); 2808668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede if (err < 0) 2818668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede return err; 2828668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede 28371e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moine err = stv06xx_write_bridge(sd, 0x050b, gain); 2848668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede if (err < 0) 2858668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede return err; 2868668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede 28771e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moine /* 2 mystery writes */ 28871e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moine err = stv06xx_write_bridge(sd, 0x050c, 0x2a); 2898668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede if (err < 0) 2908668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede return err; 2918668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede 29271e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moine return stv06xx_write_bridge(sd, 0x050d, 0x01); 2938668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede} 2948668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede 29571e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moinestatic int setexposure(struct sd *sd) 2968668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede{ 29771e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moine struct st6422_settings *sensor_settings = sd->sensor_priv; 29871e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moine u16 expo; 29971e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moine int err; 3008668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede 30171e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moine expo = sensor_settings->ctrls[EXPOSURE].val; 30271e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moine err = stv06xx_write_bridge(sd, 0x143d, expo & 0xff); 30371e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moine if (err < 0) 30471e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moine return err; 3058668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede 30671e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moine return stv06xx_write_bridge(sd, 0x143e, expo >> 8); 3078668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede} 3088668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede 30971e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moinestatic int st6422_start(struct sd *sd) 3108668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede{ 3118668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede int err; 31271e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moine struct cam *cam = &sd->gspca_dev.cam; 3138668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede 31471e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moine if (cam->cam_mode[sd->gspca_dev.curr_mode].priv) 31571e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moine err = stv06xx_write_bridge(sd, 0x1505, 0x0f); 31671e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moine else 31771e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moine err = stv06xx_write_bridge(sd, 0x1505, 0x02); 31871e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moine if (err < 0) 31971e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moine return err; 3208668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede 32171e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moine err = setbrightness(sd); 32271e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moine if (err < 0) 32371e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moine return err; 3248668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede 32571e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moine err = setcontrast(sd); 32671e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moine if (err < 0) 32771e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moine return err; 32871e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moine 32971e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moine err = setexposure(sd); 33071e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moine if (err < 0) 33171e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moine return err; 33271e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moine 33371e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moine err = setgain(sd); 3348668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede if (err < 0) 3358668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede return err; 3368668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede 3378668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede /* commit settings */ 3388668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede err = stv06xx_write_bridge(sd, 0x143f, 0x01); 3398668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede return (err < 0) ? err : 0; 3408668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede} 3418668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede 34271e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moinestatic int st6422_stop(struct sd *sd) 3438668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede{ 34471e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moine PDEBUG(D_STREAM, "Halting stream"); 3458668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede 3468668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede return 0; 3478668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede} 3488668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede 34971e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moinestatic void st6422_set_brightness(struct gspca_dev *gspca_dev) 3508668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede{ 3518668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede int err; 3528668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede struct sd *sd = (struct sd *) gspca_dev; 3538668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede 35471e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moine err = setbrightness(sd); 3558668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede 3568668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede /* commit settings */ 35771e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moine if (err >= 0) 35871e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moine err = stv06xx_write_bridge(sd, 0x143f, 0x01); 3598668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede 36071e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moine gspca_dev->usb_err = err; 3618668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede} 3628668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede 36371e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moinestatic void st6422_set_contrast(struct gspca_dev *gspca_dev) 3648668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede{ 3658668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede int err; 3668668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede struct sd *sd = (struct sd *) gspca_dev; 3678668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede 36871e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moine err = setcontrast(sd); 3698668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede 3708668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede /* commit settings */ 37171e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moine if (err >= 0) 37271e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moine err = stv06xx_write_bridge(sd, 0x143f, 0x01); 37371e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moine 37471e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moine gspca_dev->usb_err = err; 3758668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede} 3768668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede 37771e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moinestatic void st6422_set_gain(struct gspca_dev *gspca_dev) 3788668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede{ 37971e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moine int err; 3808668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede struct sd *sd = (struct sd *) gspca_dev; 3818668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede 38271e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moine err = setgain(sd); 3838668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede 38471e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moine /* commit settings */ 38571e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moine if (err >= 0) 38671e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moine err = stv06xx_write_bridge(sd, 0x143f, 0x01); 3878668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede 38871e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moine gspca_dev->usb_err = err; 3898668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede} 3908668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede 39171e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moinestatic void st6422_set_exposure(struct gspca_dev *gspca_dev) 3928668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede{ 3938668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede int err; 3948668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede struct sd *sd = (struct sd *) gspca_dev; 3958668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede 39671e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moine err = setexposure(sd); 3978668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede 3988668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede /* commit settings */ 39971e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moine if (err >= 0) 40071e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moine err = stv06xx_write_bridge(sd, 0x143f, 0x01); 40171e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moine 40271e84ea7f082eb02df6ef40f55d2c4a998f6e1dfJean-François Moine gspca_dev->usb_err = err; 4038668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede} 404