18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * SPCA505 chip based cameras initialization data 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * V4L2 by Jean-Francis Moine <http://moinejf.free.fr> 68c2ecf20Sopenharmony_ci */ 78c2ecf20Sopenharmony_ci 88c2ecf20Sopenharmony_ci#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_ci#define MODULE_NAME "spca505" 118c2ecf20Sopenharmony_ci 128c2ecf20Sopenharmony_ci#include "gspca.h" 138c2ecf20Sopenharmony_ci 148c2ecf20Sopenharmony_ciMODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>"); 158c2ecf20Sopenharmony_ciMODULE_DESCRIPTION("GSPCA/SPCA505 USB Camera Driver"); 168c2ecf20Sopenharmony_ciMODULE_LICENSE("GPL"); 178c2ecf20Sopenharmony_ci 188c2ecf20Sopenharmony_ci/* specific webcam descriptor */ 198c2ecf20Sopenharmony_cistruct sd { 208c2ecf20Sopenharmony_ci struct gspca_dev gspca_dev; /* !! must be the first item */ 218c2ecf20Sopenharmony_ci 228c2ecf20Sopenharmony_ci u8 subtype; 238c2ecf20Sopenharmony_ci#define IntelPCCameraPro 0 248c2ecf20Sopenharmony_ci#define Nxultra 1 258c2ecf20Sopenharmony_ci}; 268c2ecf20Sopenharmony_ci 278c2ecf20Sopenharmony_cistatic const struct v4l2_pix_format vga_mode[] = { 288c2ecf20Sopenharmony_ci {160, 120, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, 298c2ecf20Sopenharmony_ci .bytesperline = 160, 308c2ecf20Sopenharmony_ci .sizeimage = 160 * 120 * 3 / 2, 318c2ecf20Sopenharmony_ci .colorspace = V4L2_COLORSPACE_SRGB, 328c2ecf20Sopenharmony_ci .priv = 4}, 338c2ecf20Sopenharmony_ci {176, 144, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, 348c2ecf20Sopenharmony_ci .bytesperline = 176, 358c2ecf20Sopenharmony_ci .sizeimage = 176 * 144 * 3 / 2, 368c2ecf20Sopenharmony_ci .colorspace = V4L2_COLORSPACE_SRGB, 378c2ecf20Sopenharmony_ci .priv = 3}, 388c2ecf20Sopenharmony_ci {320, 240, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, 398c2ecf20Sopenharmony_ci .bytesperline = 320, 408c2ecf20Sopenharmony_ci .sizeimage = 320 * 240 * 3 / 2, 418c2ecf20Sopenharmony_ci .colorspace = V4L2_COLORSPACE_SRGB, 428c2ecf20Sopenharmony_ci .priv = 2}, 438c2ecf20Sopenharmony_ci {352, 288, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, 448c2ecf20Sopenharmony_ci .bytesperline = 352, 458c2ecf20Sopenharmony_ci .sizeimage = 352 * 288 * 3 / 2, 468c2ecf20Sopenharmony_ci .colorspace = V4L2_COLORSPACE_SRGB, 478c2ecf20Sopenharmony_ci .priv = 1}, 488c2ecf20Sopenharmony_ci {640, 480, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, 498c2ecf20Sopenharmony_ci .bytesperline = 640, 508c2ecf20Sopenharmony_ci .sizeimage = 640 * 480 * 3 / 2, 518c2ecf20Sopenharmony_ci .colorspace = V4L2_COLORSPACE_SRGB, 528c2ecf20Sopenharmony_ci .priv = 0}, 538c2ecf20Sopenharmony_ci}; 548c2ecf20Sopenharmony_ci 558c2ecf20Sopenharmony_ci#define SPCA50X_OFFSET_DATA 10 568c2ecf20Sopenharmony_ci 578c2ecf20Sopenharmony_ci#define SPCA50X_REG_USB 0x02 /* spca505 501 */ 588c2ecf20Sopenharmony_ci 598c2ecf20Sopenharmony_ci#define SPCA50X_USB_CTRL 0x00 /* spca505 */ 608c2ecf20Sopenharmony_ci#define SPCA50X_CUSB_ENABLE 0x01 /* spca505 */ 618c2ecf20Sopenharmony_ci 628c2ecf20Sopenharmony_ci#define SPCA50X_REG_GLOBAL 0x03 /* spca505 */ 638c2ecf20Sopenharmony_ci#define SPCA50X_GMISC0_IDSEL 0x01 /* Global control device ID select spca505 */ 648c2ecf20Sopenharmony_ci#define SPCA50X_GLOBAL_MISC0 0x00 /* Global control miscellaneous 0 spca505 */ 658c2ecf20Sopenharmony_ci 668c2ecf20Sopenharmony_ci#define SPCA50X_GLOBAL_MISC1 0x01 /* 505 */ 678c2ecf20Sopenharmony_ci#define SPCA50X_GLOBAL_MISC3 0x03 /* 505 */ 688c2ecf20Sopenharmony_ci#define SPCA50X_GMISC3_SAA7113RST 0x20 /* Not sure about this one spca505 */ 698c2ecf20Sopenharmony_ci 708c2ecf20Sopenharmony_ci/* Image format and compression control */ 718c2ecf20Sopenharmony_ci#define SPCA50X_REG_COMPRESS 0x04 728c2ecf20Sopenharmony_ci 738c2ecf20Sopenharmony_ci/* 748c2ecf20Sopenharmony_ci * Data to initialize a SPCA505. Common to the CCD and external modes 758c2ecf20Sopenharmony_ci */ 768c2ecf20Sopenharmony_cistatic const u8 spca505_init_data[][3] = { 778c2ecf20Sopenharmony_ci /* bmRequest,value,index */ 788c2ecf20Sopenharmony_ci {SPCA50X_REG_GLOBAL, SPCA50X_GMISC3_SAA7113RST, SPCA50X_GLOBAL_MISC3}, 798c2ecf20Sopenharmony_ci /* Sensor reset */ 808c2ecf20Sopenharmony_ci {SPCA50X_REG_GLOBAL, 0x00, SPCA50X_GLOBAL_MISC3}, 818c2ecf20Sopenharmony_ci {SPCA50X_REG_GLOBAL, 0x00, SPCA50X_GLOBAL_MISC1}, 828c2ecf20Sopenharmony_ci /* Block USB reset */ 838c2ecf20Sopenharmony_ci {SPCA50X_REG_GLOBAL, SPCA50X_GMISC0_IDSEL, SPCA50X_GLOBAL_MISC0}, 848c2ecf20Sopenharmony_ci 858c2ecf20Sopenharmony_ci {0x05, 0x01, 0x10}, 868c2ecf20Sopenharmony_ci /* Maybe power down some stuff */ 878c2ecf20Sopenharmony_ci {0x05, 0x0f, 0x11}, 888c2ecf20Sopenharmony_ci 898c2ecf20Sopenharmony_ci /* Setup internal CCD ? */ 908c2ecf20Sopenharmony_ci {0x06, 0x10, 0x08}, 918c2ecf20Sopenharmony_ci {0x06, 0x00, 0x09}, 928c2ecf20Sopenharmony_ci {0x06, 0x00, 0x0a}, 938c2ecf20Sopenharmony_ci {0x06, 0x00, 0x0b}, 948c2ecf20Sopenharmony_ci {0x06, 0x10, 0x0c}, 958c2ecf20Sopenharmony_ci {0x06, 0x00, 0x0d}, 968c2ecf20Sopenharmony_ci {0x06, 0x00, 0x0e}, 978c2ecf20Sopenharmony_ci {0x06, 0x00, 0x0f}, 988c2ecf20Sopenharmony_ci {0x06, 0x10, 0x10}, 998c2ecf20Sopenharmony_ci {0x06, 0x02, 0x11}, 1008c2ecf20Sopenharmony_ci {0x06, 0x00, 0x12}, 1018c2ecf20Sopenharmony_ci {0x06, 0x04, 0x13}, 1028c2ecf20Sopenharmony_ci {0x06, 0x02, 0x14}, 1038c2ecf20Sopenharmony_ci {0x06, 0x8a, 0x51}, 1048c2ecf20Sopenharmony_ci {0x06, 0x40, 0x52}, 1058c2ecf20Sopenharmony_ci {0x06, 0xb6, 0x53}, 1068c2ecf20Sopenharmony_ci {0x06, 0x3d, 0x54}, 1078c2ecf20Sopenharmony_ci {} 1088c2ecf20Sopenharmony_ci}; 1098c2ecf20Sopenharmony_ci 1108c2ecf20Sopenharmony_ci/* 1118c2ecf20Sopenharmony_ci * Data to initialize the camera using the internal CCD 1128c2ecf20Sopenharmony_ci */ 1138c2ecf20Sopenharmony_cistatic const u8 spca505_open_data_ccd[][3] = { 1148c2ecf20Sopenharmony_ci /* bmRequest,value,index */ 1158c2ecf20Sopenharmony_ci /* Internal CCD data set */ 1168c2ecf20Sopenharmony_ci {0x03, 0x04, 0x01}, 1178c2ecf20Sopenharmony_ci /* This could be a reset */ 1188c2ecf20Sopenharmony_ci {0x03, 0x00, 0x01}, 1198c2ecf20Sopenharmony_ci 1208c2ecf20Sopenharmony_ci /* Setup compression and image registers. 0x6 and 0x7 seem to be 1218c2ecf20Sopenharmony_ci related to H&V hold, and are resolution mode specific */ 1228c2ecf20Sopenharmony_ci {0x04, 0x10, 0x01}, 1238c2ecf20Sopenharmony_ci /* DIFF(0x50), was (0x10) */ 1248c2ecf20Sopenharmony_ci {0x04, 0x00, 0x04}, 1258c2ecf20Sopenharmony_ci {0x04, 0x00, 0x05}, 1268c2ecf20Sopenharmony_ci {0x04, 0x20, 0x06}, 1278c2ecf20Sopenharmony_ci {0x04, 0x20, 0x07}, 1288c2ecf20Sopenharmony_ci 1298c2ecf20Sopenharmony_ci {0x08, 0x0a, 0x00}, 1308c2ecf20Sopenharmony_ci /* DIFF (0x4a), was (0xa) */ 1318c2ecf20Sopenharmony_ci 1328c2ecf20Sopenharmony_ci {0x05, 0x00, 0x10}, 1338c2ecf20Sopenharmony_ci {0x05, 0x00, 0x11}, 1348c2ecf20Sopenharmony_ci {0x05, 0x00, 0x00}, 1358c2ecf20Sopenharmony_ci /* DIFF not written */ 1368c2ecf20Sopenharmony_ci {0x05, 0x00, 0x01}, 1378c2ecf20Sopenharmony_ci /* DIFF not written */ 1388c2ecf20Sopenharmony_ci {0x05, 0x00, 0x02}, 1398c2ecf20Sopenharmony_ci /* DIFF not written */ 1408c2ecf20Sopenharmony_ci {0x05, 0x00, 0x03}, 1418c2ecf20Sopenharmony_ci /* DIFF not written */ 1428c2ecf20Sopenharmony_ci {0x05, 0x00, 0x04}, 1438c2ecf20Sopenharmony_ci /* DIFF not written */ 1448c2ecf20Sopenharmony_ci {0x05, 0x80, 0x05}, 1458c2ecf20Sopenharmony_ci /* DIFF not written */ 1468c2ecf20Sopenharmony_ci {0x05, 0xe0, 0x06}, 1478c2ecf20Sopenharmony_ci /* DIFF not written */ 1488c2ecf20Sopenharmony_ci {0x05, 0x20, 0x07}, 1498c2ecf20Sopenharmony_ci /* DIFF not written */ 1508c2ecf20Sopenharmony_ci {0x05, 0xa0, 0x08}, 1518c2ecf20Sopenharmony_ci /* DIFF not written */ 1528c2ecf20Sopenharmony_ci {0x05, 0x0, 0x12}, 1538c2ecf20Sopenharmony_ci /* DIFF not written */ 1548c2ecf20Sopenharmony_ci {0x05, 0x02, 0x0f}, 1558c2ecf20Sopenharmony_ci /* DIFF not written */ 1568c2ecf20Sopenharmony_ci {0x05, 0x10, 0x46}, 1578c2ecf20Sopenharmony_ci /* DIFF not written */ 1588c2ecf20Sopenharmony_ci {0x05, 0x8, 0x4a}, 1598c2ecf20Sopenharmony_ci /* DIFF not written */ 1608c2ecf20Sopenharmony_ci 1618c2ecf20Sopenharmony_ci {0x03, 0x08, 0x03}, 1628c2ecf20Sopenharmony_ci /* DIFF (0x3,0x28,0x3) */ 1638c2ecf20Sopenharmony_ci {0x03, 0x08, 0x01}, 1648c2ecf20Sopenharmony_ci {0x03, 0x0c, 0x03}, 1658c2ecf20Sopenharmony_ci /* DIFF not written */ 1668c2ecf20Sopenharmony_ci {0x03, 0x21, 0x00}, 1678c2ecf20Sopenharmony_ci /* DIFF (0x39) */ 1688c2ecf20Sopenharmony_ci 1698c2ecf20Sopenharmony_ci/* Extra block copied from init to hopefully ensure CCD is in a sane state */ 1708c2ecf20Sopenharmony_ci {0x06, 0x10, 0x08}, 1718c2ecf20Sopenharmony_ci {0x06, 0x00, 0x09}, 1728c2ecf20Sopenharmony_ci {0x06, 0x00, 0x0a}, 1738c2ecf20Sopenharmony_ci {0x06, 0x00, 0x0b}, 1748c2ecf20Sopenharmony_ci {0x06, 0x10, 0x0c}, 1758c2ecf20Sopenharmony_ci {0x06, 0x00, 0x0d}, 1768c2ecf20Sopenharmony_ci {0x06, 0x00, 0x0e}, 1778c2ecf20Sopenharmony_ci {0x06, 0x00, 0x0f}, 1788c2ecf20Sopenharmony_ci {0x06, 0x10, 0x10}, 1798c2ecf20Sopenharmony_ci {0x06, 0x02, 0x11}, 1808c2ecf20Sopenharmony_ci {0x06, 0x00, 0x12}, 1818c2ecf20Sopenharmony_ci {0x06, 0x04, 0x13}, 1828c2ecf20Sopenharmony_ci {0x06, 0x02, 0x14}, 1838c2ecf20Sopenharmony_ci {0x06, 0x8a, 0x51}, 1848c2ecf20Sopenharmony_ci {0x06, 0x40, 0x52}, 1858c2ecf20Sopenharmony_ci {0x06, 0xb6, 0x53}, 1868c2ecf20Sopenharmony_ci {0x06, 0x3d, 0x54}, 1878c2ecf20Sopenharmony_ci /* End of extra block */ 1888c2ecf20Sopenharmony_ci 1898c2ecf20Sopenharmony_ci {0x06, 0x3f, 0x1}, 1908c2ecf20Sopenharmony_ci /* Block skipped */ 1918c2ecf20Sopenharmony_ci {0x06, 0x10, 0x02}, 1928c2ecf20Sopenharmony_ci {0x06, 0x64, 0x07}, 1938c2ecf20Sopenharmony_ci {0x06, 0x10, 0x08}, 1948c2ecf20Sopenharmony_ci {0x06, 0x00, 0x09}, 1958c2ecf20Sopenharmony_ci {0x06, 0x00, 0x0a}, 1968c2ecf20Sopenharmony_ci {0x06, 0x00, 0x0b}, 1978c2ecf20Sopenharmony_ci {0x06, 0x10, 0x0c}, 1988c2ecf20Sopenharmony_ci {0x06, 0x00, 0x0d}, 1998c2ecf20Sopenharmony_ci {0x06, 0x00, 0x0e}, 2008c2ecf20Sopenharmony_ci {0x06, 0x00, 0x0f}, 2018c2ecf20Sopenharmony_ci {0x06, 0x10, 0x10}, 2028c2ecf20Sopenharmony_ci {0x06, 0x02, 0x11}, 2038c2ecf20Sopenharmony_ci {0x06, 0x00, 0x12}, 2048c2ecf20Sopenharmony_ci {0x06, 0x04, 0x13}, 2058c2ecf20Sopenharmony_ci {0x06, 0x02, 0x14}, 2068c2ecf20Sopenharmony_ci {0x06, 0x8a, 0x51}, 2078c2ecf20Sopenharmony_ci {0x06, 0x40, 0x52}, 2088c2ecf20Sopenharmony_ci {0x06, 0xb6, 0x53}, 2098c2ecf20Sopenharmony_ci {0x06, 0x3d, 0x54}, 2108c2ecf20Sopenharmony_ci {0x06, 0x60, 0x57}, 2118c2ecf20Sopenharmony_ci {0x06, 0x20, 0x58}, 2128c2ecf20Sopenharmony_ci {0x06, 0x15, 0x59}, 2138c2ecf20Sopenharmony_ci {0x06, 0x05, 0x5a}, 2148c2ecf20Sopenharmony_ci 2158c2ecf20Sopenharmony_ci {0x05, 0x01, 0xc0}, 2168c2ecf20Sopenharmony_ci {0x05, 0x10, 0xcb}, 2178c2ecf20Sopenharmony_ci {0x05, 0x80, 0xc1}, 2188c2ecf20Sopenharmony_ci /* */ 2198c2ecf20Sopenharmony_ci {0x05, 0x0, 0xc2}, 2208c2ecf20Sopenharmony_ci /* 4 was 0 */ 2218c2ecf20Sopenharmony_ci {0x05, 0x00, 0xca}, 2228c2ecf20Sopenharmony_ci {0x05, 0x80, 0xc1}, 2238c2ecf20Sopenharmony_ci /* */ 2248c2ecf20Sopenharmony_ci {0x05, 0x04, 0xc2}, 2258c2ecf20Sopenharmony_ci {0x05, 0x00, 0xca}, 2268c2ecf20Sopenharmony_ci {0x05, 0x0, 0xc1}, 2278c2ecf20Sopenharmony_ci /* */ 2288c2ecf20Sopenharmony_ci {0x05, 0x00, 0xc2}, 2298c2ecf20Sopenharmony_ci {0x05, 0x00, 0xca}, 2308c2ecf20Sopenharmony_ci {0x05, 0x40, 0xc1}, 2318c2ecf20Sopenharmony_ci /* */ 2328c2ecf20Sopenharmony_ci {0x05, 0x17, 0xc2}, 2338c2ecf20Sopenharmony_ci {0x05, 0x00, 0xca}, 2348c2ecf20Sopenharmony_ci {0x05, 0x80, 0xc1}, 2358c2ecf20Sopenharmony_ci /* */ 2368c2ecf20Sopenharmony_ci {0x05, 0x06, 0xc2}, 2378c2ecf20Sopenharmony_ci {0x05, 0x00, 0xca}, 2388c2ecf20Sopenharmony_ci {0x05, 0x80, 0xc1}, 2398c2ecf20Sopenharmony_ci /* */ 2408c2ecf20Sopenharmony_ci {0x05, 0x04, 0xc2}, 2418c2ecf20Sopenharmony_ci {0x05, 0x00, 0xca}, 2428c2ecf20Sopenharmony_ci 2438c2ecf20Sopenharmony_ci {0x03, 0x4c, 0x3}, 2448c2ecf20Sopenharmony_ci {0x03, 0x18, 0x1}, 2458c2ecf20Sopenharmony_ci 2468c2ecf20Sopenharmony_ci {0x06, 0x70, 0x51}, 2478c2ecf20Sopenharmony_ci {0x06, 0xbe, 0x53}, 2488c2ecf20Sopenharmony_ci {0x06, 0x71, 0x57}, 2498c2ecf20Sopenharmony_ci {0x06, 0x20, 0x58}, 2508c2ecf20Sopenharmony_ci {0x06, 0x05, 0x59}, 2518c2ecf20Sopenharmony_ci {0x06, 0x15, 0x5a}, 2528c2ecf20Sopenharmony_ci 2538c2ecf20Sopenharmony_ci {0x04, 0x00, 0x08}, 2548c2ecf20Sopenharmony_ci /* Compress = OFF (0x1 to turn on) */ 2558c2ecf20Sopenharmony_ci {0x04, 0x12, 0x09}, 2568c2ecf20Sopenharmony_ci {0x04, 0x21, 0x0a}, 2578c2ecf20Sopenharmony_ci {0x04, 0x10, 0x0b}, 2588c2ecf20Sopenharmony_ci {0x04, 0x21, 0x0c}, 2598c2ecf20Sopenharmony_ci {0x04, 0x05, 0x00}, 2608c2ecf20Sopenharmony_ci /* was 5 (Image Type ? ) */ 2618c2ecf20Sopenharmony_ci {0x04, 0x00, 0x01}, 2628c2ecf20Sopenharmony_ci 2638c2ecf20Sopenharmony_ci {0x06, 0x3f, 0x01}, 2648c2ecf20Sopenharmony_ci 2658c2ecf20Sopenharmony_ci {0x04, 0x00, 0x04}, 2668c2ecf20Sopenharmony_ci {0x04, 0x00, 0x05}, 2678c2ecf20Sopenharmony_ci {0x04, 0x40, 0x06}, 2688c2ecf20Sopenharmony_ci {0x04, 0x40, 0x07}, 2698c2ecf20Sopenharmony_ci 2708c2ecf20Sopenharmony_ci {0x06, 0x1c, 0x17}, 2718c2ecf20Sopenharmony_ci {0x06, 0xe2, 0x19}, 2728c2ecf20Sopenharmony_ci {0x06, 0x1c, 0x1b}, 2738c2ecf20Sopenharmony_ci {0x06, 0xe2, 0x1d}, 2748c2ecf20Sopenharmony_ci {0x06, 0xaa, 0x1f}, 2758c2ecf20Sopenharmony_ci {0x06, 0x70, 0x20}, 2768c2ecf20Sopenharmony_ci 2778c2ecf20Sopenharmony_ci {0x05, 0x01, 0x10}, 2788c2ecf20Sopenharmony_ci {0x05, 0x00, 0x11}, 2798c2ecf20Sopenharmony_ci {0x05, 0x01, 0x00}, 2808c2ecf20Sopenharmony_ci {0x05, 0x05, 0x01}, 2818c2ecf20Sopenharmony_ci {0x05, 0x00, 0xc1}, 2828c2ecf20Sopenharmony_ci /* */ 2838c2ecf20Sopenharmony_ci {0x05, 0x00, 0xc2}, 2848c2ecf20Sopenharmony_ci {0x05, 0x00, 0xca}, 2858c2ecf20Sopenharmony_ci 2868c2ecf20Sopenharmony_ci {0x06, 0x70, 0x51}, 2878c2ecf20Sopenharmony_ci {0x06, 0xbe, 0x53}, 2888c2ecf20Sopenharmony_ci {} 2898c2ecf20Sopenharmony_ci}; 2908c2ecf20Sopenharmony_ci 2918c2ecf20Sopenharmony_ci/* 2928c2ecf20Sopenharmony_ci * Made by Tomasz Zablocki (skalamandra@poczta.onet.pl) 2938c2ecf20Sopenharmony_ci * SPCA505b chip based cameras initialization data 2948c2ecf20Sopenharmony_ci */ 2958c2ecf20Sopenharmony_ci/* jfm */ 2968c2ecf20Sopenharmony_ci#define initial_brightness 0x7f /* 0x0(white)-0xff(black) */ 2978c2ecf20Sopenharmony_ci/* #define initial_brightness 0x0 //0x0(white)-0xff(black) */ 2988c2ecf20Sopenharmony_ci/* 2998c2ecf20Sopenharmony_ci * Data to initialize a SPCA505. Common to the CCD and external modes 3008c2ecf20Sopenharmony_ci */ 3018c2ecf20Sopenharmony_cistatic const u8 spca505b_init_data[][3] = { 3028c2ecf20Sopenharmony_ci/* start */ 3038c2ecf20Sopenharmony_ci {0x02, 0x00, 0x00}, /* init */ 3048c2ecf20Sopenharmony_ci {0x02, 0x00, 0x01}, 3058c2ecf20Sopenharmony_ci {0x02, 0x00, 0x02}, 3068c2ecf20Sopenharmony_ci {0x02, 0x00, 0x03}, 3078c2ecf20Sopenharmony_ci {0x02, 0x00, 0x04}, 3088c2ecf20Sopenharmony_ci {0x02, 0x00, 0x05}, 3098c2ecf20Sopenharmony_ci {0x02, 0x00, 0x06}, 3108c2ecf20Sopenharmony_ci {0x02, 0x00, 0x07}, 3118c2ecf20Sopenharmony_ci {0x02, 0x00, 0x08}, 3128c2ecf20Sopenharmony_ci {0x02, 0x00, 0x09}, 3138c2ecf20Sopenharmony_ci {0x03, 0x00, 0x00}, 3148c2ecf20Sopenharmony_ci {0x03, 0x00, 0x01}, 3158c2ecf20Sopenharmony_ci {0x03, 0x00, 0x02}, 3168c2ecf20Sopenharmony_ci {0x03, 0x00, 0x03}, 3178c2ecf20Sopenharmony_ci {0x03, 0x00, 0x04}, 3188c2ecf20Sopenharmony_ci {0x03, 0x00, 0x05}, 3198c2ecf20Sopenharmony_ci {0x03, 0x00, 0x06}, 3208c2ecf20Sopenharmony_ci {0x04, 0x00, 0x00}, 3218c2ecf20Sopenharmony_ci {0x04, 0x00, 0x02}, 3228c2ecf20Sopenharmony_ci {0x04, 0x00, 0x04}, 3238c2ecf20Sopenharmony_ci {0x04, 0x00, 0x05}, 3248c2ecf20Sopenharmony_ci {0x04, 0x00, 0x06}, 3258c2ecf20Sopenharmony_ci {0x04, 0x00, 0x07}, 3268c2ecf20Sopenharmony_ci {0x04, 0x00, 0x08}, 3278c2ecf20Sopenharmony_ci {0x04, 0x00, 0x09}, 3288c2ecf20Sopenharmony_ci {0x04, 0x00, 0x0a}, 3298c2ecf20Sopenharmony_ci {0x04, 0x00, 0x0b}, 3308c2ecf20Sopenharmony_ci {0x04, 0x00, 0x0c}, 3318c2ecf20Sopenharmony_ci {0x07, 0x00, 0x00}, 3328c2ecf20Sopenharmony_ci {0x07, 0x00, 0x03}, 3338c2ecf20Sopenharmony_ci {0x08, 0x00, 0x00}, 3348c2ecf20Sopenharmony_ci {0x08, 0x00, 0x01}, 3358c2ecf20Sopenharmony_ci {0x08, 0x00, 0x02}, 3368c2ecf20Sopenharmony_ci {0x06, 0x18, 0x08}, 3378c2ecf20Sopenharmony_ci {0x06, 0xfc, 0x09}, 3388c2ecf20Sopenharmony_ci {0x06, 0xfc, 0x0a}, 3398c2ecf20Sopenharmony_ci {0x06, 0xfc, 0x0b}, 3408c2ecf20Sopenharmony_ci {0x06, 0x18, 0x0c}, 3418c2ecf20Sopenharmony_ci {0x06, 0xfc, 0x0d}, 3428c2ecf20Sopenharmony_ci {0x06, 0xfc, 0x0e}, 3438c2ecf20Sopenharmony_ci {0x06, 0xfc, 0x0f}, 3448c2ecf20Sopenharmony_ci {0x06, 0x18, 0x10}, 3458c2ecf20Sopenharmony_ci {0x06, 0xfe, 0x12}, 3468c2ecf20Sopenharmony_ci {0x06, 0x00, 0x11}, 3478c2ecf20Sopenharmony_ci {0x06, 0x00, 0x14}, 3488c2ecf20Sopenharmony_ci {0x06, 0x00, 0x13}, 3498c2ecf20Sopenharmony_ci {0x06, 0x28, 0x51}, 3508c2ecf20Sopenharmony_ci {0x06, 0xff, 0x53}, 3518c2ecf20Sopenharmony_ci {0x02, 0x00, 0x08}, 3528c2ecf20Sopenharmony_ci 3538c2ecf20Sopenharmony_ci {0x03, 0x00, 0x03}, 3548c2ecf20Sopenharmony_ci {0x03, 0x10, 0x03}, 3558c2ecf20Sopenharmony_ci {} 3568c2ecf20Sopenharmony_ci}; 3578c2ecf20Sopenharmony_ci 3588c2ecf20Sopenharmony_ci/* 3598c2ecf20Sopenharmony_ci * Data to initialize the camera using the internal CCD 3608c2ecf20Sopenharmony_ci */ 3618c2ecf20Sopenharmony_cistatic const u8 spca505b_open_data_ccd[][3] = { 3628c2ecf20Sopenharmony_ci 3638c2ecf20Sopenharmony_ci/* {0x02,0x00,0x00}, */ 3648c2ecf20Sopenharmony_ci {0x03, 0x04, 0x01}, /* rst */ 3658c2ecf20Sopenharmony_ci {0x03, 0x00, 0x01}, 3668c2ecf20Sopenharmony_ci {0x03, 0x00, 0x00}, 3678c2ecf20Sopenharmony_ci {0x03, 0x21, 0x00}, 3688c2ecf20Sopenharmony_ci {0x03, 0x00, 0x04}, 3698c2ecf20Sopenharmony_ci {0x03, 0x00, 0x03}, 3708c2ecf20Sopenharmony_ci {0x03, 0x18, 0x03}, 3718c2ecf20Sopenharmony_ci {0x03, 0x08, 0x01}, 3728c2ecf20Sopenharmony_ci {0x03, 0x1c, 0x03}, 3738c2ecf20Sopenharmony_ci {0x03, 0x5c, 0x03}, 3748c2ecf20Sopenharmony_ci {0x03, 0x5c, 0x03}, 3758c2ecf20Sopenharmony_ci {0x03, 0x18, 0x01}, 3768c2ecf20Sopenharmony_ci 3778c2ecf20Sopenharmony_ci/* same as 505 */ 3788c2ecf20Sopenharmony_ci {0x04, 0x10, 0x01}, 3798c2ecf20Sopenharmony_ci {0x04, 0x00, 0x04}, 3808c2ecf20Sopenharmony_ci {0x04, 0x00, 0x05}, 3818c2ecf20Sopenharmony_ci {0x04, 0x20, 0x06}, 3828c2ecf20Sopenharmony_ci {0x04, 0x20, 0x07}, 3838c2ecf20Sopenharmony_ci 3848c2ecf20Sopenharmony_ci {0x08, 0x0a, 0x00}, 3858c2ecf20Sopenharmony_ci 3868c2ecf20Sopenharmony_ci {0x05, 0x00, 0x10}, 3878c2ecf20Sopenharmony_ci {0x05, 0x00, 0x11}, 3888c2ecf20Sopenharmony_ci {0x05, 0x00, 0x12}, 3898c2ecf20Sopenharmony_ci {0x05, 0x6f, 0x00}, 3908c2ecf20Sopenharmony_ci {0x05, initial_brightness >> 6, 0x00}, 3918c2ecf20Sopenharmony_ci {0x05, (initial_brightness << 2) & 0xff, 0x01}, 3928c2ecf20Sopenharmony_ci {0x05, 0x00, 0x02}, 3938c2ecf20Sopenharmony_ci {0x05, 0x01, 0x03}, 3948c2ecf20Sopenharmony_ci {0x05, 0x00, 0x04}, 3958c2ecf20Sopenharmony_ci {0x05, 0x03, 0x05}, 3968c2ecf20Sopenharmony_ci {0x05, 0xe0, 0x06}, 3978c2ecf20Sopenharmony_ci {0x05, 0x20, 0x07}, 3988c2ecf20Sopenharmony_ci {0x05, 0xa0, 0x08}, 3998c2ecf20Sopenharmony_ci {0x05, 0x00, 0x12}, 4008c2ecf20Sopenharmony_ci {0x05, 0x02, 0x0f}, 4018c2ecf20Sopenharmony_ci {0x05, 0x80, 0x14}, /* max exposure off (0=on) */ 4028c2ecf20Sopenharmony_ci {0x05, 0x01, 0xb0}, 4038c2ecf20Sopenharmony_ci {0x05, 0x01, 0xbf}, 4048c2ecf20Sopenharmony_ci {0x03, 0x02, 0x06}, 4058c2ecf20Sopenharmony_ci {0x05, 0x10, 0x46}, 4068c2ecf20Sopenharmony_ci {0x05, 0x08, 0x4a}, 4078c2ecf20Sopenharmony_ci 4088c2ecf20Sopenharmony_ci {0x06, 0x00, 0x01}, 4098c2ecf20Sopenharmony_ci {0x06, 0x10, 0x02}, 4108c2ecf20Sopenharmony_ci {0x06, 0x64, 0x07}, 4118c2ecf20Sopenharmony_ci {0x06, 0x18, 0x08}, 4128c2ecf20Sopenharmony_ci {0x06, 0xfc, 0x09}, 4138c2ecf20Sopenharmony_ci {0x06, 0xfc, 0x0a}, 4148c2ecf20Sopenharmony_ci {0x06, 0xfc, 0x0b}, 4158c2ecf20Sopenharmony_ci {0x04, 0x00, 0x01}, 4168c2ecf20Sopenharmony_ci {0x06, 0x18, 0x0c}, 4178c2ecf20Sopenharmony_ci {0x06, 0xfc, 0x0d}, 4188c2ecf20Sopenharmony_ci {0x06, 0xfc, 0x0e}, 4198c2ecf20Sopenharmony_ci {0x06, 0xfc, 0x0f}, 4208c2ecf20Sopenharmony_ci {0x06, 0x11, 0x10}, /* contrast */ 4218c2ecf20Sopenharmony_ci {0x06, 0x00, 0x11}, 4228c2ecf20Sopenharmony_ci {0x06, 0xfe, 0x12}, 4238c2ecf20Sopenharmony_ci {0x06, 0x00, 0x13}, 4248c2ecf20Sopenharmony_ci {0x06, 0x00, 0x14}, 4258c2ecf20Sopenharmony_ci {0x06, 0x9d, 0x51}, 4268c2ecf20Sopenharmony_ci {0x06, 0x40, 0x52}, 4278c2ecf20Sopenharmony_ci {0x06, 0x7c, 0x53}, 4288c2ecf20Sopenharmony_ci {0x06, 0x40, 0x54}, 4298c2ecf20Sopenharmony_ci {0x06, 0x02, 0x57}, 4308c2ecf20Sopenharmony_ci {0x06, 0x03, 0x58}, 4318c2ecf20Sopenharmony_ci {0x06, 0x15, 0x59}, 4328c2ecf20Sopenharmony_ci {0x06, 0x05, 0x5a}, 4338c2ecf20Sopenharmony_ci {0x06, 0x03, 0x56}, 4348c2ecf20Sopenharmony_ci {0x06, 0x02, 0x3f}, 4358c2ecf20Sopenharmony_ci {0x06, 0x00, 0x40}, 4368c2ecf20Sopenharmony_ci {0x06, 0x39, 0x41}, 4378c2ecf20Sopenharmony_ci {0x06, 0x69, 0x42}, 4388c2ecf20Sopenharmony_ci {0x06, 0x87, 0x43}, 4398c2ecf20Sopenharmony_ci {0x06, 0x9e, 0x44}, 4408c2ecf20Sopenharmony_ci {0x06, 0xb1, 0x45}, 4418c2ecf20Sopenharmony_ci {0x06, 0xbf, 0x46}, 4428c2ecf20Sopenharmony_ci {0x06, 0xcc, 0x47}, 4438c2ecf20Sopenharmony_ci {0x06, 0xd5, 0x48}, 4448c2ecf20Sopenharmony_ci {0x06, 0xdd, 0x49}, 4458c2ecf20Sopenharmony_ci {0x06, 0xe3, 0x4a}, 4468c2ecf20Sopenharmony_ci {0x06, 0xe8, 0x4b}, 4478c2ecf20Sopenharmony_ci {0x06, 0xed, 0x4c}, 4488c2ecf20Sopenharmony_ci {0x06, 0xf2, 0x4d}, 4498c2ecf20Sopenharmony_ci {0x06, 0xf7, 0x4e}, 4508c2ecf20Sopenharmony_ci {0x06, 0xfc, 0x4f}, 4518c2ecf20Sopenharmony_ci {0x06, 0xff, 0x50}, 4528c2ecf20Sopenharmony_ci 4538c2ecf20Sopenharmony_ci {0x05, 0x01, 0xc0}, 4548c2ecf20Sopenharmony_ci {0x05, 0x10, 0xcb}, 4558c2ecf20Sopenharmony_ci {0x05, 0x40, 0xc1}, 4568c2ecf20Sopenharmony_ci {0x05, 0x04, 0xc2}, 4578c2ecf20Sopenharmony_ci {0x05, 0x00, 0xca}, 4588c2ecf20Sopenharmony_ci {0x05, 0x40, 0xc1}, 4598c2ecf20Sopenharmony_ci {0x05, 0x09, 0xc2}, 4608c2ecf20Sopenharmony_ci {0x05, 0x00, 0xca}, 4618c2ecf20Sopenharmony_ci {0x05, 0xc0, 0xc1}, 4628c2ecf20Sopenharmony_ci {0x05, 0x09, 0xc2}, 4638c2ecf20Sopenharmony_ci {0x05, 0x00, 0xca}, 4648c2ecf20Sopenharmony_ci {0x05, 0x40, 0xc1}, 4658c2ecf20Sopenharmony_ci {0x05, 0x59, 0xc2}, 4668c2ecf20Sopenharmony_ci {0x05, 0x00, 0xca}, 4678c2ecf20Sopenharmony_ci {0x04, 0x00, 0x01}, 4688c2ecf20Sopenharmony_ci {0x05, 0x80, 0xc1}, 4698c2ecf20Sopenharmony_ci {0x05, 0xec, 0xc2}, 4708c2ecf20Sopenharmony_ci {0x05, 0x0, 0xca}, 4718c2ecf20Sopenharmony_ci 4728c2ecf20Sopenharmony_ci {0x06, 0x02, 0x57}, 4738c2ecf20Sopenharmony_ci {0x06, 0x01, 0x58}, 4748c2ecf20Sopenharmony_ci {0x06, 0x15, 0x59}, 4758c2ecf20Sopenharmony_ci {0x06, 0x0a, 0x5a}, 4768c2ecf20Sopenharmony_ci {0x06, 0x01, 0x57}, 4778c2ecf20Sopenharmony_ci {0x06, 0x8a, 0x03}, 4788c2ecf20Sopenharmony_ci {0x06, 0x0a, 0x6c}, 4798c2ecf20Sopenharmony_ci {0x06, 0x30, 0x01}, 4808c2ecf20Sopenharmony_ci {0x06, 0x20, 0x02}, 4818c2ecf20Sopenharmony_ci {0x06, 0x00, 0x03}, 4828c2ecf20Sopenharmony_ci 4838c2ecf20Sopenharmony_ci {0x05, 0x8c, 0x25}, 4848c2ecf20Sopenharmony_ci 4858c2ecf20Sopenharmony_ci {0x06, 0x4d, 0x51}, /* maybe saturation (4d) */ 4868c2ecf20Sopenharmony_ci {0x06, 0x84, 0x53}, /* making green (84) */ 4878c2ecf20Sopenharmony_ci {0x06, 0x00, 0x57}, /* sharpness (1) */ 4888c2ecf20Sopenharmony_ci {0x06, 0x18, 0x08}, 4898c2ecf20Sopenharmony_ci {0x06, 0xfc, 0x09}, 4908c2ecf20Sopenharmony_ci {0x06, 0xfc, 0x0a}, 4918c2ecf20Sopenharmony_ci {0x06, 0xfc, 0x0b}, 4928c2ecf20Sopenharmony_ci {0x06, 0x18, 0x0c}, /* maybe hue (18) */ 4938c2ecf20Sopenharmony_ci {0x06, 0xfc, 0x0d}, 4948c2ecf20Sopenharmony_ci {0x06, 0xfc, 0x0e}, 4958c2ecf20Sopenharmony_ci {0x06, 0xfc, 0x0f}, 4968c2ecf20Sopenharmony_ci {0x06, 0x18, 0x10}, /* maybe contrast (18) */ 4978c2ecf20Sopenharmony_ci 4988c2ecf20Sopenharmony_ci {0x05, 0x01, 0x02}, 4998c2ecf20Sopenharmony_ci 5008c2ecf20Sopenharmony_ci {0x04, 0x00, 0x08}, /* compression */ 5018c2ecf20Sopenharmony_ci {0x04, 0x12, 0x09}, 5028c2ecf20Sopenharmony_ci {0x04, 0x21, 0x0a}, 5038c2ecf20Sopenharmony_ci {0x04, 0x10, 0x0b}, 5048c2ecf20Sopenharmony_ci {0x04, 0x21, 0x0c}, 5058c2ecf20Sopenharmony_ci {0x04, 0x1d, 0x00}, /* imagetype (1d) */ 5068c2ecf20Sopenharmony_ci {0x04, 0x41, 0x01}, /* hardware snapcontrol */ 5078c2ecf20Sopenharmony_ci 5088c2ecf20Sopenharmony_ci {0x04, 0x00, 0x04}, 5098c2ecf20Sopenharmony_ci {0x04, 0x00, 0x05}, 5108c2ecf20Sopenharmony_ci {0x04, 0x10, 0x06}, 5118c2ecf20Sopenharmony_ci {0x04, 0x10, 0x07}, 5128c2ecf20Sopenharmony_ci {0x04, 0x40, 0x06}, 5138c2ecf20Sopenharmony_ci {0x04, 0x40, 0x07}, 5148c2ecf20Sopenharmony_ci {0x04, 0x00, 0x04}, 5158c2ecf20Sopenharmony_ci {0x04, 0x00, 0x05}, 5168c2ecf20Sopenharmony_ci 5178c2ecf20Sopenharmony_ci {0x06, 0x1c, 0x17}, 5188c2ecf20Sopenharmony_ci {0x06, 0xe2, 0x19}, 5198c2ecf20Sopenharmony_ci {0x06, 0x1c, 0x1b}, 5208c2ecf20Sopenharmony_ci {0x06, 0xe2, 0x1d}, 5218c2ecf20Sopenharmony_ci {0x06, 0x5f, 0x1f}, 5228c2ecf20Sopenharmony_ci {0x06, 0x32, 0x20}, 5238c2ecf20Sopenharmony_ci 5248c2ecf20Sopenharmony_ci {0x05, initial_brightness >> 6, 0x00}, 5258c2ecf20Sopenharmony_ci {0x05, (initial_brightness << 2) & 0xff, 0x01}, 5268c2ecf20Sopenharmony_ci {0x05, 0x06, 0xc1}, 5278c2ecf20Sopenharmony_ci {0x05, 0x58, 0xc2}, 5288c2ecf20Sopenharmony_ci {0x05, 0x00, 0xca}, 5298c2ecf20Sopenharmony_ci {0x05, 0x00, 0x11}, 5308c2ecf20Sopenharmony_ci {} 5318c2ecf20Sopenharmony_ci}; 5328c2ecf20Sopenharmony_ci 5338c2ecf20Sopenharmony_cistatic int reg_write(struct gspca_dev *gspca_dev, 5348c2ecf20Sopenharmony_ci u16 req, u16 index, u16 value) 5358c2ecf20Sopenharmony_ci{ 5368c2ecf20Sopenharmony_ci int ret; 5378c2ecf20Sopenharmony_ci struct usb_device *dev = gspca_dev->dev; 5388c2ecf20Sopenharmony_ci 5398c2ecf20Sopenharmony_ci ret = usb_control_msg(dev, 5408c2ecf20Sopenharmony_ci usb_sndctrlpipe(dev, 0), 5418c2ecf20Sopenharmony_ci req, 5428c2ecf20Sopenharmony_ci USB_TYPE_VENDOR | USB_RECIP_DEVICE, 5438c2ecf20Sopenharmony_ci value, index, NULL, 0, 500); 5448c2ecf20Sopenharmony_ci gspca_dbg(gspca_dev, D_USBO, "reg write: 0x%02x,0x%02x:0x%02x, %d\n", 5458c2ecf20Sopenharmony_ci req, index, value, ret); 5468c2ecf20Sopenharmony_ci if (ret < 0) 5478c2ecf20Sopenharmony_ci pr_err("reg write: error %d\n", ret); 5488c2ecf20Sopenharmony_ci return ret; 5498c2ecf20Sopenharmony_ci} 5508c2ecf20Sopenharmony_ci 5518c2ecf20Sopenharmony_ci/* returns: negative is error, pos or zero is data */ 5528c2ecf20Sopenharmony_cistatic int reg_read(struct gspca_dev *gspca_dev, 5538c2ecf20Sopenharmony_ci u16 req, /* bRequest */ 5548c2ecf20Sopenharmony_ci u16 index) /* wIndex */ 5558c2ecf20Sopenharmony_ci{ 5568c2ecf20Sopenharmony_ci int ret; 5578c2ecf20Sopenharmony_ci 5588c2ecf20Sopenharmony_ci ret = usb_control_msg(gspca_dev->dev, 5598c2ecf20Sopenharmony_ci usb_rcvctrlpipe(gspca_dev->dev, 0), 5608c2ecf20Sopenharmony_ci req, 5618c2ecf20Sopenharmony_ci USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 5628c2ecf20Sopenharmony_ci 0, /* value */ 5638c2ecf20Sopenharmony_ci index, 5648c2ecf20Sopenharmony_ci gspca_dev->usb_buf, 2, 5658c2ecf20Sopenharmony_ci 500); /* timeout */ 5668c2ecf20Sopenharmony_ci if (ret < 0) 5678c2ecf20Sopenharmony_ci return ret; 5688c2ecf20Sopenharmony_ci return (gspca_dev->usb_buf[1] << 8) + gspca_dev->usb_buf[0]; 5698c2ecf20Sopenharmony_ci} 5708c2ecf20Sopenharmony_ci 5718c2ecf20Sopenharmony_cistatic int write_vector(struct gspca_dev *gspca_dev, 5728c2ecf20Sopenharmony_ci const u8 data[][3]) 5738c2ecf20Sopenharmony_ci{ 5748c2ecf20Sopenharmony_ci int ret, i = 0; 5758c2ecf20Sopenharmony_ci 5768c2ecf20Sopenharmony_ci while (data[i][0] != 0) { 5778c2ecf20Sopenharmony_ci ret = reg_write(gspca_dev, data[i][0], data[i][2], 5788c2ecf20Sopenharmony_ci data[i][1]); 5798c2ecf20Sopenharmony_ci if (ret < 0) 5808c2ecf20Sopenharmony_ci return ret; 5818c2ecf20Sopenharmony_ci i++; 5828c2ecf20Sopenharmony_ci } 5838c2ecf20Sopenharmony_ci return 0; 5848c2ecf20Sopenharmony_ci} 5858c2ecf20Sopenharmony_ci 5868c2ecf20Sopenharmony_ci/* this function is called at probe time */ 5878c2ecf20Sopenharmony_cistatic int sd_config(struct gspca_dev *gspca_dev, 5888c2ecf20Sopenharmony_ci const struct usb_device_id *id) 5898c2ecf20Sopenharmony_ci{ 5908c2ecf20Sopenharmony_ci struct sd *sd = (struct sd *) gspca_dev; 5918c2ecf20Sopenharmony_ci struct cam *cam; 5928c2ecf20Sopenharmony_ci 5938c2ecf20Sopenharmony_ci cam = &gspca_dev->cam; 5948c2ecf20Sopenharmony_ci cam->cam_mode = vga_mode; 5958c2ecf20Sopenharmony_ci sd->subtype = id->driver_info; 5968c2ecf20Sopenharmony_ci if (sd->subtype != IntelPCCameraPro) 5978c2ecf20Sopenharmony_ci cam->nmodes = ARRAY_SIZE(vga_mode); 5988c2ecf20Sopenharmony_ci else /* no 640x480 for IntelPCCameraPro */ 5998c2ecf20Sopenharmony_ci cam->nmodes = ARRAY_SIZE(vga_mode) - 1; 6008c2ecf20Sopenharmony_ci 6018c2ecf20Sopenharmony_ci return 0; 6028c2ecf20Sopenharmony_ci} 6038c2ecf20Sopenharmony_ci 6048c2ecf20Sopenharmony_ci/* this function is called at probe and resume time */ 6058c2ecf20Sopenharmony_cistatic int sd_init(struct gspca_dev *gspca_dev) 6068c2ecf20Sopenharmony_ci{ 6078c2ecf20Sopenharmony_ci struct sd *sd = (struct sd *) gspca_dev; 6088c2ecf20Sopenharmony_ci 6098c2ecf20Sopenharmony_ci if (write_vector(gspca_dev, 6108c2ecf20Sopenharmony_ci sd->subtype == Nxultra 6118c2ecf20Sopenharmony_ci ? spca505b_init_data 6128c2ecf20Sopenharmony_ci : spca505_init_data)) 6138c2ecf20Sopenharmony_ci return -EIO; 6148c2ecf20Sopenharmony_ci return 0; 6158c2ecf20Sopenharmony_ci} 6168c2ecf20Sopenharmony_ci 6178c2ecf20Sopenharmony_cistatic void setbrightness(struct gspca_dev *gspca_dev, s32 brightness) 6188c2ecf20Sopenharmony_ci{ 6198c2ecf20Sopenharmony_ci reg_write(gspca_dev, 0x05, 0x00, (255 - brightness) >> 6); 6208c2ecf20Sopenharmony_ci reg_write(gspca_dev, 0x05, 0x01, (255 - brightness) << 2); 6218c2ecf20Sopenharmony_ci} 6228c2ecf20Sopenharmony_ci 6238c2ecf20Sopenharmony_cistatic int sd_start(struct gspca_dev *gspca_dev) 6248c2ecf20Sopenharmony_ci{ 6258c2ecf20Sopenharmony_ci struct sd *sd = (struct sd *) gspca_dev; 6268c2ecf20Sopenharmony_ci int ret, mode; 6278c2ecf20Sopenharmony_ci static u8 mode_tb[][3] = { 6288c2ecf20Sopenharmony_ci /* r00 r06 r07 */ 6298c2ecf20Sopenharmony_ci {0x00, 0x10, 0x10}, /* 640x480 */ 6308c2ecf20Sopenharmony_ci {0x01, 0x1a, 0x1a}, /* 352x288 */ 6318c2ecf20Sopenharmony_ci {0x02, 0x1c, 0x1d}, /* 320x240 */ 6328c2ecf20Sopenharmony_ci {0x04, 0x34, 0x34}, /* 176x144 */ 6338c2ecf20Sopenharmony_ci {0x05, 0x40, 0x40} /* 160x120 */ 6348c2ecf20Sopenharmony_ci }; 6358c2ecf20Sopenharmony_ci 6368c2ecf20Sopenharmony_ci if (sd->subtype == Nxultra) 6378c2ecf20Sopenharmony_ci write_vector(gspca_dev, spca505b_open_data_ccd); 6388c2ecf20Sopenharmony_ci else 6398c2ecf20Sopenharmony_ci write_vector(gspca_dev, spca505_open_data_ccd); 6408c2ecf20Sopenharmony_ci ret = reg_read(gspca_dev, 0x06, 0x16); 6418c2ecf20Sopenharmony_ci 6428c2ecf20Sopenharmony_ci if (ret < 0) { 6438c2ecf20Sopenharmony_ci gspca_err(gspca_dev, "register read failed err: %d\n", ret); 6448c2ecf20Sopenharmony_ci return ret; 6458c2ecf20Sopenharmony_ci } 6468c2ecf20Sopenharmony_ci if (ret != 0x0101) { 6478c2ecf20Sopenharmony_ci pr_err("After vector read returns 0x%04x should be 0x0101\n", 6488c2ecf20Sopenharmony_ci ret); 6498c2ecf20Sopenharmony_ci } 6508c2ecf20Sopenharmony_ci 6518c2ecf20Sopenharmony_ci ret = reg_write(gspca_dev, 0x06, 0x16, 0x0a); 6528c2ecf20Sopenharmony_ci if (ret < 0) 6538c2ecf20Sopenharmony_ci return ret; 6548c2ecf20Sopenharmony_ci reg_write(gspca_dev, 0x05, 0xc2, 0x12); 6558c2ecf20Sopenharmony_ci 6568c2ecf20Sopenharmony_ci /* necessary because without it we can see stream 6578c2ecf20Sopenharmony_ci * only once after loading module */ 6588c2ecf20Sopenharmony_ci /* stopping usb registers Tomasz change */ 6598c2ecf20Sopenharmony_ci reg_write(gspca_dev, 0x02, 0x00, 0x00); 6608c2ecf20Sopenharmony_ci 6618c2ecf20Sopenharmony_ci mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; 6628c2ecf20Sopenharmony_ci reg_write(gspca_dev, SPCA50X_REG_COMPRESS, 0x00, mode_tb[mode][0]); 6638c2ecf20Sopenharmony_ci reg_write(gspca_dev, SPCA50X_REG_COMPRESS, 0x06, mode_tb[mode][1]); 6648c2ecf20Sopenharmony_ci reg_write(gspca_dev, SPCA50X_REG_COMPRESS, 0x07, mode_tb[mode][2]); 6658c2ecf20Sopenharmony_ci 6668c2ecf20Sopenharmony_ci return reg_write(gspca_dev, SPCA50X_REG_USB, 6678c2ecf20Sopenharmony_ci SPCA50X_USB_CTRL, 6688c2ecf20Sopenharmony_ci SPCA50X_CUSB_ENABLE); 6698c2ecf20Sopenharmony_ci} 6708c2ecf20Sopenharmony_ci 6718c2ecf20Sopenharmony_cistatic void sd_stopN(struct gspca_dev *gspca_dev) 6728c2ecf20Sopenharmony_ci{ 6738c2ecf20Sopenharmony_ci /* Disable ISO packet machine */ 6748c2ecf20Sopenharmony_ci reg_write(gspca_dev, 0x02, 0x00, 0x00); 6758c2ecf20Sopenharmony_ci} 6768c2ecf20Sopenharmony_ci 6778c2ecf20Sopenharmony_ci/* called on streamoff with alt 0 and on disconnect */ 6788c2ecf20Sopenharmony_cistatic void sd_stop0(struct gspca_dev *gspca_dev) 6798c2ecf20Sopenharmony_ci{ 6808c2ecf20Sopenharmony_ci if (!gspca_dev->present) 6818c2ecf20Sopenharmony_ci return; 6828c2ecf20Sopenharmony_ci 6838c2ecf20Sopenharmony_ci /* This maybe reset or power control */ 6848c2ecf20Sopenharmony_ci reg_write(gspca_dev, 0x03, 0x03, 0x20); 6858c2ecf20Sopenharmony_ci reg_write(gspca_dev, 0x03, 0x01, 0x00); 6868c2ecf20Sopenharmony_ci reg_write(gspca_dev, 0x03, 0x00, 0x01); 6878c2ecf20Sopenharmony_ci reg_write(gspca_dev, 0x05, 0x10, 0x01); 6888c2ecf20Sopenharmony_ci reg_write(gspca_dev, 0x05, 0x11, 0x0f); 6898c2ecf20Sopenharmony_ci} 6908c2ecf20Sopenharmony_ci 6918c2ecf20Sopenharmony_cistatic void sd_pkt_scan(struct gspca_dev *gspca_dev, 6928c2ecf20Sopenharmony_ci u8 *data, /* isoc packet */ 6938c2ecf20Sopenharmony_ci int len) /* iso packet length */ 6948c2ecf20Sopenharmony_ci{ 6958c2ecf20Sopenharmony_ci switch (data[0]) { 6968c2ecf20Sopenharmony_ci case 0: /* start of frame */ 6978c2ecf20Sopenharmony_ci gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0); 6988c2ecf20Sopenharmony_ci data += SPCA50X_OFFSET_DATA; 6998c2ecf20Sopenharmony_ci len -= SPCA50X_OFFSET_DATA; 7008c2ecf20Sopenharmony_ci gspca_frame_add(gspca_dev, FIRST_PACKET, data, len); 7018c2ecf20Sopenharmony_ci break; 7028c2ecf20Sopenharmony_ci case 0xff: /* drop */ 7038c2ecf20Sopenharmony_ci break; 7048c2ecf20Sopenharmony_ci default: 7058c2ecf20Sopenharmony_ci data += 1; 7068c2ecf20Sopenharmony_ci len -= 1; 7078c2ecf20Sopenharmony_ci gspca_frame_add(gspca_dev, INTER_PACKET, data, len); 7088c2ecf20Sopenharmony_ci break; 7098c2ecf20Sopenharmony_ci } 7108c2ecf20Sopenharmony_ci} 7118c2ecf20Sopenharmony_ci 7128c2ecf20Sopenharmony_cistatic int sd_s_ctrl(struct v4l2_ctrl *ctrl) 7138c2ecf20Sopenharmony_ci{ 7148c2ecf20Sopenharmony_ci struct gspca_dev *gspca_dev = 7158c2ecf20Sopenharmony_ci container_of(ctrl->handler, struct gspca_dev, ctrl_handler); 7168c2ecf20Sopenharmony_ci 7178c2ecf20Sopenharmony_ci gspca_dev->usb_err = 0; 7188c2ecf20Sopenharmony_ci 7198c2ecf20Sopenharmony_ci if (!gspca_dev->streaming) 7208c2ecf20Sopenharmony_ci return 0; 7218c2ecf20Sopenharmony_ci 7228c2ecf20Sopenharmony_ci switch (ctrl->id) { 7238c2ecf20Sopenharmony_ci case V4L2_CID_BRIGHTNESS: 7248c2ecf20Sopenharmony_ci setbrightness(gspca_dev, ctrl->val); 7258c2ecf20Sopenharmony_ci break; 7268c2ecf20Sopenharmony_ci } 7278c2ecf20Sopenharmony_ci return gspca_dev->usb_err; 7288c2ecf20Sopenharmony_ci} 7298c2ecf20Sopenharmony_ci 7308c2ecf20Sopenharmony_cistatic const struct v4l2_ctrl_ops sd_ctrl_ops = { 7318c2ecf20Sopenharmony_ci .s_ctrl = sd_s_ctrl, 7328c2ecf20Sopenharmony_ci}; 7338c2ecf20Sopenharmony_ci 7348c2ecf20Sopenharmony_cistatic int sd_init_controls(struct gspca_dev *gspca_dev) 7358c2ecf20Sopenharmony_ci{ 7368c2ecf20Sopenharmony_ci struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler; 7378c2ecf20Sopenharmony_ci 7388c2ecf20Sopenharmony_ci gspca_dev->vdev.ctrl_handler = hdl; 7398c2ecf20Sopenharmony_ci v4l2_ctrl_handler_init(hdl, 5); 7408c2ecf20Sopenharmony_ci v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, 7418c2ecf20Sopenharmony_ci V4L2_CID_BRIGHTNESS, 0, 255, 1, 127); 7428c2ecf20Sopenharmony_ci 7438c2ecf20Sopenharmony_ci if (hdl->error) { 7448c2ecf20Sopenharmony_ci pr_err("Could not initialize controls\n"); 7458c2ecf20Sopenharmony_ci return hdl->error; 7468c2ecf20Sopenharmony_ci } 7478c2ecf20Sopenharmony_ci return 0; 7488c2ecf20Sopenharmony_ci} 7498c2ecf20Sopenharmony_ci 7508c2ecf20Sopenharmony_ci/* sub-driver description */ 7518c2ecf20Sopenharmony_cistatic const struct sd_desc sd_desc = { 7528c2ecf20Sopenharmony_ci .name = MODULE_NAME, 7538c2ecf20Sopenharmony_ci .config = sd_config, 7548c2ecf20Sopenharmony_ci .init_controls = sd_init_controls, 7558c2ecf20Sopenharmony_ci .init = sd_init, 7568c2ecf20Sopenharmony_ci .start = sd_start, 7578c2ecf20Sopenharmony_ci .stopN = sd_stopN, 7588c2ecf20Sopenharmony_ci .stop0 = sd_stop0, 7598c2ecf20Sopenharmony_ci .pkt_scan = sd_pkt_scan, 7608c2ecf20Sopenharmony_ci}; 7618c2ecf20Sopenharmony_ci 7628c2ecf20Sopenharmony_ci/* -- module initialisation -- */ 7638c2ecf20Sopenharmony_cistatic const struct usb_device_id device_table[] = { 7648c2ecf20Sopenharmony_ci {USB_DEVICE(0x041e, 0x401d), .driver_info = Nxultra}, 7658c2ecf20Sopenharmony_ci {USB_DEVICE(0x0733, 0x0430), .driver_info = IntelPCCameraPro}, 7668c2ecf20Sopenharmony_ci/*fixme: may be UsbGrabberPV321 BRIDGE_SPCA506 SENSOR_SAA7113 */ 7678c2ecf20Sopenharmony_ci {} 7688c2ecf20Sopenharmony_ci}; 7698c2ecf20Sopenharmony_ciMODULE_DEVICE_TABLE(usb, device_table); 7708c2ecf20Sopenharmony_ci 7718c2ecf20Sopenharmony_ci/* -- device connect -- */ 7728c2ecf20Sopenharmony_cistatic int sd_probe(struct usb_interface *intf, 7738c2ecf20Sopenharmony_ci const struct usb_device_id *id) 7748c2ecf20Sopenharmony_ci{ 7758c2ecf20Sopenharmony_ci return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), 7768c2ecf20Sopenharmony_ci THIS_MODULE); 7778c2ecf20Sopenharmony_ci} 7788c2ecf20Sopenharmony_ci 7798c2ecf20Sopenharmony_cistatic struct usb_driver sd_driver = { 7808c2ecf20Sopenharmony_ci .name = MODULE_NAME, 7818c2ecf20Sopenharmony_ci .id_table = device_table, 7828c2ecf20Sopenharmony_ci .probe = sd_probe, 7838c2ecf20Sopenharmony_ci .disconnect = gspca_disconnect, 7848c2ecf20Sopenharmony_ci#ifdef CONFIG_PM 7858c2ecf20Sopenharmony_ci .suspend = gspca_suspend, 7868c2ecf20Sopenharmony_ci .resume = gspca_resume, 7878c2ecf20Sopenharmony_ci .reset_resume = gspca_resume, 7888c2ecf20Sopenharmony_ci#endif 7898c2ecf20Sopenharmony_ci}; 7908c2ecf20Sopenharmony_ci 7918c2ecf20Sopenharmony_cimodule_usb_driver(sd_driver); 792