spca500.c 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * SPCA500 chip based cameras initialization data
  4. *
  5. * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
  6. */
  7. #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  8. #define MODULE_NAME "spca500"
  9. #include "gspca.h"
  10. #include "jpeg.h"
  11. MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
  12. MODULE_DESCRIPTION("GSPCA/SPCA500 USB Camera Driver");
  13. MODULE_LICENSE("GPL");
  14. #define QUALITY 85
  15. /* specific webcam descriptor */
  16. struct sd {
  17. struct gspca_dev gspca_dev; /* !! must be the first item */
  18. char subtype;
  19. #define AgfaCl20 0
  20. #define AiptekPocketDV 1
  21. #define BenqDC1016 2
  22. #define CreativePCCam300 3
  23. #define DLinkDSC350 4
  24. #define Gsmartmini 5
  25. #define IntelPocketPCCamera 6
  26. #define KodakEZ200 7
  27. #define LogitechClickSmart310 8
  28. #define LogitechClickSmart510 9
  29. #define LogitechTraveler 10
  30. #define MustekGsmart300 11
  31. #define Optimedia 12
  32. #define PalmPixDC85 13
  33. #define ToptroIndus 14
  34. u8 jpeg_hdr[JPEG_HDR_SZ];
  35. };
  36. static const struct v4l2_pix_format vga_mode[] = {
  37. {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
  38. .bytesperline = 320,
  39. .sizeimage = 320 * 240 * 3 / 8 + 590,
  40. .colorspace = V4L2_COLORSPACE_JPEG,
  41. .priv = 1},
  42. {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
  43. .bytesperline = 640,
  44. .sizeimage = 640 * 480 * 3 / 8 + 590,
  45. .colorspace = V4L2_COLORSPACE_JPEG,
  46. .priv = 0},
  47. };
  48. static const struct v4l2_pix_format sif_mode[] = {
  49. {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
  50. .bytesperline = 176,
  51. .sizeimage = 176 * 144 * 3 / 8 + 590,
  52. .colorspace = V4L2_COLORSPACE_JPEG,
  53. .priv = 1},
  54. {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
  55. .bytesperline = 352,
  56. .sizeimage = 352 * 288 * 3 / 8 + 590,
  57. .colorspace = V4L2_COLORSPACE_JPEG,
  58. .priv = 0},
  59. };
  60. /* Frame packet header offsets for the spca500 */
  61. #define SPCA500_OFFSET_PADDINGLB 2
  62. #define SPCA500_OFFSET_PADDINGHB 3
  63. #define SPCA500_OFFSET_MODE 4
  64. #define SPCA500_OFFSET_IMGWIDTH 5
  65. #define SPCA500_OFFSET_IMGHEIGHT 6
  66. #define SPCA500_OFFSET_IMGMODE 7
  67. #define SPCA500_OFFSET_QTBLINDEX 8
  68. #define SPCA500_OFFSET_FRAMSEQ 9
  69. #define SPCA500_OFFSET_CDSPINFO 10
  70. #define SPCA500_OFFSET_GPIO 11
  71. #define SPCA500_OFFSET_AUGPIO 12
  72. #define SPCA500_OFFSET_DATA 16
  73. static const __u16 spca500_visual_defaults[][3] = {
  74. {0x00, 0x0003, 0x816b}, /* SSI not active sync with vsync,
  75. * hue (H byte) = 0,
  76. * saturation/hue enable,
  77. * brightness/contrast enable.
  78. */
  79. {0x00, 0x0000, 0x8167}, /* brightness = 0 */
  80. {0x00, 0x0020, 0x8168}, /* contrast = 0 */
  81. {0x00, 0x0003, 0x816b}, /* SSI not active sync with vsync,
  82. * hue (H byte) = 0, saturation/hue enable,
  83. * brightness/contrast enable.
  84. * was 0x0003, now 0x0000.
  85. */
  86. {0x00, 0x0000, 0x816a}, /* hue (L byte) = 0 */
  87. {0x00, 0x0020, 0x8169}, /* saturation = 0x20 */
  88. {0x00, 0x0050, 0x8157}, /* edge gain high threshold */
  89. {0x00, 0x0030, 0x8158}, /* edge gain low threshold */
  90. {0x00, 0x0028, 0x8159}, /* edge bandwidth high threshold */
  91. {0x00, 0x000a, 0x815a}, /* edge bandwidth low threshold */
  92. {0x00, 0x0001, 0x8202}, /* clock rate compensation = 1/25 sec/frame */
  93. {0x0c, 0x0004, 0x0000},
  94. /* set interface */
  95. {}
  96. };
  97. static const __u16 Clicksmart510_defaults[][3] = {
  98. {0x00, 0x00, 0x8211},
  99. {0x00, 0x01, 0x82c0},
  100. {0x00, 0x10, 0x82cb},
  101. {0x00, 0x0f, 0x800d},
  102. {0x00, 0x82, 0x8225},
  103. {0x00, 0x21, 0x8228},
  104. {0x00, 0x00, 0x8203},
  105. {0x00, 0x00, 0x8204},
  106. {0x00, 0x08, 0x8205},
  107. {0x00, 0xf8, 0x8206},
  108. {0x00, 0x28, 0x8207},
  109. {0x00, 0xa0, 0x8208},
  110. {0x00, 0x08, 0x824a},
  111. {0x00, 0x08, 0x8214},
  112. {0x00, 0x80, 0x82c1},
  113. {0x00, 0x00, 0x82c2},
  114. {0x00, 0x00, 0x82ca},
  115. {0x00, 0x80, 0x82c1},
  116. {0x00, 0x04, 0x82c2},
  117. {0x00, 0x00, 0x82ca},
  118. {0x00, 0xfc, 0x8100},
  119. {0x00, 0xfc, 0x8105},
  120. {0x00, 0x30, 0x8101},
  121. {0x00, 0x00, 0x8102},
  122. {0x00, 0x00, 0x8103},
  123. {0x00, 0x66, 0x8107},
  124. {0x00, 0x00, 0x816b},
  125. {0x00, 0x00, 0x8155},
  126. {0x00, 0x01, 0x8156},
  127. {0x00, 0x60, 0x8157},
  128. {0x00, 0x40, 0x8158},
  129. {0x00, 0x0a, 0x8159},
  130. {0x00, 0x06, 0x815a},
  131. {0x00, 0x00, 0x813f},
  132. {0x00, 0x00, 0x8200},
  133. {0x00, 0x19, 0x8201},
  134. {0x00, 0x00, 0x82c1},
  135. {0x00, 0xa0, 0x82c2},
  136. {0x00, 0x00, 0x82ca},
  137. {0x00, 0x00, 0x8117},
  138. {0x00, 0x00, 0x8118},
  139. {0x00, 0x65, 0x8119},
  140. {0x00, 0x00, 0x811a},
  141. {0x00, 0x00, 0x811b},
  142. {0x00, 0x55, 0x811c},
  143. {0x00, 0x65, 0x811d},
  144. {0x00, 0x55, 0x811e},
  145. {0x00, 0x16, 0x811f},
  146. {0x00, 0x19, 0x8120},
  147. {0x00, 0x80, 0x8103},
  148. {0x00, 0x83, 0x816b},
  149. {0x00, 0x25, 0x8168},
  150. {0x00, 0x01, 0x820f},
  151. {0x00, 0xff, 0x8115},
  152. {0x00, 0x48, 0x8116},
  153. {0x00, 0x50, 0x8151},
  154. {0x00, 0x40, 0x8152},
  155. {0x00, 0x78, 0x8153},
  156. {0x00, 0x40, 0x8154},
  157. {0x00, 0x00, 0x8167},
  158. {0x00, 0x20, 0x8168},
  159. {0x00, 0x00, 0x816a},
  160. {0x00, 0x03, 0x816b},
  161. {0x00, 0x20, 0x8169},
  162. {0x00, 0x60, 0x8157},
  163. {0x00, 0x00, 0x8190},
  164. {0x00, 0x00, 0x81a1},
  165. {0x00, 0x00, 0x81b2},
  166. {0x00, 0x27, 0x8191},
  167. {0x00, 0x27, 0x81a2},
  168. {0x00, 0x27, 0x81b3},
  169. {0x00, 0x4b, 0x8192},
  170. {0x00, 0x4b, 0x81a3},
  171. {0x00, 0x4b, 0x81b4},
  172. {0x00, 0x66, 0x8193},
  173. {0x00, 0x66, 0x81a4},
  174. {0x00, 0x66, 0x81b5},
  175. {0x00, 0x79, 0x8194},
  176. {0x00, 0x79, 0x81a5},
  177. {0x00, 0x79, 0x81b6},
  178. {0x00, 0x8a, 0x8195},
  179. {0x00, 0x8a, 0x81a6},
  180. {0x00, 0x8a, 0x81b7},
  181. {0x00, 0x9b, 0x8196},
  182. {0x00, 0x9b, 0x81a7},
  183. {0x00, 0x9b, 0x81b8},
  184. {0x00, 0xa6, 0x8197},
  185. {0x00, 0xa6, 0x81a8},
  186. {0x00, 0xa6, 0x81b9},
  187. {0x00, 0xb2, 0x8198},
  188. {0x00, 0xb2, 0x81a9},
  189. {0x00, 0xb2, 0x81ba},
  190. {0x00, 0xbe, 0x8199},
  191. {0x00, 0xbe, 0x81aa},
  192. {0x00, 0xbe, 0x81bb},
  193. {0x00, 0xc8, 0x819a},
  194. {0x00, 0xc8, 0x81ab},
  195. {0x00, 0xc8, 0x81bc},
  196. {0x00, 0xd2, 0x819b},
  197. {0x00, 0xd2, 0x81ac},
  198. {0x00, 0xd2, 0x81bd},
  199. {0x00, 0xdb, 0x819c},
  200. {0x00, 0xdb, 0x81ad},
  201. {0x00, 0xdb, 0x81be},
  202. {0x00, 0xe4, 0x819d},
  203. {0x00, 0xe4, 0x81ae},
  204. {0x00, 0xe4, 0x81bf},
  205. {0x00, 0xed, 0x819e},
  206. {0x00, 0xed, 0x81af},
  207. {0x00, 0xed, 0x81c0},
  208. {0x00, 0xf7, 0x819f},
  209. {0x00, 0xf7, 0x81b0},
  210. {0x00, 0xf7, 0x81c1},
  211. {0x00, 0xff, 0x81a0},
  212. {0x00, 0xff, 0x81b1},
  213. {0x00, 0xff, 0x81c2},
  214. {0x00, 0x03, 0x8156},
  215. {0x00, 0x00, 0x8211},
  216. {0x00, 0x20, 0x8168},
  217. {0x00, 0x01, 0x8202},
  218. {0x00, 0x30, 0x8101},
  219. {0x00, 0x00, 0x8111},
  220. {0x00, 0x00, 0x8112},
  221. {0x00, 0x00, 0x8113},
  222. {0x00, 0x00, 0x8114},
  223. {}
  224. };
  225. static const __u8 qtable_creative_pccam[2][64] = {
  226. { /* Q-table Y-components */
  227. 0x05, 0x03, 0x03, 0x05, 0x07, 0x0c, 0x0f, 0x12,
  228. 0x04, 0x04, 0x04, 0x06, 0x08, 0x11, 0x12, 0x11,
  229. 0x04, 0x04, 0x05, 0x07, 0x0c, 0x11, 0x15, 0x11,
  230. 0x04, 0x05, 0x07, 0x09, 0x0f, 0x1a, 0x18, 0x13,
  231. 0x05, 0x07, 0x0b, 0x11, 0x14, 0x21, 0x1f, 0x17,
  232. 0x07, 0x0b, 0x11, 0x13, 0x18, 0x1f, 0x22, 0x1c,
  233. 0x0f, 0x13, 0x17, 0x1a, 0x1f, 0x24, 0x24, 0x1e,
  234. 0x16, 0x1c, 0x1d, 0x1d, 0x22, 0x1e, 0x1f, 0x1e},
  235. { /* Q-table C-components */
  236. 0x05, 0x05, 0x07, 0x0e, 0x1e, 0x1e, 0x1e, 0x1e,
  237. 0x05, 0x06, 0x08, 0x14, 0x1e, 0x1e, 0x1e, 0x1e,
  238. 0x07, 0x08, 0x11, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
  239. 0x0e, 0x14, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
  240. 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
  241. 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
  242. 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
  243. 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e}
  244. };
  245. static const __u8 qtable_kodak_ez200[2][64] = {
  246. { /* Q-table Y-components */
  247. 0x02, 0x01, 0x01, 0x02, 0x02, 0x04, 0x05, 0x06,
  248. 0x01, 0x01, 0x01, 0x02, 0x03, 0x06, 0x06, 0x06,
  249. 0x01, 0x01, 0x02, 0x02, 0x04, 0x06, 0x07, 0x06,
  250. 0x01, 0x02, 0x02, 0x03, 0x05, 0x09, 0x08, 0x06,
  251. 0x02, 0x02, 0x04, 0x06, 0x07, 0x0b, 0x0a, 0x08,
  252. 0x02, 0x04, 0x06, 0x06, 0x08, 0x0a, 0x0b, 0x09,
  253. 0x05, 0x06, 0x08, 0x09, 0x0a, 0x0c, 0x0c, 0x0a,
  254. 0x07, 0x09, 0x0a, 0x0a, 0x0b, 0x0a, 0x0a, 0x0a},
  255. { /* Q-table C-components */
  256. 0x02, 0x02, 0x02, 0x05, 0x0a, 0x0a, 0x0a, 0x0a,
  257. 0x02, 0x02, 0x03, 0x07, 0x0a, 0x0a, 0x0a, 0x0a,
  258. 0x02, 0x03, 0x06, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
  259. 0x05, 0x07, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
  260. 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
  261. 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
  262. 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
  263. 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a}
  264. };
  265. static const __u8 qtable_pocketdv[2][64] = {
  266. { /* Q-table Y-components start registers 0x8800 */
  267. 0x06, 0x04, 0x04, 0x06, 0x0a, 0x10, 0x14, 0x18,
  268. 0x05, 0x05, 0x06, 0x08, 0x0a, 0x17, 0x18, 0x16,
  269. 0x06, 0x05, 0x06, 0x0a, 0x10, 0x17, 0x1c, 0x16,
  270. 0x06, 0x07, 0x09, 0x0c, 0x14, 0x23, 0x20, 0x19,
  271. 0x07, 0x09, 0x0f, 0x16, 0x1b, 0x2c, 0x29, 0x1f,
  272. 0x0a, 0x0e, 0x16, 0x1a, 0x20, 0x2a, 0x2d, 0x25,
  273. 0x14, 0x1a, 0x1f, 0x23, 0x29, 0x30, 0x30, 0x28,
  274. 0x1d, 0x25, 0x26, 0x27, 0x2d, 0x28, 0x29, 0x28,
  275. },
  276. { /* Q-table C-components start registers 0x8840 */
  277. 0x07, 0x07, 0x0a, 0x13, 0x28, 0x28, 0x28, 0x28,
  278. 0x07, 0x08, 0x0a, 0x1a, 0x28, 0x28, 0x28, 0x28,
  279. 0x0a, 0x0a, 0x16, 0x28, 0x28, 0x28, 0x28, 0x28,
  280. 0x13, 0x1a, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
  281. 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
  282. 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
  283. 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
  284. 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28}
  285. };
  286. /* read 'len' bytes to gspca_dev->usb_buf */
  287. static void reg_r(struct gspca_dev *gspca_dev,
  288. __u16 index,
  289. __u16 length)
  290. {
  291. usb_control_msg(gspca_dev->dev,
  292. usb_rcvctrlpipe(gspca_dev->dev, 0),
  293. 0,
  294. USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
  295. 0, /* value */
  296. index, gspca_dev->usb_buf, length, 500);
  297. }
  298. static int reg_w(struct gspca_dev *gspca_dev,
  299. __u16 req, __u16 index, __u16 value)
  300. {
  301. int ret;
  302. gspca_dbg(gspca_dev, D_USBO, "reg write: [0x%02x] = 0x%02x\n",
  303. index, value);
  304. ret = usb_control_msg(gspca_dev->dev,
  305. usb_sndctrlpipe(gspca_dev->dev, 0),
  306. req,
  307. USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
  308. value, index, NULL, 0, 500);
  309. if (ret < 0)
  310. pr_err("reg write: error %d\n", ret);
  311. return ret;
  312. }
  313. /* returns: negative is error, pos or zero is data */
  314. static int reg_r_12(struct gspca_dev *gspca_dev,
  315. __u16 req, /* bRequest */
  316. __u16 index, /* wIndex */
  317. __u16 length) /* wLength (1 or 2 only) */
  318. {
  319. int ret;
  320. gspca_dev->usb_buf[1] = 0;
  321. ret = usb_control_msg(gspca_dev->dev,
  322. usb_rcvctrlpipe(gspca_dev->dev, 0),
  323. req,
  324. USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
  325. 0, /* value */
  326. index,
  327. gspca_dev->usb_buf, length,
  328. 500); /* timeout */
  329. if (ret < 0) {
  330. pr_err("reg_r_12 err %d\n", ret);
  331. return ret;
  332. }
  333. return (gspca_dev->usb_buf[1] << 8) + gspca_dev->usb_buf[0];
  334. }
  335. /*
  336. * Simple function to wait for a given 8-bit value to be returned from
  337. * a reg_read call.
  338. * Returns: negative is error or timeout, zero is success.
  339. */
  340. static int reg_r_wait(struct gspca_dev *gspca_dev,
  341. __u16 reg, __u16 index, __u16 value)
  342. {
  343. int ret, cnt = 20;
  344. while (--cnt > 0) {
  345. ret = reg_r_12(gspca_dev, reg, index, 1);
  346. if (ret == value)
  347. return 0;
  348. msleep(50);
  349. }
  350. return -EIO;
  351. }
  352. static int write_vector(struct gspca_dev *gspca_dev,
  353. const __u16 data[][3])
  354. {
  355. int ret, i = 0;
  356. while (data[i][0] != 0 || data[i][1] != 0 || data[i][2] != 0) {
  357. ret = reg_w(gspca_dev, data[i][0], data[i][2], data[i][1]);
  358. if (ret < 0)
  359. return ret;
  360. i++;
  361. }
  362. return 0;
  363. }
  364. static int spca50x_setup_qtable(struct gspca_dev *gspca_dev,
  365. unsigned int request,
  366. unsigned int ybase,
  367. unsigned int cbase,
  368. const __u8 qtable[2][64])
  369. {
  370. int i, err;
  371. /* loop over y components */
  372. for (i = 0; i < 64; i++) {
  373. err = reg_w(gspca_dev, request, ybase + i, qtable[0][i]);
  374. if (err < 0)
  375. return err;
  376. }
  377. /* loop over c components */
  378. for (i = 0; i < 64; i++) {
  379. err = reg_w(gspca_dev, request, cbase + i, qtable[1][i]);
  380. if (err < 0)
  381. return err;
  382. }
  383. return 0;
  384. }
  385. static void spca500_ping310(struct gspca_dev *gspca_dev)
  386. {
  387. reg_r(gspca_dev, 0x0d04, 2);
  388. gspca_dbg(gspca_dev, D_STREAM, "ClickSmart310 ping 0x0d04 0x%02x 0x%02x\n",
  389. gspca_dev->usb_buf[0], gspca_dev->usb_buf[1]);
  390. }
  391. static void spca500_clksmart310_init(struct gspca_dev *gspca_dev)
  392. {
  393. reg_r(gspca_dev, 0x0d05, 2);
  394. gspca_dbg(gspca_dev, D_STREAM, "ClickSmart310 init 0x0d05 0x%02x 0x%02x\n",
  395. gspca_dev->usb_buf[0], gspca_dev->usb_buf[1]);
  396. reg_w(gspca_dev, 0x00, 0x8167, 0x5a);
  397. spca500_ping310(gspca_dev);
  398. reg_w(gspca_dev, 0x00, 0x8168, 0x22);
  399. reg_w(gspca_dev, 0x00, 0x816a, 0xc0);
  400. reg_w(gspca_dev, 0x00, 0x816b, 0x0b);
  401. reg_w(gspca_dev, 0x00, 0x8169, 0x25);
  402. reg_w(gspca_dev, 0x00, 0x8157, 0x5b);
  403. reg_w(gspca_dev, 0x00, 0x8158, 0x5b);
  404. reg_w(gspca_dev, 0x00, 0x813f, 0x03);
  405. reg_w(gspca_dev, 0x00, 0x8151, 0x4a);
  406. reg_w(gspca_dev, 0x00, 0x8153, 0x78);
  407. reg_w(gspca_dev, 0x00, 0x0d01, 0x04);
  408. /* 00 for adjust shutter */
  409. reg_w(gspca_dev, 0x00, 0x0d02, 0x01);
  410. reg_w(gspca_dev, 0x00, 0x8169, 0x25);
  411. reg_w(gspca_dev, 0x00, 0x0d01, 0x02);
  412. }
  413. static void spca500_setmode(struct gspca_dev *gspca_dev,
  414. __u8 xmult, __u8 ymult)
  415. {
  416. int mode;
  417. /* set x multiplier */
  418. reg_w(gspca_dev, 0, 0x8001, xmult);
  419. /* set y multiplier */
  420. reg_w(gspca_dev, 0, 0x8002, ymult);
  421. /* use compressed mode, VGA, with mode specific subsample */
  422. mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
  423. reg_w(gspca_dev, 0, 0x8003, mode << 4);
  424. }
  425. static int spca500_full_reset(struct gspca_dev *gspca_dev)
  426. {
  427. int err;
  428. /* send the reset command */
  429. err = reg_w(gspca_dev, 0xe0, 0x0001, 0x0000);
  430. if (err < 0)
  431. return err;
  432. /* wait for the reset to complete */
  433. err = reg_r_wait(gspca_dev, 0x06, 0x0000, 0x0000);
  434. if (err < 0)
  435. return err;
  436. err = reg_w(gspca_dev, 0xe0, 0x0000, 0x0000);
  437. if (err < 0)
  438. return err;
  439. err = reg_r_wait(gspca_dev, 0x06, 0, 0);
  440. if (err < 0) {
  441. gspca_err(gspca_dev, "reg_r_wait() failed\n");
  442. return err;
  443. }
  444. /* all ok */
  445. return 0;
  446. }
  447. /* Synchro the Bridge with sensor */
  448. /* Maybe that will work on all spca500 chip */
  449. /* because i only own a clicksmart310 try for that chip */
  450. /* using spca50x_set_packet_size() cause an Ooops here */
  451. /* usb_set_interface from kernel 2.6.x clear all the urb stuff */
  452. /* up-port the same feature as in 2.4.x kernel */
  453. static int spca500_synch310(struct gspca_dev *gspca_dev)
  454. {
  455. if (usb_set_interface(gspca_dev->dev, gspca_dev->iface, 0) < 0) {
  456. gspca_err(gspca_dev, "Set packet size: set interface error\n");
  457. goto error;
  458. }
  459. spca500_ping310(gspca_dev);
  460. reg_r(gspca_dev, 0x0d00, 1);
  461. /* need alt setting here */
  462. gspca_dbg(gspca_dev, D_PACK, "ClickSmart310 sync alt: %d\n",
  463. gspca_dev->alt);
  464. /* Windoze use pipe with altsetting 6 why 7 here */
  465. if (usb_set_interface(gspca_dev->dev,
  466. gspca_dev->iface,
  467. gspca_dev->alt) < 0) {
  468. gspca_err(gspca_dev, "Set packet size: set interface error\n");
  469. goto error;
  470. }
  471. return 0;
  472. error:
  473. return -EBUSY;
  474. }
  475. static void spca500_reinit(struct gspca_dev *gspca_dev)
  476. {
  477. int err;
  478. __u8 Data;
  479. /* some unknown command from Aiptek pocket dv and family300 */
  480. reg_w(gspca_dev, 0x00, 0x0d01, 0x01);
  481. reg_w(gspca_dev, 0x00, 0x0d03, 0x00);
  482. reg_w(gspca_dev, 0x00, 0x0d02, 0x01);
  483. /* enable drop packet */
  484. reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
  485. err = spca50x_setup_qtable(gspca_dev, 0x00, 0x8800, 0x8840,
  486. qtable_pocketdv);
  487. if (err < 0)
  488. gspca_err(gspca_dev, "spca50x_setup_qtable failed on init\n");
  489. /* set qtable index */
  490. reg_w(gspca_dev, 0x00, 0x8880, 2);
  491. /* family cam Quicksmart stuff */
  492. reg_w(gspca_dev, 0x00, 0x800a, 0x00);
  493. /* Set agc transfer: synced between frames */
  494. reg_w(gspca_dev, 0x00, 0x820f, 0x01);
  495. /* Init SDRAM - needed for SDRAM access */
  496. reg_w(gspca_dev, 0x00, 0x870a, 0x04);
  497. /*Start init sequence or stream */
  498. reg_w(gspca_dev, 0, 0x8003, 0x00);
  499. /* switch to video camera mode */
  500. reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
  501. msleep(2000);
  502. if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0) {
  503. reg_r(gspca_dev, 0x816b, 1);
  504. Data = gspca_dev->usb_buf[0];
  505. reg_w(gspca_dev, 0x00, 0x816b, Data);
  506. }
  507. }
  508. /* this function is called at probe time */
  509. static int sd_config(struct gspca_dev *gspca_dev,
  510. const struct usb_device_id *id)
  511. {
  512. struct sd *sd = (struct sd *) gspca_dev;
  513. struct cam *cam;
  514. cam = &gspca_dev->cam;
  515. sd->subtype = id->driver_info;
  516. if (sd->subtype != LogitechClickSmart310) {
  517. cam->cam_mode = vga_mode;
  518. cam->nmodes = ARRAY_SIZE(vga_mode);
  519. } else {
  520. cam->cam_mode = sif_mode;
  521. cam->nmodes = ARRAY_SIZE(sif_mode);
  522. }
  523. return 0;
  524. }
  525. /* this function is called at probe and resume time */
  526. static int sd_init(struct gspca_dev *gspca_dev)
  527. {
  528. struct sd *sd = (struct sd *) gspca_dev;
  529. /* initialisation of spca500 based cameras is deferred */
  530. gspca_dbg(gspca_dev, D_STREAM, "SPCA500 init\n");
  531. if (sd->subtype == LogitechClickSmart310)
  532. spca500_clksmart310_init(gspca_dev);
  533. /* else
  534. spca500_initialise(gspca_dev); */
  535. gspca_dbg(gspca_dev, D_STREAM, "SPCA500 init done\n");
  536. return 0;
  537. }
  538. static int sd_start(struct gspca_dev *gspca_dev)
  539. {
  540. struct sd *sd = (struct sd *) gspca_dev;
  541. int err;
  542. __u8 Data;
  543. __u8 xmult, ymult;
  544. /* create the JPEG header */
  545. jpeg_define(sd->jpeg_hdr, gspca_dev->pixfmt.height,
  546. gspca_dev->pixfmt.width,
  547. 0x22); /* JPEG 411 */
  548. jpeg_set_qual(sd->jpeg_hdr, QUALITY);
  549. if (sd->subtype == LogitechClickSmart310) {
  550. xmult = 0x16;
  551. ymult = 0x12;
  552. } else {
  553. xmult = 0x28;
  554. ymult = 0x1e;
  555. }
  556. /* is there a sensor here ? */
  557. reg_r(gspca_dev, 0x8a04, 1);
  558. gspca_dbg(gspca_dev, D_STREAM, "Spca500 Sensor Address 0x%02x\n",
  559. gspca_dev->usb_buf[0]);
  560. gspca_dbg(gspca_dev, D_STREAM, "Spca500 curr_mode: %d Xmult: 0x%02x, Ymult: 0x%02x",
  561. gspca_dev->curr_mode, xmult, ymult);
  562. /* setup qtable */
  563. switch (sd->subtype) {
  564. case LogitechClickSmart310:
  565. spca500_setmode(gspca_dev, xmult, ymult);
  566. /* enable drop packet */
  567. reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
  568. reg_w(gspca_dev, 0x00, 0x8880, 3);
  569. err = spca50x_setup_qtable(gspca_dev,
  570. 0x00, 0x8800, 0x8840,
  571. qtable_creative_pccam);
  572. if (err < 0)
  573. gspca_err(gspca_dev, "spca50x_setup_qtable failed\n");
  574. /* Init SDRAM - needed for SDRAM access */
  575. reg_w(gspca_dev, 0x00, 0x870a, 0x04);
  576. /* switch to video camera mode */
  577. reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
  578. msleep(500);
  579. if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0)
  580. gspca_err(gspca_dev, "reg_r_wait() failed\n");
  581. reg_r(gspca_dev, 0x816b, 1);
  582. Data = gspca_dev->usb_buf[0];
  583. reg_w(gspca_dev, 0x00, 0x816b, Data);
  584. spca500_synch310(gspca_dev);
  585. write_vector(gspca_dev, spca500_visual_defaults);
  586. spca500_setmode(gspca_dev, xmult, ymult);
  587. /* enable drop packet */
  588. err = reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
  589. if (err < 0)
  590. gspca_err(gspca_dev, "failed to enable drop packet\n");
  591. reg_w(gspca_dev, 0x00, 0x8880, 3);
  592. err = spca50x_setup_qtable(gspca_dev,
  593. 0x00, 0x8800, 0x8840,
  594. qtable_creative_pccam);
  595. if (err < 0)
  596. gspca_err(gspca_dev, "spca50x_setup_qtable failed\n");
  597. /* Init SDRAM - needed for SDRAM access */
  598. reg_w(gspca_dev, 0x00, 0x870a, 0x04);
  599. /* switch to video camera mode */
  600. reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
  601. if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0)
  602. gspca_err(gspca_dev, "reg_r_wait() failed\n");
  603. reg_r(gspca_dev, 0x816b, 1);
  604. Data = gspca_dev->usb_buf[0];
  605. reg_w(gspca_dev, 0x00, 0x816b, Data);
  606. break;
  607. case CreativePCCam300: /* Creative PC-CAM 300 640x480 CCD */
  608. case IntelPocketPCCamera: /* FIXME: Temporary fix for
  609. * Intel Pocket PC Camera
  610. * - NWG (Sat 29th March 2003) */
  611. /* do a full reset */
  612. err = spca500_full_reset(gspca_dev);
  613. if (err < 0)
  614. gspca_err(gspca_dev, "spca500_full_reset failed\n");
  615. /* enable drop packet */
  616. err = reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
  617. if (err < 0)
  618. gspca_err(gspca_dev, "failed to enable drop packet\n");
  619. reg_w(gspca_dev, 0x00, 0x8880, 3);
  620. err = spca50x_setup_qtable(gspca_dev,
  621. 0x00, 0x8800, 0x8840,
  622. qtable_creative_pccam);
  623. if (err < 0)
  624. gspca_err(gspca_dev, "spca50x_setup_qtable failed\n");
  625. spca500_setmode(gspca_dev, xmult, ymult);
  626. reg_w(gspca_dev, 0x20, 0x0001, 0x0004);
  627. /* switch to video camera mode */
  628. reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
  629. if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0)
  630. gspca_err(gspca_dev, "reg_r_wait() failed\n");
  631. reg_r(gspca_dev, 0x816b, 1);
  632. Data = gspca_dev->usb_buf[0];
  633. reg_w(gspca_dev, 0x00, 0x816b, Data);
  634. /* write_vector(gspca_dev, spca500_visual_defaults); */
  635. break;
  636. case KodakEZ200: /* Kodak EZ200 */
  637. /* do a full reset */
  638. err = spca500_full_reset(gspca_dev);
  639. if (err < 0)
  640. gspca_err(gspca_dev, "spca500_full_reset failed\n");
  641. /* enable drop packet */
  642. reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
  643. reg_w(gspca_dev, 0x00, 0x8880, 0);
  644. err = spca50x_setup_qtable(gspca_dev,
  645. 0x00, 0x8800, 0x8840,
  646. qtable_kodak_ez200);
  647. if (err < 0)
  648. gspca_err(gspca_dev, "spca50x_setup_qtable failed\n");
  649. spca500_setmode(gspca_dev, xmult, ymult);
  650. reg_w(gspca_dev, 0x20, 0x0001, 0x0004);
  651. /* switch to video camera mode */
  652. reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
  653. if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0)
  654. gspca_err(gspca_dev, "reg_r_wait() failed\n");
  655. reg_r(gspca_dev, 0x816b, 1);
  656. Data = gspca_dev->usb_buf[0];
  657. reg_w(gspca_dev, 0x00, 0x816b, Data);
  658. /* write_vector(gspca_dev, spca500_visual_defaults); */
  659. break;
  660. case BenqDC1016:
  661. case DLinkDSC350: /* FamilyCam 300 */
  662. case AiptekPocketDV: /* Aiptek PocketDV */
  663. case Gsmartmini: /*Mustek Gsmart Mini */
  664. case MustekGsmart300: /* Mustek Gsmart 300 */
  665. case PalmPixDC85:
  666. case Optimedia:
  667. case ToptroIndus:
  668. case AgfaCl20:
  669. spca500_reinit(gspca_dev);
  670. reg_w(gspca_dev, 0x00, 0x0d01, 0x01);
  671. /* enable drop packet */
  672. reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
  673. err = spca50x_setup_qtable(gspca_dev,
  674. 0x00, 0x8800, 0x8840, qtable_pocketdv);
  675. if (err < 0)
  676. gspca_err(gspca_dev, "spca50x_setup_qtable failed\n");
  677. reg_w(gspca_dev, 0x00, 0x8880, 2);
  678. /* familycam Quicksmart pocketDV stuff */
  679. reg_w(gspca_dev, 0x00, 0x800a, 0x00);
  680. /* Set agc transfer: synced between frames */
  681. reg_w(gspca_dev, 0x00, 0x820f, 0x01);
  682. /* Init SDRAM - needed for SDRAM access */
  683. reg_w(gspca_dev, 0x00, 0x870a, 0x04);
  684. spca500_setmode(gspca_dev, xmult, ymult);
  685. /* switch to video camera mode */
  686. reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
  687. reg_r_wait(gspca_dev, 0, 0x8000, 0x44);
  688. reg_r(gspca_dev, 0x816b, 1);
  689. Data = gspca_dev->usb_buf[0];
  690. reg_w(gspca_dev, 0x00, 0x816b, Data);
  691. break;
  692. case LogitechTraveler:
  693. case LogitechClickSmart510:
  694. reg_w(gspca_dev, 0x02, 0x00, 0x00);
  695. /* enable drop packet */
  696. reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
  697. err = spca50x_setup_qtable(gspca_dev,
  698. 0x00, 0x8800,
  699. 0x8840, qtable_creative_pccam);
  700. if (err < 0)
  701. gspca_err(gspca_dev, "spca50x_setup_qtable failed\n");
  702. reg_w(gspca_dev, 0x00, 0x8880, 3);
  703. reg_w(gspca_dev, 0x00, 0x800a, 0x00);
  704. /* Init SDRAM - needed for SDRAM access */
  705. reg_w(gspca_dev, 0x00, 0x870a, 0x04);
  706. spca500_setmode(gspca_dev, xmult, ymult);
  707. /* switch to video camera mode */
  708. reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
  709. reg_r_wait(gspca_dev, 0, 0x8000, 0x44);
  710. reg_r(gspca_dev, 0x816b, 1);
  711. Data = gspca_dev->usb_buf[0];
  712. reg_w(gspca_dev, 0x00, 0x816b, Data);
  713. write_vector(gspca_dev, Clicksmart510_defaults);
  714. break;
  715. }
  716. return 0;
  717. }
  718. static void sd_stopN(struct gspca_dev *gspca_dev)
  719. {
  720. reg_w(gspca_dev, 0, 0x8003, 0x00);
  721. /* switch to video camera mode */
  722. reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
  723. reg_r(gspca_dev, 0x8000, 1);
  724. gspca_dbg(gspca_dev, D_STREAM, "stop SPCA500 done reg8000: 0x%2x\n",
  725. gspca_dev->usb_buf[0]);
  726. }
  727. static void sd_pkt_scan(struct gspca_dev *gspca_dev,
  728. u8 *data, /* isoc packet */
  729. int len) /* iso packet length */
  730. {
  731. struct sd *sd = (struct sd *) gspca_dev;
  732. int i;
  733. static __u8 ffd9[] = {0xff, 0xd9};
  734. /* frames are jpeg 4.1.1 without 0xff escape */
  735. if (data[0] == 0xff) {
  736. if (data[1] != 0x01) { /* drop packet */
  737. /* gspca_dev->last_packet_type = DISCARD_PACKET; */
  738. return;
  739. }
  740. gspca_frame_add(gspca_dev, LAST_PACKET,
  741. ffd9, 2);
  742. /* put the JPEG header in the new frame */
  743. gspca_frame_add(gspca_dev, FIRST_PACKET,
  744. sd->jpeg_hdr, JPEG_HDR_SZ);
  745. data += SPCA500_OFFSET_DATA;
  746. len -= SPCA500_OFFSET_DATA;
  747. } else {
  748. data += 1;
  749. len -= 1;
  750. }
  751. /* add 0x00 after 0xff */
  752. i = 0;
  753. do {
  754. if (data[i] == 0xff) {
  755. gspca_frame_add(gspca_dev, INTER_PACKET,
  756. data, i + 1);
  757. len -= i;
  758. data += i;
  759. *data = 0x00;
  760. i = 0;
  761. }
  762. i++;
  763. } while (i < len);
  764. gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
  765. }
  766. static void setbrightness(struct gspca_dev *gspca_dev, s32 val)
  767. {
  768. reg_w(gspca_dev, 0x00, 0x8167,
  769. (__u8) (val - 128));
  770. }
  771. static void setcontrast(struct gspca_dev *gspca_dev, s32 val)
  772. {
  773. reg_w(gspca_dev, 0x00, 0x8168, val);
  774. }
  775. static void setcolors(struct gspca_dev *gspca_dev, s32 val)
  776. {
  777. reg_w(gspca_dev, 0x00, 0x8169, val);
  778. }
  779. static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
  780. {
  781. struct gspca_dev *gspca_dev =
  782. container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
  783. gspca_dev->usb_err = 0;
  784. if (!gspca_dev->streaming)
  785. return 0;
  786. switch (ctrl->id) {
  787. case V4L2_CID_BRIGHTNESS:
  788. setbrightness(gspca_dev, ctrl->val);
  789. break;
  790. case V4L2_CID_CONTRAST:
  791. setcontrast(gspca_dev, ctrl->val);
  792. break;
  793. case V4L2_CID_SATURATION:
  794. setcolors(gspca_dev, ctrl->val);
  795. break;
  796. }
  797. return gspca_dev->usb_err;
  798. }
  799. static const struct v4l2_ctrl_ops sd_ctrl_ops = {
  800. .s_ctrl = sd_s_ctrl,
  801. };
  802. static int sd_init_controls(struct gspca_dev *gspca_dev)
  803. {
  804. struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
  805. gspca_dev->vdev.ctrl_handler = hdl;
  806. v4l2_ctrl_handler_init(hdl, 3);
  807. v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
  808. V4L2_CID_BRIGHTNESS, 0, 255, 1, 127);
  809. v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
  810. V4L2_CID_CONTRAST, 0, 63, 1, 31);
  811. v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
  812. V4L2_CID_SATURATION, 0, 63, 1, 31);
  813. if (hdl->error) {
  814. pr_err("Could not initialize controls\n");
  815. return hdl->error;
  816. }
  817. return 0;
  818. }
  819. /* sub-driver description */
  820. static const struct sd_desc sd_desc = {
  821. .name = MODULE_NAME,
  822. .config = sd_config,
  823. .init = sd_init,
  824. .init_controls = sd_init_controls,
  825. .start = sd_start,
  826. .stopN = sd_stopN,
  827. .pkt_scan = sd_pkt_scan,
  828. };
  829. /* -- module initialisation -- */
  830. static const struct usb_device_id device_table[] = {
  831. {USB_DEVICE(0x040a, 0x0300), .driver_info = KodakEZ200},
  832. {USB_DEVICE(0x041e, 0x400a), .driver_info = CreativePCCam300},
  833. {USB_DEVICE(0x046d, 0x0890), .driver_info = LogitechTraveler},
  834. {USB_DEVICE(0x046d, 0x0900), .driver_info = LogitechClickSmart310},
  835. {USB_DEVICE(0x046d, 0x0901), .driver_info = LogitechClickSmart510},
  836. {USB_DEVICE(0x04a5, 0x300c), .driver_info = BenqDC1016},
  837. {USB_DEVICE(0x04fc, 0x7333), .driver_info = PalmPixDC85},
  838. {USB_DEVICE(0x055f, 0xc200), .driver_info = MustekGsmart300},
  839. {USB_DEVICE(0x055f, 0xc220), .driver_info = Gsmartmini},
  840. {USB_DEVICE(0x06bd, 0x0404), .driver_info = AgfaCl20},
  841. {USB_DEVICE(0x06be, 0x0800), .driver_info = Optimedia},
  842. {USB_DEVICE(0x084d, 0x0003), .driver_info = DLinkDSC350},
  843. {USB_DEVICE(0x08ca, 0x0103), .driver_info = AiptekPocketDV},
  844. {USB_DEVICE(0x2899, 0x012c), .driver_info = ToptroIndus},
  845. {USB_DEVICE(0x8086, 0x0630), .driver_info = IntelPocketPCCamera},
  846. {}
  847. };
  848. MODULE_DEVICE_TABLE(usb, device_table);
  849. /* -- device connect -- */
  850. static int sd_probe(struct usb_interface *intf,
  851. const struct usb_device_id *id)
  852. {
  853. return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
  854. THIS_MODULE);
  855. }
  856. static struct usb_driver sd_driver = {
  857. .name = MODULE_NAME,
  858. .id_table = device_table,
  859. .probe = sd_probe,
  860. .disconnect = gspca_disconnect,
  861. #ifdef CONFIG_PM
  862. .suspend = gspca_suspend,
  863. .resume = gspca_resume,
  864. .reset_resume = gspca_resume,
  865. #endif
  866. };
  867. module_usb_driver(sd_driver);