m5mols_core.c 26 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036
  1. /*
  2. * Driver for M-5MOLS 8M Pixel camera sensor with ISP
  3. *
  4. * Copyright (C) 2011 Samsung Electronics Co., Ltd.
  5. * Author: HeungJun Kim <riverful.kim@samsung.com>
  6. *
  7. * Copyright (C) 2009 Samsung Electronics Co., Ltd.
  8. * Author: Dongsoo Nathaniel Kim <dongsoo45.kim@samsung.com>
  9. *
  10. * This program is free software; you can redistribute it and/or modify
  11. * it under the terms of the GNU General Public License as published by
  12. * the Free Software Foundation; either version 2 of the License, or
  13. * (at your option) any later version.
  14. */
  15. #include <linux/i2c.h>
  16. #include <linux/slab.h>
  17. #include <linux/irq.h>
  18. #include <linux/interrupt.h>
  19. #include <linux/delay.h>
  20. #include <linux/gpio.h>
  21. #include <linux/regulator/consumer.h>
  22. #include <linux/videodev2.h>
  23. #include <linux/module.h>
  24. #include <media/v4l2-ctrls.h>
  25. #include <media/v4l2-device.h>
  26. #include <media/v4l2-subdev.h>
  27. #include <media/m5mols.h>
  28. #include "m5mols.h"
  29. #include "m5mols_reg.h"
  30. int m5mols_debug;
  31. module_param(m5mols_debug, int, 0644);
  32. #define MODULE_NAME "M5MOLS"
  33. #define M5MOLS_I2C_CHECK_RETRY 500
  34. /* The regulator consumer names for external voltage regulators */
  35. static struct regulator_bulk_data supplies[] = {
  36. {
  37. .supply = "core", /* ARM core power, 1.2V */
  38. }, {
  39. .supply = "dig_18", /* digital power 1, 1.8V */
  40. }, {
  41. .supply = "d_sensor", /* sensor power 1, 1.8V */
  42. }, {
  43. .supply = "dig_28", /* digital power 2, 2.8V */
  44. }, {
  45. .supply = "a_sensor", /* analog power */
  46. }, {
  47. .supply = "dig_12", /* digital power 3, 1.2V */
  48. },
  49. };
  50. static struct v4l2_mbus_framefmt m5mols_default_ffmt[M5MOLS_RESTYPE_MAX] = {
  51. [M5MOLS_RESTYPE_MONITOR] = {
  52. .width = 1920,
  53. .height = 1080,
  54. .code = V4L2_MBUS_FMT_VYUY8_2X8,
  55. .field = V4L2_FIELD_NONE,
  56. .colorspace = V4L2_COLORSPACE_JPEG,
  57. },
  58. [M5MOLS_RESTYPE_CAPTURE] = {
  59. .width = 1920,
  60. .height = 1080,
  61. .code = V4L2_MBUS_FMT_JPEG_1X8,
  62. .field = V4L2_FIELD_NONE,
  63. .colorspace = V4L2_COLORSPACE_JPEG,
  64. },
  65. };
  66. #define SIZE_DEFAULT_FFMT ARRAY_SIZE(m5mols_default_ffmt)
  67. static const struct m5mols_resolution m5mols_reg_res[] = {
  68. { 0x01, M5MOLS_RESTYPE_MONITOR, 128, 96 }, /* SUB-QCIF */
  69. { 0x03, M5MOLS_RESTYPE_MONITOR, 160, 120 }, /* QQVGA */
  70. { 0x05, M5MOLS_RESTYPE_MONITOR, 176, 144 }, /* QCIF */
  71. { 0x06, M5MOLS_RESTYPE_MONITOR, 176, 176 },
  72. { 0x08, M5MOLS_RESTYPE_MONITOR, 240, 320 }, /* QVGA */
  73. { 0x09, M5MOLS_RESTYPE_MONITOR, 320, 240 }, /* QVGA */
  74. { 0x0c, M5MOLS_RESTYPE_MONITOR, 240, 400 }, /* WQVGA */
  75. { 0x0d, M5MOLS_RESTYPE_MONITOR, 400, 240 }, /* WQVGA */
  76. { 0x0e, M5MOLS_RESTYPE_MONITOR, 352, 288 }, /* CIF */
  77. { 0x13, M5MOLS_RESTYPE_MONITOR, 480, 360 },
  78. { 0x15, M5MOLS_RESTYPE_MONITOR, 640, 360 }, /* qHD */
  79. { 0x17, M5MOLS_RESTYPE_MONITOR, 640, 480 }, /* VGA */
  80. { 0x18, M5MOLS_RESTYPE_MONITOR, 720, 480 },
  81. { 0x1a, M5MOLS_RESTYPE_MONITOR, 800, 480 }, /* WVGA */
  82. { 0x1f, M5MOLS_RESTYPE_MONITOR, 800, 600 }, /* SVGA */
  83. { 0x21, M5MOLS_RESTYPE_MONITOR, 1280, 720 }, /* HD */
  84. { 0x25, M5MOLS_RESTYPE_MONITOR, 1920, 1080 }, /* 1080p */
  85. { 0x29, M5MOLS_RESTYPE_MONITOR, 3264, 2448 }, /* 2.63fps 8M */
  86. { 0x39, M5MOLS_RESTYPE_MONITOR, 800, 602 }, /* AHS_MON debug */
  87. { 0x02, M5MOLS_RESTYPE_CAPTURE, 320, 240 }, /* QVGA */
  88. { 0x04, M5MOLS_RESTYPE_CAPTURE, 400, 240 }, /* WQVGA */
  89. { 0x07, M5MOLS_RESTYPE_CAPTURE, 480, 360 },
  90. { 0x08, M5MOLS_RESTYPE_CAPTURE, 640, 360 }, /* qHD */
  91. { 0x09, M5MOLS_RESTYPE_CAPTURE, 640, 480 }, /* VGA */
  92. { 0x0a, M5MOLS_RESTYPE_CAPTURE, 800, 480 }, /* WVGA */
  93. { 0x10, M5MOLS_RESTYPE_CAPTURE, 1280, 720 }, /* HD */
  94. { 0x14, M5MOLS_RESTYPE_CAPTURE, 1280, 960 }, /* 1M */
  95. { 0x17, M5MOLS_RESTYPE_CAPTURE, 1600, 1200 }, /* 2M */
  96. { 0x19, M5MOLS_RESTYPE_CAPTURE, 1920, 1080 }, /* Full-HD */
  97. { 0x1a, M5MOLS_RESTYPE_CAPTURE, 2048, 1152 }, /* 3Mega */
  98. { 0x1b, M5MOLS_RESTYPE_CAPTURE, 2048, 1536 },
  99. { 0x1c, M5MOLS_RESTYPE_CAPTURE, 2560, 1440 }, /* 4Mega */
  100. { 0x1d, M5MOLS_RESTYPE_CAPTURE, 2560, 1536 },
  101. { 0x1f, M5MOLS_RESTYPE_CAPTURE, 2560, 1920 }, /* 5Mega */
  102. { 0x21, M5MOLS_RESTYPE_CAPTURE, 3264, 1836 }, /* 6Mega */
  103. { 0x22, M5MOLS_RESTYPE_CAPTURE, 3264, 1960 },
  104. { 0x25, M5MOLS_RESTYPE_CAPTURE, 3264, 2448 }, /* 8Mega */
  105. };
  106. /**
  107. * m5mols_swap_byte - an byte array to integer conversion function
  108. * @size: size in bytes of I2C packet defined in the M-5MOLS datasheet
  109. *
  110. * Convert I2C data byte array with performing any required byte
  111. * reordering to assure proper values for each data type, regardless
  112. * of the architecture endianness.
  113. */
  114. static u32 m5mols_swap_byte(u8 *data, u8 length)
  115. {
  116. if (length == 1)
  117. return *data;
  118. else if (length == 2)
  119. return be16_to_cpu(*((u16 *)data));
  120. else
  121. return be32_to_cpu(*((u32 *)data));
  122. }
  123. /**
  124. * m5mols_read - I2C read function
  125. * @reg: combination of size, category and command for the I2C packet
  126. * @size: desired size of I2C packet
  127. * @val: read value
  128. */
  129. static int m5mols_read(struct v4l2_subdev *sd, u32 size, u32 reg, u32 *val)
  130. {
  131. struct i2c_client *client = v4l2_get_subdevdata(sd);
  132. u8 rbuf[M5MOLS_I2C_MAX_SIZE + 1];
  133. u8 category = I2C_CATEGORY(reg);
  134. u8 cmd = I2C_COMMAND(reg);
  135. struct i2c_msg msg[2];
  136. u8 wbuf[5];
  137. int ret;
  138. if (!client->adapter)
  139. return -ENODEV;
  140. msg[0].addr = client->addr;
  141. msg[0].flags = 0;
  142. msg[0].len = 5;
  143. msg[0].buf = wbuf;
  144. wbuf[0] = 5;
  145. wbuf[1] = M5MOLS_BYTE_READ;
  146. wbuf[2] = category;
  147. wbuf[3] = cmd;
  148. wbuf[4] = size;
  149. msg[1].addr = client->addr;
  150. msg[1].flags = I2C_M_RD;
  151. msg[1].len = size + 1;
  152. msg[1].buf = rbuf;
  153. /* minimum stabilization time */
  154. usleep_range(200, 200);
  155. ret = i2c_transfer(client->adapter, msg, 2);
  156. if (ret < 0) {
  157. v4l2_err(sd, "read failed: size:%d cat:%02x cmd:%02x. %d\n",
  158. size, category, cmd, ret);
  159. return ret;
  160. }
  161. *val = m5mols_swap_byte(&rbuf[1], size);
  162. return 0;
  163. }
  164. int m5mols_read_u8(struct v4l2_subdev *sd, u32 reg, u8 *val)
  165. {
  166. u32 val_32;
  167. int ret;
  168. if (I2C_SIZE(reg) != 1) {
  169. v4l2_err(sd, "Wrong data size\n");
  170. return -EINVAL;
  171. }
  172. ret = m5mols_read(sd, I2C_SIZE(reg), reg, &val_32);
  173. if (ret)
  174. return ret;
  175. *val = (u8)val_32;
  176. return ret;
  177. }
  178. int m5mols_read_u16(struct v4l2_subdev *sd, u32 reg, u16 *val)
  179. {
  180. u32 val_32;
  181. int ret;
  182. if (I2C_SIZE(reg) != 2) {
  183. v4l2_err(sd, "Wrong data size\n");
  184. return -EINVAL;
  185. }
  186. ret = m5mols_read(sd, I2C_SIZE(reg), reg, &val_32);
  187. if (ret)
  188. return ret;
  189. *val = (u16)val_32;
  190. return ret;
  191. }
  192. int m5mols_read_u32(struct v4l2_subdev *sd, u32 reg, u32 *val)
  193. {
  194. if (I2C_SIZE(reg) != 4) {
  195. v4l2_err(sd, "Wrong data size\n");
  196. return -EINVAL;
  197. }
  198. return m5mols_read(sd, I2C_SIZE(reg), reg, val);
  199. }
  200. /**
  201. * m5mols_write - I2C command write function
  202. * @reg: combination of size, category and command for the I2C packet
  203. * @val: value to write
  204. */
  205. int m5mols_write(struct v4l2_subdev *sd, u32 reg, u32 val)
  206. {
  207. struct i2c_client *client = v4l2_get_subdevdata(sd);
  208. u8 wbuf[M5MOLS_I2C_MAX_SIZE + 4];
  209. u8 category = I2C_CATEGORY(reg);
  210. u8 cmd = I2C_COMMAND(reg);
  211. u8 size = I2C_SIZE(reg);
  212. u32 *buf = (u32 *)&wbuf[4];
  213. struct i2c_msg msg[1];
  214. int ret;
  215. if (!client->adapter)
  216. return -ENODEV;
  217. if (size != 1 && size != 2 && size != 4) {
  218. v4l2_err(sd, "Wrong data size\n");
  219. return -EINVAL;
  220. }
  221. msg->addr = client->addr;
  222. msg->flags = 0;
  223. msg->len = (u16)size + 4;
  224. msg->buf = wbuf;
  225. wbuf[0] = size + 4;
  226. wbuf[1] = M5MOLS_BYTE_WRITE;
  227. wbuf[2] = category;
  228. wbuf[3] = cmd;
  229. *buf = m5mols_swap_byte((u8 *)&val, size);
  230. usleep_range(200, 200);
  231. ret = i2c_transfer(client->adapter, msg, 1);
  232. if (ret < 0) {
  233. v4l2_err(sd, "write failed: size:%d cat:%02x cmd:%02x. %d\n",
  234. size, category, cmd, ret);
  235. return ret;
  236. }
  237. return 0;
  238. }
  239. /**
  240. * m5mols_busy_wait - Busy waiting with I2C register polling
  241. * @reg: the I2C_REG() address of an 8-bit status register to check
  242. * @value: expected status register value
  243. * @mask: bit mask for the read status register value
  244. * @timeout: timeout in miliseconds, or -1 for default timeout
  245. *
  246. * The @reg register value is ORed with @mask before comparing with @value.
  247. *
  248. * Return: 0 if the requested condition became true within less than
  249. * @timeout ms, or else negative errno.
  250. */
  251. int m5mols_busy_wait(struct v4l2_subdev *sd, u32 reg, u32 value, u32 mask,
  252. int timeout)
  253. {
  254. int ms = timeout < 0 ? M5MOLS_BUSY_WAIT_DEF_TIMEOUT : timeout;
  255. unsigned long end = jiffies + msecs_to_jiffies(ms);
  256. u8 status;
  257. do {
  258. int ret = m5mols_read_u8(sd, reg, &status);
  259. if (ret < 0 && !(mask & M5MOLS_I2C_RDY_WAIT_FL))
  260. return ret;
  261. if (!ret && (status & mask & 0xff) == (value & 0xff))
  262. return 0;
  263. usleep_range(100, 250);
  264. } while (ms > 0 && time_is_after_jiffies(end));
  265. return -EBUSY;
  266. }
  267. /**
  268. * m5mols_enable_interrupt - Clear interrupt pending bits and unmask interrupts
  269. *
  270. * Before writing desired interrupt value the INT_FACTOR register should
  271. * be read to clear pending interrupts.
  272. */
  273. int m5mols_enable_interrupt(struct v4l2_subdev *sd, u8 reg)
  274. {
  275. struct m5mols_info *info = to_m5mols(sd);
  276. u8 mask = is_available_af(info) ? REG_INT_AF : 0;
  277. u8 dummy;
  278. int ret;
  279. ret = m5mols_read_u8(sd, SYSTEM_INT_FACTOR, &dummy);
  280. if (!ret)
  281. ret = m5mols_write(sd, SYSTEM_INT_ENABLE, reg & ~mask);
  282. return ret;
  283. }
  284. int m5mols_wait_interrupt(struct v4l2_subdev *sd, u8 irq_mask, u32 timeout)
  285. {
  286. struct m5mols_info *info = to_m5mols(sd);
  287. int ret = wait_event_interruptible_timeout(info->irq_waitq,
  288. atomic_add_unless(&info->irq_done, -1, 0),
  289. msecs_to_jiffies(timeout));
  290. if (ret <= 0)
  291. return ret ? ret : -ETIMEDOUT;
  292. return m5mols_busy_wait(sd, SYSTEM_INT_FACTOR, irq_mask,
  293. M5MOLS_I2C_RDY_WAIT_FL | irq_mask, -1);
  294. }
  295. /**
  296. * m5mols_reg_mode - Write the mode and check busy status
  297. *
  298. * It always accompanies a little delay changing the M-5MOLS mode, so it is
  299. * needed checking current busy status to guarantee right mode.
  300. */
  301. static int m5mols_reg_mode(struct v4l2_subdev *sd, u8 mode)
  302. {
  303. int ret = m5mols_write(sd, SYSTEM_SYSMODE, mode);
  304. if (ret < 0)
  305. return ret;
  306. return m5mols_busy_wait(sd, SYSTEM_SYSMODE, mode, 0xff,
  307. M5MOLS_MODE_CHANGE_TIMEOUT);
  308. }
  309. /**
  310. * m5mols_mode - manage the M-5MOLS's mode
  311. * @mode: the required operation mode
  312. *
  313. * The commands of M-5MOLS are grouped into specific modes. Each functionality
  314. * can be guaranteed only when the sensor is operating in mode which which
  315. * a command belongs to.
  316. */
  317. int m5mols_mode(struct m5mols_info *info, u8 mode)
  318. {
  319. struct v4l2_subdev *sd = &info->sd;
  320. int ret = -EINVAL;
  321. u8 reg;
  322. if (mode < REG_PARAMETER || mode > REG_CAPTURE)
  323. return ret;
  324. ret = m5mols_read_u8(sd, SYSTEM_SYSMODE, &reg);
  325. if ((!ret && reg == mode) || ret)
  326. return ret;
  327. switch (reg) {
  328. case REG_PARAMETER:
  329. ret = m5mols_reg_mode(sd, REG_MONITOR);
  330. if (!ret && mode == REG_MONITOR)
  331. break;
  332. if (!ret)
  333. ret = m5mols_reg_mode(sd, REG_CAPTURE);
  334. break;
  335. case REG_MONITOR:
  336. if (mode == REG_PARAMETER) {
  337. ret = m5mols_reg_mode(sd, REG_PARAMETER);
  338. break;
  339. }
  340. ret = m5mols_reg_mode(sd, REG_CAPTURE);
  341. break;
  342. case REG_CAPTURE:
  343. ret = m5mols_reg_mode(sd, REG_MONITOR);
  344. if (!ret && mode == REG_MONITOR)
  345. break;
  346. if (!ret)
  347. ret = m5mols_reg_mode(sd, REG_PARAMETER);
  348. break;
  349. default:
  350. v4l2_warn(sd, "Wrong mode: %d\n", mode);
  351. }
  352. if (!ret)
  353. info->mode = mode;
  354. return ret;
  355. }
  356. /**
  357. * m5mols_get_version - retrieve full revisions information of M-5MOLS
  358. *
  359. * The version information includes revisions of hardware and firmware,
  360. * AutoFocus alghorithm version and the version string.
  361. */
  362. static int m5mols_get_version(struct v4l2_subdev *sd)
  363. {
  364. struct m5mols_info *info = to_m5mols(sd);
  365. struct m5mols_version *ver = &info->ver;
  366. u8 *str = ver->str;
  367. int i;
  368. int ret;
  369. ret = m5mols_read_u8(sd, SYSTEM_VER_CUSTOMER, &ver->customer);
  370. if (!ret)
  371. ret = m5mols_read_u8(sd, SYSTEM_VER_PROJECT, &ver->project);
  372. if (!ret)
  373. ret = m5mols_read_u16(sd, SYSTEM_VER_FIRMWARE, &ver->fw);
  374. if (!ret)
  375. ret = m5mols_read_u16(sd, SYSTEM_VER_HARDWARE, &ver->hw);
  376. if (!ret)
  377. ret = m5mols_read_u16(sd, SYSTEM_VER_PARAMETER, &ver->param);
  378. if (!ret)
  379. ret = m5mols_read_u16(sd, SYSTEM_VER_AWB, &ver->awb);
  380. if (!ret)
  381. ret = m5mols_read_u8(sd, AF_VERSION, &ver->af);
  382. if (ret)
  383. return ret;
  384. for (i = 0; i < VERSION_STRING_SIZE; i++) {
  385. ret = m5mols_read_u8(sd, SYSTEM_VER_STRING, &str[i]);
  386. if (ret)
  387. return ret;
  388. }
  389. ver->fw = be16_to_cpu(ver->fw);
  390. ver->hw = be16_to_cpu(ver->hw);
  391. ver->param = be16_to_cpu(ver->param);
  392. ver->awb = be16_to_cpu(ver->awb);
  393. v4l2_info(sd, "Manufacturer\t[%s]\n",
  394. is_manufacturer(info, REG_SAMSUNG_ELECTRO) ?
  395. "Samsung Electro-Machanics" :
  396. is_manufacturer(info, REG_SAMSUNG_OPTICS) ?
  397. "Samsung Fiber-Optics" :
  398. is_manufacturer(info, REG_SAMSUNG_TECHWIN) ?
  399. "Samsung Techwin" : "None");
  400. v4l2_info(sd, "Customer/Project\t[0x%02x/0x%02x]\n",
  401. info->ver.customer, info->ver.project);
  402. if (!is_available_af(info))
  403. v4l2_info(sd, "No support Auto Focus on this firmware\n");
  404. return ret;
  405. }
  406. /**
  407. * __find_restype - Lookup M-5MOLS resolution type according to pixel code
  408. * @code: pixel code
  409. */
  410. static enum m5mols_restype __find_restype(enum v4l2_mbus_pixelcode code)
  411. {
  412. enum m5mols_restype type = M5MOLS_RESTYPE_MONITOR;
  413. do {
  414. if (code == m5mols_default_ffmt[type].code)
  415. return type;
  416. } while (type++ != SIZE_DEFAULT_FFMT);
  417. return 0;
  418. }
  419. /**
  420. * __find_resolution - Lookup preset and type of M-5MOLS's resolution
  421. * @mf: pixel format to find/negotiate the resolution preset for
  422. * @type: M-5MOLS resolution type
  423. * @resolution: M-5MOLS resolution preset register value
  424. *
  425. * Find nearest resolution matching resolution preset and adjust mf
  426. * to supported values.
  427. */
  428. static int __find_resolution(struct v4l2_subdev *sd,
  429. struct v4l2_mbus_framefmt *mf,
  430. enum m5mols_restype *type,
  431. u32 *resolution)
  432. {
  433. const struct m5mols_resolution *fsize = &m5mols_reg_res[0];
  434. const struct m5mols_resolution *match = NULL;
  435. enum m5mols_restype stype = __find_restype(mf->code);
  436. int i = ARRAY_SIZE(m5mols_reg_res);
  437. unsigned int min_err = ~0;
  438. while (i--) {
  439. int err;
  440. if (stype == fsize->type) {
  441. err = abs(fsize->width - mf->width)
  442. + abs(fsize->height - mf->height);
  443. if (err < min_err) {
  444. min_err = err;
  445. match = fsize;
  446. }
  447. }
  448. fsize++;
  449. }
  450. if (match) {
  451. mf->width = match->width;
  452. mf->height = match->height;
  453. *resolution = match->reg;
  454. *type = stype;
  455. return 0;
  456. }
  457. return -EINVAL;
  458. }
  459. static struct v4l2_mbus_framefmt *__find_format(struct m5mols_info *info,
  460. struct v4l2_subdev_fh *fh,
  461. enum v4l2_subdev_format_whence which,
  462. enum m5mols_restype type)
  463. {
  464. if (which == V4L2_SUBDEV_FORMAT_TRY)
  465. return fh ? v4l2_subdev_get_try_format(fh, 0) : NULL;
  466. return &info->ffmt[type];
  467. }
  468. static int m5mols_get_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
  469. struct v4l2_subdev_format *fmt)
  470. {
  471. struct m5mols_info *info = to_m5mols(sd);
  472. struct v4l2_mbus_framefmt *format;
  473. format = __find_format(info, fh, fmt->which, info->res_type);
  474. if (!format)
  475. return -EINVAL;
  476. fmt->format = *format;
  477. return 0;
  478. }
  479. static int m5mols_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
  480. struct v4l2_subdev_format *fmt)
  481. {
  482. struct m5mols_info *info = to_m5mols(sd);
  483. struct v4l2_mbus_framefmt *format = &fmt->format;
  484. struct v4l2_mbus_framefmt *sfmt;
  485. enum m5mols_restype type;
  486. u32 resolution = 0;
  487. int ret;
  488. ret = __find_resolution(sd, format, &type, &resolution);
  489. if (ret < 0)
  490. return ret;
  491. sfmt = __find_format(info, fh, fmt->which, type);
  492. if (!sfmt)
  493. return 0;
  494. format->code = m5mols_default_ffmt[type].code;
  495. format->colorspace = V4L2_COLORSPACE_JPEG;
  496. format->field = V4L2_FIELD_NONE;
  497. if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
  498. *sfmt = *format;
  499. info->resolution = resolution;
  500. info->res_type = type;
  501. }
  502. return 0;
  503. }
  504. static int m5mols_enum_mbus_code(struct v4l2_subdev *sd,
  505. struct v4l2_subdev_fh *fh,
  506. struct v4l2_subdev_mbus_code_enum *code)
  507. {
  508. if (!code || code->index >= SIZE_DEFAULT_FFMT)
  509. return -EINVAL;
  510. code->code = m5mols_default_ffmt[code->index].code;
  511. return 0;
  512. }
  513. static struct v4l2_subdev_pad_ops m5mols_pad_ops = {
  514. .enum_mbus_code = m5mols_enum_mbus_code,
  515. .get_fmt = m5mols_get_fmt,
  516. .set_fmt = m5mols_set_fmt,
  517. };
  518. /**
  519. * m5mols_sync_controls - Apply default scene mode and the current controls
  520. *
  521. * This is used only streaming for syncing between v4l2_ctrl framework and
  522. * m5mols's controls. First, do the scenemode to the sensor, then call
  523. * v4l2_ctrl_handler_setup. It can be same between some commands and
  524. * the scenemode's in the default v4l2_ctrls. But, such commands of control
  525. * should be prior to the scenemode's one.
  526. */
  527. int m5mols_sync_controls(struct m5mols_info *info)
  528. {
  529. int ret = -EINVAL;
  530. if (!is_ctrl_synced(info)) {
  531. ret = m5mols_do_scenemode(info, REG_SCENE_NORMAL);
  532. if (ret)
  533. return ret;
  534. v4l2_ctrl_handler_setup(&info->handle);
  535. info->ctrl_sync = true;
  536. }
  537. return ret;
  538. }
  539. /**
  540. * m5mols_start_monitor - Start the monitor mode
  541. *
  542. * Before applying the controls setup the resolution and frame rate
  543. * in PARAMETER mode, and then switch over to MONITOR mode.
  544. */
  545. static int m5mols_start_monitor(struct m5mols_info *info)
  546. {
  547. struct v4l2_subdev *sd = &info->sd;
  548. int ret;
  549. ret = m5mols_mode(info, REG_PARAMETER);
  550. if (!ret)
  551. ret = m5mols_write(sd, PARM_MON_SIZE, info->resolution);
  552. if (!ret)
  553. ret = m5mols_write(sd, PARM_MON_FPS, REG_FPS_30);
  554. if (!ret)
  555. ret = m5mols_mode(info, REG_MONITOR);
  556. if (!ret)
  557. ret = m5mols_sync_controls(info);
  558. return ret;
  559. }
  560. static int m5mols_s_stream(struct v4l2_subdev *sd, int enable)
  561. {
  562. struct m5mols_info *info = to_m5mols(sd);
  563. u32 code = info->ffmt[info->res_type].code;
  564. if (enable) {
  565. int ret = -EINVAL;
  566. if (is_code(code, M5MOLS_RESTYPE_MONITOR))
  567. ret = m5mols_start_monitor(info);
  568. if (is_code(code, M5MOLS_RESTYPE_CAPTURE))
  569. ret = m5mols_start_capture(info);
  570. return ret;
  571. }
  572. return m5mols_mode(info, REG_PARAMETER);
  573. }
  574. static const struct v4l2_subdev_video_ops m5mols_video_ops = {
  575. .s_stream = m5mols_s_stream,
  576. };
  577. static int m5mols_s_ctrl(struct v4l2_ctrl *ctrl)
  578. {
  579. struct v4l2_subdev *sd = to_sd(ctrl);
  580. struct m5mols_info *info = to_m5mols(sd);
  581. int ret;
  582. info->mode_save = info->mode;
  583. ret = m5mols_mode(info, REG_PARAMETER);
  584. if (!ret)
  585. ret = m5mols_set_ctrl(ctrl);
  586. if (!ret)
  587. ret = m5mols_mode(info, info->mode_save);
  588. return ret;
  589. }
  590. static const struct v4l2_ctrl_ops m5mols_ctrl_ops = {
  591. .s_ctrl = m5mols_s_ctrl,
  592. };
  593. static int m5mols_sensor_power(struct m5mols_info *info, bool enable)
  594. {
  595. struct v4l2_subdev *sd = &info->sd;
  596. struct i2c_client *client = v4l2_get_subdevdata(sd);
  597. const struct m5mols_platform_data *pdata = info->pdata;
  598. int ret;
  599. if (enable) {
  600. if (is_powered(info))
  601. return 0;
  602. if (info->set_power) {
  603. ret = info->set_power(&client->dev, 1);
  604. if (ret)
  605. return ret;
  606. }
  607. ret = regulator_bulk_enable(ARRAY_SIZE(supplies), supplies);
  608. if (ret) {
  609. info->set_power(&client->dev, 0);
  610. return ret;
  611. }
  612. gpio_set_value(pdata->gpio_reset, !pdata->reset_polarity);
  613. usleep_range(1000, 1000);
  614. info->power = true;
  615. return ret;
  616. }
  617. if (!is_powered(info))
  618. return 0;
  619. ret = regulator_bulk_disable(ARRAY_SIZE(supplies), supplies);
  620. if (ret)
  621. return ret;
  622. if (info->set_power)
  623. info->set_power(&client->dev, 0);
  624. gpio_set_value(pdata->gpio_reset, pdata->reset_polarity);
  625. usleep_range(1000, 1000);
  626. info->power = false;
  627. return ret;
  628. }
  629. /* m5mols_update_fw - optional firmware update routine */
  630. int __attribute__ ((weak)) m5mols_update_fw(struct v4l2_subdev *sd,
  631. int (*set_power)(struct m5mols_info *, bool))
  632. {
  633. return 0;
  634. }
  635. /**
  636. * m5mols_sensor_armboot - Booting M-5MOLS internal ARM core.
  637. *
  638. * Booting internal ARM core makes the M-5MOLS is ready for getting commands
  639. * with I2C. It's the first thing to be done after it powered up. It must wait
  640. * at least 520ms recommended by M-5MOLS datasheet, after executing arm booting.
  641. */
  642. static int m5mols_sensor_armboot(struct v4l2_subdev *sd)
  643. {
  644. int ret;
  645. ret = m5mols_write(sd, FLASH_CAM_START, REG_START_ARM_BOOT);
  646. if (ret < 0)
  647. return ret;
  648. msleep(520);
  649. ret = m5mols_get_version(sd);
  650. if (!ret)
  651. ret = m5mols_update_fw(sd, m5mols_sensor_power);
  652. if (ret)
  653. return ret;
  654. v4l2_dbg(1, m5mols_debug, sd, "Success ARM Booting\n");
  655. ret = m5mols_write(sd, PARM_INTERFACE, REG_INTERFACE_MIPI);
  656. if (!ret)
  657. ret = m5mols_enable_interrupt(sd, REG_INT_AF);
  658. return ret;
  659. }
  660. static int m5mols_init_controls(struct m5mols_info *info)
  661. {
  662. struct v4l2_subdev *sd = &info->sd;
  663. u16 max_exposure;
  664. u16 step_zoom;
  665. int ret;
  666. /* Determine value's range & step of controls for various FW version */
  667. ret = m5mols_read_u16(sd, AE_MAX_GAIN_MON, &max_exposure);
  668. if (!ret)
  669. step_zoom = is_manufacturer(info, REG_SAMSUNG_OPTICS) ? 31 : 1;
  670. if (ret)
  671. return ret;
  672. v4l2_ctrl_handler_init(&info->handle, 6);
  673. info->autowb = v4l2_ctrl_new_std(&info->handle,
  674. &m5mols_ctrl_ops, V4L2_CID_AUTO_WHITE_BALANCE,
  675. 0, 1, 1, 0);
  676. info->saturation = v4l2_ctrl_new_std(&info->handle,
  677. &m5mols_ctrl_ops, V4L2_CID_SATURATION,
  678. 1, 5, 1, 3);
  679. info->zoom = v4l2_ctrl_new_std(&info->handle,
  680. &m5mols_ctrl_ops, V4L2_CID_ZOOM_ABSOLUTE,
  681. 1, 70, step_zoom, 1);
  682. info->exposure = v4l2_ctrl_new_std(&info->handle,
  683. &m5mols_ctrl_ops, V4L2_CID_EXPOSURE,
  684. 0, max_exposure, 1, (int)max_exposure/2);
  685. info->colorfx = v4l2_ctrl_new_std_menu(&info->handle,
  686. &m5mols_ctrl_ops, V4L2_CID_COLORFX,
  687. 4, (1 << V4L2_COLORFX_BW), V4L2_COLORFX_NONE);
  688. info->autoexposure = v4l2_ctrl_new_std_menu(&info->handle,
  689. &m5mols_ctrl_ops, V4L2_CID_EXPOSURE_AUTO,
  690. 1, 0, V4L2_EXPOSURE_MANUAL);
  691. sd->ctrl_handler = &info->handle;
  692. if (info->handle.error) {
  693. v4l2_err(sd, "Failed to initialize controls: %d\n", ret);
  694. v4l2_ctrl_handler_free(&info->handle);
  695. return info->handle.error;
  696. }
  697. v4l2_ctrl_cluster(2, &info->autoexposure);
  698. return 0;
  699. }
  700. /**
  701. * m5mols_s_power - Main sensor power control function
  702. *
  703. * To prevent breaking the lens when the sensor is powered off the Soft-Landing
  704. * algorithm is called where available. The Soft-Landing algorithm availability
  705. * dependends on the firmware provider.
  706. */
  707. static int m5mols_s_power(struct v4l2_subdev *sd, int on)
  708. {
  709. struct m5mols_info *info = to_m5mols(sd);
  710. int ret;
  711. if (on) {
  712. ret = m5mols_sensor_power(info, true);
  713. if (!ret)
  714. ret = m5mols_sensor_armboot(sd);
  715. if (!ret)
  716. ret = m5mols_init_controls(info);
  717. if (ret)
  718. return ret;
  719. info->ffmt[M5MOLS_RESTYPE_MONITOR] =
  720. m5mols_default_ffmt[M5MOLS_RESTYPE_MONITOR];
  721. info->ffmt[M5MOLS_RESTYPE_CAPTURE] =
  722. m5mols_default_ffmt[M5MOLS_RESTYPE_CAPTURE];
  723. return ret;
  724. }
  725. if (is_manufacturer(info, REG_SAMSUNG_TECHWIN)) {
  726. ret = m5mols_mode(info, REG_MONITOR);
  727. if (!ret)
  728. ret = m5mols_write(sd, AF_EXECUTE, REG_AF_STOP);
  729. if (!ret)
  730. ret = m5mols_write(sd, AF_MODE, REG_AF_POWEROFF);
  731. if (!ret)
  732. ret = m5mols_busy_wait(sd, SYSTEM_STATUS, REG_AF_IDLE,
  733. 0xff, -1);
  734. if (ret < 0)
  735. v4l2_warn(sd, "Soft landing lens failed\n");
  736. }
  737. ret = m5mols_sensor_power(info, false);
  738. if (!ret) {
  739. v4l2_ctrl_handler_free(&info->handle);
  740. info->ctrl_sync = false;
  741. }
  742. return ret;
  743. }
  744. static int m5mols_log_status(struct v4l2_subdev *sd)
  745. {
  746. struct m5mols_info *info = to_m5mols(sd);
  747. v4l2_ctrl_handler_log_status(&info->handle, sd->name);
  748. return 0;
  749. }
  750. static const struct v4l2_subdev_core_ops m5mols_core_ops = {
  751. .s_power = m5mols_s_power,
  752. .g_ctrl = v4l2_subdev_g_ctrl,
  753. .s_ctrl = v4l2_subdev_s_ctrl,
  754. .queryctrl = v4l2_subdev_queryctrl,
  755. .querymenu = v4l2_subdev_querymenu,
  756. .g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
  757. .try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
  758. .s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
  759. .log_status = m5mols_log_status,
  760. };
  761. static const struct v4l2_subdev_ops m5mols_ops = {
  762. .core = &m5mols_core_ops,
  763. .pad = &m5mols_pad_ops,
  764. .video = &m5mols_video_ops,
  765. };
  766. static irqreturn_t m5mols_irq_handler(int irq, void *data)
  767. {
  768. struct m5mols_info *info = to_m5mols(data);
  769. atomic_set(&info->irq_done, 1);
  770. wake_up_interruptible(&info->irq_waitq);
  771. return IRQ_HANDLED;
  772. }
  773. static int __devinit m5mols_probe(struct i2c_client *client,
  774. const struct i2c_device_id *id)
  775. {
  776. const struct m5mols_platform_data *pdata = client->dev.platform_data;
  777. struct m5mols_info *info;
  778. struct v4l2_subdev *sd;
  779. int ret;
  780. if (pdata == NULL) {
  781. dev_err(&client->dev, "No platform data\n");
  782. return -EINVAL;
  783. }
  784. if (!gpio_is_valid(pdata->gpio_reset)) {
  785. dev_err(&client->dev, "No valid RESET GPIO specified\n");
  786. return -EINVAL;
  787. }
  788. if (!client->irq) {
  789. dev_err(&client->dev, "Interrupt not assigned\n");
  790. return -EINVAL;
  791. }
  792. info = kzalloc(sizeof(struct m5mols_info), GFP_KERNEL);
  793. if (!info)
  794. return -ENOMEM;
  795. info->pdata = pdata;
  796. info->set_power = pdata->set_power;
  797. ret = gpio_request(pdata->gpio_reset, "M5MOLS_NRST");
  798. if (ret) {
  799. dev_err(&client->dev, "Failed to request gpio: %d\n", ret);
  800. goto out_free;
  801. }
  802. gpio_direction_output(pdata->gpio_reset, pdata->reset_polarity);
  803. ret = regulator_bulk_get(&client->dev, ARRAY_SIZE(supplies), supplies);
  804. if (ret) {
  805. dev_err(&client->dev, "Failed to get regulators: %d\n", ret);
  806. goto out_gpio;
  807. }
  808. sd = &info->sd;
  809. strlcpy(sd->name, MODULE_NAME, sizeof(sd->name));
  810. v4l2_i2c_subdev_init(sd, client, &m5mols_ops);
  811. info->pad.flags = MEDIA_PAD_FL_SOURCE;
  812. ret = media_entity_init(&sd->entity, 1, &info->pad, 0);
  813. if (ret < 0)
  814. goto out_reg;
  815. sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;
  816. init_waitqueue_head(&info->irq_waitq);
  817. ret = request_irq(client->irq, m5mols_irq_handler,
  818. IRQF_TRIGGER_RISING, MODULE_NAME, sd);
  819. if (ret) {
  820. dev_err(&client->dev, "Interrupt request failed: %d\n", ret);
  821. goto out_me;
  822. }
  823. info->res_type = M5MOLS_RESTYPE_MONITOR;
  824. return 0;
  825. out_me:
  826. media_entity_cleanup(&sd->entity);
  827. out_reg:
  828. regulator_bulk_free(ARRAY_SIZE(supplies), supplies);
  829. out_gpio:
  830. gpio_free(pdata->gpio_reset);
  831. out_free:
  832. kfree(info);
  833. return ret;
  834. }
  835. static int __devexit m5mols_remove(struct i2c_client *client)
  836. {
  837. struct v4l2_subdev *sd = i2c_get_clientdata(client);
  838. struct m5mols_info *info = to_m5mols(sd);
  839. v4l2_device_unregister_subdev(sd);
  840. free_irq(client->irq, sd);
  841. regulator_bulk_free(ARRAY_SIZE(supplies), supplies);
  842. gpio_free(info->pdata->gpio_reset);
  843. media_entity_cleanup(&sd->entity);
  844. kfree(info);
  845. return 0;
  846. }
  847. static const struct i2c_device_id m5mols_id[] = {
  848. { MODULE_NAME, 0 },
  849. { },
  850. };
  851. MODULE_DEVICE_TABLE(i2c, m5mols_id);
  852. static struct i2c_driver m5mols_i2c_driver = {
  853. .driver = {
  854. .name = MODULE_NAME,
  855. },
  856. .probe = m5mols_probe,
  857. .remove = __devexit_p(m5mols_remove),
  858. .id_table = m5mols_id,
  859. };
  860. static int __init m5mols_mod_init(void)
  861. {
  862. return i2c_add_driver(&m5mols_i2c_driver);
  863. }
  864. static void __exit m5mols_mod_exit(void)
  865. {
  866. i2c_del_driver(&m5mols_i2c_driver);
  867. }
  868. module_init(m5mols_mod_init);
  869. module_exit(m5mols_mod_exit);
  870. MODULE_AUTHOR("HeungJun Kim <riverful.kim@samsung.com>");
  871. MODULE_AUTHOR("Dongsoo Kim <dongsoo45.kim@samsung.com>");
  872. MODULE_DESCRIPTION("Fujitsu M-5MOLS 8M Pixel camera driver");
  873. MODULE_LICENSE("GPL");