stv06xx_hdcs.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540
  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. * Copyright (c) 2008 Chia-I Wu
  7. *
  8. * This program is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation; either version 2 of the License, or
  11. * (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * P/N 861037: Sensor HDCS1000 ASIC STV0600
  19. * P/N 861050-0010: Sensor HDCS1000 ASIC STV0600
  20. * P/N 861050-0020: Sensor Photobit PB100 ASIC STV0600-1 - QuickCam Express
  21. * P/N 861055: Sensor ST VV6410 ASIC STV0610 - LEGO cam
  22. * P/N 861075-0040: Sensor HDCS1000 ASIC
  23. * P/N 961179-0700: Sensor ST VV6410 ASIC STV0602 - Dexxa WebCam USB
  24. * P/N 861040-0000: Sensor ST VV6410 ASIC STV0610 - QuickCam Web
  25. */
  26. #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  27. #include "stv06xx_hdcs.h"
  28. static struct v4l2_pix_format hdcs1x00_mode[] = {
  29. {
  30. HDCS_1X00_DEF_WIDTH,
  31. HDCS_1X00_DEF_HEIGHT,
  32. V4L2_PIX_FMT_SGRBG8,
  33. V4L2_FIELD_NONE,
  34. .sizeimage =
  35. HDCS_1X00_DEF_WIDTH * HDCS_1X00_DEF_HEIGHT,
  36. .bytesperline = HDCS_1X00_DEF_WIDTH,
  37. .colorspace = V4L2_COLORSPACE_SRGB,
  38. .priv = 1
  39. }
  40. };
  41. static struct v4l2_pix_format hdcs1020_mode[] = {
  42. {
  43. HDCS_1020_DEF_WIDTH,
  44. HDCS_1020_DEF_HEIGHT,
  45. V4L2_PIX_FMT_SGRBG8,
  46. V4L2_FIELD_NONE,
  47. .sizeimage =
  48. HDCS_1020_DEF_WIDTH * HDCS_1020_DEF_HEIGHT,
  49. .bytesperline = HDCS_1020_DEF_WIDTH,
  50. .colorspace = V4L2_COLORSPACE_SRGB,
  51. .priv = 1
  52. }
  53. };
  54. enum hdcs_power_state {
  55. HDCS_STATE_SLEEP,
  56. HDCS_STATE_IDLE,
  57. HDCS_STATE_RUN
  58. };
  59. /* no lock? */
  60. struct hdcs {
  61. enum hdcs_power_state state;
  62. int w, h;
  63. /* visible area of the sensor array */
  64. struct {
  65. int left, top;
  66. int width, height;
  67. int border;
  68. } array;
  69. struct {
  70. /* Column timing overhead */
  71. u8 cto;
  72. /* Column processing overhead */
  73. u8 cpo;
  74. /* Row sample period constant */
  75. u16 rs;
  76. /* Exposure reset duration */
  77. u16 er;
  78. } exp;
  79. int psmp;
  80. };
  81. static int hdcs_reg_write_seq(struct sd *sd, u8 reg, u8 *vals, u8 len)
  82. {
  83. u8 regs[I2C_MAX_BYTES * 2];
  84. int i;
  85. if (unlikely((len <= 0) || (len >= I2C_MAX_BYTES) ||
  86. (reg + len > 0xff)))
  87. return -EINVAL;
  88. for (i = 0; i < len; i++) {
  89. regs[2 * i] = reg;
  90. regs[2 * i + 1] = vals[i];
  91. /* All addresses are shifted left one bit
  92. * as bit 0 toggles r/w */
  93. reg += 2;
  94. }
  95. return stv06xx_write_sensor_bytes(sd, regs, len);
  96. }
  97. static int hdcs_set_state(struct sd *sd, enum hdcs_power_state state)
  98. {
  99. struct hdcs *hdcs = sd->sensor_priv;
  100. u8 val;
  101. int ret;
  102. if (hdcs->state == state)
  103. return 0;
  104. /* we need to go idle before running or sleeping */
  105. if (hdcs->state != HDCS_STATE_IDLE) {
  106. ret = stv06xx_write_sensor(sd, HDCS_REG_CONTROL(sd), 0);
  107. if (ret)
  108. return ret;
  109. }
  110. hdcs->state = HDCS_STATE_IDLE;
  111. if (state == HDCS_STATE_IDLE)
  112. return 0;
  113. switch (state) {
  114. case HDCS_STATE_SLEEP:
  115. val = HDCS_SLEEP_MODE;
  116. break;
  117. case HDCS_STATE_RUN:
  118. val = HDCS_RUN_ENABLE;
  119. break;
  120. default:
  121. return -EINVAL;
  122. }
  123. ret = stv06xx_write_sensor(sd, HDCS_REG_CONTROL(sd), val);
  124. /* Update the state if the write succeeded */
  125. if (!ret)
  126. hdcs->state = state;
  127. return ret;
  128. }
  129. static int hdcs_reset(struct sd *sd)
  130. {
  131. struct hdcs *hdcs = sd->sensor_priv;
  132. int err;
  133. err = stv06xx_write_sensor(sd, HDCS_REG_CONTROL(sd), 1);
  134. if (err < 0)
  135. return err;
  136. err = stv06xx_write_sensor(sd, HDCS_REG_CONTROL(sd), 0);
  137. if (err < 0)
  138. hdcs->state = HDCS_STATE_IDLE;
  139. return err;
  140. }
  141. static int hdcs_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
  142. {
  143. struct sd *sd = (struct sd *) gspca_dev;
  144. struct hdcs *hdcs = sd->sensor_priv;
  145. int rowexp, srowexp;
  146. int max_srowexp;
  147. /* Column time period */
  148. int ct;
  149. /* Column processing period */
  150. int cp;
  151. /* Row processing period */
  152. int rp;
  153. /* Minimum number of column timing periods
  154. within the column processing period */
  155. int mnct;
  156. int cycles, err;
  157. u8 exp[14];
  158. cycles = val * HDCS_CLK_FREQ_MHZ * 257;
  159. ct = hdcs->exp.cto + hdcs->psmp + (HDCS_ADC_START_SIG_DUR + 2);
  160. cp = hdcs->exp.cto + (hdcs->w * ct / 2);
  161. /* the cycles one row takes */
  162. rp = hdcs->exp.rs + cp;
  163. rowexp = cycles / rp;
  164. /* the remaining cycles */
  165. cycles -= rowexp * rp;
  166. /* calculate sub-row exposure */
  167. if (IS_1020(sd)) {
  168. /* see HDCS-1020 datasheet 3.5.6.4, p. 63 */
  169. srowexp = hdcs->w - (cycles + hdcs->exp.er + 13) / ct;
  170. mnct = (hdcs->exp.er + 12 + ct - 1) / ct;
  171. max_srowexp = hdcs->w - mnct;
  172. } else {
  173. /* see HDCS-1000 datasheet 3.4.5.5, p. 61 */
  174. srowexp = cp - hdcs->exp.er - 6 - cycles;
  175. mnct = (hdcs->exp.er + 5 + ct - 1) / ct;
  176. max_srowexp = cp - mnct * ct - 1;
  177. }
  178. if (srowexp < 0)
  179. srowexp = 0;
  180. else if (srowexp > max_srowexp)
  181. srowexp = max_srowexp;
  182. if (IS_1020(sd)) {
  183. exp[0] = HDCS20_CONTROL;
  184. exp[1] = 0x00; /* Stop streaming */
  185. exp[2] = HDCS_ROWEXPL;
  186. exp[3] = rowexp & 0xff;
  187. exp[4] = HDCS_ROWEXPH;
  188. exp[5] = rowexp >> 8;
  189. exp[6] = HDCS20_SROWEXP;
  190. exp[7] = (srowexp >> 2) & 0xff;
  191. exp[8] = HDCS20_ERROR;
  192. exp[9] = 0x10; /* Clear exposure error flag*/
  193. exp[10] = HDCS20_CONTROL;
  194. exp[11] = 0x04; /* Restart streaming */
  195. err = stv06xx_write_sensor_bytes(sd, exp, 6);
  196. } else {
  197. exp[0] = HDCS00_CONTROL;
  198. exp[1] = 0x00; /* Stop streaming */
  199. exp[2] = HDCS_ROWEXPL;
  200. exp[3] = rowexp & 0xff;
  201. exp[4] = HDCS_ROWEXPH;
  202. exp[5] = rowexp >> 8;
  203. exp[6] = HDCS00_SROWEXPL;
  204. exp[7] = srowexp & 0xff;
  205. exp[8] = HDCS00_SROWEXPH;
  206. exp[9] = srowexp >> 8;
  207. exp[10] = HDCS_STATUS;
  208. exp[11] = 0x10; /* Clear exposure error flag*/
  209. exp[12] = HDCS00_CONTROL;
  210. exp[13] = 0x04; /* Restart streaming */
  211. err = stv06xx_write_sensor_bytes(sd, exp, 7);
  212. if (err < 0)
  213. return err;
  214. }
  215. gspca_dbg(gspca_dev, D_CONF, "Writing exposure %d, rowexp %d, srowexp %d\n",
  216. val, rowexp, srowexp);
  217. return err;
  218. }
  219. static int hdcs_set_gains(struct sd *sd, u8 g)
  220. {
  221. int err;
  222. u8 gains[4];
  223. /* the voltage gain Av = (1 + 19 * val / 127) * (1 + bit7) */
  224. if (g > 127)
  225. g = 0x80 | (g / 2);
  226. gains[0] = g;
  227. gains[1] = g;
  228. gains[2] = g;
  229. gains[3] = g;
  230. err = hdcs_reg_write_seq(sd, HDCS_ERECPGA, gains, 4);
  231. return err;
  232. }
  233. static int hdcs_set_gain(struct gspca_dev *gspca_dev, __s32 val)
  234. {
  235. gspca_dbg(gspca_dev, D_CONF, "Writing gain %d\n", val);
  236. return hdcs_set_gains((struct sd *) gspca_dev,
  237. val & 0xff);
  238. }
  239. static int hdcs_set_size(struct sd *sd,
  240. unsigned int width, unsigned int height)
  241. {
  242. struct hdcs *hdcs = sd->sensor_priv;
  243. u8 win[4];
  244. unsigned int x, y;
  245. int err;
  246. /* must be multiple of 4 */
  247. width = (width + 3) & ~0x3;
  248. height = (height + 3) & ~0x3;
  249. if (width > hdcs->array.width)
  250. width = hdcs->array.width;
  251. if (IS_1020(sd)) {
  252. /* the borders are also invalid */
  253. if (height + 2 * hdcs->array.border + HDCS_1020_BOTTOM_Y_SKIP
  254. > hdcs->array.height)
  255. height = hdcs->array.height - 2 * hdcs->array.border -
  256. HDCS_1020_BOTTOM_Y_SKIP;
  257. y = (hdcs->array.height - HDCS_1020_BOTTOM_Y_SKIP - height) / 2
  258. + hdcs->array.top;
  259. } else {
  260. if (height > hdcs->array.height)
  261. height = hdcs->array.height;
  262. y = hdcs->array.top + (hdcs->array.height - height) / 2;
  263. }
  264. x = hdcs->array.left + (hdcs->array.width - width) / 2;
  265. win[0] = y / 4;
  266. win[1] = x / 4;
  267. win[2] = (y + height) / 4 - 1;
  268. win[3] = (x + width) / 4 - 1;
  269. err = hdcs_reg_write_seq(sd, HDCS_FWROW, win, 4);
  270. if (err < 0)
  271. return err;
  272. /* Update the current width and height */
  273. hdcs->w = width;
  274. hdcs->h = height;
  275. return err;
  276. }
  277. static int hdcs_s_ctrl(struct v4l2_ctrl *ctrl)
  278. {
  279. struct gspca_dev *gspca_dev =
  280. container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
  281. int err = -EINVAL;
  282. switch (ctrl->id) {
  283. case V4L2_CID_GAIN:
  284. err = hdcs_set_gain(gspca_dev, ctrl->val);
  285. break;
  286. case V4L2_CID_EXPOSURE:
  287. err = hdcs_set_exposure(gspca_dev, ctrl->val);
  288. break;
  289. }
  290. return err;
  291. }
  292. static const struct v4l2_ctrl_ops hdcs_ctrl_ops = {
  293. .s_ctrl = hdcs_s_ctrl,
  294. };
  295. static int hdcs_init_controls(struct sd *sd)
  296. {
  297. struct v4l2_ctrl_handler *hdl = &sd->gspca_dev.ctrl_handler;
  298. v4l2_ctrl_handler_init(hdl, 2);
  299. v4l2_ctrl_new_std(hdl, &hdcs_ctrl_ops,
  300. V4L2_CID_EXPOSURE, 0, 0xff, 1, HDCS_DEFAULT_EXPOSURE);
  301. v4l2_ctrl_new_std(hdl, &hdcs_ctrl_ops,
  302. V4L2_CID_GAIN, 0, 0xff, 1, HDCS_DEFAULT_GAIN);
  303. return hdl->error;
  304. }
  305. static int hdcs_probe_1x00(struct sd *sd)
  306. {
  307. struct hdcs *hdcs;
  308. u16 sensor;
  309. int ret;
  310. ret = stv06xx_read_sensor(sd, HDCS_IDENT, &sensor);
  311. if (ret < 0 || sensor != 0x08)
  312. return -ENODEV;
  313. pr_info("HDCS-1000/1100 sensor detected\n");
  314. sd->gspca_dev.cam.cam_mode = hdcs1x00_mode;
  315. sd->gspca_dev.cam.nmodes = ARRAY_SIZE(hdcs1x00_mode);
  316. hdcs = kmalloc(sizeof(struct hdcs), GFP_KERNEL);
  317. if (!hdcs)
  318. return -ENOMEM;
  319. hdcs->array.left = 8;
  320. hdcs->array.top = 8;
  321. hdcs->array.width = HDCS_1X00_DEF_WIDTH;
  322. hdcs->array.height = HDCS_1X00_DEF_HEIGHT;
  323. hdcs->array.border = 4;
  324. hdcs->exp.cto = 4;
  325. hdcs->exp.cpo = 2;
  326. hdcs->exp.rs = 186;
  327. hdcs->exp.er = 100;
  328. /*
  329. * Frame rate on HDCS-1000 with STV600 depends on PSMP:
  330. * 4 = doesn't work at all
  331. * 5 = 7.8 fps,
  332. * 6 = 6.9 fps,
  333. * 8 = 6.3 fps,
  334. * 10 = 5.5 fps,
  335. * 15 = 4.4 fps,
  336. * 31 = 2.8 fps
  337. *
  338. * Frame rate on HDCS-1000 with STV602 depends on PSMP:
  339. * 15 = doesn't work at all
  340. * 18 = doesn't work at all
  341. * 19 = 7.3 fps
  342. * 20 = 7.4 fps
  343. * 21 = 7.4 fps
  344. * 22 = 7.4 fps
  345. * 24 = 6.3 fps
  346. * 30 = 5.4 fps
  347. */
  348. hdcs->psmp = (sd->bridge == BRIDGE_STV602) ? 20 : 5;
  349. sd->sensor_priv = hdcs;
  350. return 0;
  351. }
  352. static int hdcs_probe_1020(struct sd *sd)
  353. {
  354. struct hdcs *hdcs;
  355. u16 sensor;
  356. int ret;
  357. ret = stv06xx_read_sensor(sd, HDCS_IDENT, &sensor);
  358. if (ret < 0 || sensor != 0x10)
  359. return -ENODEV;
  360. pr_info("HDCS-1020 sensor detected\n");
  361. sd->gspca_dev.cam.cam_mode = hdcs1020_mode;
  362. sd->gspca_dev.cam.nmodes = ARRAY_SIZE(hdcs1020_mode);
  363. hdcs = kmalloc(sizeof(struct hdcs), GFP_KERNEL);
  364. if (!hdcs)
  365. return -ENOMEM;
  366. /*
  367. * From Andrey's test image: looks like HDCS-1020 upper-left
  368. * visible pixel is at 24,8 (y maybe even smaller?) and lower-right
  369. * visible pixel at 375,299 (x maybe even larger?)
  370. */
  371. hdcs->array.left = 24;
  372. hdcs->array.top = 4;
  373. hdcs->array.width = HDCS_1020_DEF_WIDTH;
  374. hdcs->array.height = 304;
  375. hdcs->array.border = 4;
  376. hdcs->psmp = 6;
  377. hdcs->exp.cto = 3;
  378. hdcs->exp.cpo = 3;
  379. hdcs->exp.rs = 155;
  380. hdcs->exp.er = 96;
  381. sd->sensor_priv = hdcs;
  382. return 0;
  383. }
  384. static int hdcs_start(struct sd *sd)
  385. {
  386. struct gspca_dev *gspca_dev = (struct gspca_dev *)sd;
  387. gspca_dbg(gspca_dev, D_STREAM, "Starting stream\n");
  388. return hdcs_set_state(sd, HDCS_STATE_RUN);
  389. }
  390. static int hdcs_stop(struct sd *sd)
  391. {
  392. struct gspca_dev *gspca_dev = (struct gspca_dev *)sd;
  393. gspca_dbg(gspca_dev, D_STREAM, "Halting stream\n");
  394. return hdcs_set_state(sd, HDCS_STATE_SLEEP);
  395. }
  396. static int hdcs_init(struct sd *sd)
  397. {
  398. struct hdcs *hdcs = sd->sensor_priv;
  399. int i, err = 0;
  400. /* Set the STV0602AA in STV0600 emulation mode */
  401. if (sd->bridge == BRIDGE_STV602)
  402. stv06xx_write_bridge(sd, STV_STV0600_EMULATION, 1);
  403. /* Execute the bridge init */
  404. for (i = 0; i < ARRAY_SIZE(stv_bridge_init) && !err; i++) {
  405. err = stv06xx_write_bridge(sd, stv_bridge_init[i][0],
  406. stv_bridge_init[i][1]);
  407. }
  408. if (err < 0)
  409. return err;
  410. /* sensor soft reset */
  411. hdcs_reset(sd);
  412. /* Execute the sensor init */
  413. for (i = 0; i < ARRAY_SIZE(stv_sensor_init) && !err; i++) {
  414. err = stv06xx_write_sensor(sd, stv_sensor_init[i][0],
  415. stv_sensor_init[i][1]);
  416. }
  417. if (err < 0)
  418. return err;
  419. /* Enable continuous frame capture, bit 2: stop when frame complete */
  420. err = stv06xx_write_sensor(sd, HDCS_REG_CONFIG(sd), BIT(3));
  421. if (err < 0)
  422. return err;
  423. /* Set PGA sample duration
  424. (was 0x7E for the STV602, but caused slow framerate with HDCS-1020) */
  425. if (IS_1020(sd))
  426. err = stv06xx_write_sensor(sd, HDCS_TCTRL,
  427. (HDCS_ADC_START_SIG_DUR << 6) | hdcs->psmp);
  428. else
  429. err = stv06xx_write_sensor(sd, HDCS_TCTRL,
  430. (HDCS_ADC_START_SIG_DUR << 5) | hdcs->psmp);
  431. if (err < 0)
  432. return err;
  433. return hdcs_set_size(sd, hdcs->array.width, hdcs->array.height);
  434. }
  435. static int hdcs_dump(struct sd *sd)
  436. {
  437. u16 reg, val;
  438. pr_info("Dumping sensor registers:\n");
  439. for (reg = HDCS_IDENT; reg <= HDCS_ROWEXPH; reg++) {
  440. stv06xx_read_sensor(sd, reg, &val);
  441. pr_info("reg 0x%02x = 0x%02x\n", reg, val);
  442. }
  443. return 0;
  444. }