pac7311.c 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975
  1. /*
  2. * Pixart PAC7311 library
  3. * Copyright (C) 2005 Thomas Kaiser thomas@kaiser-linux.li
  4. *
  5. * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2 of the License, or
  10. * any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  20. */
  21. /* Some documentation about various registers as determined by trial and error.
  22. When the register addresses differ between the 7202 and the 7311 the 2
  23. different addresses are written as 7302addr/7311addr, when one of the 2
  24. addresses is a - sign that register description is not valid for the
  25. matching IC.
  26. Register page 1:
  27. Address Description
  28. -/0x08 Unknown compressor related, must always be 8 except when not
  29. in 640x480 resolution and page 4 reg 2 <= 3 then set it to 9 !
  30. -/0x1b Auto white balance related, bit 0 is AWB enable (inverted)
  31. bits 345 seem to toggle per color gains on/off (inverted)
  32. 0x78 Global control, bit 6 controls the LED (inverted)
  33. -/0x80 JPEG compression ratio ? Best not touched
  34. Register page 3/4:
  35. Address Description
  36. 0x02 Clock divider 2-63, fps =~ 60 / val. Must be a multiple of 3 on
  37. the 7302, so one of 3, 6, 9, ...
  38. -/0x0f Master gain 1-245, low value = high gain
  39. 0x10/- Master gain 0-31
  40. -/0x10 Another gain 0-15, limited influence (1-2x gain I guess)
  41. 0x21 Bitfield: 0-1 unused, 2-3 vflip/hflip, 4-5 unknown, 6-7 unused
  42. */
  43. #define MODULE_NAME "pac7311"
  44. #include "gspca.h"
  45. MODULE_AUTHOR("Thomas Kaiser thomas@kaiser-linux.li");
  46. MODULE_DESCRIPTION("Pixart PAC7311");
  47. MODULE_LICENSE("GPL");
  48. /* specific webcam descriptor */
  49. struct sd {
  50. struct gspca_dev gspca_dev; /* !! must be the first item */
  51. unsigned char brightness;
  52. unsigned char contrast;
  53. unsigned char colors;
  54. unsigned char autogain;
  55. __u8 hflip;
  56. __u8 vflip;
  57. __u8 sensor;
  58. #define SENSOR_PAC7302 0
  59. #define SENSOR_PAC7311 1
  60. u8 sof_read;
  61. u8 header_read;
  62. u8 autogain_ignore_frames;
  63. atomic_t avg_lum;
  64. };
  65. /* V4L2 controls supported by the driver */
  66. static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
  67. static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
  68. static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
  69. static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
  70. static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
  71. static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
  72. static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
  73. static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
  74. static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val);
  75. static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val);
  76. static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val);
  77. static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val);
  78. static struct ctrl sd_ctrls[] = {
  79. {
  80. {
  81. .id = V4L2_CID_BRIGHTNESS,
  82. .type = V4L2_CTRL_TYPE_INTEGER,
  83. .name = "Brightness",
  84. .minimum = 0,
  85. #define BRIGHTNESS_MAX 0x20
  86. .maximum = BRIGHTNESS_MAX,
  87. .step = 1,
  88. #define BRIGHTNESS_DEF 0x10
  89. .default_value = BRIGHTNESS_DEF,
  90. },
  91. .set = sd_setbrightness,
  92. .get = sd_getbrightness,
  93. },
  94. {
  95. {
  96. .id = V4L2_CID_CONTRAST,
  97. .type = V4L2_CTRL_TYPE_INTEGER,
  98. .name = "Contrast",
  99. .minimum = 0,
  100. #define CONTRAST_MAX 255
  101. .maximum = CONTRAST_MAX,
  102. .step = 1,
  103. #define CONTRAST_DEF 127
  104. .default_value = CONTRAST_DEF,
  105. },
  106. .set = sd_setcontrast,
  107. .get = sd_getcontrast,
  108. },
  109. {
  110. {
  111. .id = V4L2_CID_SATURATION,
  112. .type = V4L2_CTRL_TYPE_INTEGER,
  113. .name = "Saturation",
  114. .minimum = 0,
  115. #define COLOR_MAX 255
  116. .maximum = COLOR_MAX,
  117. .step = 1,
  118. #define COLOR_DEF 127
  119. .default_value = COLOR_DEF,
  120. },
  121. .set = sd_setcolors,
  122. .get = sd_getcolors,
  123. },
  124. {
  125. {
  126. .id = V4L2_CID_AUTOGAIN,
  127. .type = V4L2_CTRL_TYPE_BOOLEAN,
  128. .name = "Auto Gain",
  129. .minimum = 0,
  130. .maximum = 1,
  131. .step = 1,
  132. #define AUTOGAIN_DEF 1
  133. .default_value = AUTOGAIN_DEF,
  134. },
  135. .set = sd_setautogain,
  136. .get = sd_getautogain,
  137. },
  138. /* next controls work with pac7302 only */
  139. {
  140. {
  141. .id = V4L2_CID_HFLIP,
  142. .type = V4L2_CTRL_TYPE_BOOLEAN,
  143. .name = "Mirror",
  144. .minimum = 0,
  145. .maximum = 1,
  146. .step = 1,
  147. #define HFLIP_DEF 0
  148. .default_value = HFLIP_DEF,
  149. },
  150. .set = sd_sethflip,
  151. .get = sd_gethflip,
  152. },
  153. {
  154. {
  155. .id = V4L2_CID_VFLIP,
  156. .type = V4L2_CTRL_TYPE_BOOLEAN,
  157. .name = "Vflip",
  158. .minimum = 0,
  159. .maximum = 1,
  160. .step = 1,
  161. #define VFLIP_DEF 0
  162. .default_value = VFLIP_DEF,
  163. },
  164. .set = sd_setvflip,
  165. .get = sd_getvflip,
  166. },
  167. };
  168. static struct v4l2_pix_format vga_mode[] = {
  169. {160, 120, V4L2_PIX_FMT_PJPG, V4L2_FIELD_NONE,
  170. .bytesperline = 160,
  171. .sizeimage = 160 * 120 * 3 / 8 + 590,
  172. .colorspace = V4L2_COLORSPACE_JPEG,
  173. .priv = 2},
  174. {320, 240, V4L2_PIX_FMT_PJPG, V4L2_FIELD_NONE,
  175. .bytesperline = 320,
  176. .sizeimage = 320 * 240 * 3 / 8 + 590,
  177. .colorspace = V4L2_COLORSPACE_JPEG,
  178. .priv = 1},
  179. {640, 480, V4L2_PIX_FMT_PJPG, V4L2_FIELD_NONE,
  180. .bytesperline = 640,
  181. .sizeimage = 640 * 480 * 3 / 8 + 590,
  182. .colorspace = V4L2_COLORSPACE_JPEG,
  183. .priv = 0},
  184. };
  185. /* pac 7302 */
  186. static const __u8 probe_7302[] = {
  187. /* index,value */
  188. 0xff, 0x01, /* page 1 */
  189. 0x78, 0x00, /* deactivate */
  190. 0xff, 0x01,
  191. 0x78, 0x40, /* led off */
  192. };
  193. static const __u8 start_7302[] = {
  194. /* index, len, [value]* */
  195. 0xff, 1, 0x00, /* page 0 */
  196. 0x00, 12, 0x01, 0x40, 0x40, 0x40, 0x01, 0xe0, 0x02, 0x80,
  197. 0x00, 0x00, 0x00, 0x00,
  198. 0x0d, 24, 0x03, 0x01, 0x00, 0xb5, 0x07, 0xcb, 0x00, 0x00,
  199. 0x07, 0xc8, 0x00, 0xea, 0x07, 0xcf, 0x07, 0xf7,
  200. 0x07, 0x7e, 0x01, 0x0b, 0x00, 0x00, 0x00, 0x11,
  201. 0x26, 2, 0xaa, 0xaa,
  202. 0x2e, 1, 0x31,
  203. 0x38, 1, 0x01,
  204. 0x3a, 3, 0x14, 0xff, 0x5a,
  205. 0x43, 11, 0x00, 0x0a, 0x18, 0x11, 0x01, 0x2c, 0x88, 0x11,
  206. 0x00, 0x54, 0x11,
  207. 0x55, 1, 0x00,
  208. 0x62, 4, 0x10, 0x1e, 0x1e, 0x18,
  209. 0x6b, 1, 0x00,
  210. 0x6e, 3, 0x08, 0x06, 0x00,
  211. 0x72, 3, 0x00, 0xff, 0x00,
  212. 0x7d, 23, 0x01, 0x01, 0x58, 0x46, 0x50, 0x3c, 0x50, 0x3c,
  213. 0x54, 0x46, 0x54, 0x56, 0x52, 0x50, 0x52, 0x50,
  214. 0x56, 0x64, 0xa4, 0x00, 0xda, 0x00, 0x00,
  215. 0xa2, 10, 0x22, 0x2c, 0x3c, 0x54, 0x69, 0x7c, 0x9c, 0xb9,
  216. 0xd2, 0xeb,
  217. 0xaf, 1, 0x02,
  218. 0xb5, 2, 0x08, 0x08,
  219. 0xb8, 2, 0x08, 0x88,
  220. 0xc4, 4, 0xae, 0x01, 0x04, 0x01,
  221. 0xcc, 1, 0x00,
  222. 0xd1, 11, 0x01, 0x30, 0x49, 0x5e, 0x6f, 0x7f, 0x8e, 0xa9,
  223. 0xc1, 0xd7, 0xec,
  224. 0xdc, 1, 0x01,
  225. 0xff, 1, 0x01, /* page 1 */
  226. 0x12, 3, 0x02, 0x00, 0x01,
  227. 0x3e, 2, 0x00, 0x00,
  228. 0x76, 5, 0x01, 0x20, 0x40, 0x00, 0xf2,
  229. 0x7c, 1, 0x00,
  230. 0x7f, 10, 0x4b, 0x0f, 0x01, 0x2c, 0x02, 0x58, 0x03, 0x20,
  231. 0x02, 0x00,
  232. 0x96, 5, 0x01, 0x10, 0x04, 0x01, 0x04,
  233. 0xc8, 14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00,
  234. 0x07, 0x00, 0x01, 0x07, 0x04, 0x01,
  235. 0xd8, 1, 0x01,
  236. 0xdb, 2, 0x00, 0x01,
  237. 0xde, 7, 0x00, 0x01, 0x04, 0x04, 0x00, 0x00, 0x00,
  238. 0xe6, 4, 0x00, 0x00, 0x00, 0x01,
  239. 0xeb, 1, 0x00,
  240. 0xff, 1, 0x02, /* page 2 */
  241. 0x22, 1, 0x00,
  242. 0xff, 1, 0x03, /* page 3 */
  243. 0x00, 255, /* load the page 3 */
  244. 0x11, 1, 0x01,
  245. 0xff, 1, 0x02, /* page 2 */
  246. 0x13, 1, 0x00,
  247. 0x22, 4, 0x1f, 0xa4, 0xf0, 0x96,
  248. 0x27, 2, 0x14, 0x0c,
  249. 0x2a, 5, 0xc8, 0x00, 0x18, 0x12, 0x22,
  250. 0x64, 8, 0x00, 0x00, 0xf0, 0x01, 0x14, 0x44, 0x44, 0x44,
  251. 0x6e, 1, 0x08,
  252. 0xff, 1, 0x01, /* page 1 */
  253. 0x78, 1, 0x00,
  254. 0, 0 /* end of sequence */
  255. };
  256. /* page 3 - the value 0xaa says skip the index - see reg_w_page() */
  257. static const __u8 page3_7302[] = {
  258. 0x90, 0x40, 0x03, 0x50, 0xc2, 0x01, 0x14, 0x16,
  259. 0x14, 0x12, 0x00, 0x00, 0x00, 0x02, 0x33, 0x00,
  260. 0x0f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  261. 0x00, 0x00, 0x00, 0x47, 0x01, 0xb3, 0x01, 0x00,
  262. 0x00, 0x08, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x21,
  263. 0x00, 0x00, 0x00, 0x54, 0xf4, 0x02, 0x52, 0x54,
  264. 0xa4, 0xb8, 0xe0, 0x2a, 0xf6, 0x00, 0x00, 0x00,
  265. 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  266. 0x00, 0xfc, 0x00, 0xf2, 0x1f, 0x04, 0x00, 0x00,
  267. 0x00, 0x00, 0x00, 0xc0, 0xc0, 0x10, 0x00, 0x00,
  268. 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  269. 0x00, 0x40, 0xff, 0x03, 0x19, 0x00, 0x00, 0x00,
  270. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  271. 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0xc8, 0xc8,
  272. 0xc8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
  273. 0x08, 0x10, 0x24, 0x40, 0x00, 0x00, 0x00, 0x00,
  274. 0x01, 0x00, 0x02, 0x47, 0x00, 0x00, 0x00, 0x00,
  275. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  276. 0x00, 0x02, 0xfa, 0x00, 0x64, 0x5a, 0x28, 0x00,
  277. 0x00
  278. };
  279. /* pac 7311 */
  280. static const __u8 probe_7311[] = {
  281. 0x78, 0x40, /* Bit_0=start stream, Bit_6=LED */
  282. 0x78, 0x40, /* Bit_0=start stream, Bit_6=LED */
  283. 0x78, 0x44, /* Bit_0=start stream, Bit_6=LED */
  284. 0xff, 0x04,
  285. 0x27, 0x80,
  286. 0x28, 0xca,
  287. 0x29, 0x53,
  288. 0x2a, 0x0e,
  289. 0xff, 0x01,
  290. 0x3e, 0x20,
  291. };
  292. static const __u8 start_7311[] = {
  293. /* index, len, [value]* */
  294. 0xff, 1, 0x01, /* page 1 */
  295. 0x02, 43, 0x48, 0x0a, 0x40, 0x08, 0x00, 0x00, 0x08, 0x00,
  296. 0x06, 0xff, 0x11, 0xff, 0x5a, 0x30, 0x90, 0x4c,
  297. 0x00, 0x07, 0x00, 0x0a, 0x10, 0x00, 0xa0, 0x10,
  298. 0x02, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x01, 0x00,
  299. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  300. 0x00, 0x00, 0x00,
  301. 0x3e, 42, 0x00, 0x00, 0x78, 0x52, 0x4a, 0x52, 0x78, 0x6e,
  302. 0x48, 0x46, 0x48, 0x6e, 0x5f, 0x49, 0x42, 0x49,
  303. 0x5f, 0x5f, 0x49, 0x42, 0x49, 0x5f, 0x6e, 0x48,
  304. 0x46, 0x48, 0x6e, 0x78, 0x52, 0x4a, 0x52, 0x78,
  305. 0x00, 0x00, 0x09, 0x1b, 0x34, 0x49, 0x5c, 0x9b,
  306. 0xd0, 0xff,
  307. 0x78, 6, 0x44, 0x00, 0xf2, 0x01, 0x01, 0x80,
  308. 0x7f, 18, 0x2a, 0x1c, 0x00, 0xc8, 0x02, 0x58, 0x03, 0x84,
  309. 0x12, 0x00, 0x1a, 0x04, 0x08, 0x0c, 0x10, 0x14,
  310. 0x18, 0x20,
  311. 0x96, 3, 0x01, 0x08, 0x04,
  312. 0xa0, 4, 0x44, 0x44, 0x44, 0x04,
  313. 0xf0, 13, 0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x20, 0x00,
  314. 0x3f, 0x00, 0x0a, 0x01, 0x00,
  315. 0xff, 1, 0x04, /* page 4 */
  316. 0x00, 254, /* load the page 4 */
  317. 0x11, 1, 0x01,
  318. 0, 0 /* end of sequence */
  319. };
  320. /* page 4 - the value 0xaa says skip the index - see reg_w_page() */
  321. static const __u8 page4_7311[] = {
  322. 0xaa, 0xaa, 0x04, 0x54, 0x07, 0x2b, 0x09, 0x0f,
  323. 0x09, 0x00, 0xaa, 0xaa, 0x07, 0x00, 0x00, 0x62,
  324. 0x08, 0xaa, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
  325. 0x00, 0x00, 0x00, 0x03, 0xa0, 0x01, 0xf4, 0xaa,
  326. 0xaa, 0x00, 0x08, 0xaa, 0x03, 0xaa, 0x00, 0x01,
  327. 0xca, 0x10, 0x06, 0x78, 0x00, 0x00, 0x00, 0x00,
  328. 0x23, 0x28, 0x04, 0x11, 0x00, 0x00
  329. };
  330. static void reg_w_buf(struct gspca_dev *gspca_dev,
  331. __u8 index,
  332. const char *buffer, int len)
  333. {
  334. memcpy(gspca_dev->usb_buf, buffer, len);
  335. usb_control_msg(gspca_dev->dev,
  336. usb_sndctrlpipe(gspca_dev->dev, 0),
  337. 1, /* request */
  338. USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
  339. 0, /* value */
  340. index, gspca_dev->usb_buf, len,
  341. 500);
  342. }
  343. static void reg_w(struct gspca_dev *gspca_dev,
  344. __u8 index,
  345. __u8 value)
  346. {
  347. gspca_dev->usb_buf[0] = value;
  348. usb_control_msg(gspca_dev->dev,
  349. usb_sndctrlpipe(gspca_dev->dev, 0),
  350. 0, /* request */
  351. USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
  352. value, index, gspca_dev->usb_buf, 1,
  353. 500);
  354. }
  355. static void reg_w_seq(struct gspca_dev *gspca_dev,
  356. const __u8 *seq, int len)
  357. {
  358. while (--len >= 0) {
  359. reg_w(gspca_dev, seq[0], seq[1]);
  360. seq += 2;
  361. }
  362. }
  363. /* load the beginning of a page */
  364. static void reg_w_page(struct gspca_dev *gspca_dev,
  365. const __u8 *page, int len)
  366. {
  367. int index;
  368. for (index = 0; index < len; index++) {
  369. if (page[index] == 0xaa) /* skip this index */
  370. continue;
  371. gspca_dev->usb_buf[0] = page[index];
  372. usb_control_msg(gspca_dev->dev,
  373. usb_sndctrlpipe(gspca_dev->dev, 0),
  374. 0, /* request */
  375. USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
  376. 0, index, gspca_dev->usb_buf, 1,
  377. 500);
  378. }
  379. }
  380. /* output a variable sequence */
  381. static void reg_w_var(struct gspca_dev *gspca_dev,
  382. const __u8 *seq)
  383. {
  384. int index, len;
  385. for (;;) {
  386. index = *seq++;
  387. len = *seq++;
  388. switch (len) {
  389. case 0:
  390. return;
  391. case 254:
  392. reg_w_page(gspca_dev, page4_7311, sizeof page4_7311);
  393. break;
  394. case 255:
  395. reg_w_page(gspca_dev, page3_7302, sizeof page3_7302);
  396. break;
  397. default:
  398. if (len > 64) {
  399. PDEBUG(D_ERR|D_STREAM,
  400. "Incorrect variable sequence");
  401. return;
  402. }
  403. while (len > 0) {
  404. if (len < 8) {
  405. reg_w_buf(gspca_dev, index, seq, len);
  406. seq += len;
  407. break;
  408. }
  409. reg_w_buf(gspca_dev, index, seq, 8);
  410. seq += 8;
  411. index += 8;
  412. len -= 8;
  413. }
  414. }
  415. }
  416. /* not reached */
  417. }
  418. /* this function is called at probe time */
  419. static int sd_config(struct gspca_dev *gspca_dev,
  420. const struct usb_device_id *id)
  421. {
  422. struct sd *sd = (struct sd *) gspca_dev;
  423. struct cam *cam;
  424. cam = &gspca_dev->cam;
  425. cam->epaddr = 0x05;
  426. sd->sensor = id->driver_info;
  427. if (sd->sensor == SENSOR_PAC7302) {
  428. PDEBUG(D_CONF, "Find Sensor PAC7302");
  429. reg_w_seq(gspca_dev, probe_7302, sizeof probe_7302);
  430. cam->cam_mode = &vga_mode[2]; /* only 640x480 */
  431. cam->nmodes = 1;
  432. } else {
  433. PDEBUG(D_CONF, "Find Sensor PAC7311");
  434. reg_w_seq(gspca_dev, probe_7311, sizeof probe_7311);
  435. cam->cam_mode = vga_mode;
  436. cam->nmodes = ARRAY_SIZE(vga_mode);
  437. }
  438. sd->brightness = BRIGHTNESS_DEF;
  439. sd->contrast = CONTRAST_DEF;
  440. sd->colors = COLOR_DEF;
  441. sd->autogain = AUTOGAIN_DEF;
  442. sd->hflip = HFLIP_DEF;
  443. sd->vflip = VFLIP_DEF;
  444. return 0;
  445. }
  446. /* rev 12a only */
  447. static void setbrightcont(struct gspca_dev *gspca_dev)
  448. {
  449. struct sd *sd = (struct sd *) gspca_dev;
  450. int i, v;
  451. static const __u8 max[10] =
  452. {0x29, 0x33, 0x42, 0x5a, 0x6e, 0x80, 0x9f, 0xbb,
  453. 0xd4, 0xec};
  454. static const __u8 delta[10] =
  455. {0x35, 0x33, 0x33, 0x2f, 0x2a, 0x25, 0x1e, 0x17,
  456. 0x11, 0x0b};
  457. reg_w(gspca_dev, 0xff, 0x00); /* page 0 */
  458. for (i = 0; i < 10; i++) {
  459. v = max[i];
  460. v += (sd->brightness - BRIGHTNESS_MAX)
  461. * 150 / BRIGHTNESS_MAX; /* 200 ? */
  462. v -= delta[i] * sd->contrast / CONTRAST_MAX;
  463. if (v < 0)
  464. v = 0;
  465. else if (v > 0xff)
  466. v = 0xff;
  467. reg_w(gspca_dev, 0xa2 + i, v);
  468. }
  469. reg_w(gspca_dev, 0xdc, 0x01);
  470. }
  471. /* This function is used by pac7302 only */
  472. static void setbrightness(struct gspca_dev *gspca_dev)
  473. {
  474. struct sd *sd = (struct sd *) gspca_dev;
  475. int brightness;
  476. if (sd->sensor == SENSOR_PAC7302) {
  477. setbrightcont(gspca_dev);
  478. return;
  479. }
  480. /* HDG: this is not brightness but gain, I'll add gain and exposure controls
  481. in a next patch */
  482. return;
  483. brightness = BRIGHTNESS_MAX - sd->brightness;
  484. reg_w(gspca_dev, 0xff, 0x04);
  485. reg_w(gspca_dev, 0x0e, 0x00);
  486. reg_w(gspca_dev, 0x0f, brightness);
  487. /* load registers to sensor (Bit 0, auto clear) */
  488. reg_w(gspca_dev, 0x11, 0x01);
  489. PDEBUG(D_CONF|D_STREAM, "brightness: %i", brightness);
  490. }
  491. static void setcontrast(struct gspca_dev *gspca_dev)
  492. {
  493. struct sd *sd = (struct sd *) gspca_dev;
  494. if (sd->sensor == SENSOR_PAC7302) {
  495. setbrightcont(gspca_dev);
  496. return;
  497. }
  498. reg_w(gspca_dev, 0xff, 0x04);
  499. reg_w(gspca_dev, 0x10, sd->contrast >> 4);
  500. /* load registers to sensor (Bit 0, auto clear) */
  501. reg_w(gspca_dev, 0x11, 0x01);
  502. }
  503. /* This function is used by pac7302 only */
  504. static void setcolors(struct gspca_dev *gspca_dev)
  505. {
  506. struct sd *sd = (struct sd *) gspca_dev;
  507. if (sd->sensor == SENSOR_PAC7302) {
  508. int i, v;
  509. static const int a[9] =
  510. {217, -212, 0, -101, 170, -67, -38, -315, 355};
  511. static const int b[9] =
  512. {19, 106, 0, 19, 106, 1, 19, 106, 1};
  513. reg_w(gspca_dev, 0xff, 0x03); /* page 3 */
  514. reg_w(gspca_dev, 0x11, 0x01);
  515. reg_w(gspca_dev, 0xff, 0x00); /* page 0 */
  516. reg_w(gspca_dev, 0xff, 0x00); /* page 0 */
  517. for (i = 0; i < 9; i++) {
  518. v = a[i] * sd->colors / COLOR_MAX + b[i];
  519. reg_w(gspca_dev, 0x0f + 2 * i, (v >> 8) & 0x07);
  520. reg_w(gspca_dev, 0x0f + 2 * i + 1, v);
  521. }
  522. reg_w(gspca_dev, 0xdc, 0x01);
  523. PDEBUG(D_CONF|D_STREAM, "color: %i", sd->colors);
  524. }
  525. }
  526. static void sethvflip(struct gspca_dev *gspca_dev)
  527. {
  528. struct sd *sd = (struct sd *) gspca_dev;
  529. __u8 data;
  530. if (sd->sensor == SENSOR_PAC7302) {
  531. reg_w(gspca_dev, 0xff, 0x03); /* page 3 */
  532. data = (sd->hflip ? 0x00 : 0x08)
  533. | (sd->vflip ? 0x04 : 0x00);
  534. } else {
  535. reg_w(gspca_dev, 0xff, 0x04); /* page 3 */
  536. data = (sd->hflip ? 0x04 : 0x00)
  537. | (sd->vflip ? 0x08 : 0x00);
  538. }
  539. reg_w(gspca_dev, 0x21, data);
  540. reg_w(gspca_dev, 0x11, 0x01);
  541. }
  542. /* this function is called at open time */
  543. static int sd_open(struct gspca_dev *gspca_dev)
  544. {
  545. return 0;
  546. }
  547. static void sd_start(struct gspca_dev *gspca_dev)
  548. {
  549. struct sd *sd = (struct sd *) gspca_dev;
  550. sd->sof_read = 0;
  551. if (sd->sensor == SENSOR_PAC7302)
  552. reg_w_var(gspca_dev, start_7302);
  553. else
  554. reg_w_var(gspca_dev, start_7311);
  555. setcontrast(gspca_dev);
  556. setbrightness(gspca_dev);
  557. setcolors(gspca_dev);
  558. /* set correct resolution */
  559. switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) {
  560. case 2: /* 160x120 pac7311 */
  561. reg_w(gspca_dev, 0xff, 0x04);
  562. reg_w(gspca_dev, 0x02, 0x03);
  563. reg_w(gspca_dev, 0xff, 0x01);
  564. reg_w(gspca_dev, 0x08, 0x09);
  565. reg_w(gspca_dev, 0x17, 0x20);
  566. reg_w(gspca_dev, 0x1b, 0x00);
  567. reg_w(gspca_dev, 0x87, 0x10);
  568. break;
  569. case 1: /* 320x240 pac7311 */
  570. reg_w(gspca_dev, 0xff, 0x04);
  571. reg_w(gspca_dev, 0x02, 0x03);
  572. reg_w(gspca_dev, 0xff, 0x01);
  573. reg_w(gspca_dev, 0x08, 0x09);
  574. reg_w(gspca_dev, 0x17, 0x30);
  575. reg_w(gspca_dev, 0x87, 0x11);
  576. break;
  577. case 0: /* 640x480 */
  578. if (sd->sensor == SENSOR_PAC7302)
  579. break;
  580. reg_w(gspca_dev, 0xff, 0x04);
  581. reg_w(gspca_dev, 0x02, 0x07);
  582. reg_w(gspca_dev, 0xff, 0x01);
  583. reg_w(gspca_dev, 0x08, 0x08);
  584. reg_w(gspca_dev, 0x17, 0x00);
  585. reg_w(gspca_dev, 0x87, 0x12);
  586. break;
  587. }
  588. /* start stream */
  589. reg_w(gspca_dev, 0xff, 0x01);
  590. if (sd->sensor == SENSOR_PAC7302) {
  591. sethvflip(gspca_dev);
  592. reg_w(gspca_dev, 0x78, 0x01);
  593. reg_w(gspca_dev, 0xff, 0x01);
  594. reg_w(gspca_dev, 0x78, 0x01);
  595. } else {
  596. reg_w(gspca_dev, 0x78, 0x44);
  597. reg_w(gspca_dev, 0x78, 0x45);
  598. }
  599. sd->sof_read = 0;
  600. sd->autogain_ignore_frames = 0;
  601. atomic_set(&sd->avg_lum, -1);
  602. }
  603. static void sd_stopN(struct gspca_dev *gspca_dev)
  604. {
  605. struct sd *sd = (struct sd *) gspca_dev;
  606. if (sd->sensor == SENSOR_PAC7302) {
  607. reg_w(gspca_dev, 0xff, 0x01);
  608. reg_w(gspca_dev, 0x78, 0x00);
  609. reg_w(gspca_dev, 0x78, 0x00);
  610. return;
  611. }
  612. reg_w(gspca_dev, 0xff, 0x04);
  613. reg_w(gspca_dev, 0x27, 0x80);
  614. reg_w(gspca_dev, 0x28, 0xca);
  615. reg_w(gspca_dev, 0x29, 0x53);
  616. reg_w(gspca_dev, 0x2a, 0x0e);
  617. reg_w(gspca_dev, 0xff, 0x01);
  618. reg_w(gspca_dev, 0x3e, 0x20);
  619. reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
  620. reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
  621. reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
  622. }
  623. static void sd_stop0(struct gspca_dev *gspca_dev)
  624. {
  625. struct sd *sd = (struct sd *) gspca_dev;
  626. if (sd->sensor == SENSOR_PAC7302) {
  627. reg_w(gspca_dev, 0xff, 0x01);
  628. reg_w(gspca_dev, 0x78, 0x40);
  629. }
  630. }
  631. /* this function is called at close time */
  632. static void sd_close(struct gspca_dev *gspca_dev)
  633. {
  634. }
  635. static void do_autogain(struct gspca_dev *gspca_dev)
  636. {
  637. }
  638. static const unsigned char pac7311_jpeg_header1[] = {
  639. 0xff, 0xd8, 0xff, 0xc0, 0x00, 0x11, 0x08
  640. };
  641. static const unsigned char pac7311_jpeg_header2[] = {
  642. 0x03, 0x01, 0x21, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xff, 0xda,
  643. 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00
  644. };
  645. /* Include pac common sof detection functions */
  646. #include "pac_common.h"
  647. #define HEADER_LENGTH 2
  648. /* this function is run at interrupt level */
  649. static void sd_pkt_scan(struct gspca_dev *gspca_dev,
  650. struct gspca_frame *frame, /* target */
  651. __u8 *data, /* isoc packet */
  652. int len) /* iso packet length */
  653. {
  654. struct sd *sd = (struct sd *) gspca_dev;
  655. unsigned char *sof;
  656. sof = pac_find_sof(gspca_dev, data, len);
  657. if (sof) {
  658. unsigned char tmpbuf[4];
  659. int n, lum_offset, footer_length;
  660. if (sd->sensor == SENSOR_PAC7302) {
  661. lum_offset = 34 + sizeof pac_sof_marker;
  662. footer_length = 74;
  663. } else {
  664. lum_offset = 24 + sizeof pac_sof_marker;
  665. footer_length = 26;
  666. }
  667. /* Finish decoding current frame */
  668. n = (sof - data) - (footer_length + sizeof pac_sof_marker);
  669. if (n < 0) {
  670. frame->data_end += n;
  671. n = 0;
  672. }
  673. frame = gspca_frame_add(gspca_dev, INTER_PACKET, frame,
  674. data, n);
  675. if (gspca_dev->last_packet_type != DISCARD_PACKET &&
  676. frame->data_end[-2] == 0xff &&
  677. frame->data_end[-1] == 0xd9)
  678. frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
  679. NULL, 0);
  680. n = sof - data;
  681. len -= n;
  682. data = sof;
  683. /* Get average lumination */
  684. if (gspca_dev->last_packet_type == LAST_PACKET &&
  685. n >= lum_offset) {
  686. if (sd->sensor == SENSOR_PAC7302)
  687. atomic_set(&sd->avg_lum,
  688. (data[-lum_offset] << 8) |
  689. data[-lum_offset + 1]);
  690. else
  691. atomic_set(&sd->avg_lum,
  692. data[-lum_offset] +
  693. data[-lum_offset + 1]);
  694. } else {
  695. atomic_set(&sd->avg_lum, -1);
  696. }
  697. /* Start the new frame with the jpeg header */
  698. gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
  699. pac7311_jpeg_header1, sizeof(pac7311_jpeg_header1));
  700. if (sd->sensor == SENSOR_PAC7302) {
  701. /* The PAC7302 has the image rotated 90 degrees */
  702. tmpbuf[0] = gspca_dev->width >> 8;
  703. tmpbuf[1] = gspca_dev->width & 0xff;
  704. tmpbuf[2] = gspca_dev->height >> 8;
  705. tmpbuf[3] = gspca_dev->height & 0xff;
  706. } else {
  707. tmpbuf[0] = gspca_dev->height >> 8;
  708. tmpbuf[1] = gspca_dev->height & 0xff;
  709. tmpbuf[2] = gspca_dev->width >> 8;
  710. tmpbuf[3] = gspca_dev->width & 0xff;
  711. }
  712. gspca_frame_add(gspca_dev, INTER_PACKET, frame, tmpbuf, 4);
  713. gspca_frame_add(gspca_dev, INTER_PACKET, frame,
  714. pac7311_jpeg_header2, sizeof(pac7311_jpeg_header2));
  715. sd->header_read = 0;
  716. }
  717. if (sd->header_read < HEADER_LENGTH) {
  718. /* skip the variable part of the sof header */
  719. int needed = HEADER_LENGTH - sd->header_read;
  720. if (len <= needed) {
  721. sd->header_read += len;
  722. return;
  723. }
  724. data += needed;
  725. len -= needed;
  726. sd->header_read = HEADER_LENGTH;
  727. }
  728. gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
  729. }
  730. static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
  731. {
  732. struct sd *sd = (struct sd *) gspca_dev;
  733. sd->brightness = val;
  734. if (gspca_dev->streaming)
  735. setbrightness(gspca_dev);
  736. return 0;
  737. }
  738. static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
  739. {
  740. struct sd *sd = (struct sd *) gspca_dev;
  741. *val = sd->brightness;
  742. return 0;
  743. }
  744. static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
  745. {
  746. struct sd *sd = (struct sd *) gspca_dev;
  747. sd->contrast = val;
  748. if (gspca_dev->streaming)
  749. setcontrast(gspca_dev);
  750. return 0;
  751. }
  752. static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
  753. {
  754. struct sd *sd = (struct sd *) gspca_dev;
  755. *val = sd->contrast;
  756. return 0;
  757. }
  758. static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
  759. {
  760. struct sd *sd = (struct sd *) gspca_dev;
  761. sd->colors = val;
  762. if (gspca_dev->streaming)
  763. setcolors(gspca_dev);
  764. return 0;
  765. }
  766. static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
  767. {
  768. struct sd *sd = (struct sd *) gspca_dev;
  769. *val = sd->colors;
  770. return 0;
  771. }
  772. static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
  773. {
  774. struct sd *sd = (struct sd *) gspca_dev;
  775. sd->autogain = val;
  776. return 0;
  777. }
  778. static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
  779. {
  780. struct sd *sd = (struct sd *) gspca_dev;
  781. *val = sd->autogain;
  782. return 0;
  783. }
  784. static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val)
  785. {
  786. struct sd *sd = (struct sd *) gspca_dev;
  787. sd->hflip = val;
  788. if (gspca_dev->streaming)
  789. sethvflip(gspca_dev);
  790. return 0;
  791. }
  792. static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val)
  793. {
  794. struct sd *sd = (struct sd *) gspca_dev;
  795. *val = sd->hflip;
  796. return 0;
  797. }
  798. static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val)
  799. {
  800. struct sd *sd = (struct sd *) gspca_dev;
  801. sd->vflip = val;
  802. if (gspca_dev->streaming)
  803. sethvflip(gspca_dev);
  804. return 0;
  805. }
  806. static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
  807. {
  808. struct sd *sd = (struct sd *) gspca_dev;
  809. *val = sd->vflip;
  810. return 0;
  811. }
  812. /* sub-driver description */
  813. static struct sd_desc sd_desc = {
  814. .name = MODULE_NAME,
  815. .ctrls = sd_ctrls,
  816. .nctrls = ARRAY_SIZE(sd_ctrls),
  817. .config = sd_config,
  818. .open = sd_open,
  819. .start = sd_start,
  820. .stopN = sd_stopN,
  821. .stop0 = sd_stop0,
  822. .close = sd_close,
  823. .pkt_scan = sd_pkt_scan,
  824. .dq_callback = do_autogain,
  825. };
  826. /* -- module initialisation -- */
  827. static __devinitdata struct usb_device_id device_table[] = {
  828. {USB_DEVICE(0x093a, 0x2600), .driver_info = SENSOR_PAC7311},
  829. {USB_DEVICE(0x093a, 0x2601), .driver_info = SENSOR_PAC7311},
  830. {USB_DEVICE(0x093a, 0x2603), .driver_info = SENSOR_PAC7311},
  831. {USB_DEVICE(0x093a, 0x2608), .driver_info = SENSOR_PAC7311},
  832. {USB_DEVICE(0x093a, 0x260e), .driver_info = SENSOR_PAC7311},
  833. {USB_DEVICE(0x093a, 0x260f), .driver_info = SENSOR_PAC7311},
  834. {USB_DEVICE(0x093a, 0x2621), .driver_info = SENSOR_PAC7302},
  835. {}
  836. };
  837. MODULE_DEVICE_TABLE(usb, device_table);
  838. /* -- device connect -- */
  839. static int sd_probe(struct usb_interface *intf,
  840. const struct usb_device_id *id)
  841. {
  842. return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
  843. THIS_MODULE);
  844. }
  845. static struct usb_driver sd_driver = {
  846. .name = MODULE_NAME,
  847. .id_table = device_table,
  848. .probe = sd_probe,
  849. .disconnect = gspca_disconnect,
  850. #ifdef CONFIG_PM
  851. .suspend = gspca_suspend,
  852. .resume = gspca_resume,
  853. #endif
  854. };
  855. /* -- module insert / remove -- */
  856. static int __init sd_mod_init(void)
  857. {
  858. if (usb_register(&sd_driver) < 0)
  859. return -1;
  860. PDEBUG(D_PROBE, "registered");
  861. return 0;
  862. }
  863. static void __exit sd_mod_exit(void)
  864. {
  865. usb_deregister(&sd_driver);
  866. PDEBUG(D_PROBE, "deregistered");
  867. }
  868. module_init(sd_mod_init);
  869. module_exit(sd_mod_exit);