mixer_drv.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527
  1. /*
  2. * Samsung TV Mixer driver
  3. *
  4. * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
  5. *
  6. * Tomasz Stanislawski, <t.stanislaws@samsung.com>
  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
  10. * by the Free Software Foundiation. either version 2 of the License,
  11. * or (at your option) any later version
  12. */
  13. #include "mixer.h"
  14. #include <linux/module.h>
  15. #include <linux/platform_device.h>
  16. #include <linux/io.h>
  17. #include <linux/interrupt.h>
  18. #include <linux/irq.h>
  19. #include <linux/fb.h>
  20. #include <linux/delay.h>
  21. #include <linux/pm_runtime.h>
  22. #include <linux/clk.h>
  23. MODULE_AUTHOR("Tomasz Stanislawski, <t.stanislaws@samsung.com>");
  24. MODULE_DESCRIPTION("Samsung MIXER");
  25. MODULE_LICENSE("GPL");
  26. /* --------- DRIVER PARAMETERS ---------- */
  27. static struct mxr_output_conf mxr_output_conf[] = {
  28. {
  29. .output_name = "S5P HDMI connector",
  30. .module_name = "s5p-hdmi",
  31. .cookie = 1,
  32. },
  33. {
  34. .output_name = "S5P SDO connector",
  35. .module_name = "s5p-sdo",
  36. .cookie = 0,
  37. },
  38. };
  39. void mxr_get_mbus_fmt(struct mxr_device *mdev,
  40. struct v4l2_mbus_framefmt *mbus_fmt)
  41. {
  42. struct v4l2_subdev *sd;
  43. struct v4l2_subdev_format fmt = {
  44. .which = V4L2_SUBDEV_FORMAT_ACTIVE,
  45. };
  46. int ret;
  47. mutex_lock(&mdev->mutex);
  48. sd = to_outsd(mdev);
  49. ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, &fmt);
  50. *mbus_fmt = fmt.format;
  51. WARN(ret, "failed to get mbus_fmt for output %s\n", sd->name);
  52. mutex_unlock(&mdev->mutex);
  53. }
  54. void mxr_streamer_get(struct mxr_device *mdev)
  55. {
  56. mutex_lock(&mdev->mutex);
  57. ++mdev->n_streamer;
  58. mxr_dbg(mdev, "%s(%d)\n", __func__, mdev->n_streamer);
  59. if (mdev->n_streamer == 1) {
  60. struct v4l2_subdev *sd = to_outsd(mdev);
  61. struct v4l2_subdev_format fmt = {
  62. .which = V4L2_SUBDEV_FORMAT_ACTIVE,
  63. };
  64. struct v4l2_mbus_framefmt *mbus_fmt = &fmt.format;
  65. struct mxr_resources *res = &mdev->res;
  66. int ret;
  67. if (to_output(mdev)->cookie == 0)
  68. clk_set_parent(res->sclk_mixer, res->sclk_dac);
  69. else
  70. clk_set_parent(res->sclk_mixer, res->sclk_hdmi);
  71. mxr_reg_s_output(mdev, to_output(mdev)->cookie);
  72. ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, &fmt);
  73. WARN(ret, "failed to get mbus_fmt for output %s\n", sd->name);
  74. ret = v4l2_subdev_call(sd, video, s_stream, 1);
  75. WARN(ret, "starting stream failed for output %s\n", sd->name);
  76. mxr_reg_set_mbus_fmt(mdev, mbus_fmt);
  77. mxr_reg_streamon(mdev);
  78. ret = mxr_reg_wait4vsync(mdev);
  79. WARN(ret, "failed to get vsync (%d) from output\n", ret);
  80. }
  81. mutex_unlock(&mdev->mutex);
  82. mxr_reg_dump(mdev);
  83. /* FIXME: what to do when streaming fails? */
  84. }
  85. void mxr_streamer_put(struct mxr_device *mdev)
  86. {
  87. mutex_lock(&mdev->mutex);
  88. --mdev->n_streamer;
  89. mxr_dbg(mdev, "%s(%d)\n", __func__, mdev->n_streamer);
  90. if (mdev->n_streamer == 0) {
  91. int ret;
  92. struct v4l2_subdev *sd = to_outsd(mdev);
  93. mxr_reg_streamoff(mdev);
  94. /* vsync applies Mixer setup */
  95. ret = mxr_reg_wait4vsync(mdev);
  96. WARN(ret, "failed to get vsync (%d) from output\n", ret);
  97. ret = v4l2_subdev_call(sd, video, s_stream, 0);
  98. WARN(ret, "stopping stream failed for output %s\n", sd->name);
  99. }
  100. WARN(mdev->n_streamer < 0, "negative number of streamers (%d)\n",
  101. mdev->n_streamer);
  102. mutex_unlock(&mdev->mutex);
  103. mxr_reg_dump(mdev);
  104. }
  105. void mxr_output_get(struct mxr_device *mdev)
  106. {
  107. mutex_lock(&mdev->mutex);
  108. ++mdev->n_output;
  109. mxr_dbg(mdev, "%s(%d)\n", __func__, mdev->n_output);
  110. /* turn on auxiliary driver */
  111. if (mdev->n_output == 1)
  112. v4l2_subdev_call(to_outsd(mdev), core, s_power, 1);
  113. mutex_unlock(&mdev->mutex);
  114. }
  115. void mxr_output_put(struct mxr_device *mdev)
  116. {
  117. mutex_lock(&mdev->mutex);
  118. --mdev->n_output;
  119. mxr_dbg(mdev, "%s(%d)\n", __func__, mdev->n_output);
  120. /* turn on auxiliary driver */
  121. if (mdev->n_output == 0)
  122. v4l2_subdev_call(to_outsd(mdev), core, s_power, 0);
  123. WARN(mdev->n_output < 0, "negative number of output users (%d)\n",
  124. mdev->n_output);
  125. mutex_unlock(&mdev->mutex);
  126. }
  127. int mxr_power_get(struct mxr_device *mdev)
  128. {
  129. int ret = pm_runtime_get_sync(mdev->dev);
  130. /* returning 1 means that power is already enabled,
  131. * so zero success be returned */
  132. if (IS_ERR_VALUE(ret))
  133. return ret;
  134. return 0;
  135. }
  136. void mxr_power_put(struct mxr_device *mdev)
  137. {
  138. pm_runtime_put_sync(mdev->dev);
  139. }
  140. /* --------- RESOURCE MANAGEMENT -------------*/
  141. static int mxr_acquire_plat_resources(struct mxr_device *mdev,
  142. struct platform_device *pdev)
  143. {
  144. struct resource *res;
  145. int ret;
  146. res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mxr");
  147. if (res == NULL) {
  148. mxr_err(mdev, "get memory resource failed.\n");
  149. ret = -ENXIO;
  150. goto fail;
  151. }
  152. mdev->res.mxr_regs = ioremap(res->start, resource_size(res));
  153. if (mdev->res.mxr_regs == NULL) {
  154. mxr_err(mdev, "register mapping failed.\n");
  155. ret = -ENXIO;
  156. goto fail;
  157. }
  158. res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "vp");
  159. if (res == NULL) {
  160. mxr_err(mdev, "get memory resource failed.\n");
  161. ret = -ENXIO;
  162. goto fail_mxr_regs;
  163. }
  164. mdev->res.vp_regs = ioremap(res->start, resource_size(res));
  165. if (mdev->res.vp_regs == NULL) {
  166. mxr_err(mdev, "register mapping failed.\n");
  167. ret = -ENXIO;
  168. goto fail_mxr_regs;
  169. }
  170. res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "irq");
  171. if (res == NULL) {
  172. mxr_err(mdev, "get interrupt resource failed.\n");
  173. ret = -ENXIO;
  174. goto fail_vp_regs;
  175. }
  176. ret = request_irq(res->start, mxr_irq_handler, 0, "s5p-mixer", mdev);
  177. if (ret) {
  178. mxr_err(mdev, "request interrupt failed.\n");
  179. goto fail_vp_regs;
  180. }
  181. mdev->res.irq = res->start;
  182. return 0;
  183. fail_vp_regs:
  184. iounmap(mdev->res.vp_regs);
  185. fail_mxr_regs:
  186. iounmap(mdev->res.mxr_regs);
  187. fail:
  188. return ret;
  189. }
  190. static void mxr_resource_clear_clocks(struct mxr_resources *res)
  191. {
  192. res->mixer = ERR_PTR(-EINVAL);
  193. res->vp = ERR_PTR(-EINVAL);
  194. res->sclk_mixer = ERR_PTR(-EINVAL);
  195. res->sclk_hdmi = ERR_PTR(-EINVAL);
  196. res->sclk_dac = ERR_PTR(-EINVAL);
  197. }
  198. static void mxr_release_plat_resources(struct mxr_device *mdev)
  199. {
  200. free_irq(mdev->res.irq, mdev);
  201. iounmap(mdev->res.vp_regs);
  202. iounmap(mdev->res.mxr_regs);
  203. }
  204. static void mxr_release_clocks(struct mxr_device *mdev)
  205. {
  206. struct mxr_resources *res = &mdev->res;
  207. if (!IS_ERR(res->sclk_dac))
  208. clk_put(res->sclk_dac);
  209. if (!IS_ERR(res->sclk_hdmi))
  210. clk_put(res->sclk_hdmi);
  211. if (!IS_ERR(res->sclk_mixer))
  212. clk_put(res->sclk_mixer);
  213. if (!IS_ERR(res->vp))
  214. clk_put(res->vp);
  215. if (!IS_ERR(res->mixer))
  216. clk_put(res->mixer);
  217. }
  218. static int mxr_acquire_clocks(struct mxr_device *mdev)
  219. {
  220. struct mxr_resources *res = &mdev->res;
  221. struct device *dev = mdev->dev;
  222. mxr_resource_clear_clocks(res);
  223. res->mixer = clk_get(dev, "mixer");
  224. if (IS_ERR(res->mixer)) {
  225. mxr_err(mdev, "failed to get clock 'mixer'\n");
  226. goto fail;
  227. }
  228. res->vp = clk_get(dev, "vp");
  229. if (IS_ERR(res->vp)) {
  230. mxr_err(mdev, "failed to get clock 'vp'\n");
  231. goto fail;
  232. }
  233. res->sclk_mixer = clk_get(dev, "sclk_mixer");
  234. if (IS_ERR(res->sclk_mixer)) {
  235. mxr_err(mdev, "failed to get clock 'sclk_mixer'\n");
  236. goto fail;
  237. }
  238. res->sclk_hdmi = clk_get(dev, "sclk_hdmi");
  239. if (IS_ERR(res->sclk_hdmi)) {
  240. mxr_err(mdev, "failed to get clock 'sclk_hdmi'\n");
  241. goto fail;
  242. }
  243. res->sclk_dac = clk_get(dev, "sclk_dac");
  244. if (IS_ERR(res->sclk_dac)) {
  245. mxr_err(mdev, "failed to get clock 'sclk_dac'\n");
  246. goto fail;
  247. }
  248. return 0;
  249. fail:
  250. mxr_release_clocks(mdev);
  251. return -ENODEV;
  252. }
  253. static int mxr_acquire_resources(struct mxr_device *mdev,
  254. struct platform_device *pdev)
  255. {
  256. int ret;
  257. ret = mxr_acquire_plat_resources(mdev, pdev);
  258. if (ret)
  259. goto fail;
  260. ret = mxr_acquire_clocks(mdev);
  261. if (ret)
  262. goto fail_plat;
  263. mxr_info(mdev, "resources acquired\n");
  264. return 0;
  265. fail_plat:
  266. mxr_release_plat_resources(mdev);
  267. fail:
  268. mxr_err(mdev, "resources acquire failed\n");
  269. return ret;
  270. }
  271. static void mxr_release_resources(struct mxr_device *mdev)
  272. {
  273. mxr_release_clocks(mdev);
  274. mxr_release_plat_resources(mdev);
  275. memset(&mdev->res, 0, sizeof(mdev->res));
  276. mxr_resource_clear_clocks(&mdev->res);
  277. }
  278. static void mxr_release_layers(struct mxr_device *mdev)
  279. {
  280. int i;
  281. for (i = 0; i < ARRAY_SIZE(mdev->layer); ++i)
  282. if (mdev->layer[i])
  283. mxr_layer_release(mdev->layer[i]);
  284. }
  285. static int mxr_acquire_layers(struct mxr_device *mdev,
  286. struct mxr_platform_data *pdata)
  287. {
  288. mdev->layer[0] = mxr_graph_layer_create(mdev, 0);
  289. mdev->layer[1] = mxr_graph_layer_create(mdev, 1);
  290. mdev->layer[2] = mxr_vp_layer_create(mdev, 0);
  291. if (!mdev->layer[0] || !mdev->layer[1] || !mdev->layer[2]) {
  292. mxr_err(mdev, "failed to acquire layers\n");
  293. goto fail;
  294. }
  295. return 0;
  296. fail:
  297. mxr_release_layers(mdev);
  298. return -ENODEV;
  299. }
  300. /* ---------- POWER MANAGEMENT ----------- */
  301. static int mxr_runtime_resume(struct device *dev)
  302. {
  303. struct mxr_device *mdev = to_mdev(dev);
  304. struct mxr_resources *res = &mdev->res;
  305. int ret;
  306. mxr_dbg(mdev, "resume - start\n");
  307. mutex_lock(&mdev->mutex);
  308. /* turn clocks on */
  309. ret = clk_prepare_enable(res->mixer);
  310. if (ret < 0) {
  311. dev_err(mdev->dev, "clk_prepare_enable(mixer) failed\n");
  312. goto fail;
  313. }
  314. ret = clk_prepare_enable(res->vp);
  315. if (ret < 0) {
  316. dev_err(mdev->dev, "clk_prepare_enable(vp) failed\n");
  317. goto fail_mixer;
  318. }
  319. ret = clk_prepare_enable(res->sclk_mixer);
  320. if (ret < 0) {
  321. dev_err(mdev->dev, "clk_prepare_enable(sclk_mixer) failed\n");
  322. goto fail_vp;
  323. }
  324. /* apply default configuration */
  325. mxr_reg_reset(mdev);
  326. mxr_dbg(mdev, "resume - finished\n");
  327. mutex_unlock(&mdev->mutex);
  328. return 0;
  329. fail_vp:
  330. clk_disable_unprepare(res->vp);
  331. fail_mixer:
  332. clk_disable_unprepare(res->mixer);
  333. fail:
  334. mutex_unlock(&mdev->mutex);
  335. dev_err(mdev->dev, "resume failed\n");
  336. return ret;
  337. }
  338. static int mxr_runtime_suspend(struct device *dev)
  339. {
  340. struct mxr_device *mdev = to_mdev(dev);
  341. struct mxr_resources *res = &mdev->res;
  342. mxr_dbg(mdev, "suspend - start\n");
  343. mutex_lock(&mdev->mutex);
  344. /* turn clocks off */
  345. clk_disable_unprepare(res->sclk_mixer);
  346. clk_disable_unprepare(res->vp);
  347. clk_disable_unprepare(res->mixer);
  348. mutex_unlock(&mdev->mutex);
  349. mxr_dbg(mdev, "suspend - finished\n");
  350. return 0;
  351. }
  352. static const struct dev_pm_ops mxr_pm_ops = {
  353. .runtime_suspend = mxr_runtime_suspend,
  354. .runtime_resume = mxr_runtime_resume,
  355. };
  356. /* --------- DRIVER INITIALIZATION ---------- */
  357. static int mxr_probe(struct platform_device *pdev)
  358. {
  359. struct device *dev = &pdev->dev;
  360. struct mxr_platform_data *pdata = dev->platform_data;
  361. struct mxr_device *mdev;
  362. int ret;
  363. /* mdev does not exist yet so no mxr_dbg is used */
  364. dev_info(dev, "probe start\n");
  365. mdev = kzalloc(sizeof(*mdev), GFP_KERNEL);
  366. if (!mdev) {
  367. dev_err(dev, "not enough memory.\n");
  368. ret = -ENOMEM;
  369. goto fail;
  370. }
  371. /* setup pointer to master device */
  372. mdev->dev = dev;
  373. mutex_init(&mdev->mutex);
  374. spin_lock_init(&mdev->reg_slock);
  375. init_waitqueue_head(&mdev->event_queue);
  376. /* acquire resources: regs, irqs, clocks, regulators */
  377. ret = mxr_acquire_resources(mdev, pdev);
  378. if (ret)
  379. goto fail_mem;
  380. /* configure resources for video output */
  381. ret = mxr_acquire_video(mdev, mxr_output_conf,
  382. ARRAY_SIZE(mxr_output_conf));
  383. if (ret)
  384. goto fail_resources;
  385. /* configure layers */
  386. ret = mxr_acquire_layers(mdev, pdata);
  387. if (ret)
  388. goto fail_video;
  389. pm_runtime_enable(dev);
  390. mxr_info(mdev, "probe successful\n");
  391. return 0;
  392. fail_video:
  393. mxr_release_video(mdev);
  394. fail_resources:
  395. mxr_release_resources(mdev);
  396. fail_mem:
  397. kfree(mdev);
  398. fail:
  399. dev_info(dev, "probe failed\n");
  400. return ret;
  401. }
  402. static int mxr_remove(struct platform_device *pdev)
  403. {
  404. struct device *dev = &pdev->dev;
  405. struct mxr_device *mdev = to_mdev(dev);
  406. pm_runtime_disable(dev);
  407. mxr_release_layers(mdev);
  408. mxr_release_video(mdev);
  409. mxr_release_resources(mdev);
  410. kfree(mdev);
  411. dev_info(dev, "remove successful\n");
  412. return 0;
  413. }
  414. static struct platform_driver mxr_driver __refdata = {
  415. .probe = mxr_probe,
  416. .remove = mxr_remove,
  417. .driver = {
  418. .name = MXR_DRIVER_NAME,
  419. .pm = &mxr_pm_ops,
  420. }
  421. };
  422. static int __init mxr_init(void)
  423. {
  424. int i, ret;
  425. static const char banner[] __initconst =
  426. "Samsung TV Mixer driver, "
  427. "(c) 2010-2011 Samsung Electronics Co., Ltd.\n";
  428. pr_info("%s\n", banner);
  429. /* Loading auxiliary modules */
  430. for (i = 0; i < ARRAY_SIZE(mxr_output_conf); ++i)
  431. request_module(mxr_output_conf[i].module_name);
  432. ret = platform_driver_register(&mxr_driver);
  433. if (ret != 0) {
  434. pr_err("s5p-tv: registration of MIXER driver failed\n");
  435. return -ENXIO;
  436. }
  437. return 0;
  438. }
  439. module_init(mxr_init);
  440. static void __exit mxr_exit(void)
  441. {
  442. platform_driver_unregister(&mxr_driver);
  443. }
  444. module_exit(mxr_exit);