sonixb.c 31 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141
  1. /*
  2. * sonix sn9c102 (bayer) library
  3. * Copyright (C) 2003 2004 Michel Xhaard mxhaard@magic.fr
  4. * Add Pas106 Stefano Mozzi (C) 2004
  5. *
  6. * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
  7. *
  8. * This program is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation; either version 2 of the License, or
  11. * any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, write to the Free Software
  20. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  21. */
  22. #define MODULE_NAME "sonixb"
  23. #include "gspca.h"
  24. #define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7)
  25. static const char version[] = "2.1.7";
  26. MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
  27. MODULE_DESCRIPTION("GSPCA/SN9C102 USB Camera Driver");
  28. MODULE_LICENSE("GPL");
  29. /* specific webcam descriptor */
  30. struct sd {
  31. struct gspca_dev gspca_dev; /* !! must be the first item */
  32. struct sd_desc sd_desc; /* our nctrls differ dependend upon the
  33. sensor, so we use a per cam copy */
  34. atomic_t avg_lum;
  35. unsigned short gain;
  36. unsigned short exposure;
  37. unsigned char brightness;
  38. unsigned char autogain;
  39. unsigned char autogain_ignore_frames;
  40. unsigned char fr_h_sz; /* size of frame header */
  41. char sensor; /* Type of image sensor chip */
  42. char sensor_has_gain;
  43. #define SENSOR_HV7131R 0
  44. #define SENSOR_OV6650 1
  45. #define SENSOR_OV7630 2
  46. #define SENSOR_OV7630_3 3
  47. #define SENSOR_PAS106 4
  48. #define SENSOR_PAS202 5
  49. #define SENSOR_TAS5110 6
  50. #define SENSOR_TAS5130CXX 7
  51. };
  52. #define COMP2 0x8f
  53. #define COMP 0xc7 /* 0x87 //0x07 */
  54. #define COMP1 0xc9 /* 0x89 //0x09 */
  55. #define MCK_INIT 0x63
  56. #define MCK_INIT1 0x20 /*fixme: Bayer - 0x50 for JPEG ??*/
  57. #define SYS_CLK 0x04
  58. /* We calculate the autogain at the end of the transfer of a frame, at this
  59. moment a frame with the old settings is being transmitted, and a frame is
  60. being captured with the old settings. So if we adjust the autogain we must
  61. ignore atleast the 2 next frames for the new settings to come into effect
  62. before doing any other adjustments */
  63. #define AUTOGAIN_IGNORE_FRAMES 3
  64. #define AUTOGAIN_DEADZONE 500
  65. #define DESIRED_AVG_LUM 7000
  66. /* V4L2 controls supported by the driver */
  67. static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
  68. static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
  69. static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val);
  70. static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val);
  71. static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val);
  72. static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val);
  73. static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
  74. static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
  75. static struct ctrl sd_ctrls[] = {
  76. {
  77. {
  78. .id = V4L2_CID_BRIGHTNESS,
  79. .type = V4L2_CTRL_TYPE_INTEGER,
  80. .name = "Brightness",
  81. .minimum = 0,
  82. .maximum = 255,
  83. .step = 1,
  84. #define BRIGHTNESS_DEF 127
  85. .default_value = BRIGHTNESS_DEF,
  86. },
  87. .set = sd_setbrightness,
  88. .get = sd_getbrightness,
  89. },
  90. {
  91. {
  92. .id = V4L2_CID_GAIN,
  93. .type = V4L2_CTRL_TYPE_INTEGER,
  94. .name = "Gain",
  95. .minimum = 0,
  96. .maximum = 511,
  97. .step = 1,
  98. #define GAIN_DEF 255
  99. #define GAIN_KNEE 400
  100. .default_value = GAIN_DEF,
  101. },
  102. .set = sd_setgain,
  103. .get = sd_getgain,
  104. },
  105. {
  106. {
  107. .id = V4L2_CID_EXPOSURE,
  108. .type = V4L2_CTRL_TYPE_INTEGER,
  109. .name = "Exposure",
  110. #define EXPOSURE_DEF 0
  111. #define EXPOSURE_KNEE 353 /* 10 fps */
  112. .minimum = 0,
  113. .maximum = 511,
  114. .step = 1,
  115. .default_value = EXPOSURE_DEF,
  116. .flags = 0,
  117. },
  118. .set = sd_setexposure,
  119. .get = sd_getexposure,
  120. },
  121. {
  122. {
  123. .id = V4L2_CID_AUTOGAIN,
  124. .type = V4L2_CTRL_TYPE_BOOLEAN,
  125. .name = "Automatic Gain (and Exposure)",
  126. .minimum = 0,
  127. .maximum = 1,
  128. .step = 1,
  129. #define AUTOGAIN_DEF 1
  130. .default_value = AUTOGAIN_DEF,
  131. .flags = 0,
  132. },
  133. .set = sd_setautogain,
  134. .get = sd_getautogain,
  135. },
  136. };
  137. static struct v4l2_pix_format vga_mode[] = {
  138. {160, 120, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
  139. .bytesperline = 160,
  140. .sizeimage = 160 * 120,
  141. .colorspace = V4L2_COLORSPACE_SRGB,
  142. .priv = 2},
  143. {320, 240, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
  144. .bytesperline = 320,
  145. .sizeimage = 320 * 240,
  146. .colorspace = V4L2_COLORSPACE_SRGB,
  147. .priv = 1},
  148. {640, 480, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
  149. .bytesperline = 640,
  150. .sizeimage = 640 * 480,
  151. .colorspace = V4L2_COLORSPACE_SRGB,
  152. .priv = 0},
  153. };
  154. static struct v4l2_pix_format sif_mode[] = {
  155. {176, 144, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
  156. .bytesperline = 176,
  157. .sizeimage = 176 * 144,
  158. .colorspace = V4L2_COLORSPACE_SRGB,
  159. .priv = 1},
  160. {352, 288, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
  161. .bytesperline = 352,
  162. .sizeimage = 352 * 288,
  163. .colorspace = V4L2_COLORSPACE_SRGB,
  164. .priv = 0},
  165. };
  166. static const __u8 probe_ov7630[] = {0x08, 0x44};
  167. static const __u8 initHv7131[] = {
  168. 0x46, 0x77, 0x00, 0x04, 0x00, 0x00, 0x00, 0x80, 0x11, 0x00, 0x00, 0x00,
  169. 0x00, 0x00,
  170. 0x00, 0x00, 0x00, 0x03, 0x01, 0x00, /* shift from 0x02 0x01 0x00 */
  171. 0x28, 0x1e, 0x60, 0x8a, 0x20,
  172. 0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c
  173. };
  174. static const __u8 hv7131_sensor_init[][8] = {
  175. {0xc0, 0x11, 0x31, 0x38, 0x2a, 0x2e, 0x00, 0x10},
  176. {0xa0, 0x11, 0x01, 0x08, 0x2a, 0x2e, 0x00, 0x10},
  177. {0xb0, 0x11, 0x20, 0x00, 0xd0, 0x2e, 0x00, 0x10},
  178. {0xc0, 0x11, 0x25, 0x03, 0x0e, 0x28, 0x00, 0x16},
  179. {0xa0, 0x11, 0x30, 0x10, 0x0e, 0x28, 0x00, 0x15},
  180. };
  181. static const __u8 initOv6650[] = {
  182. 0x44, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
  183. 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  184. 0x00, 0x02, 0x01, 0x0a, 0x16, 0x12, 0x68, 0x0b,
  185. 0x10, 0x1d, 0x10, 0x00, 0x06, 0x1f, 0x00
  186. };
  187. static const __u8 ov6650_sensor_init[][8] =
  188. {
  189. /* Bright, contrast, etc are set througth SCBB interface.
  190. * AVCAP on win2 do not send any data on this controls. */
  191. /* Anyway, some registers appears to alter bright and constrat */
  192. /* Reset sensor */
  193. {0xa0, 0x60, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10},
  194. /* Set clock register 0x11 low nibble is clock divider */
  195. {0xd0, 0x60, 0x11, 0xc0, 0x1b, 0x18, 0xc1, 0x10},
  196. /* Next some unknown stuff */
  197. {0xb0, 0x60, 0x15, 0x00, 0x02, 0x18, 0xc1, 0x10},
  198. /* {0xa0, 0x60, 0x1b, 0x01, 0x02, 0x18, 0xc1, 0x10},
  199. * THIS SET GREEN SCREEN
  200. * (pixels could be innverted in decode kind of "brg",
  201. * but blue wont be there. Avoid this data ... */
  202. {0xd0, 0x60, 0x26, 0x01, 0x14, 0xd8, 0xa4, 0x10}, /* format out? */
  203. {0xd0, 0x60, 0x26, 0x01, 0x14, 0xd8, 0xa4, 0x10},
  204. {0xa0, 0x60, 0x30, 0x3d, 0x0A, 0xd8, 0xa4, 0x10},
  205. /* Disable autobright ? */
  206. {0xb0, 0x60, 0x60, 0x66, 0x68, 0xd8, 0xa4, 0x10},
  207. /* Some more unknown stuff */
  208. {0xa0, 0x60, 0x68, 0x04, 0x68, 0xd8, 0xa4, 0x10},
  209. {0xd0, 0x60, 0x17, 0x24, 0xd6, 0x04, 0x94, 0x10}, /* Clipreg */
  210. {0xa0, 0x60, 0x10, 0x57, 0x99, 0x04, 0x94, 0x16},
  211. /* Framerate adjust register for artificial light 50 hz flicker
  212. compensation, identical to ov6630 0x2b register, see 6630 datasheet.
  213. 0x4f -> (30 fps -> 25 fps), 0x00 -> no adjustment */
  214. {0xa0, 0x60, 0x2b, 0x4f, 0x99, 0x04, 0x94, 0x15},
  215. };
  216. static const __u8 initOv7630[] = {
  217. 0x04, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, /* r01 .. r08 */
  218. 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* r09 .. r10 */
  219. 0x00, 0x02, 0x01, 0x0a, /* r11 .. r14 */
  220. 0x28, 0x1e, /* H & V sizes r15 .. r16 */
  221. 0x68, COMP1, MCK_INIT1, /* r17 .. r19 */
  222. 0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c /* r1a .. r1f */
  223. };
  224. static const __u8 initOv7630_3[] = {
  225. 0x44, 0x44, 0x00, 0x1a, 0x20, 0x20, 0x20, 0x80, /* r01 .. r08 */
  226. 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, /* r09 .. r10 */
  227. 0x00, 0x01, 0x01, 0x0a, /* r11 .. r14 */
  228. 0x16, 0x12, /* H & V sizes r15 .. r16 */
  229. 0x68, 0x8f, MCK_INIT1, /* r17 .. r19 */
  230. 0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c, 0x00, /* r1a .. r20 */
  231. 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, /* r21 .. r28 */
  232. 0x90, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0, 0xff /* r29 .. r30 */
  233. };
  234. static const __u8 ov7630_sensor_init_com[][8] = {
  235. {0xa0, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10},
  236. {0xb0, 0x21, 0x01, 0x77, 0x3a, 0x00, 0x00, 0x10},
  237. /* {0xd0, 0x21, 0x12, 0x7c, 0x01, 0x80, 0x34, 0x10}, jfm */
  238. {0xd0, 0x21, 0x12, 0x78, 0x00, 0x80, 0x34, 0x10}, /* jfm */
  239. {0xa0, 0x21, 0x1b, 0x04, 0x00, 0x80, 0x34, 0x10},
  240. {0xa0, 0x21, 0x20, 0x44, 0x00, 0x80, 0x34, 0x10},
  241. {0xa0, 0x21, 0x23, 0xee, 0x00, 0x80, 0x34, 0x10},
  242. {0xd0, 0x21, 0x26, 0xa0, 0x9a, 0xa0, 0x30, 0x10},
  243. {0xb0, 0x21, 0x2a, 0x80, 0x00, 0xa0, 0x30, 0x10},
  244. {0xb0, 0x21, 0x2f, 0x3d, 0x24, 0xa0, 0x30, 0x10},
  245. {0xa0, 0x21, 0x32, 0x86, 0x24, 0xa0, 0x30, 0x10},
  246. /* {0xb0, 0x21, 0x60, 0xa9, 0x4a, 0xa0, 0x30, 0x10}, jfm */
  247. {0xb0, 0x21, 0x60, 0xa9, 0x42, 0xa0, 0x30, 0x10}, /* jfm */
  248. {0xa0, 0x21, 0x65, 0x00, 0x42, 0xa0, 0x30, 0x10},
  249. {0xa0, 0x21, 0x69, 0x38, 0x42, 0xa0, 0x30, 0x10},
  250. {0xc0, 0x21, 0x6f, 0x88, 0x0b, 0x00, 0x30, 0x10},
  251. {0xc0, 0x21, 0x74, 0x21, 0x8e, 0x00, 0x30, 0x10},
  252. {0xa0, 0x21, 0x7d, 0xf7, 0x8e, 0x00, 0x30, 0x10},
  253. {0xd0, 0x21, 0x17, 0x1c, 0xbd, 0x06, 0xf6, 0x10},
  254. };
  255. static const __u8 ov7630_sensor_init[][8] = {
  256. {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 200ms */
  257. {0xa0, 0x21, 0x11, 0x01, 0xbd, 0x06, 0xf6, 0x10}, /* jfm */
  258. {0xa0, 0x21, 0x10, 0x57, 0xbd, 0x06, 0xf6, 0x16},
  259. {0xa0, 0x21, 0x76, 0x02, 0xbd, 0x06, 0xf6, 0x16},
  260. {0xa0, 0x21, 0x00, 0x10, 0xbd, 0x06, 0xf6, 0x15}, /* gain */
  261. };
  262. static const __u8 ov7630_sensor_init_3[][8] = {
  263. {0xa0, 0x21, 0x10, 0x83, 0xbd, 0x06, 0xf6, 0x16}, /* exposure */
  264. {0xa0, 0x21, 0x76, 0x00, 0xbd, 0x06, 0xf6, 0x16},
  265. {0xa0, 0x21, 0x11, 0x00, 0xbd, 0x06, 0xf6, 0x16},
  266. {0xa0, 0x21, 0x00, 0x10, 0xbd, 0x06, 0xf6, 0x15}, /* gain */
  267. /* {0xb0, 0x21, 0x2a, 0xc0, 0x3c, 0x06, 0xf6, 0x1d},
  268. * a0 1c,a0 1f,c0 3c frame rate ?line interval from ov6630 */
  269. /* {0xb0, 0x21, 0x2a, 0xa0, 0x1f, 0x06, 0xf6, 0x1d}, * from win */
  270. {0xb0, 0x21, 0x2a, 0x80, 0x60, 0x06, 0xf6, 0x1d},
  271. };
  272. static const __u8 initPas106[] = {
  273. 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x40, 0x00, 0x00, 0x00,
  274. 0x00, 0x00,
  275. 0x00, 0x00, 0x00, 0x05, 0x01, 0x00,
  276. 0x16, 0x12, 0x28, COMP1, MCK_INIT1,
  277. 0x18, 0x10, 0x04, 0x03, 0x11, 0x0c
  278. };
  279. /* compression 0x86 mckinit1 0x2b */
  280. static const __u8 pas106_data[][2] = {
  281. {0x02, 0x04}, /* Pixel Clock Divider 6 */
  282. {0x03, 0x13}, /* Frame Time MSB */
  283. /* {0x03, 0x12}, * Frame Time MSB */
  284. {0x04, 0x06}, /* Frame Time LSB */
  285. /* {0x04, 0x05}, * Frame Time LSB */
  286. {0x05, 0x65}, /* Shutter Time Line Offset */
  287. /* {0x05, 0x6d}, * Shutter Time Line Offset */
  288. /* {0x06, 0xb1}, * Shutter Time Pixel Offset */
  289. {0x06, 0xcd}, /* Shutter Time Pixel Offset */
  290. {0x07, 0xc1}, /* Black Level Subtract Sign */
  291. /* {0x07, 0x00}, * Black Level Subtract Sign */
  292. {0x08, 0x06}, /* Black Level Subtract Level */
  293. {0x08, 0x06}, /* Black Level Subtract Level */
  294. /* {0x08, 0x01}, * Black Level Subtract Level */
  295. {0x09, 0x05}, /* Color Gain B Pixel 5 a */
  296. {0x0a, 0x04}, /* Color Gain G1 Pixel 1 5 */
  297. {0x0b, 0x04}, /* Color Gain G2 Pixel 1 0 5 */
  298. {0x0c, 0x05}, /* Color Gain R Pixel 3 1 */
  299. {0x0d, 0x00}, /* Color GainH Pixel */
  300. {0x0e, 0x0e}, /* Global Gain */
  301. {0x0f, 0x00}, /* Contrast */
  302. {0x10, 0x06}, /* H&V synchro polarity */
  303. {0x11, 0x06}, /* ?default */
  304. {0x12, 0x06}, /* DAC scale */
  305. {0x14, 0x02}, /* ?default */
  306. {0x13, 0x01}, /* Validate Settings */
  307. };
  308. static const __u8 initPas202[] = {
  309. 0x44, 0x44, 0x21, 0x30, 0x00, 0x00, 0x00, 0x80, 0x40, 0x00, 0x00, 0x00,
  310. 0x00, 0x00,
  311. 0x00, 0x00, 0x00, 0x07, 0x03, 0x0a, /* 6 */
  312. 0x28, 0x1e, 0x28, 0x89, 0x30,
  313. 0x00, 0x00, 0x02, 0x03, 0x0f, 0x0c
  314. };
  315. static const __u8 pas202_sensor_init[][8] = {
  316. {0xa0, 0x40, 0x02, 0x03, 0x00, 0x00, 0x00, 0x10},
  317. {0xd0, 0x40, 0x04, 0x07, 0x34, 0x00, 0x09, 0x10},
  318. {0xd0, 0x40, 0x08, 0x01, 0x00, 0x00, 0x01, 0x10},
  319. {0xd0, 0x40, 0x0C, 0x00, 0x0C, 0x00, 0x32, 0x10},
  320. {0xd0, 0x40, 0x10, 0x00, 0x01, 0x00, 0x63, 0x10},
  321. {0xa0, 0x40, 0x15, 0x70, 0x01, 0x00, 0x63, 0x10},
  322. {0xa0, 0x40, 0x18, 0x00, 0x01, 0x00, 0x63, 0x10},
  323. {0xa0, 0x40, 0x11, 0x01, 0x01, 0x00, 0x63, 0x10},
  324. {0xa0, 0x40, 0x03, 0x56, 0x01, 0x00, 0x63, 0x10},
  325. {0xa0, 0x40, 0x11, 0x01, 0x01, 0x00, 0x63, 0x10},
  326. {0xb0, 0x40, 0x04, 0x07, 0x2a, 0x00, 0x63, 0x10},
  327. {0xb0, 0x40, 0x0e, 0x00, 0x3d, 0x00, 0x63, 0x10},
  328. {0xa0, 0x40, 0x11, 0x01, 0x3d, 0x00, 0x63, 0x16},
  329. {0xa0, 0x40, 0x10, 0x08, 0x3d, 0x00, 0x63, 0x15},
  330. {0xa0, 0x40, 0x02, 0x04, 0x3d, 0x00, 0x63, 0x16},
  331. {0xa0, 0x40, 0x11, 0x01, 0x3d, 0x00, 0x63, 0x16},
  332. {0xb0, 0x40, 0x0e, 0x00, 0x31, 0x00, 0x63, 0x16},
  333. {0xa0, 0x40, 0x11, 0x01, 0x31, 0x00, 0x63, 0x16},
  334. {0xa0, 0x40, 0x10, 0x0e, 0x31, 0x00, 0x63, 0x15},
  335. {0xa0, 0x40, 0x11, 0x01, 0x31, 0x00, 0x63, 0x16},
  336. };
  337. static const __u8 initTas5110[] = {
  338. 0x44, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x11, 0x00, 0x00, 0x00,
  339. 0x00, 0x00,
  340. 0x00, 0x01, 0x00, 0x46, 0x09, 0x0a, /* shift from 0x45 0x09 0x0a */
  341. 0x16, 0x12, 0x60, 0x86, 0x2b,
  342. 0x14, 0x0a, 0x02, 0x02, 0x09, 0x07
  343. };
  344. static const __u8 tas5110_sensor_init[][8] = {
  345. {0x30, 0x11, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x10},
  346. {0x30, 0x11, 0x02, 0x20, 0xa9, 0x00, 0x00, 0x10},
  347. {0xa0, 0x61, 0x9a, 0xca, 0x00, 0x00, 0x00, 0x17},
  348. };
  349. static const __u8 initTas5130[] = {
  350. 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x11, 0x00, 0x00, 0x00,
  351. 0x00, 0x00,
  352. 0x00, 0x01, 0x00, 0x69, 0x0c, 0x0a,
  353. 0x28, 0x1e, 0x60, COMP, MCK_INIT,
  354. 0x18, 0x10, 0x04, 0x03, 0x11, 0x0c
  355. };
  356. static const __u8 tas5130_sensor_init[][8] = {
  357. /* {0x30, 0x11, 0x00, 0x40, 0x47, 0x00, 0x00, 0x10},
  358. * shutter 0x47 short exposure? */
  359. {0x30, 0x11, 0x00, 0x40, 0x01, 0x00, 0x00, 0x10},
  360. /* shutter 0x01 long exposure */
  361. {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10},
  362. };
  363. /* get one byte in gspca_dev->usb_buf */
  364. static void reg_r(struct gspca_dev *gspca_dev,
  365. __u16 value)
  366. {
  367. usb_control_msg(gspca_dev->dev,
  368. usb_rcvctrlpipe(gspca_dev->dev, 0),
  369. 0, /* request */
  370. USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
  371. value,
  372. 0, /* index */
  373. gspca_dev->usb_buf, 1,
  374. 500);
  375. }
  376. static void reg_w(struct gspca_dev *gspca_dev,
  377. __u16 value,
  378. const __u8 *buffer,
  379. int len)
  380. {
  381. #ifdef CONFIG_VIDEO_ADV_DEBUG
  382. if (len > sizeof gspca_dev->usb_buf) {
  383. PDEBUG(D_ERR|D_PACK, "reg_w: buffer overflow");
  384. return;
  385. }
  386. #endif
  387. memcpy(gspca_dev->usb_buf, buffer, len);
  388. usb_control_msg(gspca_dev->dev,
  389. usb_sndctrlpipe(gspca_dev->dev, 0),
  390. 0x08, /* request */
  391. USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
  392. value,
  393. 0, /* index */
  394. gspca_dev->usb_buf, len,
  395. 500);
  396. }
  397. static void reg_w_big(struct gspca_dev *gspca_dev,
  398. __u16 value,
  399. const __u8 *buffer,
  400. int len)
  401. {
  402. __u8 *tmpbuf;
  403. tmpbuf = kmalloc(len, GFP_KERNEL);
  404. memcpy(tmpbuf, buffer, len);
  405. usb_control_msg(gspca_dev->dev,
  406. usb_sndctrlpipe(gspca_dev->dev, 0),
  407. 0x08, /* request */
  408. USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
  409. value,
  410. 0, /* index */
  411. tmpbuf, len,
  412. 500);
  413. kfree(tmpbuf);
  414. }
  415. static int i2c_w(struct gspca_dev *gspca_dev, const __u8 *buffer)
  416. {
  417. int retry = 60;
  418. /* is i2c ready */
  419. reg_w(gspca_dev, 0x08, buffer, 8);
  420. while (retry--) {
  421. msleep(10);
  422. reg_r(gspca_dev, 0x08);
  423. if (gspca_dev->usb_buf[0] == 4)
  424. return 0;
  425. }
  426. return -1;
  427. }
  428. static void i2c_w_vector(struct gspca_dev *gspca_dev,
  429. const __u8 buffer[][8], int len)
  430. {
  431. for (;;) {
  432. reg_w(gspca_dev, 0x08, *buffer, 8);
  433. len -= 8;
  434. if (len <= 0)
  435. break;
  436. buffer++;
  437. }
  438. }
  439. static void setbrightness(struct gspca_dev *gspca_dev)
  440. {
  441. struct sd *sd = (struct sd *) gspca_dev;
  442. __u8 value;
  443. switch (sd->sensor) {
  444. case SENSOR_OV6650: {
  445. __u8 i2cOV6650[] =
  446. {0xa0, 0x60, 0x06, 0x11, 0x99, 0x04, 0x94, 0x15};
  447. i2cOV6650[3] = sd->brightness;
  448. if (i2c_w(gspca_dev, i2cOV6650) < 0)
  449. goto err;
  450. break;
  451. }
  452. case SENSOR_OV7630: {
  453. __u8 i2cOV[] =
  454. {0xa0, 0x21, 0x06, 0x36, 0xbd, 0x06, 0xf6, 0x16};
  455. /* change reg 0x06 */
  456. i2cOV[3] = sd->brightness;
  457. if (i2c_w(gspca_dev, i2cOV) < 0)
  458. goto err;
  459. break;
  460. }
  461. case SENSOR_PAS106: {
  462. __u8 i2c1[] =
  463. {0xa1, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14};
  464. i2c1[3] = sd->brightness >> 3;
  465. i2c1[2] = 0x0e;
  466. if (i2c_w(gspca_dev, i2c1) < 0)
  467. goto err;
  468. i2c1[3] = 0x01;
  469. i2c1[2] = 0x13;
  470. if (i2c_w(gspca_dev, i2c1) < 0)
  471. goto err;
  472. break;
  473. }
  474. case SENSOR_PAS202: {
  475. /* __u8 i2cpexpo1[] =
  476. {0xb0, 0x40, 0x04, 0x07, 0x2a, 0x00, 0x63, 0x16}; */
  477. __u8 i2cpexpo[] =
  478. {0xb0, 0x40, 0x0e, 0x01, 0xab, 0x00, 0x63, 0x16};
  479. __u8 i2cp202[] =
  480. {0xa0, 0x40, 0x10, 0x0e, 0x31, 0x00, 0x63, 0x15};
  481. static __u8 i2cpdoit[] =
  482. {0xa0, 0x40, 0x11, 0x01, 0x31, 0x00, 0x63, 0x16};
  483. /* change reg 0x10 */
  484. i2cpexpo[4] = 0xff - sd->brightness;
  485. /* if(i2c_w(gspca_dev,i2cpexpo1) < 0)
  486. goto err; */
  487. /* if(i2c_w(gspca_dev,i2cpdoit) < 0)
  488. goto err; */
  489. if (i2c_w(gspca_dev, i2cpexpo) < 0)
  490. goto err;
  491. if (i2c_w(gspca_dev, i2cpdoit) < 0)
  492. goto err;
  493. i2cp202[3] = sd->brightness >> 3;
  494. if (i2c_w(gspca_dev, i2cp202) < 0)
  495. goto err;
  496. if (i2c_w(gspca_dev, i2cpdoit) < 0)
  497. goto err;
  498. break;
  499. }
  500. case SENSOR_TAS5130CXX: {
  501. __u8 i2c[] =
  502. {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10};
  503. value = 0xff - sd->brightness;
  504. i2c[4] = value;
  505. PDEBUG(D_CONF, "brightness %d : %d", value, i2c[4]);
  506. if (i2c_w(gspca_dev, i2c) < 0)
  507. goto err;
  508. break;
  509. }
  510. case SENSOR_TAS5110:
  511. /* FIXME figure out howto control brightness on TAS5110 */
  512. break;
  513. }
  514. return;
  515. err:
  516. PDEBUG(D_ERR, "i2c error brightness");
  517. }
  518. static void setsensorgain(struct gspca_dev *gspca_dev)
  519. {
  520. struct sd *sd = (struct sd *) gspca_dev;
  521. unsigned short gain;
  522. gain = (sd->gain + 1) >> 1;
  523. if (gain > 255)
  524. gain = 255;
  525. switch (sd->sensor) {
  526. case SENSOR_TAS5110: {
  527. __u8 i2c[] =
  528. {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10};
  529. i2c[4] = 255 - gain;
  530. if (i2c_w(gspca_dev, i2c) < 0)
  531. goto err;
  532. break;
  533. }
  534. case SENSOR_OV6650: {
  535. __u8 i2c[] = {0xa0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10};
  536. i2c[3] = gain;
  537. if (i2c_w(gspca_dev, i2c) < 0)
  538. goto err;
  539. break;
  540. }
  541. }
  542. return;
  543. err:
  544. PDEBUG(D_ERR, "i2c error gain");
  545. }
  546. static void setgain(struct gspca_dev *gspca_dev)
  547. {
  548. struct sd *sd = (struct sd *) gspca_dev;
  549. __u8 gain;
  550. __u8 rgb_value;
  551. gain = sd->gain >> 5;
  552. /* red and blue gain */
  553. rgb_value = gain << 4 | gain;
  554. reg_w(gspca_dev, 0x10, &rgb_value, 1);
  555. /* green gain */
  556. rgb_value = gain;
  557. reg_w(gspca_dev, 0x11, &rgb_value, 1);
  558. if (sd->sensor_has_gain)
  559. setsensorgain(gspca_dev);
  560. }
  561. static void setexposure(struct gspca_dev *gspca_dev)
  562. {
  563. struct sd *sd = (struct sd *) gspca_dev;
  564. /* translate 0 - 255 to a number of fps in a 30 - 1 scale */
  565. int fps = 30 - sd->exposure * 29 / 511;
  566. switch (sd->sensor) {
  567. case SENSOR_TAS5110: {
  568. __u8 reg;
  569. /* register 19's high nibble contains the sn9c10x clock divider
  570. The high nibble configures the no fps according to the
  571. formula: 60 / high_nibble. With a maximum of 30 fps */
  572. reg = 60 / fps;
  573. if (reg > 15)
  574. reg = 15;
  575. reg = (reg << 4) | 0x0b;
  576. reg_w(gspca_dev, 0x19, &reg, 1);
  577. break;
  578. }
  579. case SENSOR_OV6650: {
  580. __u8 i2c[] = {0xa0, 0x60, 0x11, 0xc0, 0x00, 0x00, 0x00, 0x10};
  581. i2c[3] = 30 / fps - 1;
  582. if (i2c[3] > 15)
  583. i2c[3] = 15;
  584. i2c[3] |= 0xc0;
  585. if (i2c_w(gspca_dev, i2c) < 0)
  586. PDEBUG(D_ERR, "i2c error exposure");
  587. break;
  588. }
  589. }
  590. }
  591. static void do_autogain(struct gspca_dev *gspca_dev)
  592. {
  593. struct sd *sd = (struct sd *) gspca_dev;
  594. int avg_lum = atomic_read(&sd->avg_lum);
  595. if (avg_lum == -1)
  596. return;
  597. if (sd->autogain_ignore_frames > 0)
  598. sd->autogain_ignore_frames--;
  599. else if (gspca_auto_gain_n_exposure(gspca_dev, avg_lum,
  600. sd->brightness * DESIRED_AVG_LUM / 127,
  601. AUTOGAIN_DEADZONE, GAIN_KNEE, EXPOSURE_KNEE))
  602. sd->autogain_ignore_frames = AUTOGAIN_IGNORE_FRAMES;
  603. }
  604. /* this function is called at probe time */
  605. static int sd_config(struct gspca_dev *gspca_dev,
  606. const struct usb_device_id *id)
  607. {
  608. struct sd *sd = (struct sd *) gspca_dev;
  609. struct cam *cam;
  610. __u16 product;
  611. int sif = 0;
  612. /* nctrls depends upon the sensor, so we use a per cam copy */
  613. memcpy(&sd->sd_desc, gspca_dev->sd_desc, sizeof(struct sd_desc));
  614. gspca_dev->sd_desc = &sd->sd_desc;
  615. sd->fr_h_sz = 12; /* default size of the frame header */
  616. sd->sd_desc.nctrls = 2; /* default nb of ctrls */
  617. product = id->idProduct;
  618. /* switch (id->idVendor) { */
  619. /* case 0x0c45: * Sonix */
  620. switch (product) {
  621. case 0x6001: /* SN9C102 */
  622. case 0x6005: /* SN9C101 */
  623. case 0x6007: /* SN9C101 */
  624. sd->sensor = SENSOR_TAS5110;
  625. sd->sensor_has_gain = 1;
  626. sd->sd_desc.nctrls = 4;
  627. sd->sd_desc.dq_callback = do_autogain;
  628. sif = 1;
  629. break;
  630. case 0x6009: /* SN9C101 */
  631. case 0x600d: /* SN9C101 */
  632. case 0x6029: /* SN9C101 */
  633. sd->sensor = SENSOR_PAS106;
  634. sif = 1;
  635. break;
  636. case 0x6011: /* SN9C101 - SN9C101G */
  637. sd->sensor = SENSOR_OV6650;
  638. sd->sensor_has_gain = 1;
  639. sd->sd_desc.nctrls = 4;
  640. sd->sd_desc.dq_callback = do_autogain;
  641. sif = 1;
  642. break;
  643. case 0x6019: /* SN9C101 */
  644. case 0x602c: /* SN9C102 */
  645. case 0x602e: /* SN9C102 */
  646. sd->sensor = SENSOR_OV7630;
  647. break;
  648. case 0x60b0: /* SN9C103 */
  649. sd->sensor = SENSOR_OV7630_3;
  650. sd->fr_h_sz = 18; /* size of frame header */
  651. break;
  652. case 0x6024: /* SN9C102 */
  653. case 0x6025: /* SN9C102 */
  654. sd->sensor = SENSOR_TAS5130CXX;
  655. break;
  656. case 0x6028: /* SN9C102 */
  657. sd->sensor = SENSOR_PAS202;
  658. break;
  659. case 0x602d: /* SN9C102 */
  660. sd->sensor = SENSOR_HV7131R;
  661. break;
  662. case 0x60af: /* SN9C103 */
  663. sd->sensor = SENSOR_PAS202;
  664. sd->fr_h_sz = 18; /* size of frame header (?) */
  665. break;
  666. }
  667. /* break; */
  668. /* } */
  669. cam = &gspca_dev->cam;
  670. cam->dev_name = (char *) id->driver_info;
  671. cam->epaddr = 0x01;
  672. if (!sif) {
  673. cam->cam_mode = vga_mode;
  674. cam->nmodes = ARRAY_SIZE(vga_mode);
  675. } else {
  676. cam->cam_mode = sif_mode;
  677. cam->nmodes = ARRAY_SIZE(sif_mode);
  678. }
  679. sd->brightness = BRIGHTNESS_DEF;
  680. sd->gain = GAIN_DEF;
  681. sd->exposure = EXPOSURE_DEF;
  682. sd->autogain = AUTOGAIN_DEF;
  683. if (sd->sensor == SENSOR_OV7630_3) /* jfm: from win trace */
  684. reg_w(gspca_dev, 0x01, probe_ov7630, sizeof probe_ov7630);
  685. return 0;
  686. }
  687. /* this function is called at open time */
  688. static int sd_open(struct gspca_dev *gspca_dev)
  689. {
  690. reg_r(gspca_dev, 0x00);
  691. if (gspca_dev->usb_buf[0] != 0x10)
  692. return -ENODEV;
  693. return 0;
  694. }
  695. static void pas106_i2cinit(struct gspca_dev *gspca_dev)
  696. {
  697. int i;
  698. const __u8 *data;
  699. __u8 i2c1[] = { 0xa1, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14 };
  700. i = ARRAY_SIZE(pas106_data);
  701. data = pas106_data[0];
  702. while (--i >= 0) {
  703. memcpy(&i2c1[2], data, 2);
  704. /* copy 2 bytes from the template */
  705. if (i2c_w(gspca_dev, i2c1) < 0)
  706. PDEBUG(D_ERR, "i2c error pas106");
  707. data += 2;
  708. }
  709. }
  710. /* -- start the camera -- */
  711. static void sd_start(struct gspca_dev *gspca_dev)
  712. {
  713. struct sd *sd = (struct sd *) gspca_dev;
  714. int mode, l;
  715. const __u8 *sn9c10x;
  716. __u8 reg01, reg17;
  717. __u8 reg17_19[3];
  718. static const __u8 reg15[2] = { 0x28, 0x1e };
  719. mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
  720. switch (sd->sensor) {
  721. case SENSOR_HV7131R:
  722. sn9c10x = initHv7131;
  723. reg17_19[0] = 0x60;
  724. reg17_19[1] = (mode << 4) | 0x8a;
  725. reg17_19[2] = 0x20;
  726. break;
  727. case SENSOR_OV6650:
  728. sn9c10x = initOv6650;
  729. reg17_19[0] = 0x68;
  730. reg17_19[1] = (mode << 4) | 0x8b;
  731. reg17_19[2] = 0x20;
  732. break;
  733. case SENSOR_OV7630:
  734. sn9c10x = initOv7630;
  735. reg17_19[0] = 0x68;
  736. reg17_19[1] = (mode << 4) | COMP2;
  737. reg17_19[2] = MCK_INIT1;
  738. break;
  739. case SENSOR_OV7630_3:
  740. sn9c10x = initOv7630_3;
  741. reg17_19[0] = 0x68;
  742. reg17_19[1] = (mode << 4) | COMP2;
  743. reg17_19[2] = MCK_INIT1;
  744. break;
  745. case SENSOR_PAS106:
  746. sn9c10x = initPas106;
  747. reg17_19[0] = 0x24; /* 0x28 */
  748. reg17_19[1] = (mode << 4) | COMP1;
  749. reg17_19[2] = MCK_INIT1;
  750. break;
  751. case SENSOR_PAS202:
  752. sn9c10x = initPas202;
  753. reg17_19[0] = mode ? 0x24 : 0x20;
  754. reg17_19[1] = (mode << 4) | 0x89;
  755. reg17_19[2] = 0x20;
  756. break;
  757. case SENSOR_TAS5110:
  758. sn9c10x = initTas5110;
  759. reg17_19[0] = 0x60;
  760. reg17_19[1] = (mode << 4) | 0x86;
  761. reg17_19[2] = 0x2b; /* 0xf3; */
  762. break;
  763. default:
  764. /* case SENSOR_TAS5130CXX: */
  765. sn9c10x = initTas5130;
  766. reg17_19[0] = 0x60;
  767. reg17_19[1] = (mode << 4) | COMP;
  768. reg17_19[2] = mode ? 0x23 : 0x43;
  769. break;
  770. }
  771. switch (sd->sensor) {
  772. case SENSOR_OV7630:
  773. reg01 = 0x06;
  774. reg17 = 0x29;
  775. l = 0x10;
  776. break;
  777. case SENSOR_OV7630_3:
  778. reg01 = 0x44;
  779. reg17 = 0x68;
  780. l = sizeof initOv7630_3;
  781. break;
  782. default:
  783. reg01 = sn9c10x[0];
  784. reg17 = sn9c10x[0x17 - 1];
  785. l = 0x1f;
  786. break;
  787. }
  788. /* reg 0x01 bit 2 video transfert on */
  789. reg_w(gspca_dev, 0x01, &reg01, 1);
  790. /* reg 0x17 SensorClk enable inv Clk 0x60 */
  791. reg_w(gspca_dev, 0x17, &reg17, 1);
  792. /*fixme: for ov7630 102
  793. reg_w(gspca_dev, 0x01, {0x06, sn9c10x[1]}, 2); */
  794. /* Set the registers from the template */
  795. reg_w_big(gspca_dev, 0x01, sn9c10x, l);
  796. switch (sd->sensor) {
  797. case SENSOR_HV7131R:
  798. i2c_w_vector(gspca_dev, hv7131_sensor_init,
  799. sizeof hv7131_sensor_init);
  800. break;
  801. case SENSOR_OV6650:
  802. i2c_w_vector(gspca_dev, ov6650_sensor_init,
  803. sizeof ov6650_sensor_init);
  804. break;
  805. case SENSOR_OV7630:
  806. i2c_w_vector(gspca_dev, ov7630_sensor_init_com,
  807. sizeof ov7630_sensor_init_com);
  808. msleep(200);
  809. i2c_w_vector(gspca_dev, ov7630_sensor_init,
  810. sizeof ov7630_sensor_init);
  811. break;
  812. case SENSOR_OV7630_3:
  813. i2c_w_vector(gspca_dev, ov7630_sensor_init_com,
  814. sizeof ov7630_sensor_init_com);
  815. msleep(200);
  816. i2c_w_vector(gspca_dev, ov7630_sensor_init_3,
  817. sizeof ov7630_sensor_init_3);
  818. break;
  819. case SENSOR_PAS106:
  820. pas106_i2cinit(gspca_dev);
  821. break;
  822. case SENSOR_PAS202:
  823. i2c_w_vector(gspca_dev, pas202_sensor_init,
  824. sizeof pas202_sensor_init);
  825. break;
  826. case SENSOR_TAS5110:
  827. i2c_w_vector(gspca_dev, tas5110_sensor_init,
  828. sizeof tas5110_sensor_init);
  829. break;
  830. default:
  831. /* case SENSOR_TAS5130CXX: */
  832. i2c_w_vector(gspca_dev, tas5130_sensor_init,
  833. sizeof tas5130_sensor_init);
  834. break;
  835. }
  836. /* H_size V_size 0x28, 0x1e maybe 640x480 */
  837. reg_w(gspca_dev, 0x15, reg15, 2);
  838. /* compression register */
  839. reg_w(gspca_dev, 0x18, &reg17_19[1], 1);
  840. if (sd->sensor != SENSOR_OV7630_3) {
  841. /* H_start */
  842. reg_w(gspca_dev, 0x12, &sn9c10x[0x12 - 1], 1);
  843. /* V_START */
  844. reg_w(gspca_dev, 0x13, &sn9c10x[0x13 - 1], 1);
  845. }
  846. /* reset 0x17 SensorClk enable inv Clk 0x60 */
  847. /*fixme: ov7630 [17]=68 8f (+20 if 102)*/
  848. reg_w(gspca_dev, 0x17, &reg17_19[0], 1);
  849. /*MCKSIZE ->3 */ /*fixme: not ov7630*/
  850. if (sd->sensor != SENSOR_OV7630_3)
  851. reg_w(gspca_dev, 0x19, &reg17_19[2], 1);
  852. /* AE_STRX AE_STRY AE_ENDX AE_ENDY */
  853. reg_w(gspca_dev, 0x1c, &sn9c10x[0x1c - 1], 4);
  854. /* Enable video transfert */
  855. reg_w(gspca_dev, 0x01, &sn9c10x[0], 1);
  856. /* Compression */
  857. reg_w(gspca_dev, 0x18, &reg17_19[1], 2);
  858. msleep(20);
  859. setgain(gspca_dev);
  860. setbrightness(gspca_dev);
  861. setexposure(gspca_dev);
  862. sd->autogain_ignore_frames = 0;
  863. atomic_set(&sd->avg_lum, -1);
  864. }
  865. static void sd_stopN(struct gspca_dev *gspca_dev)
  866. {
  867. __u8 ByteSend;
  868. ByteSend = 0x09; /* 0X00 */
  869. reg_w(gspca_dev, 0x01, &ByteSend, 1);
  870. }
  871. static void sd_stop0(struct gspca_dev *gspca_dev)
  872. {
  873. }
  874. static void sd_close(struct gspca_dev *gspca_dev)
  875. {
  876. }
  877. static void sd_pkt_scan(struct gspca_dev *gspca_dev,
  878. struct gspca_frame *frame, /* target */
  879. unsigned char *data, /* isoc packet */
  880. int len) /* iso packet length */
  881. {
  882. int i;
  883. struct sd *sd = (struct sd *) gspca_dev;
  884. if (len > 6 && len < 24) {
  885. for (i = 0; i < len - 6; i++) {
  886. if (data[0 + i] == 0xff
  887. && data[1 + i] == 0xff
  888. && data[2 + i] == 0x00
  889. && data[3 + i] == 0xc4
  890. && data[4 + i] == 0xc4
  891. && data[5 + i] == 0x96) { /* start of frame */
  892. frame = gspca_frame_add(gspca_dev, LAST_PACKET,
  893. frame, data, 0);
  894. if (i < (len - 10)) {
  895. atomic_set(&sd->avg_lum, data[i + 8] +
  896. (data[i + 9] << 8));
  897. } else {
  898. atomic_set(&sd->avg_lum, -1);
  899. #ifdef CONFIG_VIDEO_ADV_DEBUG
  900. PDEBUG(D_STREAM, "packet too short to "
  901. "get avg brightness");
  902. #endif
  903. }
  904. data += i + sd->fr_h_sz;
  905. len -= i + sd->fr_h_sz;
  906. gspca_frame_add(gspca_dev, FIRST_PACKET,
  907. frame, data, len);
  908. return;
  909. }
  910. }
  911. }
  912. gspca_frame_add(gspca_dev, INTER_PACKET,
  913. frame, data, len);
  914. }
  915. static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
  916. {
  917. struct sd *sd = (struct sd *) gspca_dev;
  918. sd->brightness = val;
  919. if (gspca_dev->streaming)
  920. setbrightness(gspca_dev);
  921. return 0;
  922. }
  923. static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
  924. {
  925. struct sd *sd = (struct sd *) gspca_dev;
  926. *val = sd->brightness;
  927. return 0;
  928. }
  929. static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val)
  930. {
  931. struct sd *sd = (struct sd *) gspca_dev;
  932. sd->gain = val;
  933. if (gspca_dev->streaming)
  934. setgain(gspca_dev);
  935. return 0;
  936. }
  937. static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
  938. {
  939. struct sd *sd = (struct sd *) gspca_dev;
  940. *val = sd->gain;
  941. return 0;
  942. }
  943. static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val)
  944. {
  945. struct sd *sd = (struct sd *) gspca_dev;
  946. sd->exposure = val;
  947. if (gspca_dev->streaming)
  948. setexposure(gspca_dev);
  949. return 0;
  950. }
  951. static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val)
  952. {
  953. struct sd *sd = (struct sd *) gspca_dev;
  954. *val = sd->exposure;
  955. return 0;
  956. }
  957. static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
  958. {
  959. struct sd *sd = (struct sd *) gspca_dev;
  960. sd->autogain = val;
  961. /* when switching to autogain set defaults to make sure
  962. we are on a valid point of the autogain gain /
  963. exposure knee graph, and give this change time to
  964. take effect before doing autogain. */
  965. if (sd->autogain) {
  966. sd->exposure = EXPOSURE_DEF;
  967. sd->gain = GAIN_DEF;
  968. if (gspca_dev->streaming) {
  969. sd->autogain_ignore_frames = AUTOGAIN_IGNORE_FRAMES;
  970. setexposure(gspca_dev);
  971. setgain(gspca_dev);
  972. }
  973. }
  974. return 0;
  975. }
  976. static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
  977. {
  978. struct sd *sd = (struct sd *) gspca_dev;
  979. *val = sd->autogain;
  980. return 0;
  981. }
  982. /* sub-driver description */
  983. static const struct sd_desc sd_desc = {
  984. .name = MODULE_NAME,
  985. .ctrls = sd_ctrls,
  986. .nctrls = ARRAY_SIZE(sd_ctrls),
  987. .config = sd_config,
  988. .open = sd_open,
  989. .start = sd_start,
  990. .stopN = sd_stopN,
  991. .stop0 = sd_stop0,
  992. .close = sd_close,
  993. .pkt_scan = sd_pkt_scan,
  994. };
  995. /* -- module initialisation -- */
  996. #define DVNM(name) .driver_info = (kernel_ulong_t) name
  997. static __devinitdata struct usb_device_id device_table[] = {
  998. #ifndef CONFIG_USB_SN9C102
  999. {USB_DEVICE(0x0c45, 0x6001), DVNM("Genius VideoCAM NB")},
  1000. {USB_DEVICE(0x0c45, 0x6005), DVNM("Sweex Tas5110")},
  1001. {USB_DEVICE(0x0c45, 0x6007), DVNM("Sonix sn9c101 + Tas5110D")},
  1002. {USB_DEVICE(0x0c45, 0x6009), DVNM("spcaCam@120")},
  1003. {USB_DEVICE(0x0c45, 0x600d), DVNM("spcaCam@120")},
  1004. {USB_DEVICE(0x0c45, 0x6011), DVNM("MAX Webcam Microdia")},
  1005. {USB_DEVICE(0x0c45, 0x6019), DVNM("Generic Sonix OV7630")},
  1006. {USB_DEVICE(0x0c45, 0x6024), DVNM("Generic Sonix Tas5130c")},
  1007. {USB_DEVICE(0x0c45, 0x6025), DVNM("Xcam Shanga")},
  1008. {USB_DEVICE(0x0c45, 0x6028), DVNM("Sonix Btc Pc380")},
  1009. {USB_DEVICE(0x0c45, 0x6029), DVNM("spcaCam@150")},
  1010. {USB_DEVICE(0x0c45, 0x602c), DVNM("Generic Sonix OV7630")},
  1011. {USB_DEVICE(0x0c45, 0x602d), DVNM("LIC-200 LG")},
  1012. {USB_DEVICE(0x0c45, 0x602e), DVNM("Genius VideoCam Messenger")},
  1013. {USB_DEVICE(0x0c45, 0x60af), DVNM("Trust WB3100P")},
  1014. {USB_DEVICE(0x0c45, 0x60b0), DVNM("Genius VideoCam Look")},
  1015. #endif
  1016. {}
  1017. };
  1018. MODULE_DEVICE_TABLE(usb, device_table);
  1019. /* -- device connect -- */
  1020. static int sd_probe(struct usb_interface *intf,
  1021. const struct usb_device_id *id)
  1022. {
  1023. return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
  1024. THIS_MODULE);
  1025. }
  1026. static struct usb_driver sd_driver = {
  1027. .name = MODULE_NAME,
  1028. .id_table = device_table,
  1029. .probe = sd_probe,
  1030. .disconnect = gspca_disconnect,
  1031. };
  1032. /* -- module insert / remove -- */
  1033. static int __init sd_mod_init(void)
  1034. {
  1035. if (usb_register(&sd_driver) < 0)
  1036. return -1;
  1037. PDEBUG(D_PROBE, "v%s registered", version);
  1038. return 0;
  1039. }
  1040. static void __exit sd_mod_exit(void)
  1041. {
  1042. usb_deregister(&sd_driver);
  1043. PDEBUG(D_PROBE, "deregistered");
  1044. }
  1045. module_init(sd_mod_init);
  1046. module_exit(sd_mod_exit);