This program is free software you can redistribute it and/or modify it under the terms of the GNU Ge

源代码在线查看: btcx-risc.c

软件大小: 190 K
上传用户: makai1630
关键词: redistribute the software program
下载地址: 免注册下载 普通下载 VIP

相关代码

				/*
				    btcx-risc.c
				
				    bt848/bt878/cx2388x risc code generator.
				
				    (c) 2000-03 Gerd Knorr  [SuSE Labs]
				
				    This program is free software; you can redistribute it and/or modify
				    it under the terms of the GNU General Public License as published by
				    the Free Software Foundation; either version 2 of the License, or
				    (at your option) any later version.
				
				    This program is distributed in the hope that it will be useful,
				    but WITHOUT ANY WARRANTY; without even the implied warranty of
				    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
				    GNU General Public License for more details.
				
				    You should have received a copy of the GNU General Public License
				    along with this program; if not, write to the Free Software
				    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
				
				*/
				
				#include 
				#include 
				#include 
				#include 
				#include 
				#include 
				#include 
				#include 
				
				#include "btcx-risc.h"
				
				MODULE_DESCRIPTION("some code shared by bttv and cx88xx drivers");
				MODULE_AUTHOR("Gerd Knorr");
				MODULE_LICENSE("GPL");
				
				static unsigned int debug = 0;
				MODULE_PARM(debug,"i");
				MODULE_PARM_DESC(debug,"debug messages, default is 0 (no)");
				
				/* ---------------------------------------------------------- */
				/* allocate/free risc memory                                  */
				
				static int memcnt;
				
				void btcx_riscmem_free(struct pci_dev *pci,
						       struct btcx_riscmem *risc)
				{
					if (NULL == risc->cpu)
						return;
					pci_free_consistent(pci, risc->size, risc->cpu, risc->dma);
					memset(risc,0,sizeof(*risc));
					if (debug) {
						memcnt--;
						printk("btcx: riscmem free [%d]\n",memcnt);
					}
				}
				
				int btcx_riscmem_alloc(struct pci_dev *pci,
						       struct btcx_riscmem *risc,
						       unsigned int size)
				{
					u32 *cpu;
					dma_addr_t dma;
				
					if (NULL != risc->cpu && risc->size < size)
						btcx_riscmem_free(pci,risc);
					if (NULL == risc->cpu) {
						cpu = pci_alloc_consistent(pci, size, &dma);
						if (NULL == cpu)
							return -ENOMEM;
						risc->cpu  = cpu;
						risc->dma  = dma;
						risc->size = size;
						if (debug) {
							memcnt++;
							printk("btcx: riscmem alloc size=%d [%d]\n",size,memcnt);
						}
					}
					memset(risc->cpu,0,risc->size);
					return 0;
				}
				
				/* ---------------------------------------------------------- */
				/* screen overlay helpers                                     */
				
				int
				btcx_screen_clips(int swidth, int sheight, struct v4l2_rect *win,
						  struct v4l2_clip *clips, unsigned int n)
				{
					if (win->left < 0) {
						/* left */
						clips[n].c.left = 0;
						clips[n].c.top = 0;
						clips[n].c.width  = -win->left;
						clips[n].c.height = win->height;
						n++;
					}
					if (win->left + win->width > swidth) {
						/* right */
						clips[n].c.left   = swidth - win->left;
						clips[n].c.top    = 0;
						clips[n].c.width  = win->width - clips[n].c.left;
						clips[n].c.height = win->height;
						n++;
					}
					if (win->top < 0) {
						/* top */
						clips[n].c.left = 0;
						clips[n].c.top = 0;
						clips[n].c.width  = win->width;
						clips[n].c.height = -win->top;
						n++;
					}
					if (win->top + win->height > sheight) {
						/* bottom */
						clips[n].c.left = 0;
						clips[n].c.top = sheight - win->top;
						clips[n].c.width  = win->width;
						clips[n].c.height = win->height - clips[n].c.top;
						n++;
					}
					return n;
				}
				
				int
				btcx_align(struct v4l2_rect *win, struct v4l2_clip *clips, unsigned int n, int mask)
				{
					s32 nx,nw,dx;
					unsigned int i;
				
					/* fixup window */
					nx = (win->left + mask) & ~mask;
					nw = (win->width) & ~mask;
					if (nx + nw > win->left + win->width)
						nw -= mask+1;
					dx = nx - win->left;
					win->left  = nx;
					win->width = nw;
					if (debug)
						printk(KERN_DEBUG "btcx: window align %dx%d+%d+%d [dx=%d]\n",
						       win->width, win->height, win->left, win->top, dx);
				
					/* fixup clips */
					for (i = 0; i < n; i++) {
						nx = (clips[i].c.left-dx) & ~mask;
						nw = (clips[i].c.width) & ~mask;
						if (nx + nw < clips[i].c.left-dx + clips[i].c.width)
							nw += mask+1;
						clips[i].c.left  = nx;
						clips[i].c.width = nw;
						if (debug)
							printk(KERN_DEBUG "btcx:   clip align %dx%d+%d+%d\n",
							       clips[i].c.width, clips[i].c.height,
							       clips[i].c.left, clips[i].c.top);
					}
					return 0;
				}
				
				void
				btcx_sort_clips(struct v4l2_clip *clips, unsigned int nclips)
				{
					struct v4l2_clip swap;
					int i,j,n;
				
					if (nclips < 2)
						return;
					for (i = nclips-2; i >= 0; i--) {
						for (n = 0, j = 0; j 							if (clips[j].c.left > clips[j+1].c.left) {
								swap = clips[j];
								clips[j] = clips[j+1];
								clips[j+1] = swap;
								n++;
							}
						}
						if (0 == n)
							break;
					}
				}
				
				void
				btcx_calc_skips(int line, int width, unsigned int *maxy,
						struct btcx_skiplist *skips, unsigned int *nskips,
						const struct v4l2_clip *clips, unsigned int nclips)
				{
					unsigned int clip,skip;
					int end,maxline;
					
					skip=0;
					maxline = 9999;
					for (clip = 0; clip < nclips; clip++) {
				
						/* sanity checks */
						if (clips[clip].c.left + clips[clip].c.width 							continue;
						if (clips[clip].c.left > (signed)width)
							break;
						
						/* vertical range */
						if (line > clips[clip].c.top+clips[clip].c.height-1)
							continue;
						if (line < clips[clip].c.top) {
							if (maxline > clips[clip].c.top-1)
								maxline = clips[clip].c.top-1;
							continue;
						}
						if (maxline > clips[clip].c.top+clips[clip].c.height-1)
							maxline = clips[clip].c.top+clips[clip].c.height-1;
				
						/* horizontal range */
						if (0 == skip || clips[clip].c.left > skips[skip-1].end) {
							/* new one */
							skips[skip].start = clips[clip].c.left;
							if (skips[skip].start < 0)
								skips[skip].start = 0;
							skips[skip].end = clips[clip].c.left + clips[clip].c.width;
							if (skips[skip].end > width)
								skips[skip].end = width;
							skip++;
						} else {
							/* overlaps -- expand last one */
							end = clips[clip].c.left + clips[clip].c.width;
							if (skips[skip-1].end < end)
								skips[skip-1].end = end;
							if (skips[skip-1].end > width)
								skips[skip-1].end = width;
						}
					}
					*nskips = skip;
					*maxy = maxline;
				
					if (debug) {
						printk(KERN_DEBUG "btcx: skips line %d-%d:",line,maxline);
						for (skip = 0; skip < *nskips; skip++) {
							printk(" %d-%d",skips[skip].start,skips[skip].end);
						}
						printk("\n");
					}
				}
				
				/* ---------------------------------------------------------- */
				
				EXPORT_SYMBOL(btcx_riscmem_alloc);
				EXPORT_SYMBOL(btcx_riscmem_free);
				
				EXPORT_SYMBOL(btcx_screen_clips);
				EXPORT_SYMBOL(btcx_align);
				EXPORT_SYMBOL(btcx_sort_clips);
				EXPORT_SYMBOL(btcx_calc_skips);
				
				/*
				 * Local variables:
				 * c-basic-offset: 8
				 * End:
				 */
							

相关资源