vpbe_venc.c 18 KB

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