mipi-csis.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884
  1. /*
  2. * Samsung S5P/EXYNOS4 SoC series MIPI-CSI receiver driver
  3. *
  4. * Copyright (C) 2011 - 2012 Samsung Electronics Co., Ltd.
  5. * Sylwester Nawrocki, <s.nawrocki@samsung.com>
  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 version 2 as
  9. * published by the Free Software Foundation.
  10. */
  11. #include <linux/clk.h>
  12. #include <linux/delay.h>
  13. #include <linux/device.h>
  14. #include <linux/errno.h>
  15. #include <linux/interrupt.h>
  16. #include <linux/io.h>
  17. #include <linux/irq.h>
  18. #include <linux/kernel.h>
  19. #include <linux/memory.h>
  20. #include <linux/module.h>
  21. #include <linux/platform_device.h>
  22. #include <linux/pm_runtime.h>
  23. #include <linux/regulator/consumer.h>
  24. #include <linux/slab.h>
  25. #include <linux/spinlock.h>
  26. #include <linux/videodev2.h>
  27. #include <media/v4l2-subdev.h>
  28. #include <plat/mipi_csis.h>
  29. #include "mipi-csis.h"
  30. static int debug;
  31. module_param(debug, int, 0644);
  32. MODULE_PARM_DESC(debug, "Debug level (0-2)");
  33. /* Register map definition */
  34. /* CSIS global control */
  35. #define S5PCSIS_CTRL 0x00
  36. #define S5PCSIS_CTRL_DPDN_DEFAULT (0 << 31)
  37. #define S5PCSIS_CTRL_DPDN_SWAP (1 << 31)
  38. #define S5PCSIS_CTRL_ALIGN_32BIT (1 << 20)
  39. #define S5PCSIS_CTRL_UPDATE_SHADOW (1 << 16)
  40. #define S5PCSIS_CTRL_WCLK_EXTCLK (1 << 8)
  41. #define S5PCSIS_CTRL_RESET (1 << 4)
  42. #define S5PCSIS_CTRL_ENABLE (1 << 0)
  43. /* D-PHY control */
  44. #define S5PCSIS_DPHYCTRL 0x04
  45. #define S5PCSIS_DPHYCTRL_HSS_MASK (0x1f << 27)
  46. #define S5PCSIS_DPHYCTRL_ENABLE (0x1f << 0)
  47. #define S5PCSIS_CONFIG 0x08
  48. #define S5PCSIS_CFG_FMT_YCBCR422_8BIT (0x1e << 2)
  49. #define S5PCSIS_CFG_FMT_RAW8 (0x2a << 2)
  50. #define S5PCSIS_CFG_FMT_RAW10 (0x2b << 2)
  51. #define S5PCSIS_CFG_FMT_RAW12 (0x2c << 2)
  52. /* User defined formats, x = 1...4 */
  53. #define S5PCSIS_CFG_FMT_USER(x) ((0x30 + x - 1) << 2)
  54. #define S5PCSIS_CFG_FMT_MASK (0x3f << 2)
  55. #define S5PCSIS_CFG_NR_LANE_MASK 3
  56. /* Interrupt mask */
  57. #define S5PCSIS_INTMSK 0x10
  58. #define S5PCSIS_INTMSK_EN_ALL 0xf000103f
  59. #define S5PCSIS_INTMSK_EVEN_BEFORE (1 << 31)
  60. #define S5PCSIS_INTMSK_EVEN_AFTER (1 << 30)
  61. #define S5PCSIS_INTMSK_ODD_BEFORE (1 << 29)
  62. #define S5PCSIS_INTMSK_ODD_AFTER (1 << 28)
  63. #define S5PCSIS_INTMSK_ERR_SOT_HS (1 << 12)
  64. #define S5PCSIS_INTMSK_ERR_LOST_FS (1 << 5)
  65. #define S5PCSIS_INTMSK_ERR_LOST_FE (1 << 4)
  66. #define S5PCSIS_INTMSK_ERR_OVER (1 << 3)
  67. #define S5PCSIS_INTMSK_ERR_ECC (1 << 2)
  68. #define S5PCSIS_INTMSK_ERR_CRC (1 << 1)
  69. #define S5PCSIS_INTMSK_ERR_UNKNOWN (1 << 0)
  70. /* Interrupt source */
  71. #define S5PCSIS_INTSRC 0x14
  72. #define S5PCSIS_INTSRC_EVEN_BEFORE (1 << 31)
  73. #define S5PCSIS_INTSRC_EVEN_AFTER (1 << 30)
  74. #define S5PCSIS_INTSRC_EVEN (0x3 << 30)
  75. #define S5PCSIS_INTSRC_ODD_BEFORE (1 << 29)
  76. #define S5PCSIS_INTSRC_ODD_AFTER (1 << 28)
  77. #define S5PCSIS_INTSRC_ODD (0x3 << 28)
  78. #define S5PCSIS_INTSRC_NON_IMAGE_DATA (0xff << 28)
  79. #define S5PCSIS_INTSRC_ERR_SOT_HS (0xf << 12)
  80. #define S5PCSIS_INTSRC_ERR_LOST_FS (1 << 5)
  81. #define S5PCSIS_INTSRC_ERR_LOST_FE (1 << 4)
  82. #define S5PCSIS_INTSRC_ERR_OVER (1 << 3)
  83. #define S5PCSIS_INTSRC_ERR_ECC (1 << 2)
  84. #define S5PCSIS_INTSRC_ERR_CRC (1 << 1)
  85. #define S5PCSIS_INTSRC_ERR_UNKNOWN (1 << 0)
  86. #define S5PCSIS_INTSRC_ERRORS 0xf03f
  87. /* Pixel resolution */
  88. #define S5PCSIS_RESOL 0x2c
  89. #define CSIS_MAX_PIX_WIDTH 0xffff
  90. #define CSIS_MAX_PIX_HEIGHT 0xffff
  91. /* Non-image packet data buffers */
  92. #define S5PCSIS_PKTDATA_ODD 0x2000
  93. #define S5PCSIS_PKTDATA_EVEN 0x3000
  94. #define S5PCSIS_PKTDATA_SIZE SZ_4K
  95. enum {
  96. CSIS_CLK_MUX,
  97. CSIS_CLK_GATE,
  98. };
  99. static char *csi_clock_name[] = {
  100. [CSIS_CLK_MUX] = "sclk_csis",
  101. [CSIS_CLK_GATE] = "csis",
  102. };
  103. #define NUM_CSIS_CLOCKS ARRAY_SIZE(csi_clock_name)
  104. static const char * const csis_supply_name[] = {
  105. "vdd11", /* 1.1V or 1.2V (s5pc100) MIPI CSI suppply */
  106. "vdd18", /* VDD 1.8V and MIPI CSI PLL supply */
  107. };
  108. #define CSIS_NUM_SUPPLIES ARRAY_SIZE(csis_supply_name)
  109. enum {
  110. ST_POWERED = 1,
  111. ST_STREAMING = 2,
  112. ST_SUSPENDED = 4,
  113. };
  114. struct s5pcsis_event {
  115. u32 mask;
  116. const char * const name;
  117. unsigned int counter;
  118. };
  119. static const struct s5pcsis_event s5pcsis_events[] = {
  120. /* Errors */
  121. { S5PCSIS_INTSRC_ERR_SOT_HS, "SOT Error" },
  122. { S5PCSIS_INTSRC_ERR_LOST_FS, "Lost Frame Start Error" },
  123. { S5PCSIS_INTSRC_ERR_LOST_FE, "Lost Frame End Error" },
  124. { S5PCSIS_INTSRC_ERR_OVER, "FIFO Overflow Error" },
  125. { S5PCSIS_INTSRC_ERR_ECC, "ECC Error" },
  126. { S5PCSIS_INTSRC_ERR_CRC, "CRC Error" },
  127. { S5PCSIS_INTSRC_ERR_UNKNOWN, "Unknown Error" },
  128. /* Non-image data receive events */
  129. { S5PCSIS_INTSRC_EVEN_BEFORE, "Non-image data before even frame" },
  130. { S5PCSIS_INTSRC_EVEN_AFTER, "Non-image data after even frame" },
  131. { S5PCSIS_INTSRC_ODD_BEFORE, "Non-image data before odd frame" },
  132. { S5PCSIS_INTSRC_ODD_AFTER, "Non-image data after odd frame" },
  133. };
  134. #define S5PCSIS_NUM_EVENTS ARRAY_SIZE(s5pcsis_events)
  135. struct csis_pktbuf {
  136. u32 *data;
  137. unsigned int len;
  138. };
  139. /**
  140. * struct csis_state - the driver's internal state data structure
  141. * @lock: mutex serializing the subdev and power management operations,
  142. * protecting @format and @flags members
  143. * @pads: CSIS pads array
  144. * @sd: v4l2_subdev associated with CSIS device instance
  145. * @pdev: CSIS platform device
  146. * @regs: mmaped I/O registers memory
  147. * @supplies: CSIS regulator supplies
  148. * @clock: CSIS clocks
  149. * @irq: requested s5p-mipi-csis irq number
  150. * @flags: the state variable for power and streaming control
  151. * @csis_fmt: current CSIS pixel format
  152. * @format: common media bus format for the source and sink pad
  153. * @slock: spinlock protecting structure members below
  154. * @pkt_buf: the frame embedded (non-image) data buffer
  155. * @events: MIPI-CSIS event (error) counters
  156. */
  157. struct csis_state {
  158. struct mutex lock;
  159. struct media_pad pads[CSIS_PADS_NUM];
  160. struct v4l2_subdev sd;
  161. struct platform_device *pdev;
  162. void __iomem *regs;
  163. struct regulator_bulk_data supplies[CSIS_NUM_SUPPLIES];
  164. struct clk *clock[NUM_CSIS_CLOCKS];
  165. int irq;
  166. u32 flags;
  167. const struct csis_pix_format *csis_fmt;
  168. struct v4l2_mbus_framefmt format;
  169. struct spinlock slock;
  170. struct csis_pktbuf pkt_buf;
  171. struct s5pcsis_event events[S5PCSIS_NUM_EVENTS];
  172. };
  173. /**
  174. * struct csis_pix_format - CSIS pixel format description
  175. * @pix_width_alignment: horizontal pixel alignment, width will be
  176. * multiple of 2^pix_width_alignment
  177. * @code: corresponding media bus code
  178. * @fmt_reg: S5PCSIS_CONFIG register value
  179. * @data_alignment: MIPI-CSI data alignment in bits
  180. */
  181. struct csis_pix_format {
  182. unsigned int pix_width_alignment;
  183. enum v4l2_mbus_pixelcode code;
  184. u32 fmt_reg;
  185. u8 data_alignment;
  186. };
  187. static const struct csis_pix_format s5pcsis_formats[] = {
  188. {
  189. .code = V4L2_MBUS_FMT_VYUY8_2X8,
  190. .fmt_reg = S5PCSIS_CFG_FMT_YCBCR422_8BIT,
  191. .data_alignment = 32,
  192. }, {
  193. .code = V4L2_MBUS_FMT_JPEG_1X8,
  194. .fmt_reg = S5PCSIS_CFG_FMT_USER(1),
  195. .data_alignment = 32,
  196. },
  197. };
  198. #define s5pcsis_write(__csis, __r, __v) writel(__v, __csis->regs + __r)
  199. #define s5pcsis_read(__csis, __r) readl(__csis->regs + __r)
  200. static struct csis_state *sd_to_csis_state(struct v4l2_subdev *sdev)
  201. {
  202. return container_of(sdev, struct csis_state, sd);
  203. }
  204. static const struct csis_pix_format *find_csis_format(
  205. struct v4l2_mbus_framefmt *mf)
  206. {
  207. int i;
  208. for (i = 0; i < ARRAY_SIZE(s5pcsis_formats); i++)
  209. if (mf->code == s5pcsis_formats[i].code)
  210. return &s5pcsis_formats[i];
  211. return NULL;
  212. }
  213. static void s5pcsis_enable_interrupts(struct csis_state *state, bool on)
  214. {
  215. u32 val = s5pcsis_read(state, S5PCSIS_INTMSK);
  216. val = on ? val | S5PCSIS_INTMSK_EN_ALL :
  217. val & ~S5PCSIS_INTMSK_EN_ALL;
  218. s5pcsis_write(state, S5PCSIS_INTMSK, val);
  219. }
  220. static void s5pcsis_reset(struct csis_state *state)
  221. {
  222. u32 val = s5pcsis_read(state, S5PCSIS_CTRL);
  223. s5pcsis_write(state, S5PCSIS_CTRL, val | S5PCSIS_CTRL_RESET);
  224. udelay(10);
  225. }
  226. static void s5pcsis_system_enable(struct csis_state *state, int on)
  227. {
  228. u32 val;
  229. val = s5pcsis_read(state, S5PCSIS_CTRL);
  230. if (on)
  231. val |= S5PCSIS_CTRL_ENABLE;
  232. else
  233. val &= ~S5PCSIS_CTRL_ENABLE;
  234. s5pcsis_write(state, S5PCSIS_CTRL, val);
  235. val = s5pcsis_read(state, S5PCSIS_DPHYCTRL);
  236. if (on)
  237. val |= S5PCSIS_DPHYCTRL_ENABLE;
  238. else
  239. val &= ~S5PCSIS_DPHYCTRL_ENABLE;
  240. s5pcsis_write(state, S5PCSIS_DPHYCTRL, val);
  241. }
  242. /* Called with the state.lock mutex held */
  243. static void __s5pcsis_set_format(struct csis_state *state)
  244. {
  245. struct v4l2_mbus_framefmt *mf = &state->format;
  246. u32 val;
  247. v4l2_dbg(1, debug, &state->sd, "fmt: %d, %d x %d\n",
  248. mf->code, mf->width, mf->height);
  249. /* Color format */
  250. val = s5pcsis_read(state, S5PCSIS_CONFIG);
  251. val = (val & ~S5PCSIS_CFG_FMT_MASK) | state->csis_fmt->fmt_reg;
  252. s5pcsis_write(state, S5PCSIS_CONFIG, val);
  253. /* Pixel resolution */
  254. val = (mf->width << 16) | mf->height;
  255. s5pcsis_write(state, S5PCSIS_RESOL, val);
  256. }
  257. static void s5pcsis_set_hsync_settle(struct csis_state *state, int settle)
  258. {
  259. u32 val = s5pcsis_read(state, S5PCSIS_DPHYCTRL);
  260. val = (val & ~S5PCSIS_DPHYCTRL_HSS_MASK) | (settle << 27);
  261. s5pcsis_write(state, S5PCSIS_DPHYCTRL, val);
  262. }
  263. static void s5pcsis_set_params(struct csis_state *state)
  264. {
  265. struct s5p_platform_mipi_csis *pdata = state->pdev->dev.platform_data;
  266. u32 val;
  267. val = s5pcsis_read(state, S5PCSIS_CONFIG);
  268. val = (val & ~S5PCSIS_CFG_NR_LANE_MASK) | (pdata->lanes - 1);
  269. s5pcsis_write(state, S5PCSIS_CONFIG, val);
  270. __s5pcsis_set_format(state);
  271. s5pcsis_set_hsync_settle(state, pdata->hs_settle);
  272. val = s5pcsis_read(state, S5PCSIS_CTRL);
  273. if (state->csis_fmt->data_alignment == 32)
  274. val |= S5PCSIS_CTRL_ALIGN_32BIT;
  275. else /* 24-bits */
  276. val &= ~S5PCSIS_CTRL_ALIGN_32BIT;
  277. /* Not using external clock. */
  278. val &= ~S5PCSIS_CTRL_WCLK_EXTCLK;
  279. s5pcsis_write(state, S5PCSIS_CTRL, val);
  280. /* Update the shadow register. */
  281. val = s5pcsis_read(state, S5PCSIS_CTRL);
  282. s5pcsis_write(state, S5PCSIS_CTRL, val | S5PCSIS_CTRL_UPDATE_SHADOW);
  283. }
  284. static void s5pcsis_clk_put(struct csis_state *state)
  285. {
  286. int i;
  287. for (i = 0; i < NUM_CSIS_CLOCKS; i++) {
  288. if (IS_ERR_OR_NULL(state->clock[i]))
  289. continue;
  290. clk_unprepare(state->clock[i]);
  291. clk_put(state->clock[i]);
  292. state->clock[i] = NULL;
  293. }
  294. }
  295. static int s5pcsis_clk_get(struct csis_state *state)
  296. {
  297. struct device *dev = &state->pdev->dev;
  298. int i, ret;
  299. for (i = 0; i < NUM_CSIS_CLOCKS; i++) {
  300. state->clock[i] = clk_get(dev, csi_clock_name[i]);
  301. if (IS_ERR(state->clock[i]))
  302. goto err;
  303. ret = clk_prepare(state->clock[i]);
  304. if (ret < 0) {
  305. clk_put(state->clock[i]);
  306. state->clock[i] = NULL;
  307. goto err;
  308. }
  309. }
  310. return 0;
  311. err:
  312. s5pcsis_clk_put(state);
  313. dev_err(dev, "failed to get clock: %s\n", csi_clock_name[i]);
  314. return -ENXIO;
  315. }
  316. static void s5pcsis_start_stream(struct csis_state *state)
  317. {
  318. s5pcsis_reset(state);
  319. s5pcsis_set_params(state);
  320. s5pcsis_system_enable(state, true);
  321. s5pcsis_enable_interrupts(state, true);
  322. }
  323. static void s5pcsis_stop_stream(struct csis_state *state)
  324. {
  325. s5pcsis_enable_interrupts(state, false);
  326. s5pcsis_system_enable(state, false);
  327. }
  328. static void s5pcsis_clear_counters(struct csis_state *state)
  329. {
  330. unsigned long flags;
  331. int i;
  332. spin_lock_irqsave(&state->slock, flags);
  333. for (i = 0; i < S5PCSIS_NUM_EVENTS; i++)
  334. state->events[i].counter = 0;
  335. spin_unlock_irqrestore(&state->slock, flags);
  336. }
  337. static void s5pcsis_log_counters(struct csis_state *state, bool non_errors)
  338. {
  339. int i = non_errors ? S5PCSIS_NUM_EVENTS : S5PCSIS_NUM_EVENTS - 4;
  340. unsigned long flags;
  341. spin_lock_irqsave(&state->slock, flags);
  342. for (i--; i >= 0; i--)
  343. if (state->events[i].counter >= 0)
  344. v4l2_info(&state->sd, "%s events: %d\n",
  345. state->events[i].name,
  346. state->events[i].counter);
  347. spin_unlock_irqrestore(&state->slock, flags);
  348. }
  349. /*
  350. * V4L2 subdev operations
  351. */
  352. static int s5pcsis_s_power(struct v4l2_subdev *sd, int on)
  353. {
  354. struct csis_state *state = sd_to_csis_state(sd);
  355. struct device *dev = &state->pdev->dev;
  356. if (on)
  357. return pm_runtime_get_sync(dev);
  358. return pm_runtime_put_sync(dev);
  359. }
  360. static int s5pcsis_s_stream(struct v4l2_subdev *sd, int enable)
  361. {
  362. struct csis_state *state = sd_to_csis_state(sd);
  363. int ret = 0;
  364. v4l2_dbg(1, debug, sd, "%s: %d, state: 0x%x\n",
  365. __func__, enable, state->flags);
  366. if (enable) {
  367. s5pcsis_clear_counters(state);
  368. ret = pm_runtime_get_sync(&state->pdev->dev);
  369. if (ret && ret != 1)
  370. return ret;
  371. }
  372. mutex_lock(&state->lock);
  373. if (enable) {
  374. if (state->flags & ST_SUSPENDED) {
  375. ret = -EBUSY;
  376. goto unlock;
  377. }
  378. s5pcsis_start_stream(state);
  379. state->flags |= ST_STREAMING;
  380. } else {
  381. s5pcsis_stop_stream(state);
  382. state->flags &= ~ST_STREAMING;
  383. if (debug > 0)
  384. s5pcsis_log_counters(state, true);
  385. }
  386. unlock:
  387. mutex_unlock(&state->lock);
  388. if (!enable)
  389. pm_runtime_put(&state->pdev->dev);
  390. return ret == 1 ? 0 : ret;
  391. }
  392. static int s5pcsis_enum_mbus_code(struct v4l2_subdev *sd,
  393. struct v4l2_subdev_fh *fh,
  394. struct v4l2_subdev_mbus_code_enum *code)
  395. {
  396. if (code->index >= ARRAY_SIZE(s5pcsis_formats))
  397. return -EINVAL;
  398. code->code = s5pcsis_formats[code->index].code;
  399. return 0;
  400. }
  401. static struct csis_pix_format const *s5pcsis_try_format(
  402. struct v4l2_mbus_framefmt *mf)
  403. {
  404. struct csis_pix_format const *csis_fmt;
  405. csis_fmt = find_csis_format(mf);
  406. if (csis_fmt == NULL)
  407. csis_fmt = &s5pcsis_formats[0];
  408. mf->code = csis_fmt->code;
  409. v4l_bound_align_image(&mf->width, 1, CSIS_MAX_PIX_WIDTH,
  410. csis_fmt->pix_width_alignment,
  411. &mf->height, 1, CSIS_MAX_PIX_HEIGHT, 1,
  412. 0);
  413. return csis_fmt;
  414. }
  415. static struct v4l2_mbus_framefmt *__s5pcsis_get_format(
  416. struct csis_state *state, struct v4l2_subdev_fh *fh,
  417. u32 pad, enum v4l2_subdev_format_whence which)
  418. {
  419. if (which == V4L2_SUBDEV_FORMAT_TRY)
  420. return fh ? v4l2_subdev_get_try_format(fh, pad) : NULL;
  421. return &state->format;
  422. }
  423. static int s5pcsis_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
  424. struct v4l2_subdev_format *fmt)
  425. {
  426. struct csis_state *state = sd_to_csis_state(sd);
  427. struct csis_pix_format const *csis_fmt;
  428. struct v4l2_mbus_framefmt *mf;
  429. if (fmt->pad != CSIS_PAD_SOURCE && fmt->pad != CSIS_PAD_SINK)
  430. return -EINVAL;
  431. mf = __s5pcsis_get_format(state, fh, fmt->pad, fmt->which);
  432. if (fmt->pad == CSIS_PAD_SOURCE) {
  433. if (mf) {
  434. mutex_lock(&state->lock);
  435. fmt->format = *mf;
  436. mutex_unlock(&state->lock);
  437. }
  438. return 0;
  439. }
  440. csis_fmt = s5pcsis_try_format(&fmt->format);
  441. if (mf) {
  442. mutex_lock(&state->lock);
  443. *mf = fmt->format;
  444. if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE)
  445. state->csis_fmt = csis_fmt;
  446. mutex_unlock(&state->lock);
  447. }
  448. return 0;
  449. }
  450. static int s5pcsis_get_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
  451. struct v4l2_subdev_format *fmt)
  452. {
  453. struct csis_state *state = sd_to_csis_state(sd);
  454. struct v4l2_mbus_framefmt *mf;
  455. if (fmt->pad != CSIS_PAD_SOURCE && fmt->pad != CSIS_PAD_SINK)
  456. return -EINVAL;
  457. mf = __s5pcsis_get_format(state, fh, fmt->pad, fmt->which);
  458. if (!mf)
  459. return -EINVAL;
  460. mutex_lock(&state->lock);
  461. fmt->format = *mf;
  462. mutex_unlock(&state->lock);
  463. return 0;
  464. }
  465. static int s5pcsis_s_rx_buffer(struct v4l2_subdev *sd, void *buf,
  466. unsigned int *size)
  467. {
  468. struct csis_state *state = sd_to_csis_state(sd);
  469. unsigned long flags;
  470. *size = min_t(unsigned int, *size, S5PCSIS_PKTDATA_SIZE);
  471. spin_lock_irqsave(&state->slock, flags);
  472. state->pkt_buf.data = buf;
  473. state->pkt_buf.len = *size;
  474. spin_unlock_irqrestore(&state->slock, flags);
  475. return 0;
  476. }
  477. static int s5pcsis_log_status(struct v4l2_subdev *sd)
  478. {
  479. struct csis_state *state = sd_to_csis_state(sd);
  480. s5pcsis_log_counters(state, true);
  481. return 0;
  482. }
  483. static int s5pcsis_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
  484. {
  485. struct v4l2_mbus_framefmt *format = v4l2_subdev_get_try_format(fh, 0);
  486. format->colorspace = V4L2_COLORSPACE_JPEG;
  487. format->code = s5pcsis_formats[0].code;
  488. format->width = S5PCSIS_DEF_PIX_WIDTH;
  489. format->height = S5PCSIS_DEF_PIX_HEIGHT;
  490. format->field = V4L2_FIELD_NONE;
  491. return 0;
  492. }
  493. static const struct v4l2_subdev_internal_ops s5pcsis_sd_internal_ops = {
  494. .open = s5pcsis_open,
  495. };
  496. static struct v4l2_subdev_core_ops s5pcsis_core_ops = {
  497. .s_power = s5pcsis_s_power,
  498. .log_status = s5pcsis_log_status,
  499. };
  500. static struct v4l2_subdev_pad_ops s5pcsis_pad_ops = {
  501. .enum_mbus_code = s5pcsis_enum_mbus_code,
  502. .get_fmt = s5pcsis_get_fmt,
  503. .set_fmt = s5pcsis_set_fmt,
  504. };
  505. static struct v4l2_subdev_video_ops s5pcsis_video_ops = {
  506. .s_rx_buffer = s5pcsis_s_rx_buffer,
  507. .s_stream = s5pcsis_s_stream,
  508. };
  509. static struct v4l2_subdev_ops s5pcsis_subdev_ops = {
  510. .core = &s5pcsis_core_ops,
  511. .pad = &s5pcsis_pad_ops,
  512. .video = &s5pcsis_video_ops,
  513. };
  514. static irqreturn_t s5pcsis_irq_handler(int irq, void *dev_id)
  515. {
  516. struct csis_state *state = dev_id;
  517. struct csis_pktbuf *pktbuf = &state->pkt_buf;
  518. unsigned long flags;
  519. u32 status;
  520. status = s5pcsis_read(state, S5PCSIS_INTSRC);
  521. spin_lock_irqsave(&state->slock, flags);
  522. if ((status & S5PCSIS_INTSRC_NON_IMAGE_DATA) && pktbuf->data) {
  523. u32 offset;
  524. if (status & S5PCSIS_INTSRC_EVEN)
  525. offset = S5PCSIS_PKTDATA_EVEN;
  526. else
  527. offset = S5PCSIS_PKTDATA_ODD;
  528. memcpy(pktbuf->data, state->regs + offset, pktbuf->len);
  529. pktbuf->data = NULL;
  530. rmb();
  531. }
  532. /* Update the event/error counters */
  533. if ((status & S5PCSIS_INTSRC_ERRORS) || debug) {
  534. int i;
  535. for (i = 0; i < S5PCSIS_NUM_EVENTS; i++) {
  536. if (!(status & state->events[i].mask))
  537. continue;
  538. state->events[i].counter++;
  539. v4l2_dbg(2, debug, &state->sd, "%s: %d\n",
  540. state->events[i].name,
  541. state->events[i].counter);
  542. }
  543. v4l2_dbg(2, debug, &state->sd, "status: %08x\n", status);
  544. }
  545. spin_unlock_irqrestore(&state->slock, flags);
  546. s5pcsis_write(state, S5PCSIS_INTSRC, status);
  547. return IRQ_HANDLED;
  548. }
  549. static int __devinit s5pcsis_probe(struct platform_device *pdev)
  550. {
  551. struct s5p_platform_mipi_csis *pdata;
  552. struct resource *mem_res;
  553. struct csis_state *state;
  554. int ret = -ENOMEM;
  555. int i;
  556. state = devm_kzalloc(&pdev->dev, sizeof(*state), GFP_KERNEL);
  557. if (!state)
  558. return -ENOMEM;
  559. mutex_init(&state->lock);
  560. spin_lock_init(&state->slock);
  561. state->pdev = pdev;
  562. pdata = pdev->dev.platform_data;
  563. if (pdata == NULL || pdata->phy_enable == NULL) {
  564. dev_err(&pdev->dev, "Platform data not fully specified\n");
  565. return -EINVAL;
  566. }
  567. if ((pdev->id == 1 && pdata->lanes > CSIS1_MAX_LANES) ||
  568. pdata->lanes > CSIS0_MAX_LANES) {
  569. dev_err(&pdev->dev, "Unsupported number of data lanes: %d\n",
  570. pdata->lanes);
  571. return -EINVAL;
  572. }
  573. mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  574. state->regs = devm_request_and_ioremap(&pdev->dev, mem_res);
  575. if (state->regs == NULL) {
  576. dev_err(&pdev->dev, "Failed to request and remap io memory\n");
  577. return -ENXIO;
  578. }
  579. state->irq = platform_get_irq(pdev, 0);
  580. if (state->irq < 0) {
  581. dev_err(&pdev->dev, "Failed to get irq\n");
  582. return state->irq;
  583. }
  584. for (i = 0; i < CSIS_NUM_SUPPLIES; i++)
  585. state->supplies[i].supply = csis_supply_name[i];
  586. ret = regulator_bulk_get(&pdev->dev, CSIS_NUM_SUPPLIES,
  587. state->supplies);
  588. if (ret)
  589. return ret;
  590. ret = s5pcsis_clk_get(state);
  591. if (ret)
  592. goto e_clkput;
  593. clk_enable(state->clock[CSIS_CLK_MUX]);
  594. if (pdata->clk_rate)
  595. clk_set_rate(state->clock[CSIS_CLK_MUX], pdata->clk_rate);
  596. else
  597. dev_WARN(&pdev->dev, "No clock frequency specified!\n");
  598. ret = devm_request_irq(&pdev->dev, state->irq, s5pcsis_irq_handler,
  599. 0, dev_name(&pdev->dev), state);
  600. if (ret) {
  601. dev_err(&pdev->dev, "Interrupt request failed\n");
  602. goto e_regput;
  603. }
  604. v4l2_subdev_init(&state->sd, &s5pcsis_subdev_ops);
  605. state->sd.owner = THIS_MODULE;
  606. strlcpy(state->sd.name, dev_name(&pdev->dev), sizeof(state->sd.name));
  607. state->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
  608. state->csis_fmt = &s5pcsis_formats[0];
  609. state->format.code = s5pcsis_formats[0].code;
  610. state->format.width = S5PCSIS_DEF_PIX_WIDTH;
  611. state->format.height = S5PCSIS_DEF_PIX_HEIGHT;
  612. state->pads[CSIS_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
  613. state->pads[CSIS_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
  614. ret = media_entity_init(&state->sd.entity,
  615. CSIS_PADS_NUM, state->pads, 0);
  616. if (ret < 0)
  617. goto e_clkput;
  618. /* This allows to retrieve the platform device id by the host driver */
  619. v4l2_set_subdevdata(&state->sd, pdev);
  620. /* .. and a pointer to the subdev. */
  621. platform_set_drvdata(pdev, &state->sd);
  622. memcpy(state->events, s5pcsis_events, sizeof(state->events));
  623. pm_runtime_enable(&pdev->dev);
  624. return 0;
  625. e_regput:
  626. regulator_bulk_free(CSIS_NUM_SUPPLIES, state->supplies);
  627. e_clkput:
  628. clk_disable(state->clock[CSIS_CLK_MUX]);
  629. s5pcsis_clk_put(state);
  630. return ret;
  631. }
  632. static int s5pcsis_pm_suspend(struct device *dev, bool runtime)
  633. {
  634. struct s5p_platform_mipi_csis *pdata = dev->platform_data;
  635. struct platform_device *pdev = to_platform_device(dev);
  636. struct v4l2_subdev *sd = platform_get_drvdata(pdev);
  637. struct csis_state *state = sd_to_csis_state(sd);
  638. int ret = 0;
  639. v4l2_dbg(1, debug, sd, "%s: flags: 0x%x\n",
  640. __func__, state->flags);
  641. mutex_lock(&state->lock);
  642. if (state->flags & ST_POWERED) {
  643. s5pcsis_stop_stream(state);
  644. ret = pdata->phy_enable(state->pdev, false);
  645. if (ret)
  646. goto unlock;
  647. ret = regulator_bulk_disable(CSIS_NUM_SUPPLIES,
  648. state->supplies);
  649. if (ret)
  650. goto unlock;
  651. clk_disable(state->clock[CSIS_CLK_GATE]);
  652. state->flags &= ~ST_POWERED;
  653. if (!runtime)
  654. state->flags |= ST_SUSPENDED;
  655. }
  656. unlock:
  657. mutex_unlock(&state->lock);
  658. return ret ? -EAGAIN : 0;
  659. }
  660. static int s5pcsis_pm_resume(struct device *dev, bool runtime)
  661. {
  662. struct s5p_platform_mipi_csis *pdata = dev->platform_data;
  663. struct platform_device *pdev = to_platform_device(dev);
  664. struct v4l2_subdev *sd = platform_get_drvdata(pdev);
  665. struct csis_state *state = sd_to_csis_state(sd);
  666. int ret = 0;
  667. v4l2_dbg(1, debug, sd, "%s: flags: 0x%x\n",
  668. __func__, state->flags);
  669. mutex_lock(&state->lock);
  670. if (!runtime && !(state->flags & ST_SUSPENDED))
  671. goto unlock;
  672. if (!(state->flags & ST_POWERED)) {
  673. ret = regulator_bulk_enable(CSIS_NUM_SUPPLIES,
  674. state->supplies);
  675. if (ret)
  676. goto unlock;
  677. ret = pdata->phy_enable(state->pdev, true);
  678. if (!ret) {
  679. state->flags |= ST_POWERED;
  680. } else {
  681. regulator_bulk_disable(CSIS_NUM_SUPPLIES,
  682. state->supplies);
  683. goto unlock;
  684. }
  685. clk_enable(state->clock[CSIS_CLK_GATE]);
  686. }
  687. if (state->flags & ST_STREAMING)
  688. s5pcsis_start_stream(state);
  689. state->flags &= ~ST_SUSPENDED;
  690. unlock:
  691. mutex_unlock(&state->lock);
  692. return ret ? -EAGAIN : 0;
  693. }
  694. #ifdef CONFIG_PM_SLEEP
  695. static int s5pcsis_suspend(struct device *dev)
  696. {
  697. return s5pcsis_pm_suspend(dev, false);
  698. }
  699. static int s5pcsis_resume(struct device *dev)
  700. {
  701. return s5pcsis_pm_resume(dev, false);
  702. }
  703. #endif
  704. #ifdef CONFIG_PM_RUNTIME
  705. static int s5pcsis_runtime_suspend(struct device *dev)
  706. {
  707. return s5pcsis_pm_suspend(dev, true);
  708. }
  709. static int s5pcsis_runtime_resume(struct device *dev)
  710. {
  711. return s5pcsis_pm_resume(dev, true);
  712. }
  713. #endif
  714. static int __devexit s5pcsis_remove(struct platform_device *pdev)
  715. {
  716. struct v4l2_subdev *sd = platform_get_drvdata(pdev);
  717. struct csis_state *state = sd_to_csis_state(sd);
  718. pm_runtime_disable(&pdev->dev);
  719. s5pcsis_pm_suspend(&pdev->dev, false);
  720. clk_disable(state->clock[CSIS_CLK_MUX]);
  721. pm_runtime_set_suspended(&pdev->dev);
  722. s5pcsis_clk_put(state);
  723. regulator_bulk_free(CSIS_NUM_SUPPLIES, state->supplies);
  724. media_entity_cleanup(&state->sd.entity);
  725. return 0;
  726. }
  727. static const struct dev_pm_ops s5pcsis_pm_ops = {
  728. SET_RUNTIME_PM_OPS(s5pcsis_runtime_suspend, s5pcsis_runtime_resume,
  729. NULL)
  730. SET_SYSTEM_SLEEP_PM_OPS(s5pcsis_suspend, s5pcsis_resume)
  731. };
  732. static struct platform_driver s5pcsis_driver = {
  733. .probe = s5pcsis_probe,
  734. .remove = __devexit_p(s5pcsis_remove),
  735. .driver = {
  736. .name = CSIS_DRIVER_NAME,
  737. .owner = THIS_MODULE,
  738. .pm = &s5pcsis_pm_ops,
  739. },
  740. };
  741. module_platform_driver(s5pcsis_driver);
  742. MODULE_AUTHOR("Sylwester Nawrocki <s.nawrocki@samsung.com>");
  743. MODULE_DESCRIPTION("Samsung S5P/EXYNOS SoC MIPI-CSI2 receiver driver");
  744. MODULE_LICENSE("GPL");