vpbe_venc.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695
  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. #include <linux/module.h>
  14. #include <linux/kernel.h>
  15. #include <linux/init.h>
  16. #include <linux/ctype.h>
  17. #include <linux/delay.h>
  18. #include <linux/device.h>
  19. #include <linux/interrupt.h>
  20. #include <linux/platform_device.h>
  21. #include <linux/videodev2.h>
  22. #include <linux/slab.h>
  23. #ifdef CONFIG_ARCH_DAVINCI
  24. #include <mach/hardware.h>
  25. #include <mach/mux.h>
  26. #endif
  27. #include <linux/platform_data/i2c-davinci.h>
  28. #include <linux/io.h>
  29. #include <media/davinci/vpbe_types.h>
  30. #include <media/davinci/vpbe_venc.h>
  31. #include <media/davinci/vpss.h>
  32. #include <media/v4l2-device.h>
  33. #include "vpbe_venc_regs.h"
  34. #define MODULE_NAME "davinci-vpbe-venc"
  35. static const struct platform_device_id vpbe_venc_devtype[] = {
  36. {
  37. .name = DM644X_VPBE_VENC_SUBDEV_NAME,
  38. .driver_data = VPBE_VERSION_1,
  39. }, {
  40. .name = DM365_VPBE_VENC_SUBDEV_NAME,
  41. .driver_data = VPBE_VERSION_2,
  42. }, {
  43. .name = DM355_VPBE_VENC_SUBDEV_NAME,
  44. .driver_data = VPBE_VERSION_3,
  45. },
  46. {
  47. /* sentinel */
  48. }
  49. };
  50. MODULE_DEVICE_TABLE(platform, vpbe_venc_devtype);
  51. static int debug = 2;
  52. module_param(debug, int, 0644);
  53. MODULE_PARM_DESC(debug, "Debug level 0-2");
  54. struct venc_state {
  55. struct v4l2_subdev sd;
  56. struct venc_callback *callback;
  57. struct venc_platform_data *pdata;
  58. struct device *pdev;
  59. u32 output;
  60. v4l2_std_id std;
  61. spinlock_t lock;
  62. void __iomem *venc_base;
  63. void __iomem *vdaccfg_reg;
  64. enum vpbe_version venc_type;
  65. };
  66. static inline struct venc_state *to_state(struct v4l2_subdev *sd)
  67. {
  68. return container_of(sd, struct venc_state, sd);
  69. }
  70. static inline u32 venc_read(struct v4l2_subdev *sd, u32 offset)
  71. {
  72. struct venc_state *venc = to_state(sd);
  73. return readl(venc->venc_base + offset);
  74. }
  75. static inline u32 venc_write(struct v4l2_subdev *sd, u32 offset, u32 val)
  76. {
  77. struct venc_state *venc = to_state(sd);
  78. writel(val, (venc->venc_base + offset));
  79. return val;
  80. }
  81. static inline u32 venc_modify(struct v4l2_subdev *sd, u32 offset,
  82. u32 val, u32 mask)
  83. {
  84. u32 new_val = (venc_read(sd, offset) & ~mask) | (val & mask);
  85. venc_write(sd, offset, new_val);
  86. return new_val;
  87. }
  88. static inline u32 vdaccfg_write(struct v4l2_subdev *sd, u32 val)
  89. {
  90. struct venc_state *venc = to_state(sd);
  91. writel(val, venc->vdaccfg_reg);
  92. val = readl(venc->vdaccfg_reg);
  93. return val;
  94. }
  95. #define VDAC_COMPONENT 0x543
  96. #define VDAC_S_VIDEO 0x210
  97. /* This function sets the dac of the VPBE for various outputs
  98. */
  99. static int venc_set_dac(struct v4l2_subdev *sd, u32 out_index)
  100. {
  101. switch (out_index) {
  102. case 0:
  103. v4l2_dbg(debug, 1, sd, "Setting output to Composite\n");
  104. venc_write(sd, VENC_DACSEL, 0);
  105. break;
  106. case 1:
  107. v4l2_dbg(debug, 1, sd, "Setting output to Component\n");
  108. venc_write(sd, VENC_DACSEL, VDAC_COMPONENT);
  109. break;
  110. case 2:
  111. v4l2_dbg(debug, 1, sd, "Setting output to S-video\n");
  112. venc_write(sd, VENC_DACSEL, VDAC_S_VIDEO);
  113. break;
  114. default:
  115. return -EINVAL;
  116. }
  117. return 0;
  118. }
  119. static void venc_enabledigitaloutput(struct v4l2_subdev *sd, int benable)
  120. {
  121. struct venc_state *venc = to_state(sd);
  122. v4l2_dbg(debug, 2, sd, "venc_enabledigitaloutput\n");
  123. if (benable) {
  124. venc_write(sd, VENC_VMOD, 0);
  125. venc_write(sd, VENC_CVBS, 0);
  126. venc_write(sd, VENC_LCDOUT, 0);
  127. venc_write(sd, VENC_HSPLS, 0);
  128. venc_write(sd, VENC_HSTART, 0);
  129. venc_write(sd, VENC_HVALID, 0);
  130. venc_write(sd, VENC_HINT, 0);
  131. venc_write(sd, VENC_VSPLS, 0);
  132. venc_write(sd, VENC_VSTART, 0);
  133. venc_write(sd, VENC_VVALID, 0);
  134. venc_write(sd, VENC_VINT, 0);
  135. venc_write(sd, VENC_YCCCTL, 0);
  136. venc_write(sd, VENC_DACSEL, 0);
  137. } else {
  138. venc_write(sd, VENC_VMOD, 0);
  139. /* disable VCLK output pin enable */
  140. venc_write(sd, VENC_VIDCTL, 0x141);
  141. /* Disable output sync pins */
  142. venc_write(sd, VENC_SYNCCTL, 0);
  143. /* Disable DCLOCK */
  144. venc_write(sd, VENC_DCLKCTL, 0);
  145. venc_write(sd, VENC_DRGBX1, 0x0000057C);
  146. /* Disable LCD output control (accepting default polarity) */
  147. venc_write(sd, VENC_LCDOUT, 0);
  148. if (venc->venc_type != VPBE_VERSION_3)
  149. venc_write(sd, VENC_CMPNT, 0x100);
  150. venc_write(sd, VENC_HSPLS, 0);
  151. venc_write(sd, VENC_HINT, 0);
  152. venc_write(sd, VENC_HSTART, 0);
  153. venc_write(sd, VENC_HVALID, 0);
  154. venc_write(sd, VENC_VSPLS, 0);
  155. venc_write(sd, VENC_VINT, 0);
  156. venc_write(sd, VENC_VSTART, 0);
  157. venc_write(sd, VENC_VVALID, 0);
  158. venc_write(sd, VENC_HSDLY, 0);
  159. venc_write(sd, VENC_VSDLY, 0);
  160. venc_write(sd, VENC_YCCCTL, 0);
  161. venc_write(sd, VENC_VSTARTA, 0);
  162. /* Set OSD clock and OSD Sync Adavance registers */
  163. venc_write(sd, VENC_OSDCLK0, 1);
  164. venc_write(sd, VENC_OSDCLK1, 2);
  165. }
  166. }
  167. static void
  168. venc_enable_vpss_clock(int venc_type,
  169. enum vpbe_enc_timings_type type,
  170. unsigned int pclock)
  171. {
  172. if (venc_type == VPBE_VERSION_1)
  173. return;
  174. if (venc_type == VPBE_VERSION_2 && (type == VPBE_ENC_STD || (type ==
  175. VPBE_ENC_DV_TIMINGS && pclock <= 27000000))) {
  176. vpss_enable_clock(VPSS_VENC_CLOCK_SEL, 1);
  177. vpss_enable_clock(VPSS_VPBE_CLOCK, 1);
  178. return;
  179. }
  180. if (venc_type == VPBE_VERSION_3 && type == VPBE_ENC_STD)
  181. vpss_enable_clock(VPSS_VENC_CLOCK_SEL, 0);
  182. }
  183. #define VDAC_CONFIG_SD_V3 0x0E21A6B6
  184. #define VDAC_CONFIG_SD_V2 0x081141CF
  185. /*
  186. * setting NTSC mode
  187. */
  188. static int venc_set_ntsc(struct v4l2_subdev *sd)
  189. {
  190. struct venc_state *venc = to_state(sd);
  191. struct venc_platform_data *pdata = venc->pdata;
  192. v4l2_dbg(debug, 2, sd, "venc_set_ntsc\n");
  193. /* Setup clock at VPSS & VENC for SD */
  194. vpss_enable_clock(VPSS_VENC_CLOCK_SEL, 1);
  195. if (pdata->setup_clock(VPBE_ENC_STD, V4L2_STD_525_60) < 0)
  196. return -EINVAL;
  197. venc_enable_vpss_clock(venc->venc_type, VPBE_ENC_STD, V4L2_STD_525_60);
  198. venc_enabledigitaloutput(sd, 0);
  199. if (venc->venc_type == VPBE_VERSION_3) {
  200. venc_write(sd, VENC_CLKCTL, 0x01);
  201. venc_write(sd, VENC_VIDCTL, 0);
  202. vdaccfg_write(sd, VDAC_CONFIG_SD_V3);
  203. } else if (venc->venc_type == VPBE_VERSION_2) {
  204. venc_write(sd, VENC_CLKCTL, 0x01);
  205. venc_write(sd, VENC_VIDCTL, 0);
  206. vdaccfg_write(sd, VDAC_CONFIG_SD_V2);
  207. } else {
  208. /* to set VENC CLK DIV to 1 - final clock is 54 MHz */
  209. venc_modify(sd, VENC_VIDCTL, 0, 1 << 1);
  210. /* Set REC656 Mode */
  211. venc_write(sd, VENC_YCCCTL, 0x1);
  212. venc_modify(sd, VENC_VDPRO, 0, VENC_VDPRO_DAFRQ);
  213. venc_modify(sd, VENC_VDPRO, 0, VENC_VDPRO_DAUPS);
  214. }
  215. venc_write(sd, VENC_VMOD, 0);
  216. venc_modify(sd, VENC_VMOD, (1 << VENC_VMOD_VIE_SHIFT),
  217. VENC_VMOD_VIE);
  218. venc_modify(sd, VENC_VMOD, (0 << VENC_VMOD_VMD), VENC_VMOD_VMD);
  219. venc_modify(sd, VENC_VMOD, (0 << VENC_VMOD_TVTYP_SHIFT),
  220. VENC_VMOD_TVTYP);
  221. venc_write(sd, VENC_DACTST, 0x0);
  222. venc_modify(sd, VENC_VMOD, VENC_VMOD_VENC, VENC_VMOD_VENC);
  223. return 0;
  224. }
  225. /*
  226. * setting PAL mode
  227. */
  228. static int venc_set_pal(struct v4l2_subdev *sd)
  229. {
  230. struct venc_state *venc = to_state(sd);
  231. v4l2_dbg(debug, 2, sd, "venc_set_pal\n");
  232. /* Setup clock at VPSS & VENC for SD */
  233. vpss_enable_clock(VPSS_VENC_CLOCK_SEL, 1);
  234. if (venc->pdata->setup_clock(VPBE_ENC_STD, V4L2_STD_625_50) < 0)
  235. return -EINVAL;
  236. venc_enable_vpss_clock(venc->venc_type, VPBE_ENC_STD, V4L2_STD_625_50);
  237. venc_enabledigitaloutput(sd, 0);
  238. if (venc->venc_type == VPBE_VERSION_3) {
  239. venc_write(sd, VENC_CLKCTL, 0x1);
  240. venc_write(sd, VENC_VIDCTL, 0);
  241. vdaccfg_write(sd, VDAC_CONFIG_SD_V3);
  242. } else if (venc->venc_type == VPBE_VERSION_2) {
  243. venc_write(sd, VENC_CLKCTL, 0x1);
  244. venc_write(sd, VENC_VIDCTL, 0);
  245. vdaccfg_write(sd, VDAC_CONFIG_SD_V2);
  246. } else {
  247. /* to set VENC CLK DIV to 1 - final clock is 54 MHz */
  248. venc_modify(sd, VENC_VIDCTL, 0, 1 << 1);
  249. /* Set REC656 Mode */
  250. venc_write(sd, VENC_YCCCTL, 0x1);
  251. }
  252. venc_modify(sd, VENC_SYNCCTL, 1 << VENC_SYNCCTL_OVD_SHIFT,
  253. VENC_SYNCCTL_OVD);
  254. venc_write(sd, VENC_VMOD, 0);
  255. venc_modify(sd, VENC_VMOD,
  256. (1 << VENC_VMOD_VIE_SHIFT),
  257. VENC_VMOD_VIE);
  258. venc_modify(sd, VENC_VMOD,
  259. (0 << VENC_VMOD_VMD), VENC_VMOD_VMD);
  260. venc_modify(sd, VENC_VMOD,
  261. (1 << VENC_VMOD_TVTYP_SHIFT),
  262. VENC_VMOD_TVTYP);
  263. venc_write(sd, VENC_DACTST, 0x0);
  264. venc_modify(sd, VENC_VMOD, VENC_VMOD_VENC, VENC_VMOD_VENC);
  265. return 0;
  266. }
  267. #define VDAC_CONFIG_HD_V2 0x081141EF
  268. /*
  269. * venc_set_480p59_94
  270. *
  271. * This function configures the video encoder to EDTV(525p) component setting.
  272. */
  273. static int venc_set_480p59_94(struct v4l2_subdev *sd)
  274. {
  275. struct venc_state *venc = to_state(sd);
  276. struct venc_platform_data *pdata = venc->pdata;
  277. v4l2_dbg(debug, 2, sd, "venc_set_480p59_94\n");
  278. if (venc->venc_type != VPBE_VERSION_1 &&
  279. venc->venc_type != VPBE_VERSION_2)
  280. return -EINVAL;
  281. /* Setup clock at VPSS & VENC for SD */
  282. if (pdata->setup_clock(VPBE_ENC_DV_TIMINGS, 27000000) < 0)
  283. return -EINVAL;
  284. venc_enable_vpss_clock(venc->venc_type, VPBE_ENC_DV_TIMINGS, 27000000);
  285. venc_enabledigitaloutput(sd, 0);
  286. if (venc->venc_type == VPBE_VERSION_2)
  287. vdaccfg_write(sd, VDAC_CONFIG_HD_V2);
  288. venc_write(sd, VENC_OSDCLK0, 0);
  289. venc_write(sd, VENC_OSDCLK1, 1);
  290. if (venc->venc_type == VPBE_VERSION_1) {
  291. venc_modify(sd, VENC_VDPRO, VENC_VDPRO_DAFRQ,
  292. VENC_VDPRO_DAFRQ);
  293. venc_modify(sd, VENC_VDPRO, VENC_VDPRO_DAUPS,
  294. VENC_VDPRO_DAUPS);
  295. }
  296. venc_write(sd, VENC_VMOD, 0);
  297. venc_modify(sd, VENC_VMOD, (1 << VENC_VMOD_VIE_SHIFT),
  298. VENC_VMOD_VIE);
  299. venc_modify(sd, VENC_VMOD, VENC_VMOD_HDMD, VENC_VMOD_HDMD);
  300. venc_modify(sd, VENC_VMOD, (HDTV_525P << VENC_VMOD_TVTYP_SHIFT),
  301. VENC_VMOD_TVTYP);
  302. venc_modify(sd, VENC_VMOD, VENC_VMOD_VDMD_YCBCR8 <<
  303. VENC_VMOD_VDMD_SHIFT, VENC_VMOD_VDMD);
  304. venc_modify(sd, VENC_VMOD, VENC_VMOD_VENC, VENC_VMOD_VENC);
  305. return 0;
  306. }
  307. /*
  308. * venc_set_625p
  309. *
  310. * This function configures the video encoder to HDTV(625p) component setting
  311. */
  312. static int venc_set_576p50(struct v4l2_subdev *sd)
  313. {
  314. struct venc_state *venc = to_state(sd);
  315. struct venc_platform_data *pdata = venc->pdata;
  316. v4l2_dbg(debug, 2, sd, "venc_set_576p50\n");
  317. if (venc->venc_type != VPBE_VERSION_1 &&
  318. venc->venc_type != VPBE_VERSION_2)
  319. return -EINVAL;
  320. /* Setup clock at VPSS & VENC for SD */
  321. if (pdata->setup_clock(VPBE_ENC_DV_TIMINGS, 27000000) < 0)
  322. return -EINVAL;
  323. venc_enable_vpss_clock(venc->venc_type, VPBE_ENC_DV_TIMINGS, 27000000);
  324. venc_enabledigitaloutput(sd, 0);
  325. if (venc->venc_type == VPBE_VERSION_2)
  326. vdaccfg_write(sd, VDAC_CONFIG_HD_V2);
  327. venc_write(sd, VENC_OSDCLK0, 0);
  328. venc_write(sd, VENC_OSDCLK1, 1);
  329. if (venc->venc_type == VPBE_VERSION_1) {
  330. venc_modify(sd, VENC_VDPRO, VENC_VDPRO_DAFRQ,
  331. VENC_VDPRO_DAFRQ);
  332. venc_modify(sd, VENC_VDPRO, VENC_VDPRO_DAUPS,
  333. VENC_VDPRO_DAUPS);
  334. }
  335. venc_write(sd, VENC_VMOD, 0);
  336. venc_modify(sd, VENC_VMOD, (1 << VENC_VMOD_VIE_SHIFT),
  337. VENC_VMOD_VIE);
  338. venc_modify(sd, VENC_VMOD, VENC_VMOD_HDMD, VENC_VMOD_HDMD);
  339. venc_modify(sd, VENC_VMOD, (HDTV_625P << VENC_VMOD_TVTYP_SHIFT),
  340. VENC_VMOD_TVTYP);
  341. venc_modify(sd, VENC_VMOD, VENC_VMOD_VDMD_YCBCR8 <<
  342. VENC_VMOD_VDMD_SHIFT, VENC_VMOD_VDMD);
  343. venc_modify(sd, VENC_VMOD, VENC_VMOD_VENC, VENC_VMOD_VENC);
  344. return 0;
  345. }
  346. /*
  347. * venc_set_720p60_internal - Setup 720p60 in venc for dm365 only
  348. */
  349. static int venc_set_720p60_internal(struct v4l2_subdev *sd)
  350. {
  351. struct venc_state *venc = to_state(sd);
  352. struct venc_platform_data *pdata = venc->pdata;
  353. if (pdata->setup_clock(VPBE_ENC_DV_TIMINGS, 74250000) < 0)
  354. return -EINVAL;
  355. venc_enable_vpss_clock(venc->venc_type, VPBE_ENC_DV_TIMINGS, 74250000);
  356. venc_enabledigitaloutput(sd, 0);
  357. venc_write(sd, VENC_OSDCLK0, 0);
  358. venc_write(sd, VENC_OSDCLK1, 1);
  359. venc_write(sd, VENC_VMOD, 0);
  360. /* DM365 component HD mode */
  361. venc_modify(sd, VENC_VMOD, (1 << VENC_VMOD_VIE_SHIFT),
  362. VENC_VMOD_VIE);
  363. venc_modify(sd, VENC_VMOD, VENC_VMOD_HDMD, VENC_VMOD_HDMD);
  364. venc_modify(sd, VENC_VMOD, (HDTV_720P << VENC_VMOD_TVTYP_SHIFT),
  365. VENC_VMOD_TVTYP);
  366. venc_modify(sd, VENC_VMOD, VENC_VMOD_VENC, VENC_VMOD_VENC);
  367. venc_write(sd, VENC_XHINTVL, 0);
  368. return 0;
  369. }
  370. /*
  371. * venc_set_1080i30_internal - Setup 1080i30 in venc for dm365 only
  372. */
  373. static int venc_set_1080i30_internal(struct v4l2_subdev *sd)
  374. {
  375. struct venc_state *venc = to_state(sd);
  376. struct venc_platform_data *pdata = venc->pdata;
  377. if (pdata->setup_clock(VPBE_ENC_DV_TIMINGS, 74250000) < 0)
  378. return -EINVAL;
  379. venc_enable_vpss_clock(venc->venc_type, VPBE_ENC_DV_TIMINGS, 74250000);
  380. venc_enabledigitaloutput(sd, 0);
  381. venc_write(sd, VENC_OSDCLK0, 0);
  382. venc_write(sd, VENC_OSDCLK1, 1);
  383. venc_write(sd, VENC_VMOD, 0);
  384. /* DM365 component HD mode */
  385. venc_modify(sd, VENC_VMOD, (1 << VENC_VMOD_VIE_SHIFT),
  386. VENC_VMOD_VIE);
  387. venc_modify(sd, VENC_VMOD, VENC_VMOD_HDMD, VENC_VMOD_HDMD);
  388. venc_modify(sd, VENC_VMOD, (HDTV_1080I << VENC_VMOD_TVTYP_SHIFT),
  389. VENC_VMOD_TVTYP);
  390. venc_modify(sd, VENC_VMOD, VENC_VMOD_VENC, VENC_VMOD_VENC);
  391. venc_write(sd, VENC_XHINTVL, 0);
  392. return 0;
  393. }
  394. static int venc_s_std_output(struct v4l2_subdev *sd, v4l2_std_id norm)
  395. {
  396. v4l2_dbg(debug, 1, sd, "venc_s_std_output\n");
  397. if (norm & V4L2_STD_525_60)
  398. return venc_set_ntsc(sd);
  399. else if (norm & V4L2_STD_625_50)
  400. return venc_set_pal(sd);
  401. return -EINVAL;
  402. }
  403. static int venc_s_dv_timings(struct v4l2_subdev *sd,
  404. struct v4l2_dv_timings *dv_timings)
  405. {
  406. struct venc_state *venc = to_state(sd);
  407. u32 height = dv_timings->bt.height;
  408. int ret;
  409. v4l2_dbg(debug, 1, sd, "venc_s_dv_timings\n");
  410. if (height == 576)
  411. return venc_set_576p50(sd);
  412. else if (height == 480)
  413. return venc_set_480p59_94(sd);
  414. else if ((height == 720) &&
  415. (venc->venc_type == VPBE_VERSION_2)) {
  416. /* TBD setup internal 720p mode here */
  417. ret = venc_set_720p60_internal(sd);
  418. /* for DM365 VPBE, there is DAC inside */
  419. vdaccfg_write(sd, VDAC_CONFIG_HD_V2);
  420. return ret;
  421. } else if ((height == 1080) &&
  422. (venc->venc_type == VPBE_VERSION_2)) {
  423. /* TBD setup internal 1080i mode here */
  424. ret = venc_set_1080i30_internal(sd);
  425. /* for DM365 VPBE, there is DAC inside */
  426. vdaccfg_write(sd, VDAC_CONFIG_HD_V2);
  427. return ret;
  428. }
  429. return -EINVAL;
  430. }
  431. static int venc_s_routing(struct v4l2_subdev *sd, u32 input, u32 output,
  432. u32 config)
  433. {
  434. struct venc_state *venc = to_state(sd);
  435. int ret;
  436. v4l2_dbg(debug, 1, sd, "venc_s_routing\n");
  437. ret = venc_set_dac(sd, output);
  438. if (!ret)
  439. venc->output = output;
  440. return ret;
  441. }
  442. static long venc_ioctl(struct v4l2_subdev *sd,
  443. unsigned int cmd,
  444. void *arg)
  445. {
  446. u32 val;
  447. switch (cmd) {
  448. case VENC_GET_FLD:
  449. val = venc_read(sd, VENC_VSTAT);
  450. *((int *)arg) = ((val & VENC_VSTAT_FIDST) ==
  451. VENC_VSTAT_FIDST);
  452. break;
  453. default:
  454. v4l2_err(sd, "Wrong IOCTL cmd\n");
  455. break;
  456. }
  457. return 0;
  458. }
  459. static const struct v4l2_subdev_core_ops venc_core_ops = {
  460. .ioctl = venc_ioctl,
  461. };
  462. static const struct v4l2_subdev_video_ops venc_video_ops = {
  463. .s_routing = venc_s_routing,
  464. .s_std_output = venc_s_std_output,
  465. .s_dv_timings = venc_s_dv_timings,
  466. };
  467. static const struct v4l2_subdev_ops venc_ops = {
  468. .core = &venc_core_ops,
  469. .video = &venc_video_ops,
  470. };
  471. static int venc_initialize(struct v4l2_subdev *sd)
  472. {
  473. struct venc_state *venc = to_state(sd);
  474. int ret;
  475. /* Set default to output to composite and std to NTSC */
  476. venc->output = 0;
  477. venc->std = V4L2_STD_525_60;
  478. ret = venc_s_routing(sd, 0, venc->output, 0);
  479. if (ret < 0) {
  480. v4l2_err(sd, "Error setting output during init\n");
  481. return -EINVAL;
  482. }
  483. ret = venc_s_std_output(sd, venc->std);
  484. if (ret < 0) {
  485. v4l2_err(sd, "Error setting std during init\n");
  486. return -EINVAL;
  487. }
  488. return ret;
  489. }
  490. static int venc_device_get(struct device *dev, void *data)
  491. {
  492. struct platform_device *pdev = to_platform_device(dev);
  493. struct venc_state **venc = data;
  494. if (strstr(pdev->name, "vpbe-venc") != NULL)
  495. *venc = platform_get_drvdata(pdev);
  496. return 0;
  497. }
  498. struct v4l2_subdev *venc_sub_dev_init(struct v4l2_device *v4l2_dev,
  499. const char *venc_name)
  500. {
  501. struct venc_state *venc = NULL;
  502. bus_for_each_dev(&platform_bus_type, NULL, &venc,
  503. venc_device_get);
  504. if (venc == NULL)
  505. return NULL;
  506. v4l2_subdev_init(&venc->sd, &venc_ops);
  507. strcpy(venc->sd.name, venc_name);
  508. if (v4l2_device_register_subdev(v4l2_dev, &venc->sd) < 0) {
  509. v4l2_err(v4l2_dev,
  510. "vpbe unable to register venc sub device\n");
  511. return NULL;
  512. }
  513. if (venc_initialize(&venc->sd)) {
  514. v4l2_err(v4l2_dev,
  515. "vpbe venc initialization failed\n");
  516. return NULL;
  517. }
  518. return &venc->sd;
  519. }
  520. EXPORT_SYMBOL(venc_sub_dev_init);
  521. static int venc_probe(struct platform_device *pdev)
  522. {
  523. const struct platform_device_id *pdev_id;
  524. struct venc_state *venc;
  525. struct resource *res;
  526. if (!pdev->dev.platform_data) {
  527. dev_err(&pdev->dev, "No platform data for VENC sub device");
  528. return -EINVAL;
  529. }
  530. pdev_id = platform_get_device_id(pdev);
  531. if (!pdev_id)
  532. return -EINVAL;
  533. venc = devm_kzalloc(&pdev->dev, sizeof(struct venc_state), GFP_KERNEL);
  534. if (venc == NULL)
  535. return -ENOMEM;
  536. venc->venc_type = pdev_id->driver_data;
  537. venc->pdev = &pdev->dev;
  538. venc->pdata = pdev->dev.platform_data;
  539. res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  540. venc->venc_base = devm_ioremap_resource(&pdev->dev, res);
  541. if (IS_ERR(venc->venc_base))
  542. return PTR_ERR(venc->venc_base);
  543. if (venc->venc_type != VPBE_VERSION_1) {
  544. res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
  545. venc->vdaccfg_reg = devm_ioremap_resource(&pdev->dev, res);
  546. if (IS_ERR(venc->vdaccfg_reg))
  547. return PTR_ERR(venc->vdaccfg_reg);
  548. }
  549. spin_lock_init(&venc->lock);
  550. platform_set_drvdata(pdev, venc);
  551. dev_notice(venc->pdev, "VENC sub device probe success\n");
  552. return 0;
  553. }
  554. static int venc_remove(struct platform_device *pdev)
  555. {
  556. return 0;
  557. }
  558. static struct platform_driver venc_driver = {
  559. .probe = venc_probe,
  560. .remove = venc_remove,
  561. .driver = {
  562. .name = MODULE_NAME,
  563. },
  564. .id_table = vpbe_venc_devtype
  565. };
  566. module_platform_driver(venc_driver);
  567. MODULE_LICENSE("GPL");
  568. MODULE_DESCRIPTION("VPBE VENC Driver");
  569. MODULE_AUTHOR("Texas Instruments");