planb.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:70k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /* 
  2.     planb - v4l-compatible frame grabber driver for the PlanB hardware
  3.     PlanB is used in the 7x00/8x00 series of PowerMacintosh
  4.     Computers as video input DMA controller.
  5.     Copyright (C) 1998 - 2002  Michel Lanners <mailto:mlan@cpu.lu>
  6.     Based largely on the old bttv driver by Ralph Metzler
  7.     Additional debugging and coding by Takashi Oe <mailto:toe@unlserve.unl.edu>
  8.     For more information, see <http://www.cpu.lu/~mlan/planb.html>
  9.     This program is free software; you can redistribute it and/or modify
  10.     it under the terms of the GNU General Public License as published by
  11.     the Free Software Foundation; either version 2 of the License, or
  12.     (at your option) any later version.
  13.     This program is distributed in the hope that it will be useful,
  14.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16.     GNU General Public License for more details.
  17.     You should have received a copy of the GNU General Public License
  18.     along with this program; if not, write to the Free Software
  19.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20. */
  21. /* $Id: planb.c,v 2.11 2002/04/03 15:57:57 mlan Exp mlan $ */
  22. #include <linux/version.h>
  23. #include <linux/init.h>
  24. #include <linux/errno.h>
  25. #include <linux/module.h>
  26. #include <linux/kernel.h>
  27. #include <linux/major.h>
  28. #include <linux/slab.h>
  29. #include <linux/types.h>
  30. #include <linux/pci.h>
  31. #include <linux/delay.h>
  32. #include <linux/vmalloc.h>
  33. #include <linux/mm.h>
  34. #include <linux/sched.h>
  35. #include <linux/poll.h>
  36. #include <linux/wrapper.h>
  37. #include <linux/tqueue.h>
  38. #include <linux/videodev.h>
  39. #include <asm/uaccess.h>
  40. #include <asm/io.h>
  41. #include <asm/prom.h>
  42. #include <asm/dbdma.h>
  43. #include <asm/pgtable.h>
  44. #include <asm/page.h>
  45. #include <asm/irq.h>
  46. #include <asm/semaphore.h>
  47. /* Define these to get general / interrupt debugging */
  48. #undef DEBUG
  49. #undef IDEBUG
  50. //#define DEBUG
  51. #ifdef DEBUG
  52. #define DBG(x...) printk(KERN_DEBUG ## x)
  53. #else
  54. #define DBG(x...)
  55. #endif
  56. #ifdef IDEBUG
  57. #define IDBG(x...) printk(KERN_DEBUG ## x)
  58. #else
  59. #define IDBG(x...)
  60. #endif
  61. #include "planb.h"
  62. #include "saa7196.h"
  63. static struct planb planbs;
  64. static volatile struct planb_registers *planb_regs;
  65. static int def_norm = PLANB_DEF_NORM; /* default norm */
  66. static int video_nr = -1;
  67. static int vbi_nr = -1;
  68. MODULE_PARM(def_norm, "i");
  69. MODULE_PARM_DESC(def_norm, "Default startup norm (0=PAL, 1=NTSC, 2=SECAM)");
  70. MODULE_PARM(video_nr,"i");
  71. MODULE_PARM(vbi_nr,"i");
  72. MODULE_DESCRIPTION("planb - v4l driver module for Apple PlanB video in");
  73. MODULE_AUTHOR("Michel Lanners & Takashi Oe - see: http://www.cpu.lu/planb.html");
  74. MODULE_LICENSE("GPL");
  75. /* ------------------ PlanB Exported Functions ------------------ */
  76. static long planb_write(struct video_device *, const char *, unsigned long, int);
  77. static long planb_read(struct video_device *, char *, unsigned long, int);
  78. static int planb_open(struct video_device *, int);
  79. static void planb_close(struct video_device *);
  80. static int planb_ioctl(struct video_device *, unsigned int, void *);
  81. static int planb_mmap(struct video_device *, const char *, unsigned long);
  82. static void planb_irq(int, void *, struct pt_regs *);
  83. static int planb_vbi_open(struct video_device *, int);
  84. static void planb_vbi_close(struct video_device *);
  85. static long planb_vbi_read(struct video_device *, char *, unsigned long, int);
  86. static unsigned int planb_vbi_poll(struct video_device *, struct file *,
  87. poll_table *);
  88. static int planb_vbi_ioctl(struct video_device *, unsigned int, void *);
  89. static void release_planb(void);
  90. static int __init init_planbs(void);
  91. static void __exit exit_planbs(void);
  92. /* ------------------ PlanB Internal Functions ------------------ */
  93. static int planb_prepare_open(struct planb *);
  94. static int planb_prepare_vbi(struct planb *);
  95. static int planb_prepare_video(struct planb *);
  96. static void planb_prepare_close(struct planb *);
  97. static void planb_close_vbi(struct planb *);
  98. static void planb_close_video(struct planb *);
  99. static void saa_write_reg(unsigned char, unsigned char);
  100. static unsigned char saa_status(int, struct planb *);
  101. static void saa_set(unsigned char, unsigned char, struct planb *);
  102. static void saa_init_regs(struct planb *);
  103. static int grabbuf_alloc(struct planb *);
  104. static int vgrab(struct planb *, struct video_mmap *);
  105. static void add_clip(struct planb *, struct video_clip *);
  106. static void fill_cmd_buff(struct planb *);
  107. static void cmd_buff(struct planb *);
  108. static dbdma_cmd_ptr setup_grab_cmd(int, struct planb *);
  109. static void overlay_start(struct planb *);
  110. static void overlay_stop(struct planb *);
  111. static inline void tab_cmd_dbdma(dbdma_cmd_ptr, unsigned short, unsigned int);
  112. static inline void tab_cmd_store(dbdma_cmd_ptr, unsigned int, unsigned int);
  113. static inline void tab_cmd_gen(dbdma_cmd_ptr, unsigned short, unsigned short,
  114. unsigned int, unsigned int);
  115. static int init_planb(struct planb *);
  116. static int find_planb(void);
  117. static void planb_pre_capture(int, struct planb *);
  118. static dbdma_cmd_ptr cmd_geo_setup(dbdma_cmd_ptr, int, int, int, int, int,
  119. struct planb *);
  120. static inline void planb_dbdma_stop(dbdma_regs_ptr);
  121. static inline void planb_dbdma_restart(dbdma_regs_ptr);
  122. static void saa_geo_setup(int, int, int, int, struct planb *);
  123. static inline int overlay_is_active(struct planb *);
  124. /*******************************/
  125. /* Memory management functions */
  126. /*******************************/
  127. /* I know this is not the right way to allocate memory. Whoever knows
  128.  * the right way to allocate a huge buffer for DMA that can be mapped
  129.  * to user space, please tell me... or better, fix the code and send
  130.  * patches.
  131.  *
  132.  * Michel Lanners (mlan@cpu.lu)
  133.  */
  134. /* FIXME: As subsequent calls to __get_free_pages don't necessarily return
  135.  * contiguous pages, we need to do horrible things later on when setting
  136.  * up DMA, to make sure a single DMA transfer doesn't cross a page boundary.
  137.  * At least, I hope it's done right later on ;-) ......
  138.  * Anyway, there should be a way to get hold of a large buffer of contiguous
  139.  * pages for DMA....
  140.  */
  141. static int grabbuf_alloc(struct planb *pb)
  142. {
  143. int i, npage;
  144. npage = MAX_GBUFFERS * ((PLANB_MAX_FBUF / PAGE_SIZE + 1)
  145. #ifndef PLANB_GSCANLINE
  146. + MAX_LNUM
  147. #endif /* PLANB_GSCANLINE */
  148. );
  149. if ((pb->rawbuf = (unsigned char**) kmalloc (npage
  150. * sizeof(unsigned long), GFP_KERNEL)) == 0)
  151. return -ENOMEM;
  152. for (i = 0; i < npage; i++) {
  153. pb->rawbuf[i] = (unsigned char *)__get_free_pages(GFP_KERNEL |
  154. GFP_DMA, 0);
  155. if (!pb->rawbuf[i])
  156. break;
  157. mem_map_reserve(virt_to_page(pb->rawbuf[i]));
  158. }
  159. if (i-- < npage) {
  160. DBG("PlanB: init_grab: grab buffer not allocatedn");
  161. for (; i > 0; i--) {
  162. mem_map_unreserve(virt_to_page(pb->rawbuf[i]));
  163. free_pages((unsigned long)pb->rawbuf[i], 0);
  164. }
  165. kfree(pb->rawbuf);
  166. return -ENOBUFS;
  167. }
  168. pb->rawbuf_nchunks = npage;
  169. return 0;
  170. }
  171. /*****************************/
  172. /* Hardware access functions */
  173. /*****************************/
  174. static void saa_write_reg(unsigned char addr, unsigned char val)
  175. {
  176. planb_regs->saa_addr = addr; eieio();
  177. planb_regs->saa_regval = val; eieio();
  178. return;
  179. }
  180. /* return  status byte 0 or 1: */
  181. static unsigned char saa_status(int byte, struct planb *pb)
  182. {
  183. saa_regs[pb->win.norm][SAA7196_STDC] =
  184. (saa_regs[pb->win.norm][SAA7196_STDC] & ~2) | ((byte & 1) << 1);
  185. saa_write_reg (SAA7196_STDC, saa_regs[pb->win.norm][SAA7196_STDC]);
  186. /* Let's wait 30msec for this one */
  187. current->state = TASK_INTERRUPTIBLE;
  188. schedule_timeout(30 * HZ / 1000);
  189. return (unsigned char)in_8 (&planb_regs->saa_status);
  190. }
  191. static void saa_set(unsigned char addr, unsigned char val, struct planb *pb)
  192. {
  193. if(saa_regs[pb->win.norm][addr] != val) {
  194. saa_regs[pb->win.norm][addr] = val;
  195. saa_write_reg (addr, val);
  196. }
  197. return;
  198. }
  199. static void saa_init_regs(struct planb *pb)
  200. {
  201. int i;
  202. for (i = 0; i < SAA7196_NUMREGS; i++)
  203. saa_write_reg (i, saa_regs[pb->win.norm][i]);
  204. }
  205. static void saa_geo_setup(int width, int height, int interlace,
  206. int fmt, struct planb *pb)
  207. {
  208. int ht, norm = pb->win.norm;
  209. /* bits FS0, FS1 according to format spec */
  210. saa_regs[norm][SAA7196_FMTS] &= ~0x3;
  211. saa_regs[norm][SAA7196_FMTS] |= (palette2fmt[fmt].saa_fmt & 0x3);
  212. ht = (interlace ? height / 2 : height);
  213. saa_regs[norm][SAA7196_OUTPIX] = (unsigned char) (width & 0x00ff);
  214. saa_regs[norm][SAA7196_HFILT] = (saa_regs[norm][SAA7196_HFILT] & ~0x3)
  215. | (width >> 8 & 0x3);
  216. saa_regs[norm][SAA7196_OUTLINE] = (unsigned char) (ht & 0xff);
  217. saa_regs[norm][SAA7196_VYP] = (saa_regs[norm][SAA7196_VYP] & ~0x3)
  218. | (ht >> 8 & 0x3);
  219. /* feed both fields if interlaced, or else feed only even fields */
  220. saa_regs[norm][SAA7196_FMTS] = (interlace) ?
  221. (saa_regs[norm][SAA7196_FMTS] & ~0x60)
  222. : (saa_regs[norm][SAA7196_FMTS] | 0x60);
  223. /* transparent mode; extended format enabled */
  224. saa_regs[norm][SAA7196_DPATH] |= 0x3;
  225. /* bits LLV, MCT according to format spec */
  226. saa_regs[norm][SAA7196_DPATH] &= ~0x30;
  227. saa_regs[norm][SAA7196_DPATH] |= (palette2fmt[fmt].saa_fmt & 0x30);
  228. }
  229. /***************************/
  230. /* DBDMA support functions */
  231. /***************************/
  232. static inline void planb_dbdma_restart(dbdma_regs_ptr ch)
  233. {
  234. writel(PLANB_CLR(RUN), &ch->control);
  235. writel(PLANB_SET(RUN|WAKE) | PLANB_CLR(PAUSE), &ch->control);
  236. }
  237. static inline void planb_dbdma_stop(dbdma_regs_ptr ch)
  238. {
  239. int i = 0;
  240. writel(PLANB_CLR(RUN) | PLANB_SET(FLUSH), &ch->control);
  241. while((readl(&ch->status) == (ACTIVE | FLUSH)) && (i < 999)) {
  242. IDBG("PlanB: waiting for DMA to stopn");
  243. i++;
  244. }
  245. }
  246. static inline void tab_cmd_dbdma(dbdma_cmd_ptr ch, unsigned short command,
  247. unsigned int cmd_dep)
  248. {
  249. st_le16(&ch->command, command);
  250. st_le16(&ch->req_count, 0);
  251. st_le32(&ch->phy_addr, 0);
  252. st_le32(&ch->cmd_dep, cmd_dep);
  253. /* really clears res_count & xfer_status */
  254. st_le32((unsigned int *)&ch->res_count, 0);
  255. }
  256. static inline void tab_cmd_store(dbdma_cmd_ptr ch, unsigned int phy_addr,
  257. unsigned int cmd_dep)
  258. {
  259. st_le16(&ch->command, STORE_WORD | KEY_SYSTEM);
  260. st_le16(&ch->req_count, 4);
  261. st_le32(&ch->phy_addr, phy_addr);
  262. st_le32(&ch->cmd_dep, cmd_dep);
  263. st_le32((unsigned int *)&ch->res_count, 0);
  264. }
  265. static inline void tab_cmd_gen(dbdma_cmd_ptr ch, unsigned short command,
  266. unsigned short req_count, unsigned int phy_addr, unsigned int cmd_dep)
  267. {
  268. st_le16(&ch->command, command);
  269. st_le16(&ch->req_count, req_count);
  270. st_le32(&ch->phy_addr, phy_addr);
  271. st_le32(&ch->cmd_dep, cmd_dep);
  272. st_le32((unsigned int *)&ch->res_count, 0);
  273. }
  274. static dbdma_cmd_ptr cmd_geo_setup(dbdma_cmd_ptr c1, int width, int height,
  275. int interlace, int fmt, int clip, struct planb *pb)
  276. {
  277. int norm = pb->win.norm;
  278. saa_geo_setup(width, height, interlace, fmt, pb);
  279. /* if the number of DBDMA commands here (14) changes, lots of
  280.  * things need to be corrected accordingly... */
  281. tab_cmd_store(c1++, (unsigned)(&pb->planb_base_bus->saa_addr),
  282. SAA7196_FMTS);
  283. tab_cmd_store(c1++, (unsigned)(&pb->planb_base_bus->saa_regval),
  284. saa_regs[norm][SAA7196_FMTS]);
  285. tab_cmd_store(c1++, (unsigned)(&pb->planb_base_bus->saa_addr),
  286. SAA7196_DPATH);
  287. tab_cmd_store(c1++, (unsigned)(&pb->planb_base_bus->saa_regval),
  288. saa_regs[norm][SAA7196_DPATH]);
  289. tab_cmd_store(c1++, (unsigned)(&pb->planb_base_bus->even),
  290. palette2fmt[fmt].pb_fmt | ((clip)? PLANB_CLIPMASK: 0));
  291. tab_cmd_store(c1++, (unsigned)(&pb->planb_base_bus->odd),
  292. palette2fmt[fmt].pb_fmt | ((clip)? PLANB_CLIPMASK: 0));
  293. tab_cmd_store(c1++, (unsigned)(&pb->planb_base_bus->saa_addr),
  294. SAA7196_OUTPIX);
  295. tab_cmd_store(c1++, (unsigned)(&pb->planb_base_bus->saa_regval),
  296. saa_regs[norm][SAA7196_OUTPIX]);
  297. tab_cmd_store(c1++, (unsigned)(&pb->planb_base_bus->saa_addr),
  298. SAA7196_HFILT);
  299. tab_cmd_store(c1++, (unsigned)(&pb->planb_base_bus->saa_regval),
  300. saa_regs[norm][SAA7196_HFILT]);
  301. tab_cmd_store(c1++, (unsigned)(&pb->planb_base_bus->saa_addr),
  302. SAA7196_OUTLINE);
  303. tab_cmd_store(c1++, (unsigned)(&pb->planb_base_bus->saa_regval),
  304. saa_regs[norm][SAA7196_OUTLINE]);
  305. tab_cmd_store(c1++, (unsigned)(&pb->planb_base_bus->saa_addr),
  306. SAA7196_VYP);
  307. tab_cmd_store(c1++, (unsigned)(&pb->planb_base_bus->saa_regval),
  308. saa_regs[norm][SAA7196_VYP]);
  309. return c1;
  310. }
  311. /******************************/
  312. /* misc. supporting functions */
  313. /******************************/
  314. static inline void planb_lock(struct planb *pb)
  315. {
  316. DBG("PlanB: planb_lockn");
  317. down(&pb->lock);
  318. }
  319. static inline void planb_unlock(struct planb *pb)
  320. {
  321. DBG("PlanB: planb_unlockn");
  322. up(&pb->lock);
  323. }
  324. /***************/
  325. /* Driver Core */
  326. /***************/
  327. /* number of entries in the circular DBDMA command buffer
  328.  * initial stop, odd/even vbi, odd/even video, branch back */
  329. #define NUMJUMPS 6
  330. static int planb_prepare_open(struct planb *pb)
  331. {
  332. dbdma_cmd_ptr c;
  333. int size, i;
  334. size = (NUMJUMPS + 1) * sizeof(struct dbdma_cmd);
  335. if((pb->jump_raw = kmalloc (size, GFP_KERNEL|GFP_DMA)) == 0)
  336. return -ENOMEM;
  337. memset(pb->jump_raw, 0, size);
  338. c = pb->jumpbuf = (dbdma_cmd_ptr) DBDMA_ALIGN (pb->jump_raw);
  339. /* circular DBDMA command buffer, to hold jumps to transfer commands */
  340. tab_cmd_dbdma(c++, DBDMA_STOP, 0);
  341. for (i=1; i<NUMJUMPS-1; i++)
  342. tab_cmd_dbdma(c++, DBDMA_NOP, 0);
  343. tab_cmd_dbdma(c, DBDMA_NOP|BR_ALWAYS,
  344. (unsigned int)pb->jumpbuf);
  345. DBG("PlanB: planb_prepare_open, jumpbuffer at 0x%08x, length %d.n",
  346. (unsigned int)pb->jumpbuf, size); 
  347. return 0;
  348. }
  349. #define VBIDUMMY 40 /* must be even !! */
  350. static int planb_prepare_vbi(struct planb *pb)
  351. {
  352. int size;
  353. /* allocate VBI comand buffer memory
  354.    (2 fields * VBI_MAXLINES + 40 handling + alignment) */
  355. size = (2*VBI_MAXLINES + VBIDUMMY + 1) * sizeof(struct dbdma_cmd);
  356. if ((pb->vbi_raw = kmalloc (size, GFP_KERNEL|GFP_DMA)) == 0)
  357. return -ENOMEM;
  358. memset (pb->vbi_raw, 0, size);
  359. size = (VBI_MAXLINES + VBIDUMMY/2) * sizeof(struct dbdma_cmd);
  360. pb->vbi_cbo.start = (dbdma_cmd_ptr) DBDMA_ALIGN (pb->vbi_raw);
  361. pb->vbi_cbo.size = pb->vbi_cbe.size = size;
  362. pb->vbi_cbe.start = pb->vbi_cbo.start + pb->vbi_cbo.size;
  363. pb->vbi_cbo.jumpaddr = pb->jumpbuf + 1;
  364. pb->vbi_cbe.jumpaddr = pb->jumpbuf + 3;
  365. DBG("PlanB: planb_prepare_vbi, dbdma cmd_buf at 0x%08x, length %d.n",
  366. (unsigned int)pb->vbi_cbo.start, 2*size); 
  367. return 0;
  368. }
  369. static int planb_prepare_video(struct planb *pb)
  370. {
  371. int i, size;
  372. /* FIXME: This is stressing kmalloc to its limits...
  373.   We really should allocate smaller chunks. */
  374. /* allocate memory for two plus alpha command buffers (size: max lines,
  375.    plus 40 commands handling, plus 1 alignment), plus dummy command buf,
  376.    plus clipmask buffer, plus frame grabbing status */
  377. size = (pb->tab_size * (2 + MAX_GBUFFERS * TAB_FACTOR)
  378.     + MAX_GBUFFERS * PLANB_DUMMY + 1) * sizeof(struct dbdma_cmd)
  379. + (PLANB_MAXLINES * ((PLANB_MAXPIXELS + 7) & ~7)) / 8
  380. + MAX_GBUFFERS * sizeof(unsigned int);
  381. if ((pb->vid_raw = kmalloc (size, GFP_KERNEL|GFP_DMA)) == 0)
  382. return -ENOMEM;
  383. memset (pb->vid_raw, 0, size);
  384. pb->vid_cbo.start = (dbdma_cmd_ptr) DBDMA_ALIGN (pb->vid_raw);
  385. pb->vid_cbo.size = pb->vid_cbe.size = pb->tab_size/2;
  386. pb->vid_cbe.start = pb->vid_cbo.start + pb->vid_cbo.size;
  387. pb->vid_cbo.jumpaddr = pb->jumpbuf + 2;
  388. pb->vid_cbe.jumpaddr = pb->jumpbuf + 4;
  389. pb->overlay_last1 = pb->vid_cbo.start;
  390. pb->vid_cbo.bus = virt_to_bus(pb->vid_cbo.start);
  391. pb->vid_cbe.bus = virt_to_bus(pb->vid_cbe.start);
  392. pb->clip_cbo.start = pb->vid_cbe.start + pb->vid_cbe.size;
  393. pb->clip_cbo.size = pb->clip_cbe.size = pb->tab_size/2;
  394. pb->clip_cbe.start = pb->clip_cbo.start + pb->clip_cbo.size;
  395. pb->overlay_last2 = pb->clip_cbo.start;
  396. pb->clip_cbo.bus = virt_to_bus(pb->clip_cbo.start);
  397. pb->clip_cbe.bus = virt_to_bus(pb->clip_cbe.start);
  398. pb->gbuf[0].cap_cmd = pb->clip_cbe.start + pb->clip_cbe.size;
  399. pb->gbuf[0].pre_cmd = pb->gbuf[0].cap_cmd + pb->tab_size * TAB_FACTOR;
  400. for (i = 1; i < MAX_GBUFFERS; i++) {
  401. pb->gbuf[i].cap_cmd = pb->gbuf[i-1].pre_cmd + PLANB_DUMMY;
  402. pb->gbuf[i].pre_cmd = pb->gbuf[i].cap_cmd +
  403. pb->tab_size * TAB_FACTOR;
  404. }
  405. pb->gbuf[0].status = (volatile unsigned int *)
  406. (pb->gbuf[MAX_GBUFFERS-1].pre_cmd + PLANB_DUMMY);
  407. for (i = 1; i < MAX_GBUFFERS; i++)
  408. pb->gbuf[i].status = pb->gbuf[i-1].status;
  409. pb->mask = (unsigned char *)(pb->gbuf[MAX_GBUFFERS-1].status + 1);
  410. pb->rawbuf = NULL;
  411. pb->rawbuf_nchunks = 0;
  412. pb->grabbing = 0;
  413. for (i = 0; i < MAX_GBUFFERS; i++) {
  414. gbuf_ptr gbuf = &pb->gbuf[i];
  415. *gbuf->status = GBUFFER_UNUSED;
  416. gbuf->width = 0;
  417. gbuf->height = 0;
  418. gbuf->fmt = 0;
  419. gbuf->norm_switch = 0;
  420. #ifndef PLANB_GSCANLINE
  421. gbuf->lsize = 0;
  422. gbuf->lnum = 0;
  423. #endif
  424. }
  425. pb->gcount = 0;
  426. pb->suspend = 0;
  427. pb->last_fr = -999;
  428. pb->prev_last_fr = -999;
  429. /* Reset DMA controllers */
  430. planb_dbdma_stop(&pb->planb_base->ch2);
  431. planb_dbdma_stop(&pb->planb_base->ch1);
  432. DBG("PlanB: planb_prepare_video, dbdma cmd_buf at 0x%08x, "
  433. "length %d.n", (unsigned int)pb->vid_cbo.start, 2*size);
  434. return 0;
  435. }
  436. static void planb_prepare_close(struct planb *pb)
  437. {
  438. /* make sure the dma's are idle */
  439. planb_dbdma_stop(&pb->planb_base->ch2);
  440. planb_dbdma_stop(&pb->planb_base->ch1);
  441. if(pb->jump_raw != 0) {
  442. kfree(pb->jump_raw);
  443. pb->jump_raw = 0;
  444. }
  445. return;
  446. }
  447. static void planb_close_vbi(struct planb *pb)
  448. {
  449. /* FIXME: stop running DMA */
  450. /* Make sure the DMA controller doesn't jump here anymore */
  451. tab_cmd_dbdma(pb->vbi_cbo.jumpaddr, DBDMA_NOP, 0);
  452. tab_cmd_dbdma(pb->vbi_cbe.jumpaddr, DBDMA_NOP, 0);
  453. if(pb->vbi_raw != 0) {
  454. kfree (pb->vbi_raw);
  455. pb->vbi_raw = 0;
  456. }
  457. /* FIXME: deallocate VBI data buffer */
  458. /* FIXME: restart running DMA if app. */
  459. return;
  460. }
  461. static void planb_close_video(struct planb *pb)
  462. {
  463. int i;
  464. /* FIXME: stop running DMA */
  465. /* Make sure the DMA controller doesn't jump here anymore */
  466. tab_cmd_dbdma(pb->vid_cbo.jumpaddr, DBDMA_NOP, 0);
  467. tab_cmd_dbdma(pb->vid_cbe.jumpaddr, DBDMA_NOP, 0);
  468. /* No clipmask jumpbuffer yet  */
  469. #if 0
  470. tab_cmd_dbdma(pb->clip_cbo.jumpaddr, DBDMA_NOP, 0);
  471. tab_cmd_dbdma(pb->clip_cbe.jumpaddr, DBDMA_NOP, 0);
  472. #endif
  473. if(pb->vid_raw != 0) {
  474. kfree (pb->vid_raw);
  475. pb->vid_raw = 0;
  476. pb->cmd_buff_inited = 0;
  477. }
  478. if(pb->rawbuf) {
  479. for (i = 0; i < pb->rawbuf_nchunks; i++) {
  480. mem_map_unreserve(virt_to_page(pb->rawbuf[i]));
  481. free_pages((unsigned long)pb->rawbuf[i], 0);
  482. }
  483. kfree(pb->rawbuf);
  484. }
  485. pb->rawbuf = NULL;
  486. /* FIXME: restart running DMA if app. */
  487. return;
  488. }
  489. /*****************************/
  490. /* overlay support functions */
  491. /*****************************/
  492. static void overlay_start(struct planb *pb)
  493. {
  494. DBG("PlanB: overlay_start()n");
  495. if(ACTIVE & readl(&pb->planb_base->ch1.status)) {
  496. DBG("PlanB: presumably, grabbing is in progress...n");
  497. planb_dbdma_stop(&pb->planb_base->ch2);
  498. writel(pb->clip_cbo.bus, &pb->planb_base->ch2.cmdptr);
  499. planb_dbdma_restart(&pb->planb_base->ch2);
  500. st_le16 (&pb->vid_cbo.start->command, DBDMA_NOP);
  501. tab_cmd_dbdma(pb->gbuf[pb->last_fr].last_cmd,
  502. DBDMA_NOP | BR_ALWAYS, pb->vid_cbo.bus);
  503. eieio();
  504. pb->prev_last_fr = pb->last_fr;
  505. pb->last_fr = -2;
  506. if(!(ACTIVE & readl(&pb->planb_base->ch1.status))) {
  507. IDBG("PlanB: became inactive "
  508. "in the mean time... reactivatingn");
  509. planb_dbdma_stop(&pb->planb_base->ch1);
  510. writel(pb->vid_cbo.bus, &pb->planb_base->ch1.cmdptr);
  511. planb_dbdma_restart(&pb->planb_base->ch1);
  512. }
  513. } else {
  514. DBG("PlanB: currently idle, so can do whatevern");
  515. planb_dbdma_stop(&pb->planb_base->ch2);
  516. planb_dbdma_stop(&pb->planb_base->ch1);
  517. st_le32(&pb->planb_base->ch2.cmdptr, pb->clip_cbo.bus);
  518. st_le32(&pb->planb_base->ch1.cmdptr, pb->vid_cbo.bus);
  519. writew(DBDMA_NOP, &pb->vid_cbo.start->command);
  520. planb_dbdma_restart(&pb->planb_base->ch2);
  521. planb_dbdma_restart(&pb->planb_base->ch1);
  522. pb->last_fr = -1;
  523. }
  524. return;
  525. }
  526. static void overlay_stop(struct planb *pb)
  527. {
  528. DBG("PlanB: overlay_stop()n");
  529. if(pb->last_fr == -1) {
  530. DBG("PlanB: no grabbing, it seems...n");
  531. planb_dbdma_stop(&pb->planb_base->ch2);
  532. planb_dbdma_stop(&pb->planb_base->ch1);
  533. pb->last_fr = -999;
  534. } else if(pb->last_fr == -2) {
  535. unsigned int cmd_dep;
  536. tab_cmd_dbdma(pb->gbuf[pb->prev_last_fr].cap_cmd, DBDMA_STOP, 0);
  537. eieio();
  538. cmd_dep = (unsigned int)readl(&pb->overlay_last1->cmd_dep);
  539. if(overlay_is_active(pb)) {
  540. DBG("PlanB: overlay is currently activen");
  541. planb_dbdma_stop(&pb->planb_base->ch2);
  542. planb_dbdma_stop(&pb->planb_base->ch1);
  543. if(cmd_dep != pb->vid_cbo.bus) {
  544. writel(virt_to_bus(pb->overlay_last1),
  545. &pb->planb_base->ch1.cmdptr);
  546. planb_dbdma_restart(&pb->planb_base->ch1);
  547. }
  548. }
  549. pb->last_fr = pb->prev_last_fr;
  550. pb->prev_last_fr = -999;
  551. }
  552. return;
  553. }
  554. static void suspend_overlay(struct planb *pb)
  555. {
  556. int fr = -1;
  557. struct dbdma_cmd last;
  558. DBG("PlanB: suspend_overlay: %dn", pb->suspend);
  559. if(pb->suspend++)
  560. return;
  561. if(ACTIVE & readl(&pb->planb_base->ch1.status)) {
  562. if(pb->last_fr == -2) {
  563. fr = pb->prev_last_fr;
  564. memcpy(&last, (void*)pb->gbuf[fr].last_cmd, sizeof(last));
  565. tab_cmd_dbdma(pb->gbuf[fr].last_cmd, DBDMA_STOP, 0);
  566. }
  567. if(overlay_is_active(pb)) {
  568. planb_dbdma_stop(&pb->planb_base->ch2);
  569. planb_dbdma_stop(&pb->planb_base->ch1);
  570. pb->suspended.overlay = 1;
  571. pb->suspended.frame = fr;
  572. memcpy(&pb->suspended.cmd, &last, sizeof(last));
  573. return;
  574. }
  575. }
  576. pb->suspended.overlay = 0;
  577. pb->suspended.frame = fr;
  578. memcpy(&pb->suspended.cmd, &last, sizeof(last));
  579. return;
  580. }
  581. static void resume_overlay(struct planb *pb)
  582. {
  583. DBG("PlanB: resume_overlay: %dn", pb->suspend);
  584. if(pb->suspend > 1)
  585. return;
  586. if(pb->suspended.frame != -1) {
  587. memcpy((void*)pb->gbuf[pb->suspended.frame].last_cmd,
  588. &pb->suspended.cmd, sizeof(pb->suspended.cmd));
  589. }
  590. if(ACTIVE & readl(&pb->planb_base->ch1.status)) {
  591. goto finish;
  592. }
  593. if(pb->suspended.overlay) {
  594. DBG("PlanB: overlay being resumedn");
  595. st_le16 (&pb->vid_cbo.start->command, DBDMA_NOP);
  596. st_le16 (&pb->clip_cbo.start->command, DBDMA_NOP);
  597. /* Set command buffer addresses */
  598. writel(virt_to_bus(pb->overlay_last1),
  599. &pb->planb_base->ch1.cmdptr);
  600. writel(virt_to_bus(pb->overlay_last2),
  601. &pb->planb_base->ch2.cmdptr);
  602. /* Start the DMA controller */
  603. writel(PLANB_CLR(PAUSE) | PLANB_SET(RUN|WAKE),
  604. &pb->planb_base->ch2.control);
  605. writel(PLANB_CLR(PAUSE) | PLANB_SET(RUN|WAKE),
  606. &pb->planb_base->ch1.control);
  607. } else if(pb->suspended.frame != -1) {
  608. writel(virt_to_bus(pb->gbuf[pb->suspended.frame].last_cmd),
  609. &pb->planb_base->ch1.cmdptr);
  610. writel(PLANB_CLR(PAUSE) | PLANB_SET(RUN|WAKE),
  611. &pb->planb_base->ch1.control);
  612. }
  613. finish:
  614. pb->suspend--;
  615. wake_up_interruptible(&pb->suspendq);
  616. }
  617. static void add_clip(struct planb *pb, struct video_clip *clip) 
  618. {
  619. volatile unsigned char *base;
  620. int xc = clip->x, yc = clip->y;
  621. int wc = clip->width, hc = clip->height;
  622. int ww = pb->win.width, hw = pb->win.height;
  623. int x, y, xtmp1, xtmp2;
  624. DBG("PlanB: clip %dx%d+%d+%dn", wc, hc, xc, yc);
  625. if(xc < 0) {
  626. wc += xc;
  627. xc = 0;
  628. }
  629. if(yc < 0) {
  630. hc += yc;
  631. yc = 0;
  632. }
  633. if(xc + wc > ww)
  634. wc = ww - xc;
  635. if(wc <= 0) /* Nothing to do */
  636. return;
  637. if(yc + hc > hw)
  638. hc = hw - yc;
  639. for (y = yc; y < yc+hc; y++) {
  640. xtmp1=xc>>3;
  641. xtmp2=(xc+wc)>>3;
  642. base = pb->mask + y*96;
  643. if(xc != 0 || wc >= 8)
  644. *(base + xtmp1) &= (unsigned char)(0x00ff &
  645. (0xff00 >> (xc&7)));
  646. for (x = xtmp1 + 1; x < xtmp2; x++) {
  647. *(base + x) = 0;
  648. }
  649. if(xc < (ww & ~0x7))
  650. *(base + xtmp2) &= (unsigned char)(0x00ff >>
  651. ((xc+wc) & 7));
  652. }
  653. return;
  654. }
  655. static void fill_cmd_buff(struct planb *pb)
  656. {
  657. int restore = 0;
  658. dbdma_cmd_t last;
  659. DBG("PlanB: fill_cmd_buff()n");
  660. if(pb->overlay_last1 != pb->vid_cbo.start) {
  661. restore = 1;
  662. last = *(pb->overlay_last1);
  663. }
  664. memset ((void *) pb->vid_cbo.start, 0, 2 * pb->tab_size
  665. * sizeof(struct dbdma_cmd));
  666. cmd_buff (pb);
  667. if(restore)
  668. *(pb->overlay_last1) = last;
  669. if(pb->suspended.overlay) {
  670. unsigned long jump_addr = readl(&pb->overlay_last1->cmd_dep);
  671. if(jump_addr != pb->vid_cbo.bus) {
  672. int i;
  673. DBG("PlanB: adjusting ch1's jump addressn");
  674. for(i = 0; i < MAX_GBUFFERS; i++) {
  675. if(pb->gbuf[i].need_pre_capture) {
  676.     if(jump_addr == virt_to_bus(pb->gbuf[i].pre_cmd))
  677. goto found;
  678. } else {
  679.     if(jump_addr ==
  680.     virt_to_bus(pb->gbuf[i].cap_cmd))
  681. goto found;
  682. }
  683. }
  684. DBG("       not found!n");
  685. goto out;
  686. found:
  687. if(pb->gbuf[i].need_pre_capture)
  688. writel(virt_to_bus(pb->overlay_last1),
  689. &pb->gbuf[i].pre_cmd->phy_addr);
  690. else
  691. writel(virt_to_bus(pb->overlay_last1),
  692. &pb->gbuf[i].cap_cmd->phy_addr);
  693. }
  694. }
  695. out:
  696. pb->cmd_buff_inited = 1;
  697. return;
  698. }
  699. static void cmd_buff(struct planb *pb)
  700. {
  701. int i, bpp, count, nlines, stepsize, interlace;
  702. unsigned long base, jump, addr_com, addr_dep;
  703. dbdma_cmd_ptr c1 = pb->vid_cbo.start;
  704. dbdma_cmd_ptr c2 = pb->clip_cbo.start;
  705. interlace = pb->win.interlace;
  706. bpp = pb->win.bpp;
  707. count = (bpp * ((pb->win.x + pb->win.width > pb->win.swidth) ?
  708. (pb->win.swidth - pb->win.x) : pb->win.width));
  709. nlines = ((pb->win.y + pb->win.height > pb->win.sheight) ?
  710. (pb->win.sheight - pb->win.y) : pb->win.height);
  711. /* Do video in: */
  712. /* Preamble commands: */
  713. addr_com = virt_to_bus(c1);
  714. addr_dep = virt_to_bus(&c1->cmd_dep);
  715. tab_cmd_dbdma(c1++, DBDMA_NOP, 0);
  716. jump = virt_to_bus(c1+16); /* 14 by cmd_geo_setup() and 2 for padding */
  717. c1 = cmd_geo_setup(c1, pb->win.width, pb->win.height, interlace,
  718. pb->win.color_fmt, 1, pb);
  719. tab_cmd_store(c1++, addr_com, (unsigned)(DBDMA_NOP | BR_ALWAYS) << 16);
  720. tab_cmd_store(c1++, addr_dep, jump);
  721. tab_cmd_store(c1++, (unsigned)(&pb->planb_base_bus->ch1.wait_sel),
  722. PLANB_SET(FIELD_SYNC));
  723. /* (1) wait for field sync to be set */
  724. tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFCLR, 0);
  725. tab_cmd_store(c1++, (unsigned)(&pb->planb_base_bus->ch1.br_sel),
  726. PLANB_SET(ODD_FIELD));
  727. /* wait for field sync to be cleared */
  728. tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFSET, 0);
  729. /* if not odd field, wait until field sync is set again */
  730. tab_cmd_dbdma(c1, DBDMA_NOP | BR_IFSET, virt_to_bus(c1-3)); c1++;
  731. /* assert ch_sync to ch2 */
  732. tab_cmd_store(c1++, (unsigned)(&pb->planb_base_bus->ch2.control),
  733. PLANB_SET(CH_SYNC));
  734. tab_cmd_store(c1++, (unsigned)(&pb->planb_base_bus->ch1.br_sel),
  735. PLANB_SET(DMA_ABORT));
  736. base = (pb->fb.phys + pb->fb.offset + pb->win.y * (pb->win.bpl +
  737. pb->win.pad) + pb->win.x * bpp);
  738. if (interlace) {
  739. stepsize = 2;
  740. jump = virt_to_bus(c1 + (nlines + 1) / 2);
  741. } else {
  742. stepsize = 1;
  743. jump = virt_to_bus(c1 + nlines);
  744. }
  745. /* even field data: */
  746. for (i=0; i < nlines; i += stepsize, c1++)
  747. tab_cmd_gen(c1, INPUT_MORE | KEY_STREAM0 | BR_IFSET,
  748. count, base + i * (pb->win.bpl + pb->win.pad), jump);
  749. /* For non-interlaced, we use even fields only */
  750. if (!interlace)
  751. goto cmd_tab_data_end;
  752. /* Resync to odd field */
  753. /* (2) wait for field sync to be set */
  754. tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFCLR, 0);
  755. tab_cmd_store(c1++, (unsigned)(&pb->planb_base_bus->ch1.br_sel),
  756. PLANB_SET(ODD_FIELD));
  757. /* wait for field sync to be cleared */
  758. tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFSET, 0);
  759. /* if not odd field, wait until field sync is set again */
  760. tab_cmd_dbdma(c1, DBDMA_NOP | BR_IFCLR, virt_to_bus(c1-3)); c1++;
  761. /* assert ch_sync to ch2 */
  762. tab_cmd_store(c1++, (unsigned)(&pb->planb_base_bus->ch2.control),
  763. PLANB_SET(CH_SYNC));
  764. tab_cmd_store(c1++, (unsigned)(&pb->planb_base_bus->ch1.br_sel),
  765. PLANB_SET(DMA_ABORT));
  766. /* odd field data: */
  767. jump = virt_to_bus(c1 + nlines / 2);
  768. for (i=1; i < nlines; i += stepsize, c1++)
  769. tab_cmd_gen(c1, INPUT_MORE | KEY_STREAM0 | BR_IFSET, count,
  770. base + i * (pb->win.bpl + pb->win.pad), jump);
  771. /* And jump back to the start */
  772. cmd_tab_data_end:
  773. pb->overlay_last1 = c1; /* keep a pointer to the last command */
  774. tab_cmd_dbdma(c1, DBDMA_NOP | BR_ALWAYS, pb->vid_cbo.bus);
  775. /* Clipmask command buffer */
  776. /* Preamble commands: */
  777. tab_cmd_dbdma(c2++, DBDMA_NOP, 0);
  778. tab_cmd_store(c2++, (unsigned)(&pb->planb_base_bus->ch2.wait_sel),
  779. PLANB_SET(CH_SYNC));
  780. /* wait until ch1 asserts ch_sync */
  781. tab_cmd_dbdma(c2++, DBDMA_NOP | WAIT_IFCLR, 0);
  782. /* clear ch_sync asserted by ch1 */
  783. tab_cmd_store(c2++, (unsigned)(&pb->planb_base_bus->ch2.control),
  784. PLANB_CLR(CH_SYNC));
  785. tab_cmd_store(c2++, (unsigned)(&pb->planb_base_bus->ch2.wait_sel),
  786. PLANB_SET(FIELD_SYNC));
  787. tab_cmd_store(c2++, (unsigned)(&pb->planb_base_bus->ch2.br_sel),
  788. PLANB_SET(ODD_FIELD));
  789. /* jump to end of even field if appropriate */
  790. /* this points to (interlace)? pos. C: pos. B */
  791. jump = (interlace) ? virt_to_bus(c2 + (nlines + 1) / 2 + 2):
  792. virt_to_bus(c2 + nlines + 2);
  793. /* if odd field, skip over to odd field clipmasking */
  794. tab_cmd_dbdma(c2++, DBDMA_NOP | BR_IFSET, jump);
  795. /* even field mask: */
  796. tab_cmd_store(c2++, (unsigned)(&pb->planb_base_bus->ch2.br_sel),
  797. PLANB_SET(DMA_ABORT));
  798. /* this points to pos. B */
  799. jump = (interlace) ? virt_to_bus(c2 + nlines + 1):
  800. virt_to_bus(c2 + nlines);
  801. base = virt_to_bus(pb->mask);
  802. for (i=0; i < nlines; i += stepsize, c2++)
  803. tab_cmd_gen(c2, OUTPUT_MORE | KEY_STREAM0 | BR_IFSET, 96,
  804. base + i * 96, jump);
  805. /* For non-interlaced, we use only even fields */
  806. if(!interlace)
  807. goto cmd_tab_mask_end;
  808. /* odd field mask: */
  809. /* C */ tab_cmd_store(c2++, (unsigned)(&pb->planb_base_bus->ch2.br_sel),
  810. PLANB_SET(DMA_ABORT));
  811. /* this points to pos. B */
  812. jump = virt_to_bus(c2 + nlines / 2);
  813. base = virt_to_bus(pb->mask);
  814. for (i=1; i < nlines; i += 2, c2++)     /* abort if set */
  815. tab_cmd_gen(c2, OUTPUT_MORE | KEY_STREAM0 | BR_IFSET, 96,
  816. base + i * 96, jump);
  817. /* Inform channel 1 and jump back to start */
  818. cmd_tab_mask_end:
  819. /* ok, I just realized this is kind of flawed. */
  820. /* this part is reached only after odd field clipmasking. */
  821. /* wanna clean up? */
  822. /* wait for field sync to be set */
  823. /* corresponds to fsync (1) of ch1 */
  824. /* B */ tab_cmd_dbdma(c2++, DBDMA_NOP | WAIT_IFCLR, 0);
  825. /* restart ch1, meant to clear any dead bit or something */
  826. tab_cmd_store(c2++, (unsigned)(&pb->planb_base_bus->ch1.control),
  827. PLANB_CLR(RUN));
  828. tab_cmd_store(c2++, (unsigned)(&pb->planb_base_bus->ch1.control),
  829. PLANB_SET(RUN));
  830. pb->overlay_last2 = c2; /* keep a pointer to the last command */
  831. /* start over even field clipmasking */
  832. tab_cmd_dbdma(c2, DBDMA_NOP | BR_ALWAYS, pb->clip_cbo.bus);
  833. eieio();
  834. return;
  835. }
  836. /*********************************/
  837. /* grabdisplay support functions */
  838. /*********************************/
  839. static inline int overlay_is_active(struct planb *pb)
  840. {
  841. unsigned int size = pb->tab_size * sizeof(struct dbdma_cmd);
  842. unsigned int caddr = (unsigned)readl(&pb->planb_base->ch1.cmdptr);
  843. return (readl(&pb->overlay_last1->cmd_dep) == pb->vid_cbo.bus)
  844. && (caddr < (pb->vid_cbo.bus + size))
  845. && (caddr >= (unsigned)pb->vid_cbo.bus);
  846. }
  847. static int vgrab(struct planb *pb, struct video_mmap *mp)
  848. {
  849. unsigned int fr = mp->frame;
  850. unsigned int fmt = mp->format;
  851. unsigned int bpp = palette2fmt[fmt].bpp;
  852. gbuf_ptr gbuf = &pb->gbuf[fr];
  853. if(pb->rawbuf==NULL) {
  854. int err;
  855. if((err=grabbuf_alloc(pb)))
  856. return err;
  857. }
  858. DBG("PlanB: grab %d: %dx%d fmt %d (%u)n", pb->grabbing, mp->width,
  859. mp->height, fmt, fr);
  860. if(pb->grabbing >= MAX_GBUFFERS) {
  861. DBG("       no buffern");
  862. return -ENOBUFS;
  863. }
  864. if(fr > (MAX_GBUFFERS - 1) || fr < 0) {
  865. DBG("       invalid buffern");
  866. return -EINVAL;
  867. }
  868. if(mp->height <= 0 || mp->width <= 0) {
  869. DBG("       negative height or widthn");
  870. return -EINVAL;
  871. }
  872. if(mp->format < 0 || mp->format >= PLANB_PALETTE_MAX) {
  873. DBG("       format out of rangen");
  874. return -EINVAL;
  875. }
  876. if(bpp == 0) {
  877. DBG("       unsupported format %dn", mp->format);
  878. return -EINVAL;
  879. }
  880. if (mp->height * mp->width * bpp > PLANB_MAX_FBUF) {
  881. DBG("       grab bigger than buffern");
  882. return -EINVAL;
  883. }
  884. planb_lock(pb);
  885. if(mp->width != gbuf->width || mp->height != gbuf->height ||
  886. fmt != gbuf->fmt || (gbuf->norm_switch)) {
  887. int i;
  888. #ifndef PLANB_GSCANLINE
  889. unsigned int osize = gbuf->width * gbuf->height *
  890. palette2fmt[gbuf->fmt].bpp;
  891. unsigned int nsize = mp->width * mp->height * bpp;
  892. #endif
  893. DBG("PlanB: changed gwidth = %d, gheight = %d, format = %u, "
  894. "osize = %d, nsize = %dn", mp->width, mp->height, fmt,
  895. osize, nsize);
  896. /* Do we _really_ need to clear the grab buffers?? */
  897. #if 0
  898. #ifndef PLANB_GSCANLINE
  899. if(gbuf->norm_switch)
  900. nsize = 0;
  901. if (nsize < osize) {
  902. for(i = gbuf->idx; osize > 0; i++) {
  903. memset((void *)pb->rawbuf[i], 0, PAGE_SIZE);
  904. osize -= PAGE_SIZE;
  905. }
  906. }
  907. for(i = gbuf->l_fr_addr_idx; i <
  908. gbuf->l_fr_addr_idx + gbuf->lnum; i++)
  909. memset((void *)pb->rawbuf[i], 0, PAGE_SIZE);
  910. #else
  911. /* XXX TODO */
  912. /*
  913. if(gbuf->norm_switch)
  914. memset((void *)pb->gbuffer[fr], 0,
  915. pb->gbytes_per_line * gbuf->height);
  916. else {
  917. if(mp->
  918. for(i = 0; i < gbuf->height; i++) {
  919. memset((void *)(pb->gbuffer[fr]
  920. + pb->gbytes_per_line * i
  921. }
  922. }
  923. */
  924. #endif
  925. #endif /* if 0 */
  926. gbuf->width = mp->width;
  927. gbuf->height = mp->height;
  928. gbuf->fmt = fmt;
  929. gbuf->last_cmd = setup_grab_cmd(fr, pb);
  930. planb_pre_capture(fr, pb);
  931. gbuf->need_pre_capture = 1;
  932. gbuf->norm_switch = 0;
  933. } else
  934. gbuf->need_pre_capture = 0;
  935. *gbuf->status = GBUFFER_GRABBING;
  936. if(!(ACTIVE & readl(&pb->planb_base->ch1.status))) {
  937. IDBG("PlanB: ch1 inactive, initiating grabbingn");
  938. planb_dbdma_stop(&pb->planb_base->ch1);
  939. if(gbuf->need_pre_capture) {
  940. DBG("PlanB: padding pre-capture sequencen");
  941. writel(virt_to_bus(gbuf->pre_cmd),
  942. &pb->planb_base->ch1.cmdptr);
  943. } else {
  944. tab_cmd_dbdma(gbuf->last_cmd, DBDMA_STOP, 0);
  945. tab_cmd_dbdma(gbuf->cap_cmd, DBDMA_NOP, 0);
  946. /* let's be on the safe side. here is not timing critical. */
  947. tab_cmd_dbdma((gbuf->cap_cmd + 1), DBDMA_NOP, 0);
  948. writel(virt_to_bus(gbuf->cap_cmd),
  949. &pb->planb_base->ch1.cmdptr);
  950. }
  951. planb_dbdma_restart(&pb->planb_base->ch1);
  952. pb->last_fr = fr;
  953. } else {
  954. int i;
  955. DBG("PlanB: ch1 active, grabbing being queuedn");
  956. if((pb->last_fr == -1) || ((pb->last_fr == -2) &&
  957. overlay_is_active(pb))) {
  958. DBG("PlanB: overlay is active, grabbing deferedn");
  959. tab_cmd_dbdma(gbuf->last_cmd, DBDMA_NOP | BR_ALWAYS,
  960. pb->vid_cbo.bus);
  961. if(gbuf->need_pre_capture) {
  962. DBG("PlanB: padding pre-capture sequencen");
  963. tab_cmd_store(gbuf->pre_cmd,
  964.     virt_to_bus(&pb->overlay_last1->cmd_dep),
  965.     pb->vid_cbo.bus);
  966. eieio();
  967. writel(virt_to_bus(gbuf->pre_cmd),
  968. &pb->overlay_last1->cmd_dep);
  969. } else {
  970. tab_cmd_store(gbuf->cap_cmd,
  971.     virt_to_bus(&pb->overlay_last1->cmd_dep),
  972.     pb->vid_cbo.bus);
  973. tab_cmd_dbdma((gbuf->cap_cmd + 1),
  974. DBDMA_NOP, 0);
  975. eieio();
  976. writel(virt_to_bus(gbuf->cap_cmd),
  977. &pb->overlay_last1->cmd_dep);
  978. }
  979. for(i = 0; overlay_is_active(pb) && i < 999; i++)
  980. DBG("PlanB: waiting for overlay donen");
  981. tab_cmd_dbdma(pb->vid_cbo.start, DBDMA_NOP, 0);
  982. pb->prev_last_fr = fr;
  983. pb->last_fr = -2;
  984. } else if(pb->last_fr == -2) {
  985. DBG("PlanB: mixed mode detected, grabbing"
  986. " will be done before activating overlayn");
  987. tab_cmd_dbdma(pb->vid_cbo.start, DBDMA_NOP, 0);
  988. if(gbuf->need_pre_capture) {
  989. DBG("PlanB: padding pre-capture sequencen");
  990. tab_cmd_dbdma(pb->gbuf[pb->prev_last_fr].last_cmd,
  991. DBDMA_NOP | BR_ALWAYS,
  992. virt_to_bus(gbuf->pre_cmd));
  993. eieio();
  994. } else {
  995. tab_cmd_dbdma(gbuf->cap_cmd, DBDMA_NOP, 0);
  996. if(pb->gbuf[pb->prev_last_fr].width !=
  997. gbuf->width
  998. || pb->gbuf[pb->prev_last_fr].height !=
  999. gbuf->height
  1000. || pb->gbuf[pb->prev_last_fr].fmt !=
  1001. gbuf->fmt)
  1002. tab_cmd_dbdma((gbuf->cap_cmd + 1),
  1003. DBDMA_NOP, 0);
  1004. else
  1005. tab_cmd_dbdma((gbuf->cap_cmd + 1),
  1006.     DBDMA_NOP | BR_ALWAYS,
  1007.     virt_to_bus(gbuf->cap_cmd + 16));
  1008. tab_cmd_dbdma(pb->gbuf[pb->prev_last_fr].last_cmd,
  1009. DBDMA_NOP | BR_ALWAYS,
  1010. virt_to_bus(gbuf->cap_cmd));
  1011. eieio();
  1012. }
  1013. tab_cmd_dbdma(gbuf->last_cmd, DBDMA_NOP | BR_ALWAYS,
  1014. pb->vid_cbo.bus);
  1015. eieio();
  1016. pb->prev_last_fr = fr;
  1017. pb->last_fr = -2;
  1018. } else {
  1019. gbuf_ptr lastgbuf = &pb->gbuf[pb->last_fr];
  1020. DBG("PlanB: active grabbing session detectedn");
  1021. if(gbuf->need_pre_capture) {
  1022. DBG("PlanB: padding pre-capture sequencen");
  1023. tab_cmd_dbdma(lastgbuf->last_cmd,
  1024. DBDMA_NOP | BR_ALWAYS,
  1025. virt_to_bus(gbuf->pre_cmd));
  1026. eieio();
  1027. } else {
  1028. tab_cmd_dbdma(gbuf->last_cmd, DBDMA_STOP, 0);
  1029. tab_cmd_dbdma(gbuf->cap_cmd, DBDMA_NOP, 0);
  1030. if(lastgbuf->width != gbuf->width
  1031.     || lastgbuf->height != gbuf->height
  1032.     || lastgbuf->fmt != gbuf->fmt)
  1033. tab_cmd_dbdma((gbuf->cap_cmd + 1),
  1034. DBDMA_NOP, 0);
  1035. else
  1036. tab_cmd_dbdma((gbuf->cap_cmd + 1),
  1037.     DBDMA_NOP | BR_ALWAYS,
  1038.     virt_to_bus(gbuf->cap_cmd + 16));
  1039. tab_cmd_dbdma(lastgbuf->last_cmd,
  1040. DBDMA_NOP | BR_ALWAYS,
  1041. virt_to_bus(gbuf->cap_cmd));
  1042. eieio();
  1043. }
  1044. pb->last_fr = fr;
  1045. }
  1046. if(!(ACTIVE & readl(&pb->planb_base->ch1.status))) {
  1047. DBG("PlanB: became inactive in the mean time... "
  1048. "reactivatingn");
  1049. planb_dbdma_stop(&pb->planb_base->ch1);
  1050. writel(virt_to_bus(gbuf->cap_cmd),
  1051. &pb->planb_base->ch1.cmdptr);
  1052. planb_dbdma_restart(&pb->planb_base->ch1);
  1053. }
  1054. }
  1055. pb->grabbing++;
  1056. planb_unlock(pb);
  1057. return 0;
  1058. }
  1059. static void planb_pre_capture(int fr, struct planb *pb)
  1060. {
  1061. gbuf_ptr gbuf = &pb->gbuf[fr];
  1062. dbdma_cmd_ptr c1 = gbuf->pre_cmd;
  1063. int height = gbuf->height;
  1064. int interlace = (height > pb->maxlines/2)? 1: 0;
  1065. tab_cmd_dbdma(c1++, DBDMA_NOP, 0);
  1066. c1 = cmd_geo_setup(c1, gbuf->width, height, interlace, gbuf->fmt,
  1067. 0, pb);
  1068. /* Sync to even field */
  1069. tab_cmd_store(c1++, (unsigned)(&pb->planb_base_bus->ch1.wait_sel),
  1070. PLANB_SET(FIELD_SYNC));
  1071. tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFCLR, 0);
  1072. tab_cmd_store(c1++, (unsigned)(&pb->planb_base_bus->ch1.br_sel),
  1073. PLANB_SET(ODD_FIELD));
  1074. tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFSET, 0);
  1075. tab_cmd_dbdma(c1, DBDMA_NOP | BR_IFSET, virt_to_bus(c1-3)); c1++;
  1076. tab_cmd_dbdma(c1++, DBDMA_NOP | INTR_ALWAYS, 0);
  1077. tab_cmd_store(c1++, (unsigned)(&pb->planb_base_bus->ch1.br_sel),
  1078. PLANB_SET(DMA_ABORT));
  1079. /* For non-interlaced, we use even fields only */
  1080. if (interlace == 0)
  1081. goto cmd_tab_data_end;
  1082. /* Sync to odd field */
  1083. tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFCLR, 0);
  1084. tab_cmd_store(c1++, (unsigned)(&pb->planb_base_bus->ch1.br_sel),
  1085. PLANB_SET(ODD_FIELD));
  1086. tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFSET, 0);
  1087. tab_cmd_dbdma(c1, DBDMA_NOP | BR_IFCLR, virt_to_bus(c1-3)); c1++;
  1088. tab_cmd_store(c1++, (unsigned)(&pb->planb_base_bus->ch1.br_sel),
  1089. PLANB_SET(DMA_ABORT));
  1090. cmd_tab_data_end:
  1091. tab_cmd_dbdma(c1, DBDMA_NOP | BR_ALWAYS, virt_to_bus(gbuf->cap_cmd));
  1092. eieio();
  1093. }
  1094. /* This needs some explanation.
  1095.  * What we do here is write the DBDMA commands to fill the grab buffer.
  1096.  * Since the grab buffer is made up of physically non-contiguous chunks,
  1097.  * we need to make sure to not make the DMA engine write across a chunk
  1098.  * boundary: the DMA engine needs a physically contiguous memory chunk for
  1099.  * a single scan line.
  1100.  * So all those scan lines that cross a chunk boundary are written do spare
  1101.  * scratch buffers, and we keep track of this fact.
  1102.  * Later, in the interrupt routine, we copy those scan lines (in two pieces)
  1103.  * back to where they belong in the right sequence in the grab buffer.
  1104.  */
  1105. static dbdma_cmd_ptr setup_grab_cmd(int fr, struct planb *pb)
  1106. {
  1107. int i, count, nlines, stepsize, interlace;
  1108. #ifdef PLANB_GSCANLINE
  1109. int scanline;
  1110. #else
  1111. int nlpp, leftover1;
  1112. unsigned long base;
  1113. #endif
  1114. unsigned long jump;
  1115. int pagei;
  1116. dbdma_cmd_ptr c1;
  1117. dbdma_cmd_ptr jump_addr;
  1118. gbuf_ptr gbuf = &pb->gbuf[fr];
  1119. int fmt = gbuf->fmt;
  1120. c1 = gbuf->cap_cmd;
  1121. nlines = gbuf->height;
  1122. interlace = (nlines > pb->maxlines/2) ? 1 : 0;
  1123. count = palette2fmt[fmt].bpp * gbuf->width;
  1124. #ifdef PLANB_GSCANLINE
  1125. scanline = pb->gbytes_per_line;
  1126. #else
  1127. gbuf->lsize = count;
  1128. gbuf->lnum = 0;
  1129. #endif
  1130. /* Do video in: */
  1131. /* Preamble commands: */
  1132. tab_cmd_dbdma(c1++, DBDMA_NOP, 0);
  1133. tab_cmd_dbdma(c1, DBDMA_NOP | BR_ALWAYS, virt_to_bus(c1 + 16)); c1++;
  1134. c1 = cmd_geo_setup(c1, gbuf->width, nlines, interlace, fmt, 0, pb);
  1135. tab_cmd_store(c1++, (unsigned)(&pb->planb_base_bus->ch1.wait_sel),
  1136. PLANB_SET(FIELD_SYNC));
  1137. tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFCLR, 0);
  1138. tab_cmd_store(c1++, (unsigned)(&pb->planb_base_bus->ch1.br_sel),
  1139. PLANB_SET(ODD_FIELD));
  1140. tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFSET, 0);
  1141. tab_cmd_dbdma(c1, DBDMA_NOP | BR_IFSET, virt_to_bus(c1-3)); c1++;
  1142. tab_cmd_dbdma(c1++, DBDMA_NOP | INTR_ALWAYS, 0);
  1143. tab_cmd_store(c1++, (unsigned)(&pb->planb_base_bus->ch1.br_sel),
  1144. PLANB_SET(DMA_ABORT));
  1145. if (interlace) {
  1146. stepsize = 2;
  1147. jump_addr = c1 + TAB_FACTOR * (nlines + 1) / 2;
  1148. } else {
  1149. stepsize = 1;
  1150. jump_addr = c1 + TAB_FACTOR * nlines;
  1151. }
  1152. jump = virt_to_bus(jump_addr);
  1153. /* even field data: */
  1154. pagei = gbuf->idx;
  1155. #ifdef PLANB_GSCANLINE
  1156. for (i = 0; i < nlines; i += stepsize) {
  1157. tab_cmd_gen(c1++, INPUT_MORE | KEY_STREAM0 | BR_IFSET, count,
  1158.     virt_to_bus(pb->rawbuf[pagei + i * scanline / PAGE_SIZE]),
  1159. jump);
  1160. }
  1161. #else
  1162. i = 0;
  1163. leftover1 = 0;
  1164. do {
  1165.     int j;
  1166.     base = virt_to_bus(pb->rawbuf[pagei]);
  1167.     nlpp = (PAGE_SIZE - leftover1) / count / stepsize;
  1168.     for(j = 0; j < nlpp && i < nlines; j++, i += stepsize, c1++)
  1169. tab_cmd_gen(c1, INPUT_MORE | KEY_STREAM0 | BR_IFSET,
  1170.   count, base + count * j * stepsize + leftover1, jump);
  1171.     if(i < nlines) {
  1172. int lov0 = PAGE_SIZE - count * nlpp * stepsize - leftover1;
  1173. if(lov0 == 0)
  1174.     leftover1 = 0;
  1175. else {
  1176.     if(lov0 >= count) {
  1177. /* can happen only when interlacing; then other field
  1178.  * uses up leftover space (lov0 - count). */
  1179. tab_cmd_gen(c1++, INPUT_MORE | BR_IFSET, count, base
  1180. + count * nlpp * stepsize + leftover1, jump);
  1181.     } else {
  1182. /* start of free space at end of page: */
  1183. pb->l_to_addr[fr][gbuf->lnum] = pb->rawbuf[pagei]
  1184. + count * nlpp * stepsize + leftover1;
  1185. /* index where continuation is: */
  1186. pb->l_to_next_idx[fr][gbuf->lnum] = pagei + 1;
  1187. /* How much is left to do in next page: */
  1188. pb->l_to_next_size[fr][gbuf->lnum] = count - lov0;
  1189. tab_cmd_gen(c1++, INPUT_MORE | BR_IFSET, count,
  1190. virt_to_bus(pb->rawbuf[gbuf->l_fr_addr_idx
  1191. + gbuf->lnum]), jump);
  1192. if(++gbuf->lnum > MAX_LNUM) {
  1193. /* FIXME: error condition! */
  1194. gbuf->lnum--;
  1195.      }
  1196.     }
  1197.     leftover1 = count * stepsize - lov0;
  1198.     i += stepsize;
  1199. }
  1200.     }
  1201.     pagei++;
  1202. } while(i < nlines);
  1203. tab_cmd_dbdma(c1, DBDMA_NOP | BR_ALWAYS, jump);
  1204. c1 = jump_addr;
  1205. #endif /* PLANB_GSCANLINE */
  1206. /* For non-interlaced, we use even fields only */
  1207. if (!interlace)
  1208. goto cmd_tab_data_end;
  1209. /* Sync to odd field */
  1210. tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFCLR, 0);
  1211. tab_cmd_store(c1++, (unsigned)(&pb->planb_base_bus->ch1.br_sel),
  1212. PLANB_SET(ODD_FIELD));
  1213. tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFSET, 0);
  1214. tab_cmd_dbdma(c1, DBDMA_NOP | BR_IFCLR, virt_to_bus(c1-3)); c1++;
  1215. tab_cmd_store(c1++, (unsigned)(&pb->planb_base_bus->ch1.br_sel),
  1216. PLANB_SET(DMA_ABORT));
  1217. /* odd field data: */
  1218. jump_addr = c1 + TAB_FACTOR * nlines / 2;
  1219. jump = virt_to_bus(jump_addr);
  1220. #ifdef PLANB_GSCANLINE
  1221. for (i = 1; i < nlines; i += stepsize) {
  1222. tab_cmd_gen(c1++, INPUT_MORE | KEY_STREAM0 | BR_IFSET, count,
  1223. virt_to_bus(pb->rawbuf[pagei
  1224. + i * scanline / PAGE_SIZE]), jump);
  1225. }
  1226. #else
  1227. i = 1;
  1228. leftover1 = 0;
  1229. pagei = gbuf->idx;
  1230. if(nlines <= 1)
  1231.     goto skip;
  1232. do {
  1233.     int j;
  1234.     base = virt_to_bus(pb->rawbuf[pagei]);
  1235.     nlpp = (PAGE_SIZE - leftover1) / count / stepsize;
  1236.     if(leftover1 >= count) {
  1237. tab_cmd_gen(c1++, INPUT_MORE | KEY_STREAM0 | BR_IFSET, count,
  1238. base + leftover1 - count, jump);
  1239. i += stepsize;
  1240.     }
  1241.     for(j = 0; j < nlpp && i < nlines; j++, i += stepsize, c1++)
  1242. tab_cmd_gen(c1, INPUT_MORE | KEY_STREAM0 | BR_IFSET, count,
  1243. base + count * (j * stepsize + 1) + leftover1, jump);
  1244.     if(i < nlines) {
  1245. int lov0 = PAGE_SIZE - count * nlpp * stepsize - leftover1;
  1246. if(lov0 == 0)
  1247.     leftover1 = 0;
  1248. else {
  1249.     if(lov0 > count) {
  1250. pb->l_to_addr[fr][gbuf->lnum] = pb->rawbuf[pagei]
  1251. + count * (nlpp * stepsize + 1) + leftover1;
  1252. pb->l_to_next_idx[fr][gbuf->lnum] = pagei + 1;
  1253. pb->l_to_next_size[fr][gbuf->lnum] = count * stepsize
  1254. - lov0;
  1255. tab_cmd_gen(c1++, INPUT_MORE | BR_IFSET, count,
  1256. virt_to_bus(pb->rawbuf[gbuf->l_fr_addr_idx
  1257. + gbuf->lnum]), jump);
  1258. if(++gbuf->lnum > MAX_LNUM) {
  1259. /* FIXME: error condition! */
  1260. gbuf->lnum--;
  1261. }
  1262. i += stepsize;
  1263.     }
  1264.     leftover1 = count * stepsize - lov0;
  1265. }
  1266.     }
  1267.     pagei++;
  1268. } while(i < nlines);
  1269. skip:
  1270. tab_cmd_dbdma(c1, DBDMA_NOP | BR_ALWAYS, jump);
  1271. c1 = jump_addr;
  1272. #endif /* PLANB_GSCANLINE */
  1273. cmd_tab_data_end:
  1274. tab_cmd_store(c1++, (unsigned)(&pb->planb_base_bus->intr_stat),
  1275. (fr << 9) | PLANB_FRM_IRQ | PLANB_GEN_IRQ);
  1276. /* stop it */
  1277. tab_cmd_dbdma(c1, DBDMA_STOP, 0);
  1278. eieio();
  1279. return c1;
  1280. }
  1281. static void planb_irq(int irq, void *dev_id, struct pt_regs * regs)
  1282. {
  1283. unsigned int stat, astat;
  1284. struct planb *pb = (struct planb *)dev_id;
  1285. IDBG("PlanB: planb_irq()n");
  1286. /* get/clear interrupt status bits */
  1287. eieio();
  1288. stat = readl(&pb->planb_base->intr_stat);
  1289. astat = stat & pb->intr_mask;
  1290. writel(PLANB_FRM_IRQ & ~astat & stat & ~PLANB_GEN_IRQ,
  1291. &pb->planb_base->intr_stat);
  1292. IDBG("PlanB: stat = %X, astat = %Xn", stat, astat);
  1293. if(astat & PLANB_FRM_IRQ) {
  1294. unsigned int fr = stat >> 9;
  1295. gbuf_ptr gbuf = &pb->gbuf[fr];
  1296. #ifndef PLANB_GSCANLINE
  1297. int i;
  1298. #endif
  1299. IDBG("PlanB: PLANB_FRM_IRQn");
  1300. pb->gcount++;
  1301. IDBG("PlanB: grab %d: fr = %d, gcount = %dn",
  1302. pb->grabbing, fr, pb->gcount);
  1303. #ifndef PLANB_GSCANLINE
  1304. /* Now that the buffer is full, copy those lines that fell
  1305.  * on a page boundary from the spare buffers back to where
  1306.  * they belong. */
  1307. IDBG("PlanB: %d * %d bytes are being copied overn",
  1308. gbuf->lnum, gbuf->lsize);
  1309. for(i = 0; i < gbuf->lnum; i++) {
  1310. int first = gbuf->lsize - pb->l_to_next_size[fr][i];
  1311. memcpy(pb->l_to_addr[fr][i],
  1312. pb->rawbuf[gbuf->l_fr_addr_idx + i],
  1313. first);
  1314. memcpy(pb->rawbuf[pb->l_to_next_idx[fr][i]],
  1315. pb->rawbuf[gbuf->l_fr_addr_idx + i] + first,
  1316. pb->l_to_next_size[fr][i]);
  1317. }
  1318. #endif
  1319. *gbuf->status = GBUFFER_DONE;
  1320. pb->grabbing--;
  1321. wake_up_interruptible(&pb->capq);
  1322. return;
  1323. }
  1324. /* incorrect interrupts? */
  1325. pb->intr_mask = PLANB_CLR_IRQ;
  1326. writel(PLANB_CLR_IRQ, &pb->planb_base->intr_stat);
  1327. printk(KERN_ERR "PlanB: IRQ lockup, cleared interrupts"
  1328. " unconditionallyn");
  1329. }
  1330. /*******************************
  1331.  * Device Operations functions *
  1332.  *******************************/
  1333. static int planb_open(struct video_device *dev, int mode)
  1334. {
  1335. struct planb *pb = (struct planb *)dev->priv;
  1336. int err;
  1337. /* first open on driver? */
  1338. if(pb->vid_user + pb->vbi_user == 0) {
  1339. if((err = planb_prepare_open(pb)) != 0)
  1340. return err;
  1341. }
  1342. /* first open on video dev? */
  1343. if(pb->vid_user == 0) {
  1344. if((err = planb_prepare_video(pb)) != 0)
  1345. return err;
  1346. }
  1347. pb->vid_user++;
  1348. DBG("PlanB: device openedn");
  1349. MOD_INC_USE_COUNT;
  1350. return 0;   
  1351. }
  1352. static void planb_close(struct video_device *dev)
  1353. {
  1354. struct planb *pb = (struct planb *)dev->priv;
  1355. planb_lock(pb);
  1356. /* last close? then stop everything... */
  1357. if(--pb->vid_user == 0) {
  1358. if(pb->overlay) {
  1359. planb_dbdma_stop(&pb->planb_base->ch2);
  1360. planb_dbdma_stop(&pb->planb_base->ch1);
  1361. pb->overlay = 0;
  1362. }
  1363. planb_close_video(pb);
  1364. }
  1365. /* last open on PlanB hardware? */
  1366. if(pb->vid_user + pb->vbi_user == 0)
  1367. planb_prepare_close(pb);
  1368. planb_unlock(pb);
  1369. DBG("PlanB: device closedn");
  1370. MOD_DEC_USE_COUNT;
  1371. return;
  1372. }
  1373. static long planb_read(struct video_device *v, char *buf, unsigned long count,
  1374. int nonblock)
  1375. {
  1376. DBG("planb: read requestn");
  1377. return -EINVAL;
  1378. }
  1379. static long planb_write(struct video_device *v, const char *buf,
  1380. unsigned long count, int nonblock)
  1381. {
  1382. DBG("planb: write requestn");
  1383. return -EINVAL;
  1384. }
  1385. static int planb_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
  1386. {
  1387. struct planb *pb=(struct planb *)dev->priv;
  1388.   
  1389. switch (cmd)
  1390. {
  1391. case VIDIOCGCAP:
  1392. {
  1393. struct video_capability b;
  1394. DBG("PlanB: IOCTL VIDIOCGCAPn");
  1395. strcpy (b.name, pb->video_dev.name);
  1396. b.type = VID_TYPE_OVERLAY | VID_TYPE_CLIPPING |
  1397.  VID_TYPE_FRAMERAM | VID_TYPE_SCALES |
  1398.  VID_TYPE_CAPTURE;
  1399. b.channels = 2; /* composite & svhs */
  1400. b.audios = 0;
  1401. b.maxwidth = PLANB_MAXPIXELS;
  1402.                         b.maxheight = PLANB_MAXLINES;
  1403.                         b.minwidth = 32; /* wild guess */
  1404.                         b.minheight = 32;
  1405.                         if (copy_to_user(arg,&b,sizeof(b)))
  1406.                                 return -EFAULT;
  1407. return 0;
  1408. }
  1409. case VIDIOCSFBUF:
  1410. {
  1411.                         struct video_buffer v;
  1412. unsigned int fmt;
  1413. DBG("PlanB: IOCTL VIDIOCSFBUFn");
  1414.                         if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RAWIO))
  1415.                                 return -EPERM;
  1416.                         if (copy_from_user(&v, arg, sizeof(v)))
  1417.                                 return -EFAULT;
  1418. planb_lock(pb);
  1419. switch(v.depth) {
  1420.     /* xawtv only asks for 8 bit in static grey, but
  1421.      * there is no way to know what it really means.. */
  1422.     case 8:
  1423. fmt = VIDEO_PALETTE_GREY;
  1424. break;
  1425.     case 15:
  1426. fmt = VIDEO_PALETTE_RGB555;
  1427. break;
  1428.     case 32:
  1429. fmt = VIDEO_PALETTE_RGB32;
  1430. break;
  1431.     /* We don't deliver these two... */
  1432.     case 16:
  1433.     case 24:
  1434.     default:
  1435. planb_unlock(pb);
  1436.                                 return -EINVAL;
  1437. }
  1438. if (palette2fmt[fmt].bpp * v.width > v.bytesperline) {
  1439. planb_unlock(pb);
  1440. return -EINVAL;
  1441. }
  1442. pb->win.bpp = palette2fmt[fmt].bpp;
  1443. pb->win.color_fmt = fmt;
  1444. pb->fb.phys = (unsigned long) v.base;
  1445. pb->win.sheight = v.height;
  1446. pb->win.swidth = v.width;
  1447. pb->picture.depth = pb->win.depth = v.depth;
  1448. pb->win.bpl = pb->win.bpp * pb->win.swidth;
  1449. pb->win.pad = v.bytesperline - pb->win.bpl;
  1450.                         DBG("PlanB: Display at %p is %d by %d, bytedepth %d,"
  1451. " bpl %d (+ %d)n", v.base, v.width,v.height,
  1452. pb->win.bpp, pb->win.bpl, pb->win.pad);
  1453. pb->cmd_buff_inited = 0;
  1454. if(pb->overlay) {
  1455. suspend_overlay(pb);
  1456. fill_cmd_buff(pb);
  1457. resume_overlay(pb);
  1458. }
  1459. planb_unlock(pb);
  1460. return 0;
  1461. }
  1462. case VIDIOCGFBUF:
  1463. {
  1464.                         struct video_buffer v;
  1465. DBG("PlanB: IOCTL VIDIOCGFBUFn");
  1466. v.base = (void *)pb->fb.phys;
  1467. v.height = pb->win.sheight;
  1468. v.width = pb->win.swidth;
  1469. v.depth = pb->win.depth;
  1470. v.bytesperline = pb->win.bpl + pb->win.pad;
  1471. if (copy_to_user(arg, &v, sizeof(v)))
  1472.                                 return -EFAULT;
  1473. return 0;
  1474. }
  1475. case VIDIOCCAPTURE:
  1476. {
  1477. int i;
  1478.                         if(copy_from_user(&i, arg, sizeof(i)))
  1479.                                 return -EFAULT;
  1480. if(i==0) {
  1481. DBG("PlanB: IOCTL VIDIOCCAPTURE Stopn");
  1482. if (!(pb->overlay))
  1483. return 0;
  1484. planb_lock(pb);
  1485. pb->overlay = 0;
  1486. overlay_stop(pb);
  1487. planb_unlock(pb);
  1488. } else {
  1489. DBG("PlanB: IOCTL VIDIOCCAPTURE Startn");
  1490. if (pb->fb.phys == 0 ||
  1491.   pb->win.width == 0 ||
  1492.   pb->win.height == 0)
  1493. return -EINVAL;
  1494. if (pb->overlay)
  1495. return 0;
  1496. planb_lock(pb);
  1497. pb->overlay = 1;
  1498. if(!(pb->cmd_buff_inited))
  1499. fill_cmd_buff(pb);
  1500. overlay_start(pb);
  1501. planb_unlock(pb);
  1502. }
  1503. return 0;
  1504. }
  1505. case VIDIOCGCHAN:
  1506. {
  1507. struct video_channel v;
  1508. DBG("PlanB: IOCTL VIDIOCGCHANn");
  1509. if(copy_from_user(&v, arg,sizeof(v)))
  1510. return -EFAULT;
  1511. v.flags = 0;
  1512. v.tuners = 0;
  1513. v.type = VIDEO_TYPE_CAMERA;
  1514. v.norm = pb->win.norm;
  1515. switch(v.channel)
  1516. {
  1517. case 0:
  1518. strcpy(v.name,"Composite");
  1519. break;
  1520. case 1:
  1521. strcpy(v.name,"SVHS");
  1522. break;
  1523. default:
  1524. return -EINVAL;
  1525. break;
  1526. }
  1527. if(copy_to_user(arg,&v,sizeof(v)))
  1528. return -EFAULT;
  1529. return 0;
  1530. }
  1531. case VIDIOCSCHAN:
  1532. {
  1533. struct video_channel v;
  1534. DBG("PlanB: IOCTL VIDIOCSCHANn");
  1535. if(copy_from_user(&v, arg, sizeof(v)))
  1536. return -EFAULT;
  1537. if (v.norm != pb->win.norm) {
  1538. int i, maxlines;
  1539. switch (v.norm)
  1540. {
  1541. case VIDEO_MODE_PAL:
  1542. case VIDEO_MODE_SECAM:
  1543. maxlines = PLANB_MAXLINES;
  1544. break;
  1545. case VIDEO_MODE_NTSC:
  1546. maxlines = PLANB_NTSC_MAXLINES;
  1547. break;
  1548. default:
  1549. DBG("       invalid norm %d.n", v.norm);
  1550. return -EINVAL;
  1551. break;
  1552. }
  1553. planb_lock(pb);
  1554. /* empty the grabbing queue */
  1555. while(pb->grabbing)
  1556. interruptible_sleep_on(&pb->capq);
  1557. pb->maxlines = maxlines;
  1558. pb->win.norm = v.norm;
  1559. /* Stop overlay if running */
  1560. suspend_overlay(pb);
  1561. for(i = 0; i < MAX_GBUFFERS; i++)
  1562. pb->gbuf[i].norm_switch = 1;
  1563. /* I know it's an overkill, but.... */
  1564. fill_cmd_buff(pb);
  1565. /* ok, now init it accordingly */
  1566. saa_init_regs (pb);
  1567. /* restart overlay if it was running */
  1568. resume_overlay(pb);
  1569. planb_unlock(pb);
  1570. }
  1571. switch(v.channel)
  1572. {
  1573. case 0: /* Composite */
  1574. saa_set (SAA7196_IOCC,
  1575. ((saa_regs[pb->win.norm][SAA7196_IOCC] &
  1576.   ~7) | 3), pb);
  1577. break;
  1578. case 1: /* SVHS */
  1579. saa_set (SAA7196_IOCC,
  1580. ((saa_regs[pb->win.norm][SAA7196_IOCC] &
  1581.   ~7) | 4), pb);
  1582. break;
  1583. default:
  1584. DBG("       invalid channel %d.n", v.channel);
  1585. return -EINVAL;
  1586. break;
  1587. }
  1588. return 0;
  1589. }
  1590. case VIDIOCGPICT:
  1591. {
  1592. struct video_picture vp = pb->picture;
  1593. DBG("PlanB: IOCTL VIDIOCGPICTn");
  1594. vp.palette = pb->win.color_fmt;
  1595. if(copy_to_user(arg,&vp,sizeof(vp)))
  1596. return -EFAULT;
  1597. return 0;
  1598. }
  1599. case VIDIOCSPICT:
  1600. {
  1601. struct video_picture vp;
  1602. DBG("PlanB: IOCTL VIDIOCSPICTn");
  1603. if(copy_from_user(&vp,arg,sizeof(vp)))
  1604. return -EFAULT;
  1605. pb->picture = vp;
  1606. /* Should we do sanity checks here? */
  1607. planb_lock(pb);
  1608. saa_set (SAA7196_BRIG, (unsigned char)
  1609.     ((pb->picture.brightness) >> 8), pb);
  1610. saa_set (SAA7196_HUEC, (unsigned char)
  1611.     ((pb->picture.hue) >> 8) ^ 0x80, pb);
  1612. saa_set (SAA7196_CSAT, (unsigned char)
  1613.     ((pb->picture.colour) >> 9), pb);
  1614. saa_set (SAA7196_CONT, (unsigned char)
  1615.     ((pb->picture.contrast) >> 9), pb);
  1616. planb_unlock(pb);
  1617. return 0;
  1618. }
  1619. case VIDIOCSWIN:
  1620. {
  1621. struct video_window vw;
  1622. struct video_clip clip;
  1623. int  i;
  1624. DBG("PlanB: IOCTL VIDIOCSWINn");
  1625. if(copy_from_user(&vw,arg,sizeof(vw)))
  1626. return -EFAULT;
  1627. planb_lock(pb);
  1628. /* Stop overlay if running */
  1629. suspend_overlay(pb);
  1630. pb->win.interlace = (vw.height > pb->maxlines/2)? 1: 0;
  1631. if (pb->win.x != vw.x ||
  1632.     pb->win.y != vw.y ||
  1633.     pb->win.width != vw.width ||
  1634.     pb->win.height != vw.height ||
  1635.     !pb->cmd_buff_inited) {
  1636. pb->win.x = vw.x;
  1637. pb->win.y = vw.y;
  1638. pb->win.width = vw.width;
  1639. pb->win.height = vw.height;
  1640. fill_cmd_buff(pb);
  1641. }
  1642.                         DBG("PlanB: Window at (%d,%d) size %dx%dn", vw.x, vw.y, vw.width,
  1643. vw.height);
  1644. /* Reset clip mask */
  1645. memset ((void *) pb->mask, 0xff, (pb->maxlines
  1646. * ((PLANB_MAXPIXELS + 7) & ~7)) / 8);
  1647. /* Add any clip rects */
  1648. for (i = 0; i < vw.clipcount; i++) {
  1649. if (copy_from_user(&clip, vw.clips + i,
  1650. sizeof(struct video_clip)))
  1651. return -EFAULT;
  1652. add_clip(pb, &clip);
  1653. }
  1654. /* restart overlay if it was running */
  1655. resume_overlay(pb);
  1656. planb_unlock(pb);
  1657. return 0;
  1658. }
  1659. case VIDIOCGWIN:
  1660. {
  1661. struct video_window vw;
  1662. DBG("PlanB: IOCTL VIDIOCGWINn");
  1663. vw.x=pb->win.x;
  1664. vw.y=pb->win.y;
  1665. vw.width=pb->win.width;
  1666. vw.height=pb->win.height;
  1667. vw.chromakey=0;
  1668. vw.flags=0;
  1669. if(pb->win.interlace)
  1670. vw.flags|=VIDEO_WINDOW_INTERLACE;
  1671. if(copy_to_user(arg,&vw,sizeof(vw)))
  1672. return -EFAULT;
  1673. return 0;
  1674. }
  1675.         case VIDIOCSYNC: {
  1676. int i;
  1677. gbuf_ptr gbuf;
  1678. DBG("PlanB: IOCTL VIDIOCSYNCn");
  1679. if(copy_from_user((void *)&i,arg,sizeof(int)))
  1680. return -EFAULT;
  1681. DBG("PlanB: sync to frame %dn", i);
  1682.                         if(i > (MAX_GBUFFERS - 1) || i < 0)
  1683.                                 return -EINVAL;
  1684. gbuf = &pb->gbuf[i];
  1685. chk_grab:
  1686.                         switch (*gbuf->status) {
  1687.                         case GBUFFER_UNUSED:
  1688.                                 return -EINVAL;
  1689. case GBUFFER_GRABBING:
  1690. DBG("PlanB: waiting for grab"
  1691. " done (%d)n", i);
  1692.           interruptible_sleep_on(&pb->capq);
  1693. if(signal_pending(current))
  1694. return -EINTR;
  1695. goto chk_grab;
  1696.                         case GBUFFER_DONE:
  1697.                                 *gbuf->status = GBUFFER_UNUSED;
  1698.                                 break;
  1699.                         }
  1700.                         return 0;
  1701. }
  1702.         case VIDIOCMCAPTURE:
  1703. {
  1704.                         struct video_mmap vm;
  1705. int   fr;
  1706. DBG("PlanB: IOCTL VIDIOCMCAPTUREn");
  1707. if(copy_from_user((void *) &vm,(void *)arg,sizeof(vm)))
  1708. return -EFAULT;
  1709. fr = vm.frame;
  1710.                         if(fr > (MAX_GBUFFERS - 1) || fr < 0)
  1711.                                 return -EINVAL;
  1712. if (*pb->gbuf[fr].status != GBUFFER_UNUSED)
  1713. return -EBUSY;
  1714. return vgrab(pb, &vm);
  1715. }
  1716. case VIDIOCGMBUF:
  1717. {
  1718. int i;
  1719. struct video_mbuf vm;
  1720. DBG("PlanB: IOCTL VIDIOCGMBUFn");
  1721. memset(&vm, 0 , sizeof(vm));
  1722. vm.size = PLANB_MAX_FBUF * MAX_GBUFFERS;
  1723. vm.frames = MAX_GBUFFERS;
  1724. for(i = 0; i<MAX_GBUFFERS; i++)
  1725. vm.offsets[i] = PLANB_MAX_FBUF * i;
  1726. if(copy_to_user((void *)arg, (void *)&vm, sizeof(vm)))
  1727. return -EFAULT;
  1728. return 0;
  1729. }
  1730. case VIDIOCGUNIT:
  1731. {
  1732. struct video_unit vu;
  1733. DBG("PlanB: IOCTL VIDIOCGUNITn");
  1734. vu.video=pb->video_dev.minor;
  1735. vu.vbi=pb->vbi_dev.minor;
  1736. vu.radio=VIDEO_NO_UNIT;
  1737. vu.audio=VIDEO_NO_UNIT;
  1738. vu.teletext=VIDEO_NO_UNIT;
  1739. if(copy_to_user((void *)arg, (void *)&vu, sizeof(vu)))
  1740. return -EFAULT;
  1741. return 0;
  1742. }
  1743. case PLANBIOCGSAAREGS:
  1744. {
  1745. struct planb_saa_regs preg;
  1746. DBG("PlanB: IOCTL PLANBIOCGSAAREGSn");
  1747. if(copy_from_user(&preg, arg, sizeof(preg)))
  1748. return -EFAULT;
  1749. if(preg.addr >= SAA7196_NUMREGS)
  1750. return -EINVAL;
  1751. preg.val = saa_regs[pb->win.norm][preg.addr];
  1752. if(copy_to_user((void *)arg, (void *)&preg,
  1753. sizeof(preg)))
  1754. return -EFAULT;
  1755. return 0;
  1756. }
  1757. case PLANBIOCSSAAREGS:
  1758. {
  1759. struct planb_saa_regs preg;
  1760. DBG("PlanB: IOCTL PLANBIOCSSAAREGSn");
  1761. if(copy_from_user(&preg, arg, sizeof(preg)))
  1762. return -EFAULT;
  1763. if(preg.addr >= SAA7196_NUMREGS)
  1764. return -EINVAL;
  1765. saa_set (preg.addr, preg.val, pb);
  1766. return 0;
  1767. }
  1768. case PLANBIOCGSTAT:
  1769. {
  1770. struct planb_stat_regs pstat;
  1771. DBG("PlanB: IOCTL PLANBIOCGSTATn");
  1772. pstat.ch1_stat = readl(&pb->planb_base->ch1.status);
  1773. pstat.ch2_stat = readl(&pb->planb_base->ch2.status);
  1774. pstat.ch1_cmdbase = (unsigned long)pb->vid_cbo.start;
  1775. pstat.ch2_cmdbase = (unsigned long)pb->clip_cbo.start;
  1776. pstat.ch1_cmdptr = readl(&pb->planb_base->ch1.cmdptr);
  1777. pstat.ch2_cmdptr = readl(&pb->planb_base->ch2.cmdptr);
  1778. pstat.saa_stat0 = saa_status(0, pb);
  1779. pstat.saa_stat1 = saa_status(1, pb);
  1780. if(copy_to_user((void *)arg, (void *)&pstat,
  1781. sizeof(pstat)))
  1782. return -EFAULT;
  1783. return 0;
  1784. }
  1785. case PLANBIOCSMODE: {
  1786. int v;
  1787. DBG("PlanB: IOCTL PLANBIOCSMODEn");
  1788. if(copy_from_user(&v, arg, sizeof(v)))
  1789. return -EFAULT;
  1790. switch(v)
  1791. {
  1792. case PLANB_TV_MODE:
  1793. saa_set (SAA7196_STDC,
  1794. (saa_regs[pb->win.norm][SAA7196_STDC] &
  1795.   0x7f), pb);
  1796. break;
  1797. case PLANB_VTR_MODE:
  1798. saa_set (SAA7196_STDC,
  1799. (saa_regs[pb->win.norm][SAA7196_STDC] |
  1800.   0x80), pb);
  1801. break;
  1802. default:
  1803. return -EINVAL;
  1804. break;
  1805. }
  1806. pb->win.mode = v;
  1807. return 0;
  1808. }
  1809. case PLANBIOCGMODE: {
  1810. int v=pb->win.mode;
  1811. DBG("PlanB: IOCTL PLANBIOCGMODEn");
  1812. if(copy_to_user(arg,&v,sizeof(v)))
  1813. return -EFAULT;
  1814. return 0;
  1815. }
  1816. #ifdef PLANB_GSCANLINE
  1817. case PLANBG_GRAB_BPL: {
  1818. int v=pb->gbytes_per_line;
  1819. DBG("PlanB: IOCTL PLANBG_GRAB_BPLn");
  1820. if(copy_to_user(arg,&v,sizeof(v)))
  1821. return -EFAULT;
  1822. return 0;
  1823. }
  1824. #endif /* PLANB_GSCANLINE */
  1825. /* These serve only for debugging... */
  1826. #ifdef DEBUG
  1827. case PLANB_INTR_DEBUG: {
  1828. int i;
  1829. DBG("PlanB: IOCTL PLANB_INTR_DEBUGn");
  1830. if(copy_from_user(&i, arg, sizeof(i)))
  1831. return -EFAULT;
  1832. /* avoid hang ups all together */
  1833. for (i = 0; i < MAX_GBUFFERS; i++) {
  1834. if(*pb->gbuf[i].status == GBUFFER_GRABBING) {
  1835. *pb->gbuf[i].status = GBUFFER_DONE;
  1836. }
  1837. }
  1838. if(pb->grabbing)
  1839. pb->grabbing--;
  1840. wake_up_interruptible(&pb->capq);
  1841. return 0;
  1842. }
  1843. case PLANB_INV_REGS: {
  1844. int i;
  1845. struct planb_any_regs any;
  1846. DBG("PlanB: IOCTL PLANB_INV_REGSn");
  1847. if(copy_from_user(&any, arg, sizeof(any)))
  1848. return -EFAULT;
  1849. if(any.offset < 0 || any.offset + any.bytes > 0x400)
  1850. return -EINVAL;
  1851. if(any.bytes > 128)
  1852. return -EINVAL;
  1853. for (i = 0; i < any.bytes; i++) {
  1854. any.data[i] =
  1855. readb((unsigned char *)pb->planb_base
  1856. + any.offset + i);
  1857. }
  1858. if(copy_to_user(arg,&any,sizeof(any)))
  1859. return -EFAULT;
  1860. return 0;
  1861. }
  1862. case PLANBIOCGDBDMABUF:
  1863. {
  1864. struct planb_buf_regs buf;
  1865. dbdma_cmd_ptr dc;
  1866. int i;
  1867. DBG("PlanB: IOCTL PLANBIOCGDBDMABUFn");
  1868. if(copy_from_user(&buf, arg, sizeof(buf)))
  1869. return -EFAULT;
  1870. buf.end &= ~0xf;
  1871. if( (buf.start < 0) || (buf.end < 0x10) ||
  1872.     (buf.end < buf.start+0x10) ||
  1873.     (buf.end > 2*pb->tab_size) )
  1874. return -EINVAL;
  1875. printk ("PlanB DBDMA command buffer:n");
  1876. for (i=(buf.start>>4); i<=(buf.end>>4); i++) {
  1877. printk(" 0x%04x:", i<<4);
  1878. dc = pb->vid_cbo.start + i;
  1879. printk (" %04x %04x %08x %08x %04x %04xn",
  1880.   dc->req_count, dc->command, dc->phy_addr,
  1881.   dc->cmd_dep, dc->res_count, dc->xfer_status);
  1882. }
  1883. return 0;
  1884. }
  1885. #endif /* DEBUG */
  1886. default:
  1887. {
  1888. DBG("PlanB: Unimplemented IOCTL: %d (0x%x)n", cmd, cmd);
  1889. return -ENOIOCTLCMD;
  1890. }
  1891. /* Some IOCTLs are currently unsupported on PlanB */
  1892. case VIDIOCGTUNER: {
  1893. DBG("PlanB: IOCTL VIDIOCGTUNERn");
  1894. goto unimplemented; }
  1895. case VIDIOCSTUNER: {
  1896. DBG("PlanB: IOCTL VIDIOCSTUNERn");
  1897. goto unimplemented; }
  1898. case VIDIOCSFREQ: {
  1899. DBG("PlanB: IOCTL VIDIOCSFREQn");
  1900. goto unimplemented; }
  1901. case VIDIOCGFREQ: {
  1902. DBG("PlanB: IOCTL VIDIOCGFREQn");
  1903. goto unimplemented; }
  1904. case VIDIOCKEY: {
  1905. DBG("PlanB: IOCTL VIDIOCKEYn");
  1906. goto unimplemented; }
  1907. case VIDIOCSAUDIO: {
  1908. DBG("PlanB: IOCTL VIDIOCSAUDIOn");
  1909. goto unimplemented; }
  1910. case VIDIOCGAUDIO: {
  1911. DBG("PlanB: IOCTL VIDIOCGAUDIOn");
  1912. goto unimplemented; }
  1913. unimplemented:
  1914. DBG("       Unimplementedn");
  1915. return -ENOIOCTLCMD;
  1916. }
  1917. return 0;
  1918. }
  1919. static int planb_mmap(struct video_device *dev, const char *adr, unsigned long size)
  1920. {
  1921. struct planb *pb = (struct planb *)dev->priv;
  1922.         unsigned long start = (unsigned long)adr;
  1923. int i;
  1924. if (size > MAX_GBUFFERS * PLANB_MAX_FBUF)
  1925.         return -EINVAL;
  1926. if (!pb->rawbuf) {
  1927. int err;
  1928. if((err=grabbuf_alloc(pb)))
  1929. return err;
  1930. }
  1931. for (i = 0; i < pb->rawbuf_nchunks; i++) {
  1932. if (remap_page_range(start, virt_to_phys((void *)pb->rawbuf[i]),
  1933. PAGE_SIZE, PAGE_SHARED))
  1934. return -EAGAIN;
  1935. start += PAGE_SIZE;
  1936. if (size <= PAGE_SIZE)
  1937. break;
  1938. size -= PAGE_SIZE;
  1939. }
  1940. return 0;
  1941. }
  1942. /**********************************
  1943.  * VBI device operation functions *
  1944.  **********************************/
  1945. static long planb_vbi_read(struct video_device *dev, char *buf,
  1946. unsigned long count, int nonblock)
  1947. {
  1948. struct planb *pb = (struct planb *)dev->priv;
  1949. int q,todo;
  1950. DECLARE_WAITQUEUE(wait, current);
  1951. /* Dummy for now */
  1952. printk ("PlanB: VBI read %li bytes.n", count);
  1953. return (0);
  1954. todo=count;
  1955. while (todo && todo>(q=VBIBUF_SIZE-pb->vbip)) 
  1956. {
  1957. if(copy_to_user((void *) buf, (void *) pb->vbibuf+pb->vbip, q))
  1958. return -EFAULT;
  1959. todo-=q;
  1960. buf+=q;
  1961. add_wait_queue(&pb->vbiq, &wait);
  1962. current->state = TASK_INTERRUPTIBLE;
  1963. if (todo && q==VBIBUF_SIZE-pb->vbip) {
  1964. if(nonblock) {
  1965. remove_wait_queue(&pb->vbiq, &wait);
  1966. current->state = TASK_RUNNING;
  1967. if(count==todo)
  1968. return -EWOULDBLOCK;
  1969. return count-todo;
  1970. }
  1971. schedule();
  1972. if(signal_pending(current)) {
  1973. remove_wait_queue(&pb->vbiq, &wait);
  1974. current->state = TASK_RUNNING;
  1975. if(todo==count)
  1976. return -EINTR;
  1977. else
  1978. return count-todo;
  1979. }
  1980. }
  1981. remove_wait_queue(&pb->vbiq, &wait);
  1982. current->state = TASK_RUNNING;
  1983. }
  1984. if (todo) {
  1985. if(copy_to_user((void *) buf, (void *) pb->vbibuf+pb->vbip,
  1986.     todo))
  1987. return -EFAULT;
  1988. pb->vbip+=todo;
  1989. }
  1990. return count;
  1991. }
  1992. static unsigned int planb_vbi_poll(struct video_device *dev,
  1993. struct file *file, poll_table *wait)
  1994. {
  1995. struct planb *pb = (struct planb *)dev->priv;
  1996. unsigned int mask = 0;
  1997. printk ("PlanB: VBI poll.n");
  1998. poll_wait(file, &pb->vbiq, wait);
  1999. if (pb->vbip < VBIBUF_SIZE)
  2000. mask |= (POLLIN | POLLRDNORM);
  2001. return mask;
  2002. }
  2003. static int planb_vbi_open(struct video_device *dev, int flags)
  2004. {
  2005. struct planb *pb = (struct planb *)dev->priv;
  2006. int err;
  2007. /* first open on the driver? */
  2008. if(pb->vid_user + pb->vbi_user == 0) {
  2009. if((err = planb_prepare_open(pb)) != 0)
  2010. return err;
  2011. }
  2012. /* first open on the vbi device? */
  2013. if(pb->vbi_user == 1) {
  2014. if((err = planb_prepare_vbi(pb)) != 0)
  2015. return err;
  2016. }
  2017. ++pb->vbi_user;
  2018. DBG("PlanB: VBI openn");
  2019. MOD_INC_USE_COUNT;
  2020. return 0;   
  2021. }
  2022. static void planb_vbi_close(struct video_device *dev)
  2023. {
  2024. struct planb *pb = (struct planb *)dev->priv;
  2025. /* last close on vbi device? */
  2026. if(--pb->vbi_user == 0) {
  2027. planb_close_vbi(pb);
  2028. }
  2029. /* last close on any planb device? */
  2030. if(pb->vid_user + pb->vbi_user == 0) {
  2031. planb_prepare_close(pb);
  2032. }
  2033. DBG("PlanB: VBI closen");
  2034. MOD_DEC_USE_COUNT;  
  2035. return;
  2036. }
  2037. static int planb_vbi_ioctl(struct video_device *dev, unsigned int cmd,
  2038. void *arg)
  2039. {
  2040. switch (cmd) {  
  2041. /* This is only for alevt */
  2042. case BTTV_VBISIZE:
  2043. DBG("PlanB: IOCTL BTTV_VBISIZE.n");
  2044. return VBIBUF_SIZE;
  2045. default:
  2046. DBG("PlanB: Unimplemented VBI IOCTL no. %i.n", cmd);
  2047. return -EINVAL;
  2048. }
  2049. }
  2050. static struct video_device planb_template=
  2051. {
  2052. owner: THIS_MODULE,
  2053. name: PLANB_DEVICE_NAME,
  2054. type: VID_TYPE_CAPTURE|VID_TYPE_OVERLAY,
  2055. hardware: VID_HARDWARE_PLANB,
  2056. open: planb_open,
  2057. close: planb_close,
  2058. read: planb_read,
  2059. write: planb_write, /* not implemented */
  2060. ioctl: planb_ioctl,
  2061. mmap: planb_mmap, /* mmap? */
  2062. };
  2063. static struct video_device planb_vbi_template=
  2064. {
  2065. owner: THIS_MODULE,
  2066. name: PLANB_VBI_NAME,
  2067. type: VID_TYPE_CAPTURE|VID_TYPE_TELETEXT,
  2068. hardware: VID_HARDWARE_PLANB,
  2069. open: planb_vbi_open,
  2070. close: planb_vbi_close,
  2071. read: planb_vbi_read,
  2072. write: planb_write, /* not implemented */
  2073. poll: planb_vbi_poll,
  2074. ioctl: planb_vbi_ioctl,
  2075. };
  2076. static int __devinit init_planb(struct planb *pb)
  2077. {
  2078. unsigned char saa_rev;
  2079. int i, result;
  2080. unsigned long flags;
  2081. printk(KERN_INFO "PlanB: PowerMacintosh video input driver rev. %sn", PLANB_REV);
  2082. pb->video_dev.minor = -1;
  2083. pb->vid_user = 0;
  2084. /* Simple sanity check */
  2085. if(def_norm >= NUM_SUPPORTED_NORM || def_norm < 0) {
  2086. printk(KERN_ERR "PlanB: Option(s) invalidn");
  2087. return -2;
  2088. }
  2089. memset ((void *) &pb->win, 0, sizeof (struct planb_window));
  2090. pb->win.norm = def_norm;
  2091. pb->win.mode = PLANB_TV_MODE; /* TV mode */
  2092. pb->win.interlace = 1;
  2093. pb->win.x = 0;
  2094. pb->win.y = 0;
  2095. pb->win.width = 768; /* 640 */
  2096. pb->win.height = 576; /* 480 */
  2097. pb->win.pad = 0;
  2098. pb->win.bpp = 4;
  2099. pb->win.depth = 32;
  2100. pb->win.color_fmt = VIDEO_PALETTE_RGB32;
  2101. pb->win.bpl = 1024 * pb->win.bpp;
  2102. pb->win.swidth = 1024;
  2103. pb->win.sheight = 768;
  2104. pb->maxlines = 576;
  2105. #ifdef PLANB_GSCANLINE
  2106. if((pb->gbytes_per_line = PLANB_MAXPIXELS * 4) > PAGE_SIZE
  2107. || (pb->gbytes_per_line <= 0))
  2108. return -3;
  2109. else {
  2110. /* page align pb->gbytes_per_line for DMA purpose */
  2111. for(i = PAGE_SIZE; pb->gbytes_per_line < (i >> 1);)
  2112. i >>= 1;
  2113. pb->gbytes_per_line = i;
  2114. }
  2115. #endif
  2116. pb->tab_size = PLANB_MAXLINES + 40;
  2117. pb->suspend = 0;
  2118. init_MUTEX(&pb->lock);
  2119. pb->vid_cbo.start = 0;
  2120. pb->clip_cbo.start = 0;
  2121. pb->mask = 0;
  2122. pb->vid_raw = 0;
  2123. pb->overlay = 0;
  2124. init_waitqueue_head(&pb->suspendq);
  2125. pb->cmd_buff_inited = 0;
  2126. pb->fb.phys = 0;
  2127. pb->fb.offset = 0;
  2128. /* VBI stuff: */
  2129. pb->vbi_dev.minor = -1;
  2130. pb->vbi_user = 0;
  2131. pb->vbirunning = 0;
  2132. pb->vbip = 0;
  2133. pb->vbibuf = 0;
  2134. init_waitqueue_head(&pb->vbiq);
  2135. /* Reset DMA controllers */
  2136. planb_dbdma_stop(&pb->planb_base->ch2);
  2137. planb_dbdma_stop(&pb->planb_base->ch1);
  2138. saa_rev =  (saa_status(0, pb) & 0xf0) >> 4;
  2139. printk(KERN_INFO "PlanB: SAA7196 video processor rev. %dn", saa_rev);
  2140. /* Initialize the SAA registers in memory and on chip */
  2141. saa_init_regs (pb);
  2142. /* clear interrupt mask */
  2143. pb->intr_mask = PLANB_CLR_IRQ;
  2144. save_flags(flags); cli();
  2145.         result = request_irq(pb->irq, planb_irq, 0, "PlanB", (void *)pb);
  2146.         if (result < 0) {
  2147.         if (result==-EINVAL)
  2148.                 printk(KERN_ERR "PlanB: Bad irq number (%d) "
  2149. "or handlern", (int)pb->irq);
  2150. else if (result==-EBUSY)
  2151. printk(KERN_ERR "PlanB: I don't know why, "
  2152. "but IRQ %d is busyn", (int)pb->irq);
  2153. restore_flags(flags);
  2154. return result;
  2155. }
  2156. disable_irq(pb->irq);
  2157. restore_flags(flags);
  2158.         
  2159. pb->picture.brightness=0x90<<8;
  2160. pb->picture.contrast = 0x70 << 8;
  2161. pb->picture.colour = 0x70<<8;
  2162. pb->picture.hue = 0x8000;
  2163. pb->picture.whiteness = 0;
  2164. pb->picture.depth = pb->win.depth;
  2165. init_waitqueue_head(&pb->capq);
  2166. for(i=0; i<MAX_GBUFFERS; i++) {
  2167. gbuf_ptr gbuf = &pb->gbuf[i];
  2168. gbuf->idx = PLANB_MAX_FBUF * i / PAGE_SIZE;
  2169. gbuf->width=0;
  2170. gbuf->height=0;
  2171. gbuf->fmt=0;
  2172. gbuf->cap_cmd=NULL;
  2173. #ifndef PLANB_GSCANLINE
  2174. gbuf->l_fr_addr_idx = MAX_GBUFFERS * (PLANB_MAX_FBUF
  2175. / PAGE_SIZE + 1) + MAX_LNUM * i;
  2176. gbuf->lsize = 0;
  2177. gbuf->lnum = 0;
  2178. #endif
  2179. }
  2180. pb->rawbuf=NULL;
  2181. pb->grabbing=0;
  2182. /* enable interrupts */
  2183. writel(PLANB_CLR_IRQ, &pb->planb_base->intr_stat);
  2184. pb->intr_mask = PLANB_FRM_IRQ;
  2185. enable_irq(pb->irq);
  2186. /* Now add the templates and register the device units. */
  2187. memcpy(&pb->video_dev,&planb_template,sizeof(planb_template));
  2188. pb->video_dev.priv = pb;
  2189. memcpy(&pb->vbi_dev,&planb_vbi_template,sizeof(planb_vbi_template));
  2190. if(video_register_device(&pb->video_dev, VFL_TYPE_GRABBER, video_nr)<0)
  2191. return -1;
  2192. if(video_register_device(&pb->vbi_dev, VFL_TYPE_VBI, vbi_nr)<0) {
  2193. video_unregister_device(&pb->video_dev);
  2194. return -1;
  2195. }
  2196. return 0;
  2197. }
  2198. /*
  2199.  * Scan for a PlanB controller and map the io memory 
  2200.  */
  2201. static int find_planb(void)
  2202. {
  2203. struct planb *pb;
  2204. struct pci_dev  *pdev = NULL;
  2205. unsigned long base;
  2206. int planb_num = 0;
  2207. if (_machine != _MACH_Pmac)
  2208. return 0;
  2209. pdev = pci_find_device(APPLE_VENDOR_ID, PLANB_DEV_ID, pdev);
  2210. if (pdev == NULL) {
  2211. printk(KERN_WARNING "PlanB: no device found!n");
  2212. return planb_num;
  2213. }
  2214. pb = &planbs;
  2215. planb_num = 1;
  2216. base = pdev->resource[0].start;
  2217. DBG("PlanB: Found device %s, membase 0x%lx, irq %dn",
  2218. pdev->slot_name, base, pdev->irq);
  2219. /* Enable response in memory space, bus mastering,
  2220.    use memory write and invalidate */
  2221. pci_enable_device (pdev);
  2222. pci_set_master (pdev);
  2223. pci_set_mwi(pdev);
  2224. /* value copied from MacOS... */
  2225. pci_write_config_byte (pdev, PCI_LATENCY_TIMER, 0x40);
  2226. planb_regs = (volatile struct planb_registers *)
  2227. ioremap (base, 0x400);
  2228. pb->planb_base = planb_regs;
  2229. pb->planb_base_bus = (struct planb_registers *)base;
  2230. pb->irq = pdev->irq;
  2231. return planb_num;
  2232. }
  2233. static void release_planb(void)
  2234. {
  2235. struct planb *pb;
  2236. pb=&planbs;
  2237. /* stop and flush DMAs unconditionally */
  2238. planb_dbdma_stop(&pb->planb_base->ch2);
  2239. planb_dbdma_stop(&pb->planb_base->ch1);
  2240. /* clear and free interrupts */
  2241. pb->intr_mask = PLANB_CLR_IRQ;
  2242. writel(PLANB_CLR_IRQ, &pb->planb_base->intr_stat);
  2243. free_irq(pb->irq, pb);
  2244. /* make sure all allocated memory are freed */
  2245. planb_prepare_close(pb);
  2246. printk(KERN_INFO "PlanB: unregistering with v4ln");
  2247. video_unregister_device(&pb->video_dev);
  2248. video_unregister_device(&pb->vbi_dev);
  2249. /* note that iounmap() does nothing on the PPC right now */
  2250. iounmap ((void *)pb->planb_base);
  2251. }
  2252. static int __init init_planbs(void)
  2253. {
  2254. int planb_num;
  2255. planb_num=find_planb();
  2256. if (planb_num < 0)
  2257. return -EIO;
  2258. if (planb_num == 0)
  2259. return -ENXIO;
  2260. if (init_planb(&planbs) < 0) {
  2261. printk(KERN_ERR "PlanB: error registering planb device"
  2262. " with v4ln");
  2263. release_planb();
  2264. return -EIO;
  2265. return 0;
  2266. }
  2267. static void __exit exit_planbs(void)
  2268. {
  2269. release_planb();
  2270. }
  2271. module_init(init_planbs);
  2272. module_exit(exit_planbs);