vpbe_venc.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566
  1. /*
  2. * Copyright (C) 2010 Texas Instruments Inc
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation version 2.
  7. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. *
  13. * You should have received a copy of the GNU General Public License
  14. * along with this program; if not, write to the Free Software
  15. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  16. */
  17. #include <linux/module.h>
  18. #include <linux/kernel.h>
  19. #include <linux/init.h>
  20. #include <linux/ctype.h>
  21. #include <linux/delay.h>
  22. #include <linux/device.h>
  23. #include <linux/interrupt.h>
  24. #include <linux/platform_device.h>
  25. #include <linux/videodev2.h>
  26. #include <linux/slab.h>
  27. #include <mach/hardware.h>
  28. #include <mach/mux.h>
  29. #include <mach/io.h>
  30. #include <mach/i2c.h>
  31. #include <linux/io.h>
  32. #include <media/davinci/vpbe_types.h>
  33. #include <media/davinci/vpbe_venc.h>
  34. #include <media/davinci/vpss.h>
  35. #include <media/v4l2-device.h>
  36. #include "vpbe_venc_regs.h"
  37. #define MODULE_NAME VPBE_VENC_SUBDEV_NAME
  38. static int debug = 2;
  39. module_param(debug, int, 0644);
  40. MODULE_PARM_DESC(debug, "Debug level 0-2");
  41. struct venc_state {
  42. struct v4l2_subdev sd;
  43. struct venc_callback *callback;
  44. struct venc_platform_data *pdata;
  45. struct device *pdev;
  46. u32 output;
  47. v4l2_std_id std;
  48. spinlock_t lock;
  49. void __iomem *venc_base;
  50. void __iomem *vdaccfg_reg;
  51. };
  52. static inline struct venc_state *to_state(struct v4l2_subdev *sd)
  53. {
  54. return container_of(sd, struct venc_state, sd);
  55. }
  56. static inline u32 venc_read(struct v4l2_subdev *sd, u32 offset)
  57. {
  58. struct venc_state *venc = to_state(sd);
  59. return readl(venc->venc_base + offset);
  60. }
  61. static inline u32 venc_write(struct v4l2_subdev *sd, u32 offset, u32 val)
  62. {
  63. struct venc_state *venc = to_state(sd);
  64. writel(val, (venc->venc_base + offset));
  65. return val;
  66. }
  67. static inline u32 venc_modify(struct v4l2_subdev *sd, u32 offset,
  68. u32 val, u32 mask)
  69. {
  70. u32 new_val = (venc_read(sd, offset) & ~mask) | (val & mask);
  71. venc_write(sd, offset, new_val);
  72. return new_val;
  73. }
  74. static inline u32 vdaccfg_write(struct v4l2_subdev *sd, u32 val)
  75. {
  76. struct venc_state *venc = to_state(sd);
  77. writel(val, venc->vdaccfg_reg);
  78. val = readl(venc->vdaccfg_reg);
  79. return val;
  80. }
  81. /* This function sets the dac of the VPBE for various outputs
  82. */
  83. static int venc_set_dac(struct v4l2_subdev *sd, u32 out_index)
  84. {
  85. switch (out_index) {
  86. case 0:
  87. v4l2_dbg(debug, 1, sd, "Setting output to Composite\n");
  88. venc_write(sd, VENC_DACSEL, 0);
  89. break;
  90. case 1:
  91. v4l2_dbg(debug, 1, sd, "Setting output to S-Video\n");
  92. venc_write(sd, VENC_DACSEL, 0x210);
  93. break;
  94. case 2:
  95. venc_write(sd, VENC_DACSEL, 0x543);
  96. break;
  97. default:
  98. return -EINVAL;
  99. }
  100. return 0;
  101. }
  102. static void venc_enabledigitaloutput(struct v4l2_subdev *sd, int benable)
  103. {
  104. v4l2_dbg(debug, 2, sd, "venc_enabledigitaloutput\n");
  105. if (benable) {
  106. venc_write(sd, VENC_VMOD, 0);
  107. venc_write(sd, VENC_CVBS, 0);
  108. venc_write(sd, VENC_LCDOUT, 0);
  109. venc_write(sd, VENC_HSPLS, 0);
  110. venc_write(sd, VENC_HSTART, 0);
  111. venc_write(sd, VENC_HVALID, 0);
  112. venc_write(sd, VENC_HINT, 0);
  113. venc_write(sd, VENC_VSPLS, 0);
  114. venc_write(sd, VENC_VSTART, 0);
  115. venc_write(sd, VENC_VVALID, 0);
  116. venc_write(sd, VENC_VINT, 0);
  117. venc_write(sd, VENC_YCCCTL, 0);
  118. venc_write(sd, VENC_DACSEL, 0);
  119. } else {
  120. venc_write(sd, VENC_VMOD, 0);
  121. /* disable VCLK output pin enable */
  122. venc_write(sd, VENC_VIDCTL, 0x141);
  123. /* Disable output sync pins */
  124. venc_write(sd, VENC_SYNCCTL, 0);
  125. /* Disable DCLOCK */
  126. venc_write(sd, VENC_DCLKCTL, 0);
  127. venc_write(sd, VENC_DRGBX1, 0x0000057C);
  128. /* Disable LCD output control (accepting default polarity) */
  129. venc_write(sd, VENC_LCDOUT, 0);
  130. venc_write(sd, VENC_CMPNT, 0x100);
  131. venc_write(sd, VENC_HSPLS, 0);
  132. venc_write(sd, VENC_HINT, 0);
  133. venc_write(sd, VENC_HSTART, 0);
  134. venc_write(sd, VENC_HVALID, 0);
  135. venc_write(sd, VENC_VSPLS, 0);
  136. venc_write(sd, VENC_VINT, 0);
  137. venc_write(sd, VENC_VSTART, 0);
  138. venc_write(sd, VENC_VVALID, 0);
  139. venc_write(sd, VENC_HSDLY, 0);
  140. venc_write(sd, VENC_VSDLY, 0);
  141. venc_write(sd, VENC_YCCCTL, 0);
  142. venc_write(sd, VENC_VSTARTA, 0);
  143. /* Set OSD clock and OSD Sync Adavance registers */
  144. venc_write(sd, VENC_OSDCLK0, 1);
  145. venc_write(sd, VENC_OSDCLK1, 2);
  146. }
  147. }
  148. /*
  149. * setting NTSC mode
  150. */
  151. static int venc_set_ntsc(struct v4l2_subdev *sd)
  152. {
  153. struct venc_state *venc = to_state(sd);
  154. struct venc_platform_data *pdata = venc->pdata;
  155. v4l2_dbg(debug, 2, sd, "venc_set_ntsc\n");
  156. /* Setup clock at VPSS & VENC for SD */
  157. vpss_enable_clock(VPSS_VENC_CLOCK_SEL, 1);
  158. if (pdata->setup_clock(VPBE_ENC_STD, V4L2_STD_525_60) < 0)
  159. return -EINVAL;
  160. venc_enabledigitaloutput(sd, 0);
  161. /* to set VENC CLK DIV to 1 - final clock is 54 MHz */
  162. venc_modify(sd, VENC_VIDCTL, 0, 1 << 1);
  163. /* Set REC656 Mode */
  164. venc_write(sd, VENC_YCCCTL, 0x1);
  165. venc_modify(sd, VENC_VDPRO, 0, VENC_VDPRO_DAFRQ);
  166. venc_modify(sd, VENC_VDPRO, 0, VENC_VDPRO_DAUPS);
  167. venc_write(sd, VENC_VMOD, 0);
  168. venc_modify(sd, VENC_VMOD, (1 << VENC_VMOD_VIE_SHIFT),
  169. VENC_VMOD_VIE);
  170. venc_modify(sd, VENC_VMOD, (0 << VENC_VMOD_VMD), VENC_VMOD_VMD);
  171. venc_modify(sd, VENC_VMOD, (0 << VENC_VMOD_TVTYP_SHIFT),
  172. VENC_VMOD_TVTYP);
  173. venc_write(sd, VENC_DACTST, 0x0);
  174. venc_modify(sd, VENC_VMOD, VENC_VMOD_VENC, VENC_VMOD_VENC);
  175. return 0;
  176. }
  177. /*
  178. * setting PAL mode
  179. */
  180. static int venc_set_pal(struct v4l2_subdev *sd)
  181. {
  182. struct venc_state *venc = to_state(sd);
  183. v4l2_dbg(debug, 2, sd, "venc_set_pal\n");
  184. /* Setup clock at VPSS & VENC for SD */
  185. vpss_enable_clock(VPSS_VENC_CLOCK_SEL, 1);
  186. if (venc->pdata->setup_clock(VPBE_ENC_STD, V4L2_STD_625_50) < 0)
  187. return -EINVAL;
  188. venc_enabledigitaloutput(sd, 0);
  189. /* to set VENC CLK DIV to 1 - final clock is 54 MHz */
  190. venc_modify(sd, VENC_VIDCTL, 0, 1 << 1);
  191. /* Set REC656 Mode */
  192. venc_write(sd, VENC_YCCCTL, 0x1);
  193. venc_modify(sd, VENC_SYNCCTL, 1 << VENC_SYNCCTL_OVD_SHIFT,
  194. VENC_SYNCCTL_OVD);
  195. venc_write(sd, VENC_VMOD, 0);
  196. venc_modify(sd, VENC_VMOD,
  197. (1 << VENC_VMOD_VIE_SHIFT),
  198. VENC_VMOD_VIE);
  199. venc_modify(sd, VENC_VMOD,
  200. (0 << VENC_VMOD_VMD), VENC_VMOD_VMD);
  201. venc_modify(sd, VENC_VMOD,
  202. (1 << VENC_VMOD_TVTYP_SHIFT),
  203. VENC_VMOD_TVTYP);
  204. venc_write(sd, VENC_DACTST, 0x0);
  205. venc_modify(sd, VENC_VMOD, VENC_VMOD_VENC, VENC_VMOD_VENC);
  206. return 0;
  207. }
  208. /*
  209. * venc_set_480p59_94
  210. *
  211. * This function configures the video encoder to EDTV(525p) component setting.
  212. */
  213. static int venc_set_480p59_94(struct v4l2_subdev *sd)
  214. {
  215. struct venc_state *venc = to_state(sd);
  216. struct venc_platform_data *pdata = venc->pdata;
  217. v4l2_dbg(debug, 2, sd, "venc_set_480p59_94\n");
  218. /* Setup clock at VPSS & VENC for SD */
  219. if (pdata->setup_clock(VPBE_ENC_DV_PRESET, V4L2_DV_480P59_94) < 0)
  220. return -EINVAL;
  221. venc_enabledigitaloutput(sd, 0);
  222. venc_write(sd, VENC_OSDCLK0, 0);
  223. venc_write(sd, VENC_OSDCLK1, 1);
  224. venc_modify(sd, VENC_VDPRO, VENC_VDPRO_DAFRQ,
  225. VENC_VDPRO_DAFRQ);
  226. venc_modify(sd, VENC_VDPRO, VENC_VDPRO_DAUPS,
  227. VENC_VDPRO_DAUPS);
  228. venc_write(sd, VENC_VMOD, 0);
  229. venc_modify(sd, VENC_VMOD, (1 << VENC_VMOD_VIE_SHIFT),
  230. VENC_VMOD_VIE);
  231. venc_modify(sd, VENC_VMOD, VENC_VMOD_HDMD, VENC_VMOD_HDMD);
  232. venc_modify(sd, VENC_VMOD, (HDTV_525P << VENC_VMOD_TVTYP_SHIFT),
  233. VENC_VMOD_TVTYP);
  234. venc_modify(sd, VENC_VMOD, VENC_VMOD_VDMD_YCBCR8 <<
  235. VENC_VMOD_VDMD_SHIFT, VENC_VMOD_VDMD);
  236. venc_modify(sd, VENC_VMOD, VENC_VMOD_VENC, VENC_VMOD_VENC);
  237. return 0;
  238. }
  239. /*
  240. * venc_set_625p
  241. *
  242. * This function configures the video encoder to HDTV(625p) component setting
  243. */
  244. static int venc_set_576p50(struct v4l2_subdev *sd)
  245. {
  246. struct venc_state *venc = to_state(sd);
  247. struct venc_platform_data *pdata = venc->pdata;
  248. v4l2_dbg(debug, 2, sd, "venc_set_576p50\n");
  249. /* Setup clock at VPSS & VENC for SD */
  250. if (pdata->setup_clock(VPBE_ENC_DV_PRESET, V4L2_DV_576P50) < 0)
  251. return -EINVAL;
  252. venc_enabledigitaloutput(sd, 0);
  253. venc_write(sd, VENC_OSDCLK0, 0);
  254. venc_write(sd, VENC_OSDCLK1, 1);
  255. venc_modify(sd, VENC_VDPRO, VENC_VDPRO_DAFRQ,
  256. VENC_VDPRO_DAFRQ);
  257. venc_modify(sd, VENC_VDPRO, VENC_VDPRO_DAUPS,
  258. VENC_VDPRO_DAUPS);
  259. venc_write(sd, VENC_VMOD, 0);
  260. venc_modify(sd, VENC_VMOD, (1 << VENC_VMOD_VIE_SHIFT),
  261. VENC_VMOD_VIE);
  262. venc_modify(sd, VENC_VMOD, VENC_VMOD_HDMD, VENC_VMOD_HDMD);
  263. venc_modify(sd, VENC_VMOD, (HDTV_625P << VENC_VMOD_TVTYP_SHIFT),
  264. VENC_VMOD_TVTYP);
  265. venc_modify(sd, VENC_VMOD, VENC_VMOD_VDMD_YCBCR8 <<
  266. VENC_VMOD_VDMD_SHIFT, VENC_VMOD_VDMD);
  267. venc_modify(sd, VENC_VMOD, VENC_VMOD_VENC, VENC_VMOD_VENC);
  268. return 0;
  269. }
  270. static int venc_s_std_output(struct v4l2_subdev *sd, v4l2_std_id norm)
  271. {
  272. v4l2_dbg(debug, 1, sd, "venc_s_std_output\n");
  273. if (norm & V4L2_STD_525_60)
  274. return venc_set_ntsc(sd);
  275. else if (norm & V4L2_STD_625_50)
  276. return venc_set_pal(sd);
  277. return -EINVAL;
  278. }
  279. static int venc_s_dv_preset(struct v4l2_subdev *sd,
  280. struct v4l2_dv_preset *dv_preset)
  281. {
  282. v4l2_dbg(debug, 1, sd, "venc_s_dv_preset\n");
  283. if (dv_preset->preset == V4L2_DV_576P50)
  284. return venc_set_576p50(sd);
  285. else if (dv_preset->preset == V4L2_DV_480P59_94)
  286. return venc_set_480p59_94(sd);
  287. return -EINVAL;
  288. }
  289. static int venc_s_routing(struct v4l2_subdev *sd, u32 input, u32 output,
  290. u32 config)
  291. {
  292. struct venc_state *venc = to_state(sd);
  293. int ret;
  294. v4l2_dbg(debug, 1, sd, "venc_s_routing\n");
  295. ret = venc_set_dac(sd, output);
  296. if (!ret)
  297. venc->output = output;
  298. return ret;
  299. }
  300. static long venc_ioctl(struct v4l2_subdev *sd,
  301. unsigned int cmd,
  302. void *arg)
  303. {
  304. u32 val;
  305. switch (cmd) {
  306. case VENC_GET_FLD:
  307. val = venc_read(sd, VENC_VSTAT);
  308. *((int *)arg) = ((val & VENC_VSTAT_FIDST) ==
  309. VENC_VSTAT_FIDST);
  310. break;
  311. default:
  312. v4l2_err(sd, "Wrong IOCTL cmd\n");
  313. break;
  314. }
  315. return 0;
  316. }
  317. static const struct v4l2_subdev_core_ops venc_core_ops = {
  318. .ioctl = venc_ioctl,
  319. };
  320. static const struct v4l2_subdev_video_ops venc_video_ops = {
  321. .s_routing = venc_s_routing,
  322. .s_std_output = venc_s_std_output,
  323. .s_dv_preset = venc_s_dv_preset,
  324. };
  325. static const struct v4l2_subdev_ops venc_ops = {
  326. .core = &venc_core_ops,
  327. .video = &venc_video_ops,
  328. };
  329. static int venc_initialize(struct v4l2_subdev *sd)
  330. {
  331. struct venc_state *venc = to_state(sd);
  332. int ret;
  333. /* Set default to output to composite and std to NTSC */
  334. venc->output = 0;
  335. venc->std = V4L2_STD_525_60;
  336. ret = venc_s_routing(sd, 0, venc->output, 0);
  337. if (ret < 0) {
  338. v4l2_err(sd, "Error setting output during init\n");
  339. return -EINVAL;
  340. }
  341. ret = venc_s_std_output(sd, venc->std);
  342. if (ret < 0) {
  343. v4l2_err(sd, "Error setting std during init\n");
  344. return -EINVAL;
  345. }
  346. return ret;
  347. }
  348. static int venc_device_get(struct device *dev, void *data)
  349. {
  350. struct platform_device *pdev = to_platform_device(dev);
  351. struct venc_state **venc = data;
  352. if (strcmp(MODULE_NAME, pdev->name) == 0)
  353. *venc = platform_get_drvdata(pdev);
  354. return 0;
  355. }
  356. struct v4l2_subdev *venc_sub_dev_init(struct v4l2_device *v4l2_dev,
  357. const char *venc_name)
  358. {
  359. struct venc_state *venc;
  360. int err;
  361. err = bus_for_each_dev(&platform_bus_type, NULL, &venc,
  362. venc_device_get);
  363. if (venc == NULL)
  364. return NULL;
  365. v4l2_subdev_init(&venc->sd, &venc_ops);
  366. strcpy(venc->sd.name, venc_name);
  367. if (v4l2_device_register_subdev(v4l2_dev, &venc->sd) < 0) {
  368. v4l2_err(v4l2_dev,
  369. "vpbe unable to register venc sub device\n");
  370. return NULL;
  371. }
  372. if (venc_initialize(&venc->sd)) {
  373. v4l2_err(v4l2_dev,
  374. "vpbe venc initialization failed\n");
  375. return NULL;
  376. }
  377. return &venc->sd;
  378. }
  379. EXPORT_SYMBOL(venc_sub_dev_init);
  380. static int venc_probe(struct platform_device *pdev)
  381. {
  382. struct venc_state *venc;
  383. struct resource *res;
  384. int ret;
  385. venc = kzalloc(sizeof(struct venc_state), GFP_KERNEL);
  386. if (venc == NULL)
  387. return -ENOMEM;
  388. venc->pdev = &pdev->dev;
  389. venc->pdata = pdev->dev.platform_data;
  390. if (NULL == venc->pdata) {
  391. dev_err(venc->pdev, "Unable to get platform data for"
  392. " VENC sub device");
  393. ret = -ENOENT;
  394. goto free_mem;
  395. }
  396. res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  397. if (!res) {
  398. dev_err(venc->pdev,
  399. "Unable to get VENC register address map\n");
  400. ret = -ENODEV;
  401. goto free_mem;
  402. }
  403. if (!request_mem_region(res->start, resource_size(res), "venc")) {
  404. dev_err(venc->pdev, "Unable to reserve VENC MMIO region\n");
  405. ret = -ENODEV;
  406. goto free_mem;
  407. }
  408. venc->venc_base = ioremap_nocache(res->start, resource_size(res));
  409. if (!venc->venc_base) {
  410. dev_err(venc->pdev, "Unable to map VENC IO space\n");
  411. ret = -ENODEV;
  412. goto release_venc_mem_region;
  413. }
  414. spin_lock_init(&venc->lock);
  415. platform_set_drvdata(pdev, venc);
  416. dev_notice(venc->pdev, "VENC sub device probe success\n");
  417. return 0;
  418. release_venc_mem_region:
  419. res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  420. release_mem_region(res->start, resource_size(res));
  421. free_mem:
  422. kfree(venc);
  423. return ret;
  424. }
  425. static int venc_remove(struct platform_device *pdev)
  426. {
  427. struct venc_state *venc = platform_get_drvdata(pdev);
  428. struct resource *res;
  429. res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  430. iounmap((void *)venc->venc_base);
  431. release_mem_region(res->start, resource_size(res));
  432. kfree(venc);
  433. return 0;
  434. }
  435. static struct platform_driver venc_driver = {
  436. .probe = venc_probe,
  437. .remove = venc_remove,
  438. .driver = {
  439. .name = MODULE_NAME,
  440. .owner = THIS_MODULE,
  441. },
  442. };
  443. static int venc_init(void)
  444. {
  445. if (platform_driver_register(&venc_driver)) {
  446. printk(KERN_ERR "Unable to register venc driver\n");
  447. return -ENODEV;
  448. }
  449. return 0;
  450. }
  451. static void venc_exit(void)
  452. {
  453. platform_driver_unregister(&venc_driver);
  454. return;
  455. }
  456. module_init(venc_init);
  457. module_exit(venc_exit);
  458. MODULE_LICENSE("GPL");
  459. MODULE_DESCRIPTION("VPBE VENC Driver");
  460. MODULE_AUTHOR("Texas Instruments");