stv06xx_pb0100.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430
  1. /*
  2. * Copyright (c) 2001 Jean-Fredric Clere, Nikolas Zimmermann, Georg Acher
  3. * Mark Cave-Ayland, Carlo E Prelz, Dick Streefland
  4. * Copyright (c) 2002, 2003 Tuukka Toivonen
  5. * Copyright (c) 2008 Erik Andrén
  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. * (at your option) 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. * P/N 861037: Sensor HDCS1000 ASIC STV0600
  22. * P/N 861050-0010: Sensor HDCS1000 ASIC STV0600
  23. * P/N 861050-0020: Sensor Photobit PB100 ASIC STV0600-1 - QuickCam Express
  24. * P/N 861055: Sensor ST VV6410 ASIC STV0610 - LEGO cam
  25. * P/N 861075-0040: Sensor HDCS1000 ASIC
  26. * P/N 961179-0700: Sensor ST VV6410 ASIC STV0602 - Dexxa WebCam USB
  27. * P/N 861040-0000: Sensor ST VV6410 ASIC STV0610 - QuickCam Web
  28. */
  29. /*
  30. * The spec file for the PB-0100 suggests the following for best quality
  31. * images after the sensor has been reset :
  32. *
  33. * PB_ADCGAINL = R60 = 0x03 (3 dec) : sets low reference of ADC
  34. to produce good black level
  35. * PB_PREADCTRL = R32 = 0x1400 (5120 dec) : Enables global gain changes
  36. through R53
  37. * PB_ADCMINGAIN = R52 = 0x10 (16 dec) : Sets the minimum gain for
  38. auto-exposure
  39. * PB_ADCGLOBALGAIN = R53 = 0x10 (16 dec) : Sets the global gain
  40. * PB_EXPGAIN = R14 = 0x11 (17 dec) : Sets the auto-exposure value
  41. * PB_UPDATEINT = R23 = 0x02 (2 dec) : Sets the speed on
  42. auto-exposure routine
  43. * PB_CFILLIN = R5 = 0x0E (14 dec) : Sets the frame rate
  44. */
  45. #include "stv06xx_pb0100.h"
  46. static int pb0100_probe(struct sd *sd)
  47. {
  48. u16 sensor;
  49. int i, err;
  50. s32 *sensor_settings;
  51. err = stv06xx_read_sensor(sd, PB_IDENT, &sensor);
  52. if (err < 0)
  53. return -ENODEV;
  54. if ((sensor >> 8) == 0x64) {
  55. sensor_settings = kmalloc(
  56. stv06xx_sensor_pb0100.nctrls * sizeof(s32),
  57. GFP_KERNEL);
  58. if (!sensor_settings)
  59. return -ENOMEM;
  60. info("Photobit pb0100 sensor detected");
  61. sd->gspca_dev.cam.cam_mode = stv06xx_sensor_pb0100.modes;
  62. sd->gspca_dev.cam.nmodes = stv06xx_sensor_pb0100.nmodes;
  63. sd->desc.ctrls = stv06xx_sensor_pb0100.ctrls;
  64. sd->desc.nctrls = stv06xx_sensor_pb0100.nctrls;
  65. for (i = 0; i < stv06xx_sensor_pb0100.nctrls; i++)
  66. sensor_settings[i] = stv06xx_sensor_pb0100.
  67. ctrls[i].qctrl.default_value;
  68. sd->sensor_priv = sensor_settings;
  69. return 0;
  70. }
  71. return -ENODEV;
  72. }
  73. static int pb0100_start(struct sd *sd)
  74. {
  75. int err;
  76. struct cam *cam = &sd->gspca_dev.cam;
  77. s32 *sensor_settings = sd->sensor_priv;
  78. u32 mode = cam->cam_mode[sd->gspca_dev.curr_mode].priv;
  79. /* Setup sensor window */
  80. if (mode & PB0100_CROP_TO_VGA) {
  81. stv06xx_write_sensor(sd, PB_RSTART, 30);
  82. stv06xx_write_sensor(sd, PB_CSTART, 20);
  83. stv06xx_write_sensor(sd, PB_RWSIZE, 240 - 1);
  84. stv06xx_write_sensor(sd, PB_CWSIZE, 320 - 1);
  85. } else {
  86. stv06xx_write_sensor(sd, PB_RSTART, 8);
  87. stv06xx_write_sensor(sd, PB_CSTART, 4);
  88. stv06xx_write_sensor(sd, PB_RWSIZE, 288 - 1);
  89. stv06xx_write_sensor(sd, PB_CWSIZE, 352 - 1);
  90. }
  91. if (mode & PB0100_SUBSAMPLE) {
  92. stv06xx_write_bridge(sd, STV_Y_CTRL, 0x02); /* Wrong, FIXME */
  93. stv06xx_write_bridge(sd, STV_X_CTRL, 0x06);
  94. stv06xx_write_bridge(sd, STV_SCAN_RATE, 0x10);
  95. } else {
  96. stv06xx_write_bridge(sd, STV_Y_CTRL, 0x01);
  97. stv06xx_write_bridge(sd, STV_X_CTRL, 0x0a);
  98. /* larger -> slower */
  99. stv06xx_write_bridge(sd, STV_SCAN_RATE, 0x20);
  100. }
  101. /* set_gain also sets red and blue balance */
  102. pb0100_set_gain(&sd->gspca_dev, sensor_settings[GAIN_IDX]);
  103. pb0100_set_exposure(&sd->gspca_dev, sensor_settings[EXPOSURE_IDX]);
  104. pb0100_set_autogain_target(&sd->gspca_dev,
  105. sensor_settings[AUTOGAIN_TARGET_IDX]);
  106. pb0100_set_autogain(&sd->gspca_dev, sensor_settings[AUTOGAIN_IDX]);
  107. err = stv06xx_write_sensor(sd, PB_CONTROL, BIT(5)|BIT(3)|BIT(1));
  108. PDEBUG(D_STREAM, "Started stream, status: %d", err);
  109. return (err < 0) ? err : 0;
  110. }
  111. static int pb0100_stop(struct sd *sd)
  112. {
  113. int err;
  114. err = stv06xx_write_sensor(sd, PB_ABORTFRAME, 1);
  115. if (err < 0)
  116. goto out;
  117. /* Set bit 1 to zero */
  118. err = stv06xx_write_sensor(sd, PB_CONTROL, BIT(5)|BIT(3));
  119. PDEBUG(D_STREAM, "Halting stream");
  120. out:
  121. return (err < 0) ? err : 0;
  122. }
  123. /* FIXME: Sort the init commands out and put them into tables,
  124. this is only for getting the camera to work */
  125. /* FIXME: No error handling for now,
  126. add this once the init has been converted to proper tables */
  127. static int pb0100_init(struct sd *sd)
  128. {
  129. stv06xx_write_bridge(sd, STV_REG00, 1);
  130. stv06xx_write_bridge(sd, STV_SCAN_RATE, 0);
  131. /* Reset sensor */
  132. stv06xx_write_sensor(sd, PB_RESET, 1);
  133. stv06xx_write_sensor(sd, PB_RESET, 0);
  134. /* Disable chip */
  135. stv06xx_write_sensor(sd, PB_CONTROL, BIT(5)|BIT(3));
  136. /* Gain stuff...*/
  137. stv06xx_write_sensor(sd, PB_PREADCTRL, BIT(12)|BIT(10)|BIT(6));
  138. stv06xx_write_sensor(sd, PB_ADCGLOBALGAIN, 12);
  139. /* Set up auto-exposure */
  140. /* ADC VREF_HI new setting for a transition
  141. from the Expose1 to the Expose2 setting */
  142. stv06xx_write_sensor(sd, PB_R28, 12);
  143. /* gain max for autoexposure */
  144. stv06xx_write_sensor(sd, PB_ADCMAXGAIN, 180);
  145. /* gain min for autoexposure */
  146. stv06xx_write_sensor(sd, PB_ADCMINGAIN, 12);
  147. /* Maximum frame integration time (programmed into R8)
  148. allowed for auto-exposure routine */
  149. stv06xx_write_sensor(sd, PB_R54, 3);
  150. /* Minimum frame integration time (programmed into R8)
  151. allowed for auto-exposure routine */
  152. stv06xx_write_sensor(sd, PB_R55, 0);
  153. stv06xx_write_sensor(sd, PB_UPDATEINT, 1);
  154. /* R15 Expose0 (maximum that auto-exposure may use) */
  155. stv06xx_write_sensor(sd, PB_R15, 800);
  156. /* R17 Expose2 (minimum that auto-exposure may use) */
  157. stv06xx_write_sensor(sd, PB_R17, 10);
  158. stv06xx_write_sensor(sd, PB_EXPGAIN, 0);
  159. /* 0x14 */
  160. stv06xx_write_sensor(sd, PB_VOFFSET, 0);
  161. /* 0x0D */
  162. stv06xx_write_sensor(sd, PB_ADCGAINH, 11);
  163. /* Set black level (important!) */
  164. stv06xx_write_sensor(sd, PB_ADCGAINL, 0);
  165. /* ??? */
  166. stv06xx_write_bridge(sd, STV_REG00, 0x11);
  167. stv06xx_write_bridge(sd, STV_REG03, 0x45);
  168. stv06xx_write_bridge(sd, STV_REG04, 0x07);
  169. /* ISO-Size (0x27b: 635... why? - HDCS uses 847) */
  170. stv06xx_write_bridge(sd, STV_ISO_SIZE_L, 847);
  171. /* Scan/timing for the sensor */
  172. stv06xx_write_sensor(sd, PB_ROWSPEED, BIT(4)|BIT(3)|BIT(1));
  173. stv06xx_write_sensor(sd, PB_CFILLIN, 14);
  174. stv06xx_write_sensor(sd, PB_VBL, 0);
  175. stv06xx_write_sensor(sd, PB_FINTTIME, 0);
  176. stv06xx_write_sensor(sd, PB_RINTTIME, 123);
  177. stv06xx_write_bridge(sd, STV_REG01, 0xc2);
  178. stv06xx_write_bridge(sd, STV_REG02, 0xb0);
  179. return 0;
  180. }
  181. static int pb0100_dump(struct sd *sd)
  182. {
  183. return 0;
  184. }
  185. static int pb0100_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
  186. {
  187. struct sd *sd = (struct sd *) gspca_dev;
  188. s32 *sensor_settings = sd->sensor_priv;
  189. *val = sensor_settings[GAIN_IDX];
  190. return 0;
  191. }
  192. static int pb0100_set_gain(struct gspca_dev *gspca_dev, __s32 val)
  193. {
  194. int err;
  195. struct sd *sd = (struct sd *) gspca_dev;
  196. s32 *sensor_settings = sd->sensor_priv;
  197. if (sensor_settings[AUTOGAIN_IDX])
  198. return -EBUSY;
  199. sensor_settings[GAIN_IDX] = val;
  200. err = stv06xx_write_sensor(sd, PB_G1GAIN, val);
  201. if (!err)
  202. err = stv06xx_write_sensor(sd, PB_G2GAIN, val);
  203. PDEBUG(D_V4L2, "Set green gain to %d, status: %d", val, err);
  204. if (!err)
  205. err = pb0100_set_red_balance(gspca_dev,
  206. sensor_settings[RED_BALANCE_IDX]);
  207. if (!err)
  208. err = pb0100_set_blue_balance(gspca_dev,
  209. sensor_settings[BLUE_BALANCE_IDX]);
  210. return err;
  211. }
  212. static int pb0100_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val)
  213. {
  214. struct sd *sd = (struct sd *) gspca_dev;
  215. s32 *sensor_settings = sd->sensor_priv;
  216. *val = sensor_settings[RED_BALANCE_IDX];
  217. return 0;
  218. }
  219. static int pb0100_set_red_balance(struct gspca_dev *gspca_dev, __s32 val)
  220. {
  221. int err;
  222. struct sd *sd = (struct sd *) gspca_dev;
  223. s32 *sensor_settings = sd->sensor_priv;
  224. if (sensor_settings[AUTOGAIN_IDX])
  225. return -EBUSY;
  226. sensor_settings[RED_BALANCE_IDX] = val;
  227. val += sensor_settings[GAIN_IDX];
  228. if (val < 0)
  229. val = 0;
  230. else if (val > 255)
  231. val = 255;
  232. err = stv06xx_write_sensor(sd, PB_RGAIN, val);
  233. PDEBUG(D_V4L2, "Set red gain to %d, status: %d", val, err);
  234. return err;
  235. }
  236. static int pb0100_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val)
  237. {
  238. struct sd *sd = (struct sd *) gspca_dev;
  239. s32 *sensor_settings = sd->sensor_priv;
  240. *val = sensor_settings[BLUE_BALANCE_IDX];
  241. return 0;
  242. }
  243. static int pb0100_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val)
  244. {
  245. int err;
  246. struct sd *sd = (struct sd *) gspca_dev;
  247. s32 *sensor_settings = sd->sensor_priv;
  248. if (sensor_settings[AUTOGAIN_IDX])
  249. return -EBUSY;
  250. sensor_settings[BLUE_BALANCE_IDX] = val;
  251. val += sensor_settings[GAIN_IDX];
  252. if (val < 0)
  253. val = 0;
  254. else if (val > 255)
  255. val = 255;
  256. err = stv06xx_write_sensor(sd, PB_BGAIN, val);
  257. PDEBUG(D_V4L2, "Set blue gain to %d, status: %d", val, err);
  258. return err;
  259. }
  260. static int pb0100_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
  261. {
  262. struct sd *sd = (struct sd *) gspca_dev;
  263. s32 *sensor_settings = sd->sensor_priv;
  264. *val = sensor_settings[EXPOSURE_IDX];
  265. return 0;
  266. }
  267. static int pb0100_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
  268. {
  269. int err;
  270. struct sd *sd = (struct sd *) gspca_dev;
  271. s32 *sensor_settings = sd->sensor_priv;
  272. if (sensor_settings[AUTOGAIN_IDX])
  273. return -EBUSY;
  274. sensor_settings[EXPOSURE_IDX] = val;
  275. err = stv06xx_write_sensor(sd, PB_RINTTIME, val);
  276. PDEBUG(D_V4L2, "Set exposure to %d, status: %d", val, err);
  277. return err;
  278. }
  279. static int pb0100_get_autogain(struct gspca_dev *gspca_dev, __s32 *val)
  280. {
  281. struct sd *sd = (struct sd *) gspca_dev;
  282. s32 *sensor_settings = sd->sensor_priv;
  283. *val = sensor_settings[AUTOGAIN_IDX];
  284. return 0;
  285. }
  286. static int pb0100_set_autogain(struct gspca_dev *gspca_dev, __s32 val)
  287. {
  288. int err;
  289. struct sd *sd = (struct sd *) gspca_dev;
  290. s32 *sensor_settings = sd->sensor_priv;
  291. sensor_settings[AUTOGAIN_IDX] = val;
  292. if (sensor_settings[AUTOGAIN_IDX]) {
  293. if (sensor_settings[NATURAL_IDX])
  294. val = BIT(6)|BIT(4)|BIT(0);
  295. else
  296. val = BIT(4)|BIT(0);
  297. } else
  298. val = 0;
  299. err = stv06xx_write_sensor(sd, PB_EXPGAIN, val);
  300. PDEBUG(D_V4L2, "Set autogain to %d (natural: %d), status: %d",
  301. sensor_settings[AUTOGAIN_IDX], sensor_settings[NATURAL_IDX],
  302. err);
  303. return err;
  304. }
  305. static int pb0100_get_autogain_target(struct gspca_dev *gspca_dev, __s32 *val)
  306. {
  307. struct sd *sd = (struct sd *) gspca_dev;
  308. s32 *sensor_settings = sd->sensor_priv;
  309. *val = sensor_settings[AUTOGAIN_TARGET_IDX];
  310. return 0;
  311. }
  312. static int pb0100_set_autogain_target(struct gspca_dev *gspca_dev, __s32 val)
  313. {
  314. int err, totalpixels, brightpixels, darkpixels;
  315. struct sd *sd = (struct sd *) gspca_dev;
  316. s32 *sensor_settings = sd->sensor_priv;
  317. sensor_settings[AUTOGAIN_TARGET_IDX] = val;
  318. /* Number of pixels counted by the sensor when subsampling the pixels.
  319. * Slightly larger than the real value to avoid oscillation */
  320. totalpixels = gspca_dev->width * gspca_dev->height;
  321. totalpixels = totalpixels/(8*8) + totalpixels/(64*64);
  322. brightpixels = (totalpixels * val) >> 8;
  323. darkpixels = totalpixels - brightpixels;
  324. err = stv06xx_write_sensor(sd, PB_R21, brightpixels);
  325. if (!err)
  326. err = stv06xx_write_sensor(sd, PB_R22, darkpixels);
  327. PDEBUG(D_V4L2, "Set autogain target to %d, status: %d", val, err);
  328. return err;
  329. }
  330. static int pb0100_get_natural(struct gspca_dev *gspca_dev, __s32 *val)
  331. {
  332. struct sd *sd = (struct sd *) gspca_dev;
  333. s32 *sensor_settings = sd->sensor_priv;
  334. *val = sensor_settings[NATURAL_IDX];
  335. return 0;
  336. }
  337. static int pb0100_set_natural(struct gspca_dev *gspca_dev, __s32 val)
  338. {
  339. struct sd *sd = (struct sd *) gspca_dev;
  340. s32 *sensor_settings = sd->sensor_priv;
  341. sensor_settings[NATURAL_IDX] = val;
  342. return pb0100_set_autogain(gspca_dev, sensor_settings[AUTOGAIN_IDX]);
  343. }