vpbe_venc.c 18 KB

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