spca506.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718
  1. /*
  2. * SPCA506 chip based cameras function
  3. * M Xhaard 15/04/2004 based on different work Mark Taylor and others
  4. * and my own snoopy file on a pv-321c donate by a german compagny
  5. * "Firma Frank Gmbh" from Saarbruecken
  6. *
  7. * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
  8. *
  9. * This program is free software; you can redistribute it and/or modify
  10. * it under the terms of the GNU General Public License as published by
  11. * the Free Software Foundation; either version 2 of the License, or
  12. * any later version.
  13. *
  14. * This program is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU General Public License
  20. * along with this program; if not, write to the Free Software
  21. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  22. */
  23. #define MODULE_NAME "spca506"
  24. #include "gspca.h"
  25. MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
  26. MODULE_DESCRIPTION("GSPCA/SPCA506 USB Camera Driver");
  27. MODULE_LICENSE("GPL");
  28. /* specific webcam descriptor */
  29. struct sd {
  30. struct gspca_dev gspca_dev; /* !! must be the first item */
  31. unsigned char brightness;
  32. unsigned char contrast;
  33. unsigned char colors;
  34. unsigned char hue;
  35. char norme;
  36. char channel;
  37. };
  38. /* V4L2 controls supported by the driver */
  39. static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
  40. static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
  41. static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
  42. static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
  43. static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
  44. static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
  45. static int sd_sethue(struct gspca_dev *gspca_dev, __s32 val);
  46. static int sd_gethue(struct gspca_dev *gspca_dev, __s32 *val);
  47. static const struct ctrl sd_ctrls[] = {
  48. #define SD_BRIGHTNESS 0
  49. {
  50. {
  51. .id = V4L2_CID_BRIGHTNESS,
  52. .type = V4L2_CTRL_TYPE_INTEGER,
  53. .name = "Brightness",
  54. .minimum = 0,
  55. .maximum = 0xff,
  56. .step = 1,
  57. .default_value = 0x80,
  58. },
  59. .set = sd_setbrightness,
  60. .get = sd_getbrightness,
  61. },
  62. #define SD_CONTRAST 1
  63. {
  64. {
  65. .id = V4L2_CID_CONTRAST,
  66. .type = V4L2_CTRL_TYPE_INTEGER,
  67. .name = "Contrast",
  68. .minimum = 0,
  69. .maximum = 0xff,
  70. .step = 1,
  71. .default_value = 0x47,
  72. },
  73. .set = sd_setcontrast,
  74. .get = sd_getcontrast,
  75. },
  76. #define SD_COLOR 2
  77. {
  78. {
  79. .id = V4L2_CID_SATURATION,
  80. .type = V4L2_CTRL_TYPE_INTEGER,
  81. .name = "Saturation",
  82. .minimum = 0,
  83. .maximum = 0xff,
  84. .step = 1,
  85. .default_value = 0x40,
  86. },
  87. .set = sd_setcolors,
  88. .get = sd_getcolors,
  89. },
  90. #define SD_HUE 3
  91. {
  92. {
  93. .id = V4L2_CID_HUE,
  94. .type = V4L2_CTRL_TYPE_INTEGER,
  95. .name = "Hue",
  96. .minimum = 0,
  97. .maximum = 0xff,
  98. .step = 1,
  99. .default_value = 0,
  100. },
  101. .set = sd_sethue,
  102. .get = sd_gethue,
  103. },
  104. };
  105. static const struct v4l2_pix_format vga_mode[] = {
  106. {160, 120, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE,
  107. .bytesperline = 160,
  108. .sizeimage = 160 * 120 * 3 / 2,
  109. .colorspace = V4L2_COLORSPACE_SRGB,
  110. .priv = 5},
  111. {176, 144, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE,
  112. .bytesperline = 176,
  113. .sizeimage = 176 * 144 * 3 / 2,
  114. .colorspace = V4L2_COLORSPACE_SRGB,
  115. .priv = 4},
  116. {320, 240, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE,
  117. .bytesperline = 320,
  118. .sizeimage = 320 * 240 * 3 / 2,
  119. .colorspace = V4L2_COLORSPACE_SRGB,
  120. .priv = 2},
  121. {352, 288, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE,
  122. .bytesperline = 352,
  123. .sizeimage = 352 * 288 * 3 / 2,
  124. .colorspace = V4L2_COLORSPACE_SRGB,
  125. .priv = 1},
  126. {640, 480, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE,
  127. .bytesperline = 640,
  128. .sizeimage = 640 * 480 * 3 / 2,
  129. .colorspace = V4L2_COLORSPACE_SRGB,
  130. .priv = 0},
  131. };
  132. #define SPCA50X_OFFSET_DATA 10
  133. #define SAA7113_bright 0x0a /* defaults 0x80 */
  134. #define SAA7113_contrast 0x0b /* defaults 0x47 */
  135. #define SAA7113_saturation 0x0c /* defaults 0x40 */
  136. #define SAA7113_hue 0x0d /* defaults 0x00 */
  137. #define SAA7113_I2C_BASE_WRITE 0x4a
  138. /* read 'len' bytes to gspca_dev->usb_buf */
  139. static void reg_r(struct gspca_dev *gspca_dev,
  140. __u16 req,
  141. __u16 index,
  142. __u16 length)
  143. {
  144. usb_control_msg(gspca_dev->dev,
  145. usb_rcvctrlpipe(gspca_dev->dev, 0),
  146. req,
  147. USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
  148. 0, /* value */
  149. index, gspca_dev->usb_buf, length,
  150. 500);
  151. }
  152. static void reg_w(struct usb_device *dev,
  153. __u16 req,
  154. __u16 value,
  155. __u16 index)
  156. {
  157. usb_control_msg(dev,
  158. usb_sndctrlpipe(dev, 0),
  159. req,
  160. USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
  161. value, index,
  162. NULL, 0, 500);
  163. }
  164. static void spca506_Initi2c(struct gspca_dev *gspca_dev)
  165. {
  166. reg_w(gspca_dev->dev, 0x07, SAA7113_I2C_BASE_WRITE, 0x0004);
  167. }
  168. static void spca506_WriteI2c(struct gspca_dev *gspca_dev, __u16 valeur,
  169. __u16 reg)
  170. {
  171. int retry = 60;
  172. reg_w(gspca_dev->dev, 0x07, reg, 0x0001);
  173. reg_w(gspca_dev->dev, 0x07, valeur, 0x0000);
  174. while (retry--) {
  175. reg_r(gspca_dev, 0x07, 0x0003, 2);
  176. if ((gspca_dev->usb_buf[0] | gspca_dev->usb_buf[1]) == 0x00)
  177. break;
  178. }
  179. }
  180. static void spca506_SetNormeInput(struct gspca_dev *gspca_dev,
  181. __u16 norme,
  182. __u16 channel)
  183. {
  184. struct sd *sd = (struct sd *) gspca_dev;
  185. /* fixme: check if channel == 0..3 and 6..9 (8 values) */
  186. __u8 setbit0 = 0x00;
  187. __u8 setbit1 = 0x00;
  188. __u8 videomask = 0x00;
  189. PDEBUG(D_STREAM, "** Open Set Norme **");
  190. spca506_Initi2c(gspca_dev);
  191. /* NTSC bit0 -> 1(525 l) PAL SECAM bit0 -> 0 (625 l) */
  192. /* Composite channel bit1 -> 1 S-video bit 1 -> 0 */
  193. /* and exclude SAA7113 reserved channel set default 0 otherwise */
  194. if (norme & V4L2_STD_NTSC)
  195. setbit0 = 0x01;
  196. if (channel == 4 || channel == 5 || channel > 9)
  197. channel = 0;
  198. if (channel < 4)
  199. setbit1 = 0x02;
  200. videomask = (0x48 | setbit0 | setbit1);
  201. reg_w(gspca_dev->dev, 0x08, videomask, 0x0000);
  202. spca506_WriteI2c(gspca_dev, (0xc0 | (channel & 0x0F)), 0x02);
  203. if (norme & V4L2_STD_NTSC)
  204. spca506_WriteI2c(gspca_dev, 0x33, 0x0e);
  205. /* Chrominance Control NTSC N */
  206. else if (norme & V4L2_STD_SECAM)
  207. spca506_WriteI2c(gspca_dev, 0x53, 0x0e);
  208. /* Chrominance Control SECAM */
  209. else
  210. spca506_WriteI2c(gspca_dev, 0x03, 0x0e);
  211. /* Chrominance Control PAL BGHIV */
  212. sd->norme = norme;
  213. sd->channel = channel;
  214. PDEBUG(D_STREAM, "Set Video Byte to 0x%2x", videomask);
  215. PDEBUG(D_STREAM, "Set Norme: %08x Channel %d", norme, channel);
  216. }
  217. static void spca506_GetNormeInput(struct gspca_dev *gspca_dev,
  218. __u16 *norme, __u16 *channel)
  219. {
  220. struct sd *sd = (struct sd *) gspca_dev;
  221. /* Read the register is not so good value change so
  222. we use your own copy in spca50x struct */
  223. *norme = sd->norme;
  224. *channel = sd->channel;
  225. PDEBUG(D_STREAM, "Get Norme: %d Channel %d", *norme, *channel);
  226. }
  227. static void spca506_Setsize(struct gspca_dev *gspca_dev, __u16 code,
  228. __u16 xmult, __u16 ymult)
  229. {
  230. struct usb_device *dev = gspca_dev->dev;
  231. PDEBUG(D_STREAM, "** SetSize **");
  232. reg_w(dev, 0x04, (0x18 | (code & 0x07)), 0x0000);
  233. /* Soft snap 0x40 Hard 0x41 */
  234. reg_w(dev, 0x04, 0x41, 0x0001);
  235. reg_w(dev, 0x04, 0x00, 0x0002);
  236. /* reserved */
  237. reg_w(dev, 0x04, 0x00, 0x0003);
  238. /* reserved */
  239. reg_w(dev, 0x04, 0x00, 0x0004);
  240. /* reserved */
  241. reg_w(dev, 0x04, 0x01, 0x0005);
  242. /* reserced */
  243. reg_w(dev, 0x04, xmult, 0x0006);
  244. /* reserved */
  245. reg_w(dev, 0x04, ymult, 0x0007);
  246. /* compression 1 */
  247. reg_w(dev, 0x04, 0x00, 0x0008);
  248. /* T=64 -> 2 */
  249. reg_w(dev, 0x04, 0x00, 0x0009);
  250. /* threshold2D */
  251. reg_w(dev, 0x04, 0x21, 0x000a);
  252. /* quantization */
  253. reg_w(dev, 0x04, 0x00, 0x000b);
  254. }
  255. /* this function is called at probe time */
  256. static int sd_config(struct gspca_dev *gspca_dev,
  257. const struct usb_device_id *id)
  258. {
  259. struct sd *sd = (struct sd *) gspca_dev;
  260. struct cam *cam;
  261. cam = &gspca_dev->cam;
  262. cam->cam_mode = vga_mode;
  263. cam->nmodes = ARRAY_SIZE(vga_mode);
  264. sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value;
  265. sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value;
  266. sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value;
  267. sd->hue = sd_ctrls[SD_HUE].qctrl.default_value;
  268. return 0;
  269. }
  270. /* this function is called at probe and resume time */
  271. static int sd_init(struct gspca_dev *gspca_dev)
  272. {
  273. struct usb_device *dev = gspca_dev->dev;
  274. reg_w(dev, 0x03, 0x00, 0x0004);
  275. reg_w(dev, 0x03, 0xFF, 0x0003);
  276. reg_w(dev, 0x03, 0x00, 0x0000);
  277. reg_w(dev, 0x03, 0x1c, 0x0001);
  278. reg_w(dev, 0x03, 0x18, 0x0001);
  279. /* Init on PAL and composite input0 */
  280. spca506_SetNormeInput(gspca_dev, 0, 0);
  281. reg_w(dev, 0x03, 0x1c, 0x0001);
  282. reg_w(dev, 0x03, 0x18, 0x0001);
  283. reg_w(dev, 0x05, 0x00, 0x0000);
  284. reg_w(dev, 0x05, 0xef, 0x0001);
  285. reg_w(dev, 0x05, 0x00, 0x00c1);
  286. reg_w(dev, 0x05, 0x00, 0x00c2);
  287. reg_w(dev, 0x06, 0x18, 0x0002);
  288. reg_w(dev, 0x06, 0xf5, 0x0011);
  289. reg_w(dev, 0x06, 0x02, 0x0012);
  290. reg_w(dev, 0x06, 0xfb, 0x0013);
  291. reg_w(dev, 0x06, 0x00, 0x0014);
  292. reg_w(dev, 0x06, 0xa4, 0x0051);
  293. reg_w(dev, 0x06, 0x40, 0x0052);
  294. reg_w(dev, 0x06, 0x71, 0x0053);
  295. reg_w(dev, 0x06, 0x40, 0x0054);
  296. /************************************************/
  297. reg_w(dev, 0x03, 0x00, 0x0004);
  298. reg_w(dev, 0x03, 0x00, 0x0003);
  299. reg_w(dev, 0x03, 0x00, 0x0004);
  300. reg_w(dev, 0x03, 0xFF, 0x0003);
  301. reg_w(dev, 0x02, 0x00, 0x0000);
  302. reg_w(dev, 0x03, 0x60, 0x0000);
  303. reg_w(dev, 0x03, 0x18, 0x0001);
  304. /* for a better reading mx :) */
  305. /*sdca506_WriteI2c(value,register) */
  306. spca506_Initi2c(gspca_dev);
  307. spca506_WriteI2c(gspca_dev, 0x08, 0x01);
  308. spca506_WriteI2c(gspca_dev, 0xc0, 0x02);
  309. /* input composite video */
  310. spca506_WriteI2c(gspca_dev, 0x33, 0x03);
  311. spca506_WriteI2c(gspca_dev, 0x00, 0x04);
  312. spca506_WriteI2c(gspca_dev, 0x00, 0x05);
  313. spca506_WriteI2c(gspca_dev, 0x0d, 0x06);
  314. spca506_WriteI2c(gspca_dev, 0xf0, 0x07);
  315. spca506_WriteI2c(gspca_dev, 0x98, 0x08);
  316. spca506_WriteI2c(gspca_dev, 0x03, 0x09);
  317. spca506_WriteI2c(gspca_dev, 0x80, 0x0a);
  318. spca506_WriteI2c(gspca_dev, 0x47, 0x0b);
  319. spca506_WriteI2c(gspca_dev, 0x48, 0x0c);
  320. spca506_WriteI2c(gspca_dev, 0x00, 0x0d);
  321. spca506_WriteI2c(gspca_dev, 0x03, 0x0e); /* Chroma Pal adjust */
  322. spca506_WriteI2c(gspca_dev, 0x2a, 0x0f);
  323. spca506_WriteI2c(gspca_dev, 0x00, 0x10);
  324. spca506_WriteI2c(gspca_dev, 0x0c, 0x11);
  325. spca506_WriteI2c(gspca_dev, 0xb8, 0x12);
  326. spca506_WriteI2c(gspca_dev, 0x01, 0x13);
  327. spca506_WriteI2c(gspca_dev, 0x00, 0x14);
  328. spca506_WriteI2c(gspca_dev, 0x00, 0x15);
  329. spca506_WriteI2c(gspca_dev, 0x00, 0x16);
  330. spca506_WriteI2c(gspca_dev, 0x00, 0x17);
  331. spca506_WriteI2c(gspca_dev, 0x00, 0x18);
  332. spca506_WriteI2c(gspca_dev, 0x00, 0x19);
  333. spca506_WriteI2c(gspca_dev, 0x00, 0x1a);
  334. spca506_WriteI2c(gspca_dev, 0x00, 0x1b);
  335. spca506_WriteI2c(gspca_dev, 0x00, 0x1c);
  336. spca506_WriteI2c(gspca_dev, 0x00, 0x1d);
  337. spca506_WriteI2c(gspca_dev, 0x00, 0x1e);
  338. spca506_WriteI2c(gspca_dev, 0xa1, 0x1f);
  339. spca506_WriteI2c(gspca_dev, 0x02, 0x40);
  340. spca506_WriteI2c(gspca_dev, 0xff, 0x41);
  341. spca506_WriteI2c(gspca_dev, 0xff, 0x42);
  342. spca506_WriteI2c(gspca_dev, 0xff, 0x43);
  343. spca506_WriteI2c(gspca_dev, 0xff, 0x44);
  344. spca506_WriteI2c(gspca_dev, 0xff, 0x45);
  345. spca506_WriteI2c(gspca_dev, 0xff, 0x46);
  346. spca506_WriteI2c(gspca_dev, 0xff, 0x47);
  347. spca506_WriteI2c(gspca_dev, 0xff, 0x48);
  348. spca506_WriteI2c(gspca_dev, 0xff, 0x49);
  349. spca506_WriteI2c(gspca_dev, 0xff, 0x4a);
  350. spca506_WriteI2c(gspca_dev, 0xff, 0x4b);
  351. spca506_WriteI2c(gspca_dev, 0xff, 0x4c);
  352. spca506_WriteI2c(gspca_dev, 0xff, 0x4d);
  353. spca506_WriteI2c(gspca_dev, 0xff, 0x4e);
  354. spca506_WriteI2c(gspca_dev, 0xff, 0x4f);
  355. spca506_WriteI2c(gspca_dev, 0xff, 0x50);
  356. spca506_WriteI2c(gspca_dev, 0xff, 0x51);
  357. spca506_WriteI2c(gspca_dev, 0xff, 0x52);
  358. spca506_WriteI2c(gspca_dev, 0xff, 0x53);
  359. spca506_WriteI2c(gspca_dev, 0xff, 0x54);
  360. spca506_WriteI2c(gspca_dev, 0xff, 0x55);
  361. spca506_WriteI2c(gspca_dev, 0xff, 0x56);
  362. spca506_WriteI2c(gspca_dev, 0xff, 0x57);
  363. spca506_WriteI2c(gspca_dev, 0x00, 0x58);
  364. spca506_WriteI2c(gspca_dev, 0x54, 0x59);
  365. spca506_WriteI2c(gspca_dev, 0x07, 0x5a);
  366. spca506_WriteI2c(gspca_dev, 0x83, 0x5b);
  367. spca506_WriteI2c(gspca_dev, 0x00, 0x5c);
  368. spca506_WriteI2c(gspca_dev, 0x00, 0x5d);
  369. spca506_WriteI2c(gspca_dev, 0x00, 0x5e);
  370. spca506_WriteI2c(gspca_dev, 0x00, 0x5f);
  371. spca506_WriteI2c(gspca_dev, 0x00, 0x60);
  372. spca506_WriteI2c(gspca_dev, 0x05, 0x61);
  373. spca506_WriteI2c(gspca_dev, 0x9f, 0x62);
  374. PDEBUG(D_STREAM, "** Close Init *");
  375. return 0;
  376. }
  377. static int sd_start(struct gspca_dev *gspca_dev)
  378. {
  379. struct usb_device *dev = gspca_dev->dev;
  380. __u16 norme;
  381. __u16 channel;
  382. /**************************************/
  383. reg_w(dev, 0x03, 0x00, 0x0004);
  384. reg_w(dev, 0x03, 0x00, 0x0003);
  385. reg_w(dev, 0x03, 0x00, 0x0004);
  386. reg_w(dev, 0x03, 0xFF, 0x0003);
  387. reg_w(dev, 0x02, 0x00, 0x0000);
  388. reg_w(dev, 0x03, 0x60, 0x0000);
  389. reg_w(dev, 0x03, 0x18, 0x0001);
  390. /*sdca506_WriteI2c(value,register) */
  391. spca506_Initi2c(gspca_dev);
  392. spca506_WriteI2c(gspca_dev, 0x08, 0x01); /* Increment Delay */
  393. /* spca506_WriteI2c(gspca_dev, 0xc0, 0x02); * Analog Input Control 1 */
  394. spca506_WriteI2c(gspca_dev, 0x33, 0x03);
  395. /* Analog Input Control 2 */
  396. spca506_WriteI2c(gspca_dev, 0x00, 0x04);
  397. /* Analog Input Control 3 */
  398. spca506_WriteI2c(gspca_dev, 0x00, 0x05);
  399. /* Analog Input Control 4 */
  400. spca506_WriteI2c(gspca_dev, 0x0d, 0x06);
  401. /* Horizontal Sync Start 0xe9-0x0d */
  402. spca506_WriteI2c(gspca_dev, 0xf0, 0x07);
  403. /* Horizontal Sync Stop 0x0d-0xf0 */
  404. spca506_WriteI2c(gspca_dev, 0x98, 0x08); /* Sync Control */
  405. /* Defaults value */
  406. spca506_WriteI2c(gspca_dev, 0x03, 0x09); /* Luminance Control */
  407. spca506_WriteI2c(gspca_dev, 0x80, 0x0a);
  408. /* Luminance Brightness */
  409. spca506_WriteI2c(gspca_dev, 0x47, 0x0b); /* Luminance Contrast */
  410. spca506_WriteI2c(gspca_dev, 0x48, 0x0c);
  411. /* Chrominance Saturation */
  412. spca506_WriteI2c(gspca_dev, 0x00, 0x0d);
  413. /* Chrominance Hue Control */
  414. spca506_WriteI2c(gspca_dev, 0x2a, 0x0f);
  415. /* Chrominance Gain Control */
  416. /**************************************/
  417. spca506_WriteI2c(gspca_dev, 0x00, 0x10);
  418. /* Format/Delay Control */
  419. spca506_WriteI2c(gspca_dev, 0x0c, 0x11); /* Output Control 1 */
  420. spca506_WriteI2c(gspca_dev, 0xb8, 0x12); /* Output Control 2 */
  421. spca506_WriteI2c(gspca_dev, 0x01, 0x13); /* Output Control 3 */
  422. spca506_WriteI2c(gspca_dev, 0x00, 0x14); /* reserved */
  423. spca506_WriteI2c(gspca_dev, 0x00, 0x15); /* VGATE START */
  424. spca506_WriteI2c(gspca_dev, 0x00, 0x16); /* VGATE STOP */
  425. spca506_WriteI2c(gspca_dev, 0x00, 0x17); /* VGATE Control (MSB) */
  426. spca506_WriteI2c(gspca_dev, 0x00, 0x18);
  427. spca506_WriteI2c(gspca_dev, 0x00, 0x19);
  428. spca506_WriteI2c(gspca_dev, 0x00, 0x1a);
  429. spca506_WriteI2c(gspca_dev, 0x00, 0x1b);
  430. spca506_WriteI2c(gspca_dev, 0x00, 0x1c);
  431. spca506_WriteI2c(gspca_dev, 0x00, 0x1d);
  432. spca506_WriteI2c(gspca_dev, 0x00, 0x1e);
  433. spca506_WriteI2c(gspca_dev, 0xa1, 0x1f);
  434. spca506_WriteI2c(gspca_dev, 0x02, 0x40);
  435. spca506_WriteI2c(gspca_dev, 0xff, 0x41);
  436. spca506_WriteI2c(gspca_dev, 0xff, 0x42);
  437. spca506_WriteI2c(gspca_dev, 0xff, 0x43);
  438. spca506_WriteI2c(gspca_dev, 0xff, 0x44);
  439. spca506_WriteI2c(gspca_dev, 0xff, 0x45);
  440. spca506_WriteI2c(gspca_dev, 0xff, 0x46);
  441. spca506_WriteI2c(gspca_dev, 0xff, 0x47);
  442. spca506_WriteI2c(gspca_dev, 0xff, 0x48);
  443. spca506_WriteI2c(gspca_dev, 0xff, 0x49);
  444. spca506_WriteI2c(gspca_dev, 0xff, 0x4a);
  445. spca506_WriteI2c(gspca_dev, 0xff, 0x4b);
  446. spca506_WriteI2c(gspca_dev, 0xff, 0x4c);
  447. spca506_WriteI2c(gspca_dev, 0xff, 0x4d);
  448. spca506_WriteI2c(gspca_dev, 0xff, 0x4e);
  449. spca506_WriteI2c(gspca_dev, 0xff, 0x4f);
  450. spca506_WriteI2c(gspca_dev, 0xff, 0x50);
  451. spca506_WriteI2c(gspca_dev, 0xff, 0x51);
  452. spca506_WriteI2c(gspca_dev, 0xff, 0x52);
  453. spca506_WriteI2c(gspca_dev, 0xff, 0x53);
  454. spca506_WriteI2c(gspca_dev, 0xff, 0x54);
  455. spca506_WriteI2c(gspca_dev, 0xff, 0x55);
  456. spca506_WriteI2c(gspca_dev, 0xff, 0x56);
  457. spca506_WriteI2c(gspca_dev, 0xff, 0x57);
  458. spca506_WriteI2c(gspca_dev, 0x00, 0x58);
  459. spca506_WriteI2c(gspca_dev, 0x54, 0x59);
  460. spca506_WriteI2c(gspca_dev, 0x07, 0x5a);
  461. spca506_WriteI2c(gspca_dev, 0x83, 0x5b);
  462. spca506_WriteI2c(gspca_dev, 0x00, 0x5c);
  463. spca506_WriteI2c(gspca_dev, 0x00, 0x5d);
  464. spca506_WriteI2c(gspca_dev, 0x00, 0x5e);
  465. spca506_WriteI2c(gspca_dev, 0x00, 0x5f);
  466. spca506_WriteI2c(gspca_dev, 0x00, 0x60);
  467. spca506_WriteI2c(gspca_dev, 0x05, 0x61);
  468. spca506_WriteI2c(gspca_dev, 0x9f, 0x62);
  469. /**************************************/
  470. reg_w(dev, 0x05, 0x00, 0x0003);
  471. reg_w(dev, 0x05, 0x00, 0x0004);
  472. reg_w(dev, 0x03, 0x10, 0x0001);
  473. reg_w(dev, 0x03, 0x78, 0x0000);
  474. switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) {
  475. case 0:
  476. spca506_Setsize(gspca_dev, 0, 0x10, 0x10);
  477. break;
  478. case 1:
  479. spca506_Setsize(gspca_dev, 1, 0x1a, 0x1a);
  480. break;
  481. case 2:
  482. spca506_Setsize(gspca_dev, 2, 0x1c, 0x1c);
  483. break;
  484. case 4:
  485. spca506_Setsize(gspca_dev, 4, 0x34, 0x34);
  486. break;
  487. default:
  488. /* case 5: */
  489. spca506_Setsize(gspca_dev, 5, 0x40, 0x40);
  490. break;
  491. }
  492. /* compress setting and size */
  493. /* set i2c luma */
  494. reg_w(dev, 0x02, 0x01, 0x0000);
  495. reg_w(dev, 0x03, 0x12, 0x0000);
  496. reg_r(gspca_dev, 0x04, 0x0001, 2);
  497. PDEBUG(D_STREAM, "webcam started");
  498. spca506_GetNormeInput(gspca_dev, &norme, &channel);
  499. spca506_SetNormeInput(gspca_dev, norme, channel);
  500. return 0;
  501. }
  502. static void sd_stopN(struct gspca_dev *gspca_dev)
  503. {
  504. struct usb_device *dev = gspca_dev->dev;
  505. reg_w(dev, 0x02, 0x00, 0x0000);
  506. reg_w(dev, 0x03, 0x00, 0x0004);
  507. reg_w(dev, 0x03, 0x00, 0x0003);
  508. }
  509. static void sd_pkt_scan(struct gspca_dev *gspca_dev,
  510. u8 *data, /* isoc packet */
  511. int len) /* iso packet length */
  512. {
  513. switch (data[0]) {
  514. case 0: /* start of frame */
  515. gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
  516. data += SPCA50X_OFFSET_DATA;
  517. len -= SPCA50X_OFFSET_DATA;
  518. gspca_frame_add(gspca_dev, FIRST_PACKET, data, len);
  519. break;
  520. case 0xff: /* drop */
  521. /* gspca_dev->last_packet_type = DISCARD_PACKET; */
  522. break;
  523. default:
  524. data += 1;
  525. len -= 1;
  526. gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
  527. break;
  528. }
  529. }
  530. static void setbrightness(struct gspca_dev *gspca_dev)
  531. {
  532. struct sd *sd = (struct sd *) gspca_dev;
  533. spca506_Initi2c(gspca_dev);
  534. spca506_WriteI2c(gspca_dev, sd->brightness, SAA7113_bright);
  535. spca506_WriteI2c(gspca_dev, 0x01, 0x09);
  536. }
  537. static void setcontrast(struct gspca_dev *gspca_dev)
  538. {
  539. struct sd *sd = (struct sd *) gspca_dev;
  540. spca506_Initi2c(gspca_dev);
  541. spca506_WriteI2c(gspca_dev, sd->contrast, SAA7113_contrast);
  542. spca506_WriteI2c(gspca_dev, 0x01, 0x09);
  543. }
  544. static void setcolors(struct gspca_dev *gspca_dev)
  545. {
  546. struct sd *sd = (struct sd *) gspca_dev;
  547. spca506_Initi2c(gspca_dev);
  548. spca506_WriteI2c(gspca_dev, sd->colors, SAA7113_saturation);
  549. spca506_WriteI2c(gspca_dev, 0x01, 0x09);
  550. }
  551. static void sethue(struct gspca_dev *gspca_dev)
  552. {
  553. struct sd *sd = (struct sd *) gspca_dev;
  554. spca506_Initi2c(gspca_dev);
  555. spca506_WriteI2c(gspca_dev, sd->hue, SAA7113_hue);
  556. spca506_WriteI2c(gspca_dev, 0x01, 0x09);
  557. }
  558. static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
  559. {
  560. struct sd *sd = (struct sd *) gspca_dev;
  561. sd->brightness = val;
  562. if (gspca_dev->streaming)
  563. setbrightness(gspca_dev);
  564. return 0;
  565. }
  566. static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
  567. {
  568. struct sd *sd = (struct sd *) gspca_dev;
  569. *val = sd->brightness;
  570. return 0;
  571. }
  572. static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
  573. {
  574. struct sd *sd = (struct sd *) gspca_dev;
  575. sd->contrast = val;
  576. if (gspca_dev->streaming)
  577. setcontrast(gspca_dev);
  578. return 0;
  579. }
  580. static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
  581. {
  582. struct sd *sd = (struct sd *) gspca_dev;
  583. *val = sd->contrast;
  584. return 0;
  585. }
  586. static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
  587. {
  588. struct sd *sd = (struct sd *) gspca_dev;
  589. sd->colors = val;
  590. if (gspca_dev->streaming)
  591. setcolors(gspca_dev);
  592. return 0;
  593. }
  594. static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
  595. {
  596. struct sd *sd = (struct sd *) gspca_dev;
  597. *val = sd->colors;
  598. return 0;
  599. }
  600. static int sd_sethue(struct gspca_dev *gspca_dev, __s32 val)
  601. {
  602. struct sd *sd = (struct sd *) gspca_dev;
  603. sd->hue = val;
  604. if (gspca_dev->streaming)
  605. sethue(gspca_dev);
  606. return 0;
  607. }
  608. static int sd_gethue(struct gspca_dev *gspca_dev, __s32 *val)
  609. {
  610. struct sd *sd = (struct sd *) gspca_dev;
  611. *val = sd->hue;
  612. return 0;
  613. }
  614. /* sub-driver description */
  615. static const struct sd_desc sd_desc = {
  616. .name = MODULE_NAME,
  617. .ctrls = sd_ctrls,
  618. .nctrls = ARRAY_SIZE(sd_ctrls),
  619. .config = sd_config,
  620. .init = sd_init,
  621. .start = sd_start,
  622. .stopN = sd_stopN,
  623. .pkt_scan = sd_pkt_scan,
  624. };
  625. /* -- module initialisation -- */
  626. static const struct usb_device_id device_table[] = {
  627. {USB_DEVICE(0x06e1, 0xa190)},
  628. /*fixme: may be IntelPCCameraPro BRIDGE_SPCA505
  629. {USB_DEVICE(0x0733, 0x0430)}, */
  630. {USB_DEVICE(0x0734, 0x043b)},
  631. {USB_DEVICE(0x99fa, 0x8988)},
  632. {}
  633. };
  634. MODULE_DEVICE_TABLE(usb, device_table);
  635. /* -- device connect -- */
  636. static int __devinit sd_probe(struct usb_interface *intf,
  637. const struct usb_device_id *id)
  638. {
  639. return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
  640. THIS_MODULE);
  641. }
  642. static struct usb_driver sd_driver = {
  643. .name = MODULE_NAME,
  644. .id_table = device_table,
  645. .probe = sd_probe,
  646. .disconnect = gspca_disconnect,
  647. #ifdef CONFIG_PM
  648. .suspend = gspca_suspend,
  649. .resume = gspca_resume,
  650. #endif
  651. };
  652. module_usb_driver(sd_driver);