tvafe.c 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002
  1. /*
  2. * TVAFE char device driver.
  3. *
  4. * Copyright (c) 2010 Bo Yang <bo.yang@amlogic.com>
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the smems of the GNU General Public License as published by
  8. * the Free Software Foundation; version 2 of the License.
  9. */
  10. /* Standard Linux headers */
  11. #include <linux/types.h>
  12. #include <linux/errno.h>
  13. #include <linux/init.h>
  14. #include <linux/module.h>
  15. #include <linux/kernel.h>
  16. #include <linux/slab.h>
  17. #include <linux/interrupt.h>
  18. #include <linux/fs.h>
  19. #include <linux/device.h>
  20. #include <linux/cdev.h>
  21. #include <linux/platform_device.h>
  22. #include <linux/interrupt.h>
  23. #include <linux/errno.h>
  24. #include <asm/uaccess.h>
  25. #include <linux/mutex.h>
  26. /* Amlogic headers */
  27. #include <linux/amports/canvas.h>
  28. #include <mach/am_regs.h>
  29. #include <linux/amports/vframe.h>
  30. /* Local include */
  31. #include "tvin_global.h"
  32. #include "vdin_ctl.h"
  33. #include "tvin_notifier.h"
  34. #include "tvafe_regs.h"
  35. #include "tvafe.h" /* For user used */
  36. #include "tvafe_general.h" /* For Kernel used only */
  37. #include "tvafe_adc.h" /* For Kernel used only */
  38. #include "tvafe_cvd.h" /* For Kernel used only */
  39. #define TVAFE_NAME "tvafe"
  40. #define TVAFE_DRIVER_NAME "tvafe"
  41. #define TVAFE_MODULE_NAME "tvafe"
  42. #define TVAFE_DEVICE_NAME "tvafe"
  43. #define TVAFE_CLASS_NAME "tvafe"
  44. #define TVAFE_COUNT 1
  45. static dev_t tvafe_devno;
  46. static struct class *tvafe_clsp;
  47. typedef struct tvafe_dev_s {
  48. int index;
  49. struct cdev cdev;
  50. } tvafe_dev_t;
  51. static struct tvafe_dev_s *tvafe_devp[TVAFE_COUNT];
  52. static struct tvafe_info_s tvafe_info = {
  53. 0,
  54. 0,
  55. NULL,
  56. //signal parameters
  57. {
  58. TVIN_PORT_NULL,
  59. TVIN_SIG_FMT_NULL,
  60. TVIN_SIG_STATUS_NULL,
  61. 0x81000000,
  62. 0,
  63. },
  64. TVAFE_SRC_TYPE_NULL,
  65. //VGA settings
  66. 0,
  67. TVAFE_CMD_STATUS_IDLE,
  68. //adc calibration data
  69. {
  70. 0,
  71. 0,
  72. 0,
  73. 0,
  74. 0,
  75. 0,
  76. 0,
  77. 0,
  78. 0,
  79. 0,
  80. 0,
  81. 0
  82. },
  83. //WSS data
  84. {
  85. {0, 0, 0, 0, 0},
  86. {0, 0, 0, 0, 0},
  87. },
  88. //for canvas
  89. (0xFF - (TVAFE_VF_POOL_SIZE + 2)),
  90. 0,
  91. {
  92. VIDTYPE_INTERLACE_BOTTOM,
  93. VIDTYPE_INTERLACE_TOP,
  94. VIDTYPE_INTERLACE_BOTTOM,
  95. VIDTYPE_INTERLACE_TOP,
  96. VIDTYPE_INTERLACE_BOTTOM,
  97. VIDTYPE_INTERLACE_TOP
  98. },
  99. 0x81000000,
  100. 0x70000,
  101. 0,
  102. 0,
  103. 0,
  104. 0,
  105. 0,
  106. 0,
  107. 0,
  108. 0,
  109. };
  110. static struct vdin_dev_s *vdin_devp_tvafe = NULL;
  111. //CANVAS module should be moved to vdin
  112. static inline unsigned int tvafe_index2canvas(u32 index)
  113. {
  114. int tv_group_index ;
  115. if(vdin_devp_tvafe->index )
  116. tv_group_index = 1;
  117. else
  118. tv_group_index = 0;
  119. if(index < tvafe_info.canvas_total_count)
  120. return tvin_canvas_tab[tv_group_index][index];
  121. else
  122. return 0xff;
  123. }
  124. static void tvafe_canvas_init(unsigned int mem_start, unsigned int mem_size, enum tvin_port_e port)
  125. {
  126. unsigned i, canvas_start_index;
  127. unsigned int canvas_width = 1920 << 1;
  128. unsigned int canvas_height = 1080;
  129. tvafe_info.decbuf_size = 0x400000;
  130. if ((port >= TVIN_PORT_VGA0) && (port <= TVIN_PORT_VGA7))
  131. {
  132. WRITE_CBUS_REG(VPP_PREBLEND_VD1_V_START_END, 0x00000fff);
  133. canvas_width = 1600*3; //tvin_fmt_tbl[tvafe_info.param.fmt].h_active * 3;
  134. canvas_height = 1200; //tvin_fmt_tbl[tvafe_info.param.fmt].v_active;
  135. tvafe_info.decbuf_size = 0x600000;
  136. }
  137. tvafe_info.pbufAddr = mem_start ;
  138. i = (unsigned)(mem_size / tvafe_info.decbuf_size);
  139. if(i % 2)
  140. i -= 1; //sure the counter is even
  141. tvafe_info.canvas_total_count = (TVAFE_VF_POOL_SIZE > i)? i : TVAFE_VF_POOL_SIZE;
  142. if(vdin_devp_tvafe->index )
  143. canvas_start_index = tvin_canvas_tab[1][0];
  144. else
  145. canvas_start_index = tvin_canvas_tab[0][0];
  146. pr_info("tvafe: index = %d, port = %x, decbuf_size = %x, canvas_total_count :%x \n",
  147. vdin_devp_tvafe->index, port, tvafe_info.decbuf_size, tvafe_info.canvas_total_count);
  148. for ( i = 0; i < tvafe_info.canvas_total_count; i++)
  149. {
  150. canvas_config(canvas_start_index + i, mem_start + i * tvafe_info.decbuf_size,
  151. canvas_width, canvas_height, CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_LINEAR);
  152. }
  153. }
  154. static void tvafe_release_canvas(void)
  155. {
  156. //to do ...
  157. }
  158. static int tvafe_get_current_video_buff_point(void)
  159. {
  160. unsigned cur_canvas_index, ii, tvafe_buff_addr, video_buff_addr = 0;
  161. if(vdin_devp_tvafe->index)
  162. cur_canvas_index = (READ_MPEG_REG(VD2_IF0_CANVAS0)) & 0xff ;
  163. else
  164. cur_canvas_index = (READ_MPEG_REG(VD1_IF0_CANVAS0)) & 0xff ;
  165. video_buff_addr = canvas_get_addr(cur_canvas_index);
  166. for(ii = 0; ii < tvafe_info.canvas_total_count; ii++)
  167. {
  168. tvafe_buff_addr = tvafe_info.pbufAddr + ii * tvafe_info.decbuf_size;
  169. if(video_buff_addr == tvafe_buff_addr)
  170. break;
  171. }
  172. if(ii < tvafe_info.canvas_total_count)
  173. return(ii);
  174. else
  175. return(0xff); //current video don't display tvafe input data
  176. }
  177. static void tvafe_send_interlace_buff_to_display_fifo(vframe_t * info)
  178. {
  179. info->width = tvin_fmt_tbl[tvafe_info.param.fmt].h_active;
  180. info->height = tvin_fmt_tbl[tvafe_info.param.fmt].v_active*2;
  181. info->duration = tvin_fmt_tbl[tvafe_info.param.fmt].duration;
  182. if((info->width == 0) || (info->height == 0) || (info->duration == 0))
  183. return;
  184. tvafe_info.rd_canvas_index++;
  185. if(tvafe_info.rd_canvas_index > (tvafe_info.canvas_total_count -1))
  186. {
  187. tvafe_info.rd_canvas_index = 0;
  188. tvafe_info.wrap_flag = 0;
  189. }
  190. if((tvafe_info.buff_flag[tvafe_info.rd_canvas_index] & 0xf) == VIDTYPE_INTERLACE_BOTTOM)
  191. info->type = VIDTYPE_VIU_SINGLE_PLANE | VIDTYPE_VIU_422 | VIDTYPE_VIU_FIELD | VIDTYPE_INTERLACE_BOTTOM;
  192. else
  193. info->type = VIDTYPE_VIU_SINGLE_PLANE | VIDTYPE_VIU_422 | VIDTYPE_VIU_FIELD | VIDTYPE_INTERLACE_TOP;
  194. //if (tvafe_info.src_type == TVAFE_SRC_TYPE_VGA )
  195. // info->type |= VIDTYPE_VIU_444;
  196. //else
  197. // info->type |= VIDTYPE_VIU_422;
  198. info->canvas0Addr = info->canvas1Addr = tvafe_index2canvas(tvafe_info.rd_canvas_index);
  199. }
  200. static void tvafe_send_progressive_buff_to_display_fifo(vframe_t * info)
  201. {
  202. info->width= tvin_fmt_tbl[tvafe_info.param.fmt].h_active;
  203. info->height = tvin_fmt_tbl[tvafe_info.param.fmt].v_active;
  204. info->duration = tvin_fmt_tbl[tvafe_info.param.fmt].duration;
  205. if((info->width == 0) || (info->height == 0) || (info->duration == 0))
  206. return;
  207. tvafe_info.rd_canvas_index++;
  208. if(tvafe_info.rd_canvas_index > (tvafe_info.canvas_total_count -1))
  209. {
  210. tvafe_info.rd_canvas_index = 0;
  211. tvafe_info.wrap_flag = 0;
  212. }
  213. info->canvas0Addr = info->canvas1Addr = tvafe_index2canvas(tvafe_info.rd_canvas_index);
  214. info->type = VIDTYPE_VIU_SINGLE_PLANE | VIDTYPE_VIU_FIELD | VIDTYPE_PROGRESSIVE;
  215. if (tvafe_info.src_type == TVAFE_SRC_TYPE_VGA ) {
  216. info->type |= VIDTYPE_VIU_444;
  217. } else
  218. info->type |= VIDTYPE_VIU_422;
  219. info->canvas0Addr = info->canvas1Addr = tvafe_index2canvas(tvafe_info.rd_canvas_index);
  220. return;
  221. }
  222. static void tvafe_wr_vdin_canvas(void)
  223. {
  224. unsigned char canvas_id;
  225. tvafe_info.wr_canvas_index++;
  226. if(tvafe_info.wr_canvas_index > (tvafe_info.canvas_total_count -1) )
  227. {
  228. tvafe_info.wr_canvas_index = 0;
  229. tvafe_info.wrap_flag = 1;
  230. }
  231. canvas_id = tvafe_index2canvas(tvafe_info.wr_canvas_index);
  232. vdin_set_canvas_id(vdin_devp_tvafe->index, canvas_id);
  233. }
  234. static void tvafe_vga_pinmux_enable(void)
  235. {
  236. // diable TCON
  237. //WRITE_CBUS_REG_BITS(PERIPHS_PIN_MUX_7, 0, 1, 1);
  238. // diable DVIN
  239. WRITE_CBUS_REG_BITS(PERIPHS_PIN_MUX_6, 0, 27, 1);
  240. // HS0
  241. WRITE_CBUS_REG_BITS(PERIPHS_PIN_MUX_6, 1, 15, 1);
  242. // VS0
  243. WRITE_CBUS_REG_BITS(PERIPHS_PIN_MUX_6, 1, 14, 1);
  244. // DDC_SDA0
  245. //WRITE_CBUS_REG_BITS(PERIPHS_PIN_MUX_6, 1, 13, 1);
  246. // DDC_SCL0
  247. //WRITE_CBUS_REG_BITS(PERIPHS_PIN_MUX_6, 1, 12, 1);
  248. }
  249. static void tvafe_vga_pinmux_disable(void)
  250. {
  251. // HS0
  252. WRITE_CBUS_REG_BITS(PERIPHS_PIN_MUX_6, 0, 15, 1);
  253. // VS0
  254. WRITE_CBUS_REG_BITS(PERIPHS_PIN_MUX_6, 0, 14, 1);
  255. // DDC_SDA0
  256. //WRITE_CBUS_REG_BITS(PERIPHS_PIN_MUX_6, 0, 13, 1);
  257. // DDC_SCL0
  258. //WRITE_CBUS_REG_BITS(PERIPHS_PIN_MUX_6, 0, 12, 1);
  259. }
  260. #ifdef VDIN_FIXED_FMT_TEST
  261. static int tvafe_start_dec(unsigned int mem_start, unsigned int mem_size, tvin_port_t port, tvin_sig_fmt_t fmt)
  262. #else
  263. static int tvafe_start_dec(unsigned int mem_start, unsigned int mem_size, tvin_port_t port)
  264. #endif
  265. {
  266. int ret = 0;
  267. pr_info("tvafe: tvafe_start_dec.\n");
  268. /** init canvas and variables**/
  269. //init canvas
  270. tvafe_canvas_init(mem_start, mem_size, port);
  271. tvafe_info.rd_canvas_index = 0xFF - (tvafe_info.canvas_total_count + 2);
  272. tvafe_info.wr_canvas_index = 0;
  273. tvafe_info.param.port = port;
  274. if (tvafe_info.param.port == TVIN_PORT_VGA0)
  275. tvafe_vga_pinmux_enable();
  276. tvafe_reset_module(tvafe_info.param.port);
  277. tvafe_init_state_handler();
  278. if ((port >= TVIN_PORT_VGA0) && (port <= TVIN_PORT_VGA7))
  279. tvafe_set_vga_default(TVIN_SIG_FMT_VGA_1024X768P_60D004);
  280. else if ((port >= TVIN_PORT_COMP0) && (port <= TVIN_PORT_COMP7))
  281. tvafe_set_comp_default(TVIN_SIG_FMT_COMP_720P_59D940);
  282. else //if ((port >= TVIN_PORT_CVBS0) && (port <= TVIN_PORT_CVBS7))
  283. {
  284. #ifdef VDIN_FIXED_FMT_TEST
  285. tvafe_set_cvd2_default(tvafe_info.cvd2_mem_addr, tvafe_info.cvd2_mem_size, fmt);
  286. #else
  287. tvafe_set_cvd2_default(tvafe_info.cvd2_mem_addr, tvafe_info.cvd2_mem_size,
  288. TVIN_SIG_FMT_CVBS_PAL_I);
  289. #endif
  290. }
  291. ret = tvafe_source_muxing(&tvafe_info);
  292. pr_info("tvafe: tvafe_start_dec finished \n");
  293. return ret;
  294. }
  295. static void tvafe_stop_dec(void)
  296. {
  297. pr_info("tvafe: tvafe_stop_dec.\n");
  298. if (tvafe_info.param.port == TVIN_PORT_VGA0)
  299. tvafe_vga_pinmux_disable();
  300. if ((tvafe_info.param.port >= TVIN_PORT_CVBS0) &&
  301. (tvafe_info.param.port <= TVIN_PORT_CVBS7))
  302. WRITE_APB_REG_BITS(CVD2_RESET_REGISTER, 1, SOFT_RST_BIT, SOFT_RST_WID);
  303. //tvafe_stop_module(&tvafe_info);
  304. tvafe_release_canvas();
  305. tvafe_info.param.fmt = TVIN_SIG_FMT_NULL;
  306. tvafe_info.param.status = TVIN_SIG_STATUS_NULL;
  307. tvafe_info.param.cap_addr = 0;
  308. tvafe_info.param.flag = 0;
  309. //need to do ...
  310. }
  311. /*as use the spin_lock,
  312. *1--there is no sleep,
  313. *2--it is better to shorter the time,
  314. */
  315. static int tvafe_isr_run(struct vframe_s *vf_info)
  316. {
  317. unsigned int canvas_id = 0;
  318. unsigned char field_status = 0, last_recv_index = 0, cur_canvas_index, next_buffs_index;
  319. enum tvin_scan_mode_e scan_mode = 0;
  320. /* Fetch WSS data */
  321. /* Monitoring CVBS amplitude */
  322. //video frame info setting
  323. if ((tvafe_info.param.status != TVIN_SIG_STATUS_STABLE) ||
  324. (tvafe_info.param.fmt == TVIN_SIG_FMT_NULL)) {
  325. return 0;
  326. }
  327. switch (tvafe_info.src_type) {
  328. case TVAFE_SRC_TYPE_CVBS:
  329. case TVAFE_SRC_TYPE_SVIDEO:
  330. /* TVAFE CVD2 3D works abnormally => reset cvd2 */
  331. if(tvafe_info.param.status == TVIN_SIG_STATUS_STABLE)
  332. tvafe_check_cvbs_3d_comb();
  333. break;
  334. case TVAFE_SRC_TYPE_VGA:
  335. case TVAFE_SRC_TYPE_COMP:
  336. break;
  337. case TVAFE_SRC_TYPE_SCART:
  338. break;
  339. default:
  340. break;
  341. }
  342. tvafe_vga_vs_cnt();
  343. if ((vdin_devp_tvafe->para.flag & TVIN_PARM_FLAG_CAP) != 0) //frame capture function
  344. {
  345. #if 1
  346. if (tvafe_info.wr_canvas_index == 0)
  347. last_recv_index = tvafe_info.canvas_total_count - 1;
  348. else
  349. last_recv_index = tvafe_info.wr_canvas_index - 1;
  350. if (last_recv_index != tvafe_info.rd_canvas_index)
  351. canvas_id = last_recv_index;
  352. else
  353. {
  354. if(tvafe_info.wr_canvas_index == tvafe_info.canvas_total_count - 1)
  355. canvas_id = 0;
  356. else
  357. canvas_id = tvafe_info.wr_canvas_index + 1;
  358. }
  359. #else
  360. canvas_id = tvafe_info.rd_canvas_index; //kernel & user don't use the same memory
  361. #endif
  362. vdin_devp_tvafe->para.cap_addr = tvafe_info.pbufAddr +
  363. (tvafe_info.decbuf_size * canvas_id);
  364. vdin_devp_tvafe->para.cap_size = tvafe_info.decbuf_size;
  365. vdin_devp_tvafe->para.canvas_index= canvas_id;
  366. return -1;
  367. }
  368. scan_mode = tvin_fmt_tbl[tvafe_info.param.fmt].scan_mode;
  369. if (scan_mode == TVIN_SCAN_MODE_PROGRESSIVE) {
  370. if ((tvafe_info.rd_canvas_index > 0xF0) && (tvafe_info.rd_canvas_index < 0xFF))
  371. {
  372. tvafe_info.rd_canvas_index++;
  373. tvafe_wr_vdin_canvas();
  374. return 0;
  375. }
  376. else if (tvafe_info.rd_canvas_index == 0xFF)
  377. {
  378. tvafe_info.rd_canvas_index = 0;
  379. tvafe_info.wrap_flag = 0;
  380. }
  381. else
  382. {
  383. cur_canvas_index = tvafe_get_current_video_buff_point(); //get current display index
  384. if (tvafe_info.wr_canvas_index >= (tvafe_info.canvas_total_count -1) )
  385. {
  386. next_buffs_index = 0;
  387. }
  388. else
  389. {
  390. next_buffs_index = tvafe_info.wr_canvas_index + 1;
  391. }
  392. if(((tvafe_info.wr_canvas_index == cur_canvas_index) || (next_buffs_index == cur_canvas_index)) &&
  393. (tvafe_info.wrap_flag == 1)) //avoid the overflow
  394. {
  395. tvafe_send_progressive_buff_to_display_fifo(vf_info);
  396. return 0;
  397. }
  398. if (tvafe_info.rd_canvas_index > (tvafe_info.canvas_total_count - 1))
  399. next_buffs_index = 0;
  400. else
  401. next_buffs_index = tvafe_info.rd_canvas_index + 1;
  402. if ((next_buffs_index == tvafe_info.wr_canvas_index) &&
  403. (tvafe_info.wrap_flag == 0)) //avoid the underflow
  404. {
  405. tvafe_wr_vdin_canvas();
  406. return 0;
  407. }
  408. }
  409. tvafe_send_progressive_buff_to_display_fifo(vf_info);
  410. tvafe_wr_vdin_canvas();
  411. }
  412. else {
  413. field_status = READ_CBUS_REG_BITS(VDIN_COM_STATUS0, 0, 1);
  414. if (tvafe_info.wr_canvas_index == 0)
  415. last_recv_index = tvafe_info.canvas_total_count - 1;
  416. else
  417. last_recv_index = tvafe_info.wr_canvas_index - 1;
  418. if (field_status == 1)
  419. {
  420. tvafe_info.buff_flag[tvafe_info.wr_canvas_index] = VIDTYPE_INTERLACE_BOTTOM;
  421. if((tvafe_info.buff_flag[last_recv_index] & 0x0f) == VIDTYPE_INTERLACE_BOTTOM)
  422. {
  423. return 0;
  424. }
  425. }
  426. else
  427. {
  428. tvafe_info.buff_flag[tvafe_info.wr_canvas_index] = VIDTYPE_INTERLACE_TOP;
  429. if((tvafe_info.buff_flag[last_recv_index] & 0x0f) == VIDTYPE_INTERLACE_TOP)
  430. {
  431. return 0;
  432. }
  433. }
  434. if((tvafe_info.rd_canvas_index > 0xF0) && (tvafe_info.rd_canvas_index < 0xFF))
  435. {
  436. tvafe_info.rd_canvas_index++;
  437. tvafe_wr_vdin_canvas();
  438. return 0;
  439. }
  440. else if (tvafe_info.rd_canvas_index == 0xFF)
  441. {
  442. tvafe_info.rd_canvas_index = 0;
  443. tvafe_info.wrap_flag = 0;
  444. }
  445. else
  446. {
  447. cur_canvas_index = tvafe_get_current_video_buff_point();
  448. if(tvafe_info.wr_canvas_index >= (tvafe_info.canvas_total_count -1) )
  449. {
  450. next_buffs_index = 0;
  451. }
  452. else
  453. {
  454. next_buffs_index = tvafe_info.wr_canvas_index + 1;
  455. }
  456. if(((tvafe_info.wr_canvas_index == cur_canvas_index) || (next_buffs_index == cur_canvas_index))
  457. && (tvafe_info.wrap_flag == 1)) //avoid the overflow
  458. {
  459. tvafe_send_interlace_buff_to_display_fifo(vf_info);
  460. return 0;
  461. }
  462. if(tvafe_info.rd_canvas_index > (tvafe_info.canvas_total_count -1))
  463. next_buffs_index = 0;
  464. else
  465. next_buffs_index = tvafe_info.rd_canvas_index + 1;
  466. if((next_buffs_index == tvafe_info.wr_canvas_index) && (tvafe_info.wrap_flag == 0)) //avoid the underflow
  467. {
  468. tvafe_wr_vdin_canvas();
  469. return 0;
  470. }
  471. tvafe_send_interlace_buff_to_display_fifo(vf_info);
  472. tvafe_wr_vdin_canvas();
  473. }
  474. }
  475. // fetch WSS data
  476. tvafe_get_wss_data(&tvafe_info.comp_wss);
  477. return 0;
  478. }
  479. //static int cnt = 0;
  480. static void check_tvafe_format(void )
  481. {
  482. if (vdin_devp_tvafe == NULL) //check tvafe status
  483. {
  484. pr_info("tvafe vdin_devp_tvafe == NULL\n");
  485. return;
  486. }
  487. //get frame capture flag from vdin
  488. tvafe_info.param.flag = vdin_devp_tvafe->para.flag;
  489. tvafe_run_state_handler(&tvafe_info);
  490. if (tvafe_info.vga_auto_flag == 1)
  491. {
  492. tvafe_vga_auto_adjust_handler(&tvafe_info);
  493. if ((tvafe_info.cmd_status == TVAFE_CMD_STATUS_FAILED) ||
  494. (tvafe_info.cmd_status == TVAFE_CMD_STATUS_SUCCESSFUL)
  495. )
  496. tvafe_info.vga_auto_flag = 0;
  497. }
  498. return;
  499. }
  500. static int tvafe_check_callback(struct notifier_block *block, unsigned long cmd , void *para)
  501. {
  502. int ret = 0;
  503. switch(cmd)
  504. {
  505. case TVIN_EVENT_INFO_CHECK:
  506. if(vdin_devp_tvafe != NULL)
  507. {
  508. //cvd agc handler
  509. if (tvafe_info.src_type == TVAFE_SRC_TYPE_CVBS)
  510. tvafe_cvd2_video_agc_handler(&tvafe_info);
  511. check_tvafe_format();
  512. if ((tvafe_info.param.fmt != vdin_devp_tvafe->para.fmt) ||
  513. (tvafe_info.param.status != vdin_devp_tvafe->para.status))
  514. {
  515. tvafe_set_fmt(&tvafe_info);
  516. vdin_info_update(vdin_devp_tvafe, &tvafe_info.param);
  517. }
  518. ret = NOTIFY_STOP_MASK;
  519. }
  520. break;
  521. default:
  522. //pr_dbg("command is not exit ./n");
  523. break;
  524. }
  525. return ret;
  526. }
  527. static struct notifier_block tvafe_check_notifier = {
  528. .notifier_call = tvafe_check_callback,
  529. };
  530. struct tvin_dec_ops_s tvafe_op = {
  531. .dec_run = tvafe_isr_run,
  532. };
  533. static int tvafe_notifier_callback(struct notifier_block *block,
  534. unsigned long cmd , void *para)
  535. {
  536. int ret = 0;
  537. vdin_dev_t *p = NULL;
  538. pr_info("tvafe: start listen event\n");
  539. switch(cmd)
  540. {
  541. case TVIN_EVENT_DEC_START:
  542. if(para != NULL)
  543. {
  544. p = (vdin_dev_t*)para;
  545. if ((p->para.port < TVIN_PORT_VGA0) ||
  546. (p->para.port > TVIN_PORT_SVIDEO7))
  547. {
  548. pr_info("tvafe: ignore event TVIN_EVENT_DEC_START(port=%d)\n", p->para.port);
  549. return 0;
  550. }
  551. pr_info("tvafe: start to response for event TVIN_EVENT_DEC_START(port=%d)\n", p->para.port);
  552. vdin_devp_tvafe = p;
  553. #ifdef VDIN_FIXED_FMT_TEST
  554. if (tvafe_start_dec(p->mem_start, p->mem_size, p->para.port, p->para.fmt) < 0) {
  555. #else
  556. if (tvafe_start_dec(p->mem_start, p->mem_size, p->para.port) < 0) {
  557. #endif
  558. pr_info("tvafe start error\n");
  559. vdin_devp_tvafe = NULL;
  560. return 0;
  561. }
  562. tvin_dec_register(p, &tvafe_op);
  563. tvin_check_notifier_register(&tvafe_check_notifier);
  564. ret = NOTIFY_STOP_MASK;
  565. }
  566. break;
  567. case TVIN_EVENT_DEC_STOP:
  568. if(para != NULL)
  569. {
  570. p = (vdin_dev_t*)para;
  571. if ((p->para.port < TVIN_PORT_VGA0) || (p->para.port > TVIN_PORT_SVIDEO7))
  572. {
  573. pr_info("tvafe: ignore TVIN_EVENT_DEC_STOP, port=%d \n", p->para.port);
  574. return ret;
  575. }
  576. tvafe_stop_dec();
  577. tvin_dec_unregister(vdin_devp_tvafe);
  578. tvin_check_notifier_unregister(&tvafe_check_notifier);
  579. vdin_devp_tvafe = NULL;
  580. ret = NOTIFY_STOP_MASK;
  581. }
  582. break;
  583. }
  584. return ret;
  585. }
  586. static struct notifier_block tvafe_notifier = {
  587. .notifier_call = tvafe_notifier_callback,
  588. };
  589. static int tvafe_open(struct inode *inode, struct file *file)
  590. {
  591. tvafe_dev_t *devp;
  592. /* Get the per-device structure that contains this cdev */
  593. devp = container_of(inode->i_cdev, tvafe_dev_t, cdev);
  594. file->private_data = devp;
  595. /* ... */
  596. return 0;
  597. }
  598. static int tvafe_release(struct inode *inode, struct file *file)
  599. {
  600. tvafe_dev_t *devp = file->private_data;
  601. file->private_data = NULL;
  602. /* Release some other fields */
  603. /* ... */
  604. pr_info(KERN_ERR "tvafe: device %d release ok.\n", devp->index);
  605. return 0;
  606. }
  607. static int tvafe_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
  608. {
  609. int ret = 0;
  610. enum tvafe_cvbs_video_e cvbs_lock_status = TVAFE_CVBS_VIDEO_UNLOCKED;
  611. void __user *argp = (void __user *)arg;
  612. struct tvafe_vga_edid_s edid;
  613. switch (cmd)
  614. {
  615. case TVIN_IOC_S_AFE_ADC_CAL:
  616. if (copy_from_user(&tvafe_info.adc_cal_val, argp, sizeof(struct tvafe_adc_cal_s)))
  617. {
  618. ret = -EFAULT;
  619. }
  620. else
  621. {
  622. tvafe_vga_auto_adjust_disable(&tvafe_info);
  623. tvafe_set_cal_value(&tvafe_info.adc_cal_val);
  624. }
  625. break;
  626. case TVIN_IOC_G_AFE_ADC_CAL:
  627. tvafe_get_cal_value(&tvafe_info.adc_cal_val);
  628. if (copy_to_user(argp, &tvafe_info.adc_cal_val, sizeof(struct tvafe_adc_cal_s)))
  629. {
  630. ret = -EFAULT;
  631. }
  632. break;
  633. case TVIN_IOC_G_AFE_COMP_WSS:
  634. if (copy_to_user(argp, &tvafe_info.comp_wss, sizeof(struct tvafe_comp_wss_s)))
  635. {
  636. ret = -EFAULT;
  637. }
  638. break;
  639. case TVIN_IOC_S_AFE_VGA_EDID:
  640. if (copy_from_user(&edid, argp, sizeof(struct tvafe_vga_edid_s)))
  641. {
  642. ret = -EFAULT;
  643. }
  644. else
  645. {
  646. tvafe_vga_set_edid(&edid);
  647. }
  648. break;
  649. case TVIN_IOC_G_AFE_VGA_EDID:
  650. tvafe_vga_get_edid(&edid);
  651. if (copy_to_user(argp, &edid, sizeof(struct tvafe_vga_edid_s)))
  652. {
  653. ret = -EFAULT;
  654. }
  655. break;
  656. case TVIN_IOC_S_AFE_VGA_PARM:
  657. {
  658. struct tvafe_vga_parm_s vga_parm = {0, 0, 0, 0, 0};
  659. if (copy_from_user(&vga_parm, argp, sizeof(struct tvafe_vga_parm_s)))
  660. {
  661. ret = -EFAULT;
  662. }
  663. else
  664. {
  665. tvafe_vga_auto_adjust_disable(&tvafe_info);
  666. tvafe_adc_set_param(&vga_parm, &tvafe_info);
  667. }
  668. break;
  669. }
  670. case TVIN_IOC_G_AFE_VGA_PARM:
  671. {
  672. struct tvafe_vga_parm_s vga_parm = {0, 0, 0, 0, 0};
  673. tvafe_adc_get_param(&vga_parm, &tvafe_info);
  674. if (copy_to_user(argp, &vga_parm, sizeof(struct tvafe_vga_parm_s)))
  675. {
  676. ret = -EFAULT;
  677. }
  678. break;
  679. }
  680. case TVIN_IOC_S_AFE_VGA_AUTO:
  681. ret = tvafe_vga_auto_adjust_enable(&tvafe_info);
  682. break;
  683. case TVIN_IOC_G_AFE_CMD_STATUS:
  684. if (copy_to_user(argp, &tvafe_info.cmd_status, sizeof(enum tvafe_cmd_status_e)))
  685. {
  686. ret = -EFAULT;
  687. }
  688. else
  689. {
  690. if ((tvafe_info.cmd_status == TVAFE_CMD_STATUS_SUCCESSFUL)
  691. || (tvafe_info.cmd_status == TVAFE_CMD_STATUS_FAILED)
  692. || (tvafe_info.cmd_status == TVAFE_CMD_STATUS_TERMINATED)
  693. )
  694. {
  695. tvafe_info.cmd_status = TVAFE_CMD_STATUS_IDLE;
  696. }
  697. }
  698. break;
  699. case TVIN_IOC_G_AFE_CVBS_LOCK:
  700. cvbs_lock_status = tvafe_cvd2_video_locked();
  701. if (copy_to_user(argp, &cvbs_lock_status, sizeof(int)))
  702. {
  703. ret = -EFAULT;
  704. }
  705. break;
  706. case TVIN_IOC_S_CVD2_CORDIC:
  707. if(tvafe_cvd2_set_cordic_para(argp))
  708. ret = -EFAULT;
  709. break;
  710. case TVIN_IOC_G_CVD2_CORDIC:
  711. if(tvafe_cvd2_get_cordic_para(argp))
  712. ret = -EFAULT;
  713. break;
  714. default:
  715. ret = -ENOIOCTLCMD;
  716. break;
  717. }
  718. return ret;
  719. }
  720. /* File operations structure. Defined in linux/fs.h */
  721. static struct file_operations tvafe_fops = {
  722. .owner = THIS_MODULE, /* Owner */
  723. .open = tvafe_open, /* Open method */
  724. .release = tvafe_release, /* Release method */
  725. .ioctl = tvafe_ioctl, /* Ioctl method */
  726. /* ... */
  727. };
  728. static int tvafe_probe(struct platform_device *pdev)
  729. {
  730. int ret;
  731. int i;
  732. struct device *devp;
  733. struct resource *res;
  734. pr_info("tvafe: tvafe_probe start...\n");
  735. ret = alloc_chrdev_region(&tvafe_devno, 0, TVAFE_COUNT, TVAFE_NAME);
  736. if (ret < 0) {
  737. pr_info(KERN_ERR "tvafe: failed to allocate major number\n");
  738. return 0;
  739. }
  740. tvafe_clsp = class_create(THIS_MODULE, TVAFE_NAME);
  741. if (IS_ERR(tvafe_clsp))
  742. {
  743. pr_info(KERN_ERR "tvafe: can't get tvafe_clsp\n");
  744. unregister_chrdev_region(tvafe_devno, TVAFE_COUNT);
  745. return PTR_ERR(tvafe_clsp);
  746. }
  747. /* @todo do with resources */
  748. res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  749. if (!res)
  750. {
  751. pr_info(KERN_ERR "tvafe: can't get memory resource\n");
  752. return -EFAULT;
  753. }
  754. for (i = 0; i < TVAFE_COUNT; ++i)
  755. {
  756. /* allocate memory for the per-device structure */
  757. tvafe_devp[i] = kmalloc(sizeof(struct tvafe_dev_s), GFP_KERNEL);
  758. if (!tvafe_devp[i])
  759. {
  760. pr_info(KERN_ERR "tvafe: failed to allocate memory for tvafe device\n");
  761. return -ENOMEM;
  762. }
  763. tvafe_devp[i]->index = i;
  764. /* connect the file operations with cdev */
  765. cdev_init(&tvafe_devp[i]->cdev, &tvafe_fops);
  766. tvafe_devp[i]->cdev.owner = THIS_MODULE;
  767. /* connect the major/minor number to the cdev */
  768. ret = cdev_add(&tvafe_devp[i]->cdev, (tvafe_devno + i), 1);
  769. if (ret) {
  770. pr_info(KERN_ERR "tvafe: failed to add device\n");
  771. /* @todo do with error */
  772. return ret;
  773. }
  774. /* create /dev nodes */
  775. devp = device_create(tvafe_clsp, NULL, MKDEV(MAJOR(tvafe_devno), i),
  776. NULL, "tvafe%d", i);
  777. if (IS_ERR(devp)) {
  778. pr_info(KERN_ERR "tvafe: failed to create device node\n");
  779. class_destroy(tvafe_clsp);
  780. /* @todo do with error */
  781. return PTR_ERR(devp);;
  782. }
  783. #if 1
  784. /* get device memory */
  785. res = platform_get_resource(pdev, IORESOURCE_MEM, i);
  786. if (!res) {
  787. pr_info(KERN_ERR "tvafe: can't get memory resource\n");
  788. return -EFAULT;
  789. }
  790. tvafe_info.cvd2_mem_addr = res->start;
  791. tvafe_info.cvd2_mem_size = res->end - res->start + 1;
  792. pr_info("CVD: cvd2_mem_addr=0x%x cvd2_mem_size=0x%x\n",
  793. tvafe_info.cvd2_mem_addr, tvafe_info.cvd2_mem_size);
  794. #endif
  795. tvafe_info.pinmux = pdev->dev.platform_data;
  796. if (!tvafe_info.pinmux) {
  797. pr_info(" rvafe no platform_data!\n");
  798. ret = -ENODEV;
  799. }
  800. }
  801. tvin_dec_notifier_register(&tvafe_notifier);
  802. pr_info(KERN_INFO "tvafe: driver probe ok\n");
  803. return 0;
  804. }
  805. static int tvafe_remove(struct platform_device *pdev)
  806. {
  807. int i = 0;
  808. tvin_dec_notifier_unregister(&tvafe_notifier);
  809. for (i = 0; i < TVAFE_COUNT; ++i)
  810. {
  811. device_destroy(tvafe_clsp, MKDEV(MAJOR(tvafe_devno), i));
  812. cdev_del(&tvafe_devp[i]->cdev);
  813. kfree(tvafe_devp[i]);
  814. }
  815. class_destroy(tvafe_clsp);
  816. unregister_chrdev_region(tvafe_devno, TVAFE_COUNT);
  817. pr_info(KERN_ERR "tvafe: driver removed ok.\n");
  818. return 0;
  819. }
  820. static struct platform_driver tvafe_driver = {
  821. .probe = tvafe_probe,
  822. .remove = tvafe_remove,
  823. .driver = {
  824. .name = TVAFE_DRIVER_NAME,
  825. }
  826. };
  827. static int __init tvafe_init(void)
  828. {
  829. int ret = 0;
  830. ret = platform_driver_register(&tvafe_driver);
  831. if (ret != 0) {
  832. pr_info(KERN_ERR "failed to register tvafe module, error %d\n", ret);
  833. return -ENODEV;
  834. }
  835. pr_info("tvafe: tvafe_init.\n");
  836. return ret;
  837. }
  838. static void __exit tvafe_exit(void)
  839. {
  840. platform_driver_unregister(&tvafe_driver);
  841. pr_info("tvafe: tvafe_exit.\n");
  842. }
  843. module_init(tvafe_init);
  844. module_exit(tvafe_exit);
  845. MODULE_DESCRIPTION("AMLOGIC TVAFE driver");
  846. MODULE_LICENSE("GPL");
  847. MODULE_AUTHOR("Xu Lin <lin.xu@amlogic.com>");