mt9v011.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635
  1. /*
  2. * mt9v011 -Micron 1/4-Inch VGA Digital Image Sensor
  3. *
  4. * Copyright (c) 2009 Mauro Carvalho Chehab (mchehab@redhat.com)
  5. * This code is placed under the terms of the GNU General Public License v2
  6. */
  7. #include <linux/i2c.h>
  8. #include <linux/slab.h>
  9. #include <linux/videodev2.h>
  10. #include <linux/delay.h>
  11. #include <asm/div64.h>
  12. #include <media/v4l2-device.h>
  13. #include "mt9v011.h"
  14. #include <media/v4l2-i2c-drv.h>
  15. #include <media/v4l2-chip-ident.h>
  16. MODULE_DESCRIPTION("Micron mt9v011 sensor driver");
  17. MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
  18. MODULE_LICENSE("GPL");
  19. static int debug;
  20. module_param(debug, int, 0);
  21. MODULE_PARM_DESC(debug, "Debug level (0-2)");
  22. /* supported controls */
  23. static struct v4l2_queryctrl mt9v011_qctrl[] = {
  24. {
  25. .id = V4L2_CID_GAIN,
  26. .type = V4L2_CTRL_TYPE_INTEGER,
  27. .name = "Gain",
  28. .minimum = 0,
  29. .maximum = (1 << 10) - 1,
  30. .step = 1,
  31. .default_value = 0x0020,
  32. .flags = 0,
  33. }, {
  34. .id = V4L2_CID_RED_BALANCE,
  35. .type = V4L2_CTRL_TYPE_INTEGER,
  36. .name = "Red Balance",
  37. .minimum = -1 << 9,
  38. .maximum = (1 << 9) - 1,
  39. .step = 1,
  40. .default_value = 0,
  41. .flags = 0,
  42. }, {
  43. .id = V4L2_CID_BLUE_BALANCE,
  44. .type = V4L2_CTRL_TYPE_INTEGER,
  45. .name = "Blue Balance",
  46. .minimum = -1 << 9,
  47. .maximum = (1 << 9) - 1,
  48. .step = 1,
  49. .default_value = 0,
  50. .flags = 0,
  51. }, {
  52. .id = V4L2_CID_HFLIP,
  53. .type = V4L2_CTRL_TYPE_BOOLEAN,
  54. .name = "Mirror",
  55. .minimum = 0,
  56. .maximum = 1,
  57. .step = 1,
  58. .default_value = 0,
  59. .flags = 0,
  60. }, {
  61. .id = V4L2_CID_VFLIP,
  62. .type = V4L2_CTRL_TYPE_BOOLEAN,
  63. .name = "Vflip",
  64. .minimum = 0,
  65. .maximum = 1,
  66. .step = 1,
  67. .default_value = 0,
  68. .flags = 0,
  69. }, {
  70. }
  71. };
  72. struct mt9v011 {
  73. struct v4l2_subdev sd;
  74. unsigned width, height;
  75. unsigned xtal;
  76. unsigned hflip:1;
  77. unsigned vflip:1;
  78. u16 global_gain, red_bal, blue_bal;
  79. };
  80. static inline struct mt9v011 *to_mt9v011(struct v4l2_subdev *sd)
  81. {
  82. return container_of(sd, struct mt9v011, sd);
  83. }
  84. static int mt9v011_read(struct v4l2_subdev *sd, unsigned char addr)
  85. {
  86. struct i2c_client *c = v4l2_get_subdevdata(sd);
  87. __be16 buffer;
  88. int rc, val;
  89. rc = i2c_master_send(c, &addr, 1);
  90. if (rc != 1)
  91. v4l2_dbg(0, debug, sd,
  92. "i2c i/o error: rc == %d (should be 1)\n", rc);
  93. msleep(10);
  94. rc = i2c_master_recv(c, (char *)&buffer, 2);
  95. if (rc != 2)
  96. v4l2_dbg(0, debug, sd,
  97. "i2c i/o error: rc == %d (should be 2)\n", rc);
  98. val = be16_to_cpu(buffer);
  99. v4l2_dbg(2, debug, sd, "mt9v011: read 0x%02x = 0x%04x\n", addr, val);
  100. return val;
  101. }
  102. static void mt9v011_write(struct v4l2_subdev *sd, unsigned char addr,
  103. u16 value)
  104. {
  105. struct i2c_client *c = v4l2_get_subdevdata(sd);
  106. unsigned char buffer[3];
  107. int rc;
  108. buffer[0] = addr;
  109. buffer[1] = value >> 8;
  110. buffer[2] = value & 0xff;
  111. v4l2_dbg(2, debug, sd,
  112. "mt9v011: writing 0x%02x 0x%04x\n", buffer[0], value);
  113. rc = i2c_master_send(c, buffer, 3);
  114. if (rc != 3)
  115. v4l2_dbg(0, debug, sd,
  116. "i2c i/o error: rc == %d (should be 3)\n", rc);
  117. }
  118. struct i2c_reg_value {
  119. unsigned char reg;
  120. u16 value;
  121. };
  122. /*
  123. * Values used at the original driver
  124. * Some values are marked as Reserved at the datasheet
  125. */
  126. static const struct i2c_reg_value mt9v011_init_default[] = {
  127. { R0D_MT9V011_RESET, 0x0001 },
  128. { R0D_MT9V011_RESET, 0x0000 },
  129. { R0C_MT9V011_SHUTTER_DELAY, 0x0000 },
  130. { R09_MT9V011_SHUTTER_WIDTH, 0x1fc },
  131. { R0A_MT9V011_CLK_SPEED, 0x0000 },
  132. { R1E_MT9V011_DIGITAL_ZOOM, 0x0000 },
  133. { R07_MT9V011_OUT_CTRL, 0x0002 }, /* chip enable */
  134. };
  135. static void set_balance(struct v4l2_subdev *sd)
  136. {
  137. struct mt9v011 *core = to_mt9v011(sd);
  138. u16 green1_gain, green2_gain, blue_gain, red_gain;
  139. green1_gain = core->global_gain;
  140. green2_gain = core->global_gain;
  141. blue_gain = core->global_gain +
  142. core->global_gain * core->blue_bal / (1 << 9);
  143. red_gain = core->global_gain +
  144. core->global_gain * core->blue_bal / (1 << 9);
  145. mt9v011_write(sd, R2B_MT9V011_GREEN_1_GAIN, green1_gain);
  146. mt9v011_write(sd, R2E_MT9V011_GREEN_2_GAIN, green1_gain);
  147. mt9v011_write(sd, R2C_MT9V011_BLUE_GAIN, blue_gain);
  148. mt9v011_write(sd, R2D_MT9V011_RED_GAIN, red_gain);
  149. }
  150. static void calc_fps(struct v4l2_subdev *sd, u32 *numerator, u32 *denominator)
  151. {
  152. struct mt9v011 *core = to_mt9v011(sd);
  153. unsigned height, width, hblank, vblank, speed;
  154. unsigned row_time, t_time;
  155. u64 frames_per_ms;
  156. unsigned tmp;
  157. height = mt9v011_read(sd, R03_MT9V011_HEIGHT);
  158. width = mt9v011_read(sd, R04_MT9V011_WIDTH);
  159. hblank = mt9v011_read(sd, R05_MT9V011_HBLANK);
  160. vblank = mt9v011_read(sd, R06_MT9V011_VBLANK);
  161. speed = mt9v011_read(sd, R0A_MT9V011_CLK_SPEED);
  162. row_time = (width + 113 + hblank) * (speed + 2);
  163. t_time = row_time * (height + vblank + 1);
  164. frames_per_ms = core->xtal * 1000l;
  165. do_div(frames_per_ms, t_time);
  166. tmp = frames_per_ms;
  167. v4l2_dbg(1, debug, sd, "Programmed to %u.%03u fps (%d pixel clcks)\n",
  168. tmp / 1000, tmp % 1000, t_time);
  169. if (numerator && denominator) {
  170. *numerator = 1000;
  171. *denominator = (u32)frames_per_ms;
  172. }
  173. }
  174. static u16 calc_speed(struct v4l2_subdev *sd, u32 numerator, u32 denominator)
  175. {
  176. struct mt9v011 *core = to_mt9v011(sd);
  177. unsigned height, width, hblank, vblank;
  178. unsigned row_time, line_time;
  179. u64 t_time, speed;
  180. /* Avoid bogus calculus */
  181. if (!numerator || !denominator)
  182. return 0;
  183. height = mt9v011_read(sd, R03_MT9V011_HEIGHT);
  184. width = mt9v011_read(sd, R04_MT9V011_WIDTH);
  185. hblank = mt9v011_read(sd, R05_MT9V011_HBLANK);
  186. vblank = mt9v011_read(sd, R06_MT9V011_VBLANK);
  187. row_time = width + 113 + hblank;
  188. line_time = height + vblank + 1;
  189. t_time = core->xtal * ((u64)numerator);
  190. /* round to the closest value */
  191. t_time += denominator / 2;
  192. do_div(t_time, denominator);
  193. speed = t_time;
  194. do_div(speed, row_time * line_time);
  195. /* Avoid having a negative value for speed */
  196. if (speed < 2)
  197. speed = 0;
  198. else
  199. speed -= 2;
  200. /* Avoid speed overflow */
  201. if (speed > 15)
  202. return 15;
  203. return (u16)speed;
  204. }
  205. static void set_res(struct v4l2_subdev *sd)
  206. {
  207. struct mt9v011 *core = to_mt9v011(sd);
  208. unsigned vstart, hstart;
  209. /*
  210. * The mt9v011 doesn't have scaling. So, in order to select the desired
  211. * resolution, we're cropping at the middle of the sensor.
  212. * hblank and vblank should be adjusted, in order to warrant that
  213. * we'll preserve the line timings for 30 fps, no matter what resolution
  214. * is selected.
  215. * NOTE: datasheet says that width (and height) should be filled with
  216. * width-1. However, this doesn't work, since one pixel per line will
  217. * be missing.
  218. */
  219. hstart = 14 + (640 - core->width) / 2;
  220. mt9v011_write(sd, R02_MT9V011_COLSTART, hstart);
  221. mt9v011_write(sd, R04_MT9V011_WIDTH, core->width);
  222. mt9v011_write(sd, R05_MT9V011_HBLANK, 771 - core->width);
  223. vstart = 8 + (480 - core->height) / 2;
  224. mt9v011_write(sd, R01_MT9V011_ROWSTART, vstart);
  225. mt9v011_write(sd, R03_MT9V011_HEIGHT, core->height);
  226. mt9v011_write(sd, R06_MT9V011_VBLANK, 508 - core->height);
  227. calc_fps(sd, NULL, NULL);
  228. };
  229. static void set_read_mode(struct v4l2_subdev *sd)
  230. {
  231. struct mt9v011 *core = to_mt9v011(sd);
  232. unsigned mode = 0x1000;
  233. if (core->hflip)
  234. mode |= 0x4000;
  235. if (core->vflip)
  236. mode |= 0x8000;
  237. mt9v011_write(sd, R20_MT9V011_READ_MODE, mode);
  238. }
  239. static int mt9v011_reset(struct v4l2_subdev *sd, u32 val)
  240. {
  241. int i;
  242. for (i = 0; i < ARRAY_SIZE(mt9v011_init_default); i++)
  243. mt9v011_write(sd, mt9v011_init_default[i].reg,
  244. mt9v011_init_default[i].value);
  245. set_balance(sd);
  246. set_res(sd);
  247. set_read_mode(sd);
  248. return 0;
  249. };
  250. static int mt9v011_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
  251. {
  252. struct mt9v011 *core = to_mt9v011(sd);
  253. v4l2_dbg(1, debug, sd, "g_ctrl called\n");
  254. switch (ctrl->id) {
  255. case V4L2_CID_GAIN:
  256. ctrl->value = core->global_gain;
  257. return 0;
  258. case V4L2_CID_RED_BALANCE:
  259. ctrl->value = core->red_bal;
  260. return 0;
  261. case V4L2_CID_BLUE_BALANCE:
  262. ctrl->value = core->blue_bal;
  263. return 0;
  264. case V4L2_CID_HFLIP:
  265. ctrl->value = core->hflip ? 1 : 0;
  266. return 0;
  267. case V4L2_CID_VFLIP:
  268. ctrl->value = core->vflip ? 1 : 0;
  269. return 0;
  270. }
  271. return -EINVAL;
  272. }
  273. static int mt9v011_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
  274. {
  275. int i;
  276. v4l2_dbg(1, debug, sd, "queryctrl called\n");
  277. for (i = 0; i < ARRAY_SIZE(mt9v011_qctrl); i++)
  278. if (qc->id && qc->id == mt9v011_qctrl[i].id) {
  279. memcpy(qc, &(mt9v011_qctrl[i]),
  280. sizeof(*qc));
  281. return 0;
  282. }
  283. return -EINVAL;
  284. }
  285. static int mt9v011_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
  286. {
  287. struct mt9v011 *core = to_mt9v011(sd);
  288. u8 i, n;
  289. n = ARRAY_SIZE(mt9v011_qctrl);
  290. for (i = 0; i < n; i++) {
  291. if (ctrl->id != mt9v011_qctrl[i].id)
  292. continue;
  293. if (ctrl->value < mt9v011_qctrl[i].minimum ||
  294. ctrl->value > mt9v011_qctrl[i].maximum)
  295. return -ERANGE;
  296. v4l2_dbg(1, debug, sd, "s_ctrl: id=%d, value=%d\n",
  297. ctrl->id, ctrl->value);
  298. break;
  299. }
  300. switch (ctrl->id) {
  301. case V4L2_CID_GAIN:
  302. core->global_gain = ctrl->value;
  303. break;
  304. case V4L2_CID_RED_BALANCE:
  305. core->red_bal = ctrl->value;
  306. break;
  307. case V4L2_CID_BLUE_BALANCE:
  308. core->blue_bal = ctrl->value;
  309. break;
  310. case V4L2_CID_HFLIP:
  311. core->hflip = ctrl->value;
  312. set_read_mode(sd);
  313. return 0;
  314. case V4L2_CID_VFLIP:
  315. core->vflip = ctrl->value;
  316. set_read_mode(sd);
  317. return 0;
  318. default:
  319. return -EINVAL;
  320. }
  321. set_balance(sd);
  322. return 0;
  323. }
  324. static int mt9v011_enum_fmt(struct v4l2_subdev *sd, struct v4l2_fmtdesc *fmt)
  325. {
  326. if (fmt->index > 0)
  327. return -EINVAL;
  328. fmt->flags = 0;
  329. strcpy(fmt->description, "8 bpp Bayer GRGR..BGBG");
  330. fmt->pixelformat = V4L2_PIX_FMT_SGRBG8;
  331. return 0;
  332. }
  333. static int mt9v011_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
  334. {
  335. struct v4l2_pix_format *pix = &fmt->fmt.pix;
  336. if (pix->pixelformat != V4L2_PIX_FMT_SGRBG8)
  337. return -EINVAL;
  338. v4l_bound_align_image(&pix->width, 48, 639, 1,
  339. &pix->height, 32, 480, 1, 0);
  340. return 0;
  341. }
  342. static int mt9v011_g_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms)
  343. {
  344. struct v4l2_captureparm *cp = &parms->parm.capture;
  345. if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
  346. return -EINVAL;
  347. memset(cp, 0, sizeof(struct v4l2_captureparm));
  348. cp->capability = V4L2_CAP_TIMEPERFRAME;
  349. calc_fps(sd,
  350. &cp->timeperframe.numerator,
  351. &cp->timeperframe.denominator);
  352. return 0;
  353. }
  354. static int mt9v011_s_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms)
  355. {
  356. struct v4l2_captureparm *cp = &parms->parm.capture;
  357. struct v4l2_fract *tpf = &cp->timeperframe;
  358. u16 speed;
  359. if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
  360. return -EINVAL;
  361. if (cp->extendedmode != 0)
  362. return -EINVAL;
  363. speed = calc_speed(sd, tpf->numerator, tpf->denominator);
  364. mt9v011_write(sd, R0A_MT9V011_CLK_SPEED, speed);
  365. v4l2_dbg(1, debug, sd, "Setting speed to %d\n", speed);
  366. /* Recalculate and update fps info */
  367. calc_fps(sd, &tpf->numerator, &tpf->denominator);
  368. return 0;
  369. }
  370. static int mt9v011_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
  371. {
  372. struct v4l2_pix_format *pix = &fmt->fmt.pix;
  373. struct mt9v011 *core = to_mt9v011(sd);
  374. int rc;
  375. rc = mt9v011_try_fmt(sd, fmt);
  376. if (rc < 0)
  377. return -EINVAL;
  378. core->width = pix->width;
  379. core->height = pix->height;
  380. set_res(sd);
  381. return 0;
  382. }
  383. static int mt9v011_s_config(struct v4l2_subdev *sd, int dumb, void *data)
  384. {
  385. struct mt9v011 *core = to_mt9v011(sd);
  386. unsigned *xtal = data;
  387. v4l2_dbg(1, debug, sd, "s_config called\n");
  388. if (xtal) {
  389. core->xtal = *xtal;
  390. v4l2_dbg(1, debug, sd, "xtal set to %d.%03d MHz\n",
  391. *xtal / 1000000, (*xtal / 1000) % 1000);
  392. }
  393. return 0;
  394. }
  395. #ifdef CONFIG_VIDEO_ADV_DEBUG
  396. static int mt9v011_g_register(struct v4l2_subdev *sd,
  397. struct v4l2_dbg_register *reg)
  398. {
  399. struct i2c_client *client = v4l2_get_subdevdata(sd);
  400. if (!v4l2_chip_match_i2c_client(client, &reg->match))
  401. return -EINVAL;
  402. if (!capable(CAP_SYS_ADMIN))
  403. return -EPERM;
  404. reg->val = mt9v011_read(sd, reg->reg & 0xff);
  405. reg->size = 2;
  406. return 0;
  407. }
  408. static int mt9v011_s_register(struct v4l2_subdev *sd,
  409. struct v4l2_dbg_register *reg)
  410. {
  411. struct i2c_client *client = v4l2_get_subdevdata(sd);
  412. if (!v4l2_chip_match_i2c_client(client, &reg->match))
  413. return -EINVAL;
  414. if (!capable(CAP_SYS_ADMIN))
  415. return -EPERM;
  416. mt9v011_write(sd, reg->reg & 0xff, reg->val & 0xffff);
  417. return 0;
  418. }
  419. #endif
  420. static int mt9v011_g_chip_ident(struct v4l2_subdev *sd,
  421. struct v4l2_dbg_chip_ident *chip)
  422. {
  423. u16 version;
  424. struct i2c_client *client = v4l2_get_subdevdata(sd);
  425. version = mt9v011_read(sd, R00_MT9V011_CHIP_VERSION);
  426. return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_MT9V011,
  427. version);
  428. }
  429. static const struct v4l2_subdev_core_ops mt9v011_core_ops = {
  430. .queryctrl = mt9v011_queryctrl,
  431. .g_ctrl = mt9v011_g_ctrl,
  432. .s_ctrl = mt9v011_s_ctrl,
  433. .reset = mt9v011_reset,
  434. .s_config = mt9v011_s_config,
  435. .g_chip_ident = mt9v011_g_chip_ident,
  436. #ifdef CONFIG_VIDEO_ADV_DEBUG
  437. .g_register = mt9v011_g_register,
  438. .s_register = mt9v011_s_register,
  439. #endif
  440. };
  441. static const struct v4l2_subdev_video_ops mt9v011_video_ops = {
  442. .enum_fmt = mt9v011_enum_fmt,
  443. .try_fmt = mt9v011_try_fmt,
  444. .s_fmt = mt9v011_s_fmt,
  445. .g_parm = mt9v011_g_parm,
  446. .s_parm = mt9v011_s_parm,
  447. };
  448. static const struct v4l2_subdev_ops mt9v011_ops = {
  449. .core = &mt9v011_core_ops,
  450. .video = &mt9v011_video_ops,
  451. };
  452. /****************************************************************************
  453. I2C Client & Driver
  454. ****************************************************************************/
  455. static int mt9v011_probe(struct i2c_client *c,
  456. const struct i2c_device_id *id)
  457. {
  458. u16 version;
  459. struct mt9v011 *core;
  460. struct v4l2_subdev *sd;
  461. /* Check if the adapter supports the needed features */
  462. if (!i2c_check_functionality(c->adapter,
  463. I2C_FUNC_SMBUS_READ_BYTE | I2C_FUNC_SMBUS_WRITE_BYTE_DATA))
  464. return -EIO;
  465. core = kzalloc(sizeof(struct mt9v011), GFP_KERNEL);
  466. if (!core)
  467. return -ENOMEM;
  468. sd = &core->sd;
  469. v4l2_i2c_subdev_init(sd, c, &mt9v011_ops);
  470. /* Check if the sensor is really a MT9V011 */
  471. version = mt9v011_read(sd, R00_MT9V011_CHIP_VERSION);
  472. if ((version != MT9V011_VERSION) &&
  473. (version != MT9V011_REV_B_VERSION)) {
  474. v4l2_info(sd, "*** unknown micron chip detected (0x%04x).\n",
  475. version);
  476. kfree(core);
  477. return -EINVAL;
  478. }
  479. core->global_gain = 0x0024;
  480. core->width = 640;
  481. core->height = 480;
  482. core->xtal = 27000000; /* Hz */
  483. v4l_info(c, "chip found @ 0x%02x (%s - chip version 0x%04x)\n",
  484. c->addr << 1, c->adapter->name, version);
  485. return 0;
  486. }
  487. static int mt9v011_remove(struct i2c_client *c)
  488. {
  489. struct v4l2_subdev *sd = i2c_get_clientdata(c);
  490. v4l2_dbg(1, debug, sd,
  491. "mt9v011.c: removing mt9v011 adapter on address 0x%x\n",
  492. c->addr << 1);
  493. v4l2_device_unregister_subdev(sd);
  494. kfree(to_mt9v011(sd));
  495. return 0;
  496. }
  497. /* ----------------------------------------------------------------------- */
  498. static const struct i2c_device_id mt9v011_id[] = {
  499. { "mt9v011", 0 },
  500. { }
  501. };
  502. MODULE_DEVICE_TABLE(i2c, mt9v011_id);
  503. static struct v4l2_i2c_driver_data v4l2_i2c_data = {
  504. .name = "mt9v011",
  505. .probe = mt9v011_probe,
  506. .remove = mt9v011_remove,
  507. .id_table = mt9v011_id,
  508. };