/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c

https://bitbucket.org/slukk/jb-tsm-kernel-4.2 · C · 573 lines · 406 code · 91 blank · 76 comment · 28 complexity · 57191a37be55848e3f1f6411c7a06e46 MD5 · raw file

  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 const struct ctrl pb0100_ctrl[] = {
  47. #define GAIN_IDX 0
  48. {
  49. {
  50. .id = V4L2_CID_GAIN,
  51. .type = V4L2_CTRL_TYPE_INTEGER,
  52. .name = "Gain",
  53. .minimum = 0,
  54. .maximum = 255,
  55. .step = 1,
  56. .default_value = 128
  57. },
  58. .set = pb0100_set_gain,
  59. .get = pb0100_get_gain
  60. },
  61. #define RED_BALANCE_IDX 1
  62. {
  63. {
  64. .id = V4L2_CID_RED_BALANCE,
  65. .type = V4L2_CTRL_TYPE_INTEGER,
  66. .name = "Red Balance",
  67. .minimum = -255,
  68. .maximum = 255,
  69. .step = 1,
  70. .default_value = 0
  71. },
  72. .set = pb0100_set_red_balance,
  73. .get = pb0100_get_red_balance
  74. },
  75. #define BLUE_BALANCE_IDX 2
  76. {
  77. {
  78. .id = V4L2_CID_BLUE_BALANCE,
  79. .type = V4L2_CTRL_TYPE_INTEGER,
  80. .name = "Blue Balance",
  81. .minimum = -255,
  82. .maximum = 255,
  83. .step = 1,
  84. .default_value = 0
  85. },
  86. .set = pb0100_set_blue_balance,
  87. .get = pb0100_get_blue_balance
  88. },
  89. #define EXPOSURE_IDX 3
  90. {
  91. {
  92. .id = V4L2_CID_EXPOSURE,
  93. .type = V4L2_CTRL_TYPE_INTEGER,
  94. .name = "Exposure",
  95. .minimum = 0,
  96. .maximum = 511,
  97. .step = 1,
  98. .default_value = 12
  99. },
  100. .set = pb0100_set_exposure,
  101. .get = pb0100_get_exposure
  102. },
  103. #define AUTOGAIN_IDX 4
  104. {
  105. {
  106. .id = V4L2_CID_AUTOGAIN,
  107. .type = V4L2_CTRL_TYPE_BOOLEAN,
  108. .name = "Automatic Gain and Exposure",
  109. .minimum = 0,
  110. .maximum = 1,
  111. .step = 1,
  112. .default_value = 1
  113. },
  114. .set = pb0100_set_autogain,
  115. .get = pb0100_get_autogain
  116. },
  117. #define AUTOGAIN_TARGET_IDX 5
  118. {
  119. {
  120. .id = V4L2_CTRL_CLASS_USER + 0x1000,
  121. .type = V4L2_CTRL_TYPE_INTEGER,
  122. .name = "Automatic Gain Target",
  123. .minimum = 0,
  124. .maximum = 255,
  125. .step = 1,
  126. .default_value = 128
  127. },
  128. .set = pb0100_set_autogain_target,
  129. .get = pb0100_get_autogain_target
  130. },
  131. #define NATURAL_IDX 6
  132. {
  133. {
  134. .id = V4L2_CTRL_CLASS_USER + 0x1001,
  135. .type = V4L2_CTRL_TYPE_BOOLEAN,
  136. .name = "Natural Light Source",
  137. .minimum = 0,
  138. .maximum = 1,
  139. .step = 1,
  140. .default_value = 1
  141. },
  142. .set = pb0100_set_natural,
  143. .get = pb0100_get_natural
  144. }
  145. };
  146. static struct v4l2_pix_format pb0100_mode[] = {
  147. /* low res / subsample modes disabled as they are only half res horizontal,
  148. halving the vertical resolution does not seem to work */
  149. {
  150. 320,
  151. 240,
  152. V4L2_PIX_FMT_SGRBG8,
  153. V4L2_FIELD_NONE,
  154. .sizeimage = 320 * 240,
  155. .bytesperline = 320,
  156. .colorspace = V4L2_COLORSPACE_SRGB,
  157. .priv = PB0100_CROP_TO_VGA
  158. },
  159. {
  160. 352,
  161. 288,
  162. V4L2_PIX_FMT_SGRBG8,
  163. V4L2_FIELD_NONE,
  164. .sizeimage = 352 * 288,
  165. .bytesperline = 352,
  166. .colorspace = V4L2_COLORSPACE_SRGB,
  167. .priv = 0
  168. }
  169. };
  170. static int pb0100_probe(struct sd *sd)
  171. {
  172. u16 sensor;
  173. int i, err;
  174. s32 *sensor_settings;
  175. err = stv06xx_read_sensor(sd, PB_IDENT, &sensor);
  176. if (err < 0)
  177. return -ENODEV;
  178. if ((sensor >> 8) == 0x64) {
  179. sensor_settings = kmalloc(
  180. ARRAY_SIZE(pb0100_ctrl) * sizeof(s32),
  181. GFP_KERNEL);
  182. if (!sensor_settings)
  183. return -ENOMEM;
  184. info("Photobit pb0100 sensor detected");
  185. sd->gspca_dev.cam.cam_mode = pb0100_mode;
  186. sd->gspca_dev.cam.nmodes = ARRAY_SIZE(pb0100_mode);
  187. sd->desc.ctrls = pb0100_ctrl;
  188. sd->desc.nctrls = ARRAY_SIZE(pb0100_ctrl);
  189. for (i = 0; i < sd->desc.nctrls; i++)
  190. sensor_settings[i] = pb0100_ctrl[i].qctrl.default_value;
  191. sd->sensor_priv = sensor_settings;
  192. return 0;
  193. }
  194. return -ENODEV;
  195. }
  196. static int pb0100_start(struct sd *sd)
  197. {
  198. int err, packet_size, max_packet_size;
  199. struct usb_host_interface *alt;
  200. struct usb_interface *intf;
  201. struct cam *cam = &sd->gspca_dev.cam;
  202. s32 *sensor_settings = sd->sensor_priv;
  203. u32 mode = cam->cam_mode[sd->gspca_dev.curr_mode].priv;
  204. intf = usb_ifnum_to_if(sd->gspca_dev.dev, sd->gspca_dev.iface);
  205. alt = usb_altnum_to_altsetting(intf, sd->gspca_dev.alt);
  206. if (!alt)
  207. return -ENODEV;
  208. packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
  209. /* If we don't have enough bandwidth use a lower framerate */
  210. max_packet_size = sd->sensor->max_packet_size[sd->gspca_dev.curr_mode];
  211. if (packet_size < max_packet_size)
  212. stv06xx_write_sensor(sd, PB_ROWSPEED, BIT(4)|BIT(3)|BIT(1));
  213. else
  214. stv06xx_write_sensor(sd, PB_ROWSPEED, BIT(5)|BIT(3)|BIT(1));
  215. /* Setup sensor window */
  216. if (mode & PB0100_CROP_TO_VGA) {
  217. stv06xx_write_sensor(sd, PB_RSTART, 30);
  218. stv06xx_write_sensor(sd, PB_CSTART, 20);
  219. stv06xx_write_sensor(sd, PB_RWSIZE, 240 - 1);
  220. stv06xx_write_sensor(sd, PB_CWSIZE, 320 - 1);
  221. } else {
  222. stv06xx_write_sensor(sd, PB_RSTART, 8);
  223. stv06xx_write_sensor(sd, PB_CSTART, 4);
  224. stv06xx_write_sensor(sd, PB_RWSIZE, 288 - 1);
  225. stv06xx_write_sensor(sd, PB_CWSIZE, 352 - 1);
  226. }
  227. if (mode & PB0100_SUBSAMPLE) {
  228. stv06xx_write_bridge(sd, STV_Y_CTRL, 0x02); /* Wrong, FIXME */
  229. stv06xx_write_bridge(sd, STV_X_CTRL, 0x06);
  230. stv06xx_write_bridge(sd, STV_SCAN_RATE, 0x10);
  231. } else {
  232. stv06xx_write_bridge(sd, STV_Y_CTRL, 0x01);
  233. stv06xx_write_bridge(sd, STV_X_CTRL, 0x0a);
  234. /* larger -> slower */
  235. stv06xx_write_bridge(sd, STV_SCAN_RATE, 0x20);
  236. }
  237. /* set_gain also sets red and blue balance */
  238. pb0100_set_gain(&sd->gspca_dev, sensor_settings[GAIN_IDX]);
  239. pb0100_set_exposure(&sd->gspca_dev, sensor_settings[EXPOSURE_IDX]);
  240. pb0100_set_autogain_target(&sd->gspca_dev,
  241. sensor_settings[AUTOGAIN_TARGET_IDX]);
  242. pb0100_set_autogain(&sd->gspca_dev, sensor_settings[AUTOGAIN_IDX]);
  243. err = stv06xx_write_sensor(sd, PB_CONTROL, BIT(5)|BIT(3)|BIT(1));
  244. PDEBUG(D_STREAM, "Started stream, status: %d", err);
  245. return (err < 0) ? err : 0;
  246. }
  247. static int pb0100_stop(struct sd *sd)
  248. {
  249. int err;
  250. err = stv06xx_write_sensor(sd, PB_ABORTFRAME, 1);
  251. if (err < 0)
  252. goto out;
  253. /* Set bit 1 to zero */
  254. err = stv06xx_write_sensor(sd, PB_CONTROL, BIT(5)|BIT(3));
  255. PDEBUG(D_STREAM, "Halting stream");
  256. out:
  257. return (err < 0) ? err : 0;
  258. }
  259. static void pb0100_disconnect(struct sd *sd)
  260. {
  261. sd->sensor = NULL;
  262. kfree(sd->sensor_priv);
  263. }
  264. /* FIXME: Sort the init commands out and put them into tables,
  265. this is only for getting the camera to work */
  266. /* FIXME: No error handling for now,
  267. add this once the init has been converted to proper tables */
  268. static int pb0100_init(struct sd *sd)
  269. {
  270. stv06xx_write_bridge(sd, STV_REG00, 1);
  271. stv06xx_write_bridge(sd, STV_SCAN_RATE, 0);
  272. /* Reset sensor */
  273. stv06xx_write_sensor(sd, PB_RESET, 1);
  274. stv06xx_write_sensor(sd, PB_RESET, 0);
  275. /* Disable chip */
  276. stv06xx_write_sensor(sd, PB_CONTROL, BIT(5)|BIT(3));
  277. /* Gain stuff...*/
  278. stv06xx_write_sensor(sd, PB_PREADCTRL, BIT(12)|BIT(10)|BIT(6));
  279. stv06xx_write_sensor(sd, PB_ADCGLOBALGAIN, 12);
  280. /* Set up auto-exposure */
  281. /* ADC VREF_HI new setting for a transition
  282. from the Expose1 to the Expose2 setting */
  283. stv06xx_write_sensor(sd, PB_R28, 12);
  284. /* gain max for autoexposure */
  285. stv06xx_write_sensor(sd, PB_ADCMAXGAIN, 180);
  286. /* gain min for autoexposure */
  287. stv06xx_write_sensor(sd, PB_ADCMINGAIN, 12);
  288. /* Maximum frame integration time (programmed into R8)
  289. allowed for auto-exposure routine */
  290. stv06xx_write_sensor(sd, PB_R54, 3);
  291. /* Minimum frame integration time (programmed into R8)
  292. allowed for auto-exposure routine */
  293. stv06xx_write_sensor(sd, PB_R55, 0);
  294. stv06xx_write_sensor(sd, PB_UPDATEINT, 1);
  295. /* R15 Expose0 (maximum that auto-exposure may use) */
  296. stv06xx_write_sensor(sd, PB_R15, 800);
  297. /* R17 Expose2 (minimum that auto-exposure may use) */
  298. stv06xx_write_sensor(sd, PB_R17, 10);
  299. stv06xx_write_sensor(sd, PB_EXPGAIN, 0);
  300. /* 0x14 */
  301. stv06xx_write_sensor(sd, PB_VOFFSET, 0);
  302. /* 0x0D */
  303. stv06xx_write_sensor(sd, PB_ADCGAINH, 11);
  304. /* Set black level (important!) */
  305. stv06xx_write_sensor(sd, PB_ADCGAINL, 0);
  306. /* ??? */
  307. stv06xx_write_bridge(sd, STV_REG00, 0x11);
  308. stv06xx_write_bridge(sd, STV_REG03, 0x45);
  309. stv06xx_write_bridge(sd, STV_REG04, 0x07);
  310. /* Scan/timing for the sensor */
  311. stv06xx_write_sensor(sd, PB_ROWSPEED, BIT(4)|BIT(3)|BIT(1));
  312. stv06xx_write_sensor(sd, PB_CFILLIN, 14);
  313. stv06xx_write_sensor(sd, PB_VBL, 0);
  314. stv06xx_write_sensor(sd, PB_FINTTIME, 0);
  315. stv06xx_write_sensor(sd, PB_RINTTIME, 123);
  316. stv06xx_write_bridge(sd, STV_REG01, 0xc2);
  317. stv06xx_write_bridge(sd, STV_REG02, 0xb0);
  318. return 0;
  319. }
  320. static int pb0100_dump(struct sd *sd)
  321. {
  322. return 0;
  323. }
  324. static int pb0100_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
  325. {
  326. struct sd *sd = (struct sd *) gspca_dev;
  327. s32 *sensor_settings = sd->sensor_priv;
  328. *val = sensor_settings[GAIN_IDX];
  329. return 0;
  330. }
  331. static int pb0100_set_gain(struct gspca_dev *gspca_dev, __s32 val)
  332. {
  333. int err;
  334. struct sd *sd = (struct sd *) gspca_dev;
  335. s32 *sensor_settings = sd->sensor_priv;
  336. if (sensor_settings[AUTOGAIN_IDX])
  337. return -EBUSY;
  338. sensor_settings[GAIN_IDX] = val;
  339. err = stv06xx_write_sensor(sd, PB_G1GAIN, val);
  340. if (!err)
  341. err = stv06xx_write_sensor(sd, PB_G2GAIN, val);
  342. PDEBUG(D_V4L2, "Set green gain to %d, status: %d", val, err);
  343. if (!err)
  344. err = pb0100_set_red_balance(gspca_dev,
  345. sensor_settings[RED_BALANCE_IDX]);
  346. if (!err)
  347. err = pb0100_set_blue_balance(gspca_dev,
  348. sensor_settings[BLUE_BALANCE_IDX]);
  349. return err;
  350. }
  351. static int pb0100_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val)
  352. {
  353. struct sd *sd = (struct sd *) gspca_dev;
  354. s32 *sensor_settings = sd->sensor_priv;
  355. *val = sensor_settings[RED_BALANCE_IDX];
  356. return 0;
  357. }
  358. static int pb0100_set_red_balance(struct gspca_dev *gspca_dev, __s32 val)
  359. {
  360. int err;
  361. struct sd *sd = (struct sd *) gspca_dev;
  362. s32 *sensor_settings = sd->sensor_priv;
  363. if (sensor_settings[AUTOGAIN_IDX])
  364. return -EBUSY;
  365. sensor_settings[RED_BALANCE_IDX] = val;
  366. val += sensor_settings[GAIN_IDX];
  367. if (val < 0)
  368. val = 0;
  369. else if (val > 255)
  370. val = 255;
  371. err = stv06xx_write_sensor(sd, PB_RGAIN, val);
  372. PDEBUG(D_V4L2, "Set red gain to %d, status: %d", val, err);
  373. return err;
  374. }
  375. static int pb0100_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val)
  376. {
  377. struct sd *sd = (struct sd *) gspca_dev;
  378. s32 *sensor_settings = sd->sensor_priv;
  379. *val = sensor_settings[BLUE_BALANCE_IDX];
  380. return 0;
  381. }
  382. static int pb0100_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val)
  383. {
  384. int err;
  385. struct sd *sd = (struct sd *) gspca_dev;
  386. s32 *sensor_settings = sd->sensor_priv;
  387. if (sensor_settings[AUTOGAIN_IDX])
  388. return -EBUSY;
  389. sensor_settings[BLUE_BALANCE_IDX] = val;
  390. val += sensor_settings[GAIN_IDX];
  391. if (val < 0)
  392. val = 0;
  393. else if (val > 255)
  394. val = 255;
  395. err = stv06xx_write_sensor(sd, PB_BGAIN, val);
  396. PDEBUG(D_V4L2, "Set blue gain to %d, status: %d", val, err);
  397. return err;
  398. }
  399. static int pb0100_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
  400. {
  401. struct sd *sd = (struct sd *) gspca_dev;
  402. s32 *sensor_settings = sd->sensor_priv;
  403. *val = sensor_settings[EXPOSURE_IDX];
  404. return 0;
  405. }
  406. static int pb0100_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
  407. {
  408. int err;
  409. struct sd *sd = (struct sd *) gspca_dev;
  410. s32 *sensor_settings = sd->sensor_priv;
  411. if (sensor_settings[AUTOGAIN_IDX])
  412. return -EBUSY;
  413. sensor_settings[EXPOSURE_IDX] = val;
  414. err = stv06xx_write_sensor(sd, PB_RINTTIME, val);
  415. PDEBUG(D_V4L2, "Set exposure to %d, status: %d", val, err);
  416. return err;
  417. }
  418. static int pb0100_get_autogain(struct gspca_dev *gspca_dev, __s32 *val)
  419. {
  420. struct sd *sd = (struct sd *) gspca_dev;
  421. s32 *sensor_settings = sd->sensor_priv;
  422. *val = sensor_settings[AUTOGAIN_IDX];
  423. return 0;
  424. }
  425. static int pb0100_set_autogain(struct gspca_dev *gspca_dev, __s32 val)
  426. {
  427. int err;
  428. struct sd *sd = (struct sd *) gspca_dev;
  429. s32 *sensor_settings = sd->sensor_priv;
  430. sensor_settings[AUTOGAIN_IDX] = val;
  431. if (sensor_settings[AUTOGAIN_IDX]) {
  432. if (sensor_settings[NATURAL_IDX])
  433. val = BIT(6)|BIT(4)|BIT(0);
  434. else
  435. val = BIT(4)|BIT(0);
  436. } else
  437. val = 0;
  438. err = stv06xx_write_sensor(sd, PB_EXPGAIN, val);
  439. PDEBUG(D_V4L2, "Set autogain to %d (natural: %d), status: %d",
  440. sensor_settings[AUTOGAIN_IDX], sensor_settings[NATURAL_IDX],
  441. err);
  442. return err;
  443. }
  444. static int pb0100_get_autogain_target(struct gspca_dev *gspca_dev, __s32 *val)
  445. {
  446. struct sd *sd = (struct sd *) gspca_dev;
  447. s32 *sensor_settings = sd->sensor_priv;
  448. *val = sensor_settings[AUTOGAIN_TARGET_IDX];
  449. return 0;
  450. }
  451. static int pb0100_set_autogain_target(struct gspca_dev *gspca_dev, __s32 val)
  452. {
  453. int err, totalpixels, brightpixels, darkpixels;
  454. struct sd *sd = (struct sd *) gspca_dev;
  455. s32 *sensor_settings = sd->sensor_priv;
  456. sensor_settings[AUTOGAIN_TARGET_IDX] = val;
  457. /* Number of pixels counted by the sensor when subsampling the pixels.
  458. * Slightly larger than the real value to avoid oscillation */
  459. totalpixels = gspca_dev->width * gspca_dev->height;
  460. totalpixels = totalpixels/(8*8) + totalpixels/(64*64);
  461. brightpixels = (totalpixels * val) >> 8;
  462. darkpixels = totalpixels - brightpixels;
  463. err = stv06xx_write_sensor(sd, PB_R21, brightpixels);
  464. if (!err)
  465. err = stv06xx_write_sensor(sd, PB_R22, darkpixels);
  466. PDEBUG(D_V4L2, "Set autogain target to %d, status: %d", val, err);
  467. return err;
  468. }
  469. static int pb0100_get_natural(struct gspca_dev *gspca_dev, __s32 *val)
  470. {
  471. struct sd *sd = (struct sd *) gspca_dev;
  472. s32 *sensor_settings = sd->sensor_priv;
  473. *val = sensor_settings[NATURAL_IDX];
  474. return 0;
  475. }
  476. static int pb0100_set_natural(struct gspca_dev *gspca_dev, __s32 val)
  477. {
  478. struct sd *sd = (struct sd *) gspca_dev;
  479. s32 *sensor_settings = sd->sensor_priv;
  480. sensor_settings[NATURAL_IDX] = val;
  481. return pb0100_set_autogain(gspca_dev, sensor_settings[AUTOGAIN_IDX]);
  482. }