📄 av7110.c
字号:
#ifndef _NOHANDSHAKE start = jiffies; while ( rdebi(av7110, DEBINOSWAP, HANDSHAKE_REG, 0, 2 ) ) { ddelay(1); if ((jiffies - start) > ARM_WAIT_SHAKE) { printk(KERN_ERR "%s: timeout waiting for HANDSHAKE_REG\n", __FUNCTION__); up(&av7110->dcomlock); return -1; } }#endif for (i=0; i<length/2; i++) wdebi(av7110, DEBINOSWAP, BUFF1_BASE + i*2, swab16(*(u16 *)(buf+2*i)), 2); if (length&1) wdebi(av7110, DEBINOSWAP, BUFF1_BASE + i*2, 0, 2); ret=OutCommand(av7110, cbuf, 5); up(&av7110->dcomlock); if (ret) printk("WriteText error\n"); return ret;}inline static int DrawLine(av7110_t *av7110, u8 windownr, u16 x, u16 y, u16 dx, u16 dy, u16 color){ return outcom(av7110, COMTYPE_OSD, DLine, 6, windownr, x, y, dx, dy, color);} inline static int DrawBlock(av7110_t *av7110, u8 windownr, u16 x, u16 y, u16 dx, u16 dy, u16 color){ return outcom(av7110, COMTYPE_OSD, DBox, 6, windownr, x, y, dx, dy, color);} inline static int HideWindow(av7110_t *av7110, u8 windownr){ return outcom(av7110, COMTYPE_OSD, WHide, 1, windownr);} inline static int MoveWindowRel(av7110_t *av7110, u8 windownr, u16 x, u16 y){ return outcom(av7110, COMTYPE_OSD, WMoveD, 3, windownr, x, y);} inline static int MoveWindowAbs(av7110_t *av7110, u8 windownr, u16 x, u16 y){ return outcom(av7110, COMTYPE_OSD, WMoveA, 3, windownr, x, y);} inline static int DestroyOSDWindow(av7110_t *av7110, u8 windownr){ return outcom(av7110, COMTYPE_OSD, WDestroy, 1, windownr);} #if 0static void DestroyOSDWindows(av7110_t *av7110){ int i; for (i=1; i<7; i++) outcom(av7110, COMTYPE_OSD, WDestroy, 1, i);} #endifstatic inline int CreateOSDWindow(av7110_t *av7110, u8 windownr, DISPTYPE disptype, u16 width, u16 height){ return outcom(av7110, COMTYPE_OSD, WCreate, 4, windownr, disptype, width, height);} static OSDPALTYPE bpp2pal[8]={Pal1Bit, Pal2Bit, 0, Pal4Bit, 0, 0, 0, Pal8Bit}; static DISPTYPE bpp2bit[8]={BITMAP1, BITMAP2, 0, BITMAP4, 0, 0, 0, BITMAP8}; static inline int LoadBitmap(av7110_t *av7110, u16 format, u16 dx, u16 dy, int inc, u8* data){ int bpp; int i; int d, delta; u8 c; DECLARE_WAITQUEUE(wait, current); if (av7110->bmp_state==BMP_LOADING) { add_wait_queue(&av7110->bmpq, &wait); while (1) { set_current_state(TASK_INTERRUPTIBLE); if (av7110->bmp_state!=BMP_LOADING || signal_pending(current)) break; schedule(); } current->state=TASK_RUNNING; remove_wait_queue(&av7110->bmpq, &wait); } if (av7110->bmp_state==BMP_LOADING) return -1; av7110->bmp_state=BMP_LOADING; if (format==BITMAP8) { bpp=8; delta = 1; } else if (format==BITMAP4) { bpp=4; delta = 2; } else if (format==BITMAP2) { bpp=2; delta = 4; } else if (format==BITMAP1) { bpp=1; delta = 8; } else { av7110->bmp_state=BMP_NONE; return -1; } av7110->bmplen= ((dx*dy*bpp+7)&~7)/8; av7110->bmpp=0; if (av7110->bmplen>32768) { av7110->bmp_state=BMP_NONE; return -1; } for (i=0; i<dy; i++) { if (copy_from_user(av7110->bmpbuf+1024+i*dx, data+i*inc, dx)) { av7110->bmp_state=BMP_NONE; return -1; } } if (format != BITMAP8) { for (i=0; i<dx*dy/delta; i++) { c = ((u8 *)av7110->bmpbuf)[1024+i*delta+delta-1]; for (d=delta-2; d>=0; d--) { c |= (((u8 *)av7110->bmpbuf)[1024+i*delta+d] << ((delta-d-1)*bpp)); ((u8 *)av7110->bmpbuf)[1024+i] = c; } } } av7110->bmplen+=1024; return outcom(av7110, COMTYPE_OSD, LoadBmp, 3, format, dx, dy);} static int BlitBitmap(av7110_t *av7110, u16 win, u16 x, u16 y, u16 trans){ DECLARE_WAITQUEUE(wait, current); if (av7110->bmp_state==BMP_NONE) return -1; if (av7110->bmp_state==BMP_LOADING) { add_wait_queue(&av7110->bmpq, &wait); while (1) { set_current_state(TASK_INTERRUPTIBLE); if (av7110->bmp_state!=BMP_LOADING || signal_pending(current)) break; schedule(); } current->state=TASK_RUNNING; remove_wait_queue(&av7110->bmpq, &wait); } if (av7110->bmp_state==BMP_LOADED) return outcom(av7110, COMTYPE_OSD, BlitBmp, 4, win, x, y, trans); return -1;} static inline int ReleaseBitmap(av7110_t *av7110){ if (av7110->bmp_state!=BMP_LOADED) return -1; av7110->bmp_state=BMP_NONE; return outcom(av7110, COMTYPE_OSD, ReleaseBmp, 0);} static u32 RGB2YUV(u16 R, u16 G, u16 B){ u16 y, u, v; u16 Y, Cr, Cb; y = R * 77 + G * 150 + B * 29; // Luma=0.299R+0.587G+0.114B 0..65535 u = 2048+B * 8 -(y>>5); // Cr 0..4095 v = 2048+R * 8 -(y>>5); // Cb 0..4095 Y=y/256; Cb=u/16; Cr=v/16; return Cr|(Cb<<16)|(Y<<8);}static voidOSDSetColor(av7110_t *av7110, u8 color, u8 r, u8 g, u8 b, u8 blend){ u16 ch, cl; u32 yuv; yuv=blend ? RGB2YUV(r,g,b) : 0; cl=(yuv&0xffff); ch=((yuv>>16)&0xffff); SetColor_(av7110, av7110->osdwin, bpp2pal[av7110->osdbpp[av7110->osdwin]], color, ch, cl); SetBlend_(av7110, av7110->osdwin, bpp2pal[av7110->osdbpp[av7110->osdwin]], color, ((blend>>4)&0x0f));}static intOSDSetBlock(av7110_t *av7110, int x0, int y0, int x1, int y1, int inc, u8 *data){ uint w, h, bpp, bpl, size, lpb, bnum, brest; int i; w=x1-x0+1; h=y1-y0+1; if (inc<=0) inc=w; if (w<=0 || w>720 || h<=0 || h>576) return -1; bpp=av7110->osdbpp[av7110->osdwin]+1; bpl=((w*bpp+7)&~7)/8; size=h*bpl; lpb=(32*1024)/bpl; bnum=size/(lpb*bpl); brest=size-bnum*lpb*bpl; for (i=0; i<bnum; i++) { LoadBitmap(av7110, bpp2bit[av7110->osdbpp[av7110->osdwin]], w, lpb, inc, data); BlitBitmap(av7110, av7110->osdwin, x0, y0+i*lpb, 0); data+=lpb*inc; } if (brest) { LoadBitmap(av7110, bpp2bit[av7110->osdbpp[av7110->osdwin]], w, brest/bpl, inc, data); BlitBitmap(av7110, av7110->osdwin, x0, y0+bnum*lpb, 0); } ReleaseBitmap(av7110); return 0;}static int OSD_DrawCommand(av7110_t *av7110, osd_cmd_t *dc){ switch (dc->cmd) { case OSD_Close: DestroyOSDWindow(av7110, av7110->osdwin); return 0; case OSD_Open: av7110->osdbpp[av7110->osdwin]=(dc->color-1)&7; CreateOSDWindow(av7110, av7110->osdwin, bpp2bit[av7110->osdbpp[av7110->osdwin]], dc->x1-dc->x0+1, dc->y1-dc->y0+1); if (!dc->data) { MoveWindowAbs(av7110, av7110->osdwin, dc->x0, dc->y0); SetColorBlend(av7110, av7110->osdwin); } return 0; case OSD_Show: MoveWindowRel(av7110, av7110->osdwin, 0, 0); return 0; case OSD_Hide: HideWindow(av7110, av7110->osdwin); return 0; case OSD_Clear: DrawBlock(av7110, av7110->osdwin, 0, 0, 720, 576, 0); return 0; case OSD_Fill: DrawBlock(av7110, av7110->osdwin, 0, 0, 720, 576, dc->color); return 0; case OSD_SetColor: OSDSetColor(av7110, dc->color, dc->x0, dc->y0, dc->x1, dc->y1); return 0; case OSD_SetPalette: { int i, len=dc->x0-dc->color+1; u8 *colors=(u8 *)dc->data; for (i=0; i<len; i++) OSDSetColor(av7110, dc->color+i, colors[i*4] , colors[i*4+1], colors[i*4+2], colors[i*4+3]); return 0; } case OSD_SetTrans: return 0; case OSD_SetPixel: DrawLine(av7110, av7110->osdwin, dc->x0, dc->y0, 0, 0, dc->color); return 0; case OSD_GetPixel: return 0; case OSD_SetRow: dc->y1=dc->y0; case OSD_SetBlock: OSDSetBlock(av7110, dc->x0, dc->y0, dc->x1, dc->y1, dc->color, dc->data); return 0; case OSD_FillRow: DrawBlock(av7110, av7110->osdwin, dc->x0, dc->y0, dc->x1-dc->x0+1, dc->y1, dc->color); return 0; case OSD_FillBlock: DrawBlock(av7110, av7110->osdwin, dc->x0, dc->y0, dc->x1-dc->x0+1, dc->y1-dc->y0+1, dc->color); return 0; case OSD_Line: DrawLine(av7110, av7110->osdwin, dc->x0, dc->y0, dc->x1-dc->x0, dc->y1-dc->y0, dc->color); return 0; case OSD_Query: return 0; case OSD_Test: return 0; case OSD_Text: { char textbuf[240]; if (strncpy_from_user(textbuf, dc->data, 240)<0) return -EFAULT; textbuf[239]=0; if (dc->x1>3) dc->x1=3; SetFont(av7110, av7110->osdwin, dc->x1, (u16) (dc->color&0xffff), (u16) (dc->color>>16)); FlushText(av7110); WriteText(av7110, av7110->osdwin, dc->x0, dc->y0, textbuf); return 0; } case OSD_SetWindow: if (dc->x0<1 || dc->x0>7) return -EINVAL; av7110->osdwin=dc->x0; return 0; case OSD_MoveWindow: MoveWindowAbs(av7110, av7110->osdwin, dc->x0, dc->y0); SetColorBlend(av7110, av7110->osdwin); return 0; default: return -EINVAL; }}static int dvb_osd_ioctl(struct inode *inode, struct file *file, unsigned int cmd, void *parg){ struct dvb_device *dvbdev=(struct dvb_device *) file->private_data; av7110_t *av7110=(av7110_t *) dvbdev->priv; if (cmd==OSD_SEND_CMD) return OSD_DrawCommand(av7110, (osd_cmd_t *)parg); return -EINVAL;}static struct file_operations dvb_osd_fops = { .owner = THIS_MODULE, .ioctl = dvb_generic_ioctl, .open = dvb_generic_open, .release = dvb_generic_release,};static struct dvb_device dvbdev_osd = { .priv = 0, .users = 1, .writers = 1, .fops = &dvb_osd_fops, .kernel_ioctl = dvb_osd_ioctl,};#endif /* CONFIG_DVB_AV7110_OSD *//* get version of the firmware ROM, RTSL, video ucode and ARM application */static void firmversion(av7110_t *av7110){ u16 buf[20]; u16 tag = ((COMTYPE_REQUEST << 8) + ReqVersion); RequestParameter(av7110, tag, buf, 16); av7110->arm_fw=(buf[0] << 16) + buf[1]; av7110->arm_rtsl=(buf[2] << 16) + buf[3]; av7110->arm_vid=(buf[4] << 16) + buf[5]; av7110->arm_app=(buf[6] << 16) + buf[7]; av7110->avtype=(buf[8] << 16) + buf[9]; printk ("DVB: AV711%d(%d) - firm %08x, rtsl %08x, vid %08x, app %08x\n", av7110->avtype, av7110->saa->dvb_adapter->num, av7110->arm_fw, av7110->arm_rtsl, av7110->arm_vid, av7110->arm_app); /* print firmware capabilities */ if ((av7110->arm_app >> 16) & 0x8000) printk ("DVB: AV711%d(%d) - firmware supports CI link layer interface\n", av7110->avtype, av7110->saa->dvb_adapter->num); else printk ("DVB: AV711%d(%d) - no firmware support for CI link layer interface\n", av7110->avtype, av7110->saa->dvb_adapter->num); return;}static int waitdebi(av7110_t *av7110, int adr, int state){ int k; for (k=0; k<100; k++, udelay(500)) { if (irdebi(av7110, DEBINOSWAP, adr, 0, 2) == state) return 0; } return -1;}static int load_dram(av7110_t *av7110, u32 *data, int len){ int i; int blocks, rest; u32 base, b
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -