📄 av7110_hw.c
字号:
default: break; } if (type != NULL) { /* non-immediate COMMAND type */ start = jiffies; for (;;) { err = time_after(jiffies, start + ARM_WAIT_FREE); stat = rdebi(av7110, DEBINOSWAP, MSGSTATE, 0, 2); if (stat & flags[0]) { printk(KERN_ERR "%s: %s QUEUE overflow\n", __FUNCTION__, type); return -1; } if ((stat & flags[1]) == 0) break; if (err) { printk(KERN_ERR "%s: timeout waiting on busy %s QUEUE\n", __FUNCTION__, type); return -ETIMEDOUT; } msleep(1); } } for (i = 2; i < length; i++) wdebi(av7110, DEBINOSWAP, COMMAND + 2 * i, (u32) buf[i], 2); if (length) wdebi(av7110, DEBINOSWAP, COMMAND + 2, (u32) buf[1], 2); else wdebi(av7110, DEBINOSWAP, COMMAND + 2, 0, 2); wdebi(av7110, DEBINOSWAP, COMMAND, (u32) buf[0], 2); if (FW_VERSION(av7110->arm_app) <= 0x261f) wdebi(av7110, DEBINOSWAP, COM_IF_LOCK, 0x0000, 2);#ifdef COM_DEBUG start = jiffies; while (1) { err = time_after(jiffies, start + ARM_WAIT_FREE); if (rdebi(av7110, DEBINOSWAP, COMMAND, 0, 2) == 0) break; if (err) { printk(KERN_ERR "dvb-ttpci: %s(): timeout waiting for COMMAND %d to complete\n", __FUNCTION__, (buf[0] >> 8) & 0xff); return -ETIMEDOUT; } msleep(1); } stat = rdebi(av7110, DEBINOSWAP, MSGSTATE, 0, 2); if (stat & GPMQOver) { printk(KERN_ERR "dvb-ttpci: %s(): GPMQOver\n", __FUNCTION__); return -ENOSPC; } else if (stat & OSDQOver) { printk(KERN_ERR "dvb-ttpci: %s(): OSDQOver\n", __FUNCTION__); return -ENOSPC; }#endif return 0;}static int av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length){ int ret;// dprintk(4, "%p\n", av7110); if (!av7110->arm_ready) { dprintk(1, "arm not ready.\n"); return -1; } if (down_interruptible(&av7110->dcomlock)) return -ERESTARTSYS; ret = __av7110_send_fw_cmd(av7110, buf, length); up(&av7110->dcomlock); if (ret && ret!=-ERESTARTSYS) printk(KERN_ERR "dvb-ttpci: %s(): av7110_send_fw_cmd error %d\n", __FUNCTION__, ret); return ret;}int av7110_fw_cmd(struct av7110 *av7110, int type, int com, int num, ...){ va_list args; u16 buf[num + 2]; int i, ret;// dprintk(4, "%p\n", av7110); buf[0] = ((type << 8) | com); buf[1] = num; if (num) { va_start(args, num); for (i = 0; i < num; i++) buf[i + 2] = va_arg(args, u32); va_end(args); } ret = av7110_send_fw_cmd(av7110, buf, num + 2); if (ret && ret != -ERESTARTSYS) printk(KERN_ERR "dvb-ttpci: av7110_fw_cmd error %d\n", ret); return ret;}#if 0int av7110_send_ci_cmd(struct av7110 *av7110, u8 subcom, u8 *buf, u8 len){ int i, ret; u16 cmd[18] = { ((COMTYPE_COMMON_IF << 8) + subcom), 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; dprintk(4, "%p\n", av7110); for(i = 0; i < len && i < 32; i++) { if(i % 2 == 0) cmd[(i / 2) + 2] = (u16)(buf[i]) << 8; else cmd[(i / 2) + 2] |= buf[i]; } ret = av7110_send_fw_cmd(av7110, cmd, 18); if (ret && ret != -ERESTARTSYS) printk(KERN_ERR "dvb-ttpci: av7110_send_ci_cmd error %d\n", ret); return ret;}#endif /* 0 */int av7110_fw_request(struct av7110 *av7110, u16 *request_buf, int request_buf_len, u16 *reply_buf, int reply_buf_len){ int err; s16 i; unsigned long start;#ifdef COM_DEBUG u32 stat;#endif dprintk(4, "%p\n", av7110); if (!av7110->arm_ready) { dprintk(1, "arm not ready.\n"); return -1; } if (down_interruptible(&av7110->dcomlock)) return -ERESTARTSYS; if ((err = __av7110_send_fw_cmd(av7110, request_buf, request_buf_len)) < 0) { up(&av7110->dcomlock); printk(KERN_ERR "dvb-ttpci: av7110_fw_request error %d\n", err); return err; } start = jiffies; while (1) { err = time_after(jiffies, start + ARM_WAIT_FREE); if (rdebi(av7110, DEBINOSWAP, COMMAND, 0, 2) == 0) break; if (err) { printk(KERN_ERR "%s: timeout waiting for COMMAND to complete\n", __FUNCTION__); up(&av7110->dcomlock); return -ETIMEDOUT; }#ifdef _NOHANDSHAKE msleep(1);#endif }#ifndef _NOHANDSHAKE start = jiffies; while (1) { err = time_after(jiffies, start + ARM_WAIT_SHAKE); if (rdebi(av7110, DEBINOSWAP, HANDSHAKE_REG, 0, 2) == 0) break; if (err) { printk(KERN_ERR "%s: timeout waiting for HANDSHAKE_REG\n", __FUNCTION__); up(&av7110->dcomlock); return -ETIMEDOUT; } msleep(1); }#endif#ifdef COM_DEBUG stat = rdebi(av7110, DEBINOSWAP, MSGSTATE, 0, 2); if (stat & GPMQOver) { printk(KERN_ERR "%s: GPMQOver\n", __FUNCTION__); up(&av7110->dcomlock); return -1; } else if (stat & OSDQOver) { printk(KERN_ERR "%s: OSDQOver\n", __FUNCTION__); up(&av7110->dcomlock); return -1; }#endif for (i = 0; i < reply_buf_len; i++) reply_buf[i] = rdebi(av7110, DEBINOSWAP, COM_BUFF + 2 * i, 0, 2); up(&av7110->dcomlock); return 0;}static int av7110_fw_query(struct av7110 *av7110, u16 tag, u16* buf, s16 length){ int ret; ret = av7110_fw_request(av7110, &tag, 0, buf, length); if (ret) printk(KERN_ERR "dvb-ttpci: av7110_fw_query error %d\n", ret); return ret;}/**************************************************************************** * Firmware commands ****************************************************************************//* get version of the firmware ROM, RTSL, video ucode and ARM application */int av7110_firmversion(struct av7110 *av7110){ u16 buf[20]; u16 tag = ((COMTYPE_REQUEST << 8) + ReqVersion); dprintk(4, "%p\n", av7110); if (av7110_fw_query(av7110, tag, buf, 16)) { printk("dvb-ttpci: failed to boot firmware @ card %d\n", av7110->dvb_adapter.num); return -EIO; } 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-ttpci: info @ card %d: firm %08x, rtsl %08x, vid %08x, app %08x\n", av7110->dvb_adapter.num, av7110->arm_fw, av7110->arm_rtsl, av7110->arm_vid, av7110->arm_app); /* print firmware capabilities */ if (FW_CI_LL_SUPPORT(av7110->arm_app)) printk("dvb-ttpci: firmware @ card %d supports CI link layer interface\n", av7110->dvb_adapter.num); else printk("dvb-ttpci: no firmware support for CI link layer interface @ card %d\n", av7110->dvb_adapter.num); return 0;}int av7110_diseqc_send(struct av7110 *av7110, int len, u8 *msg, unsigned long burst){ int i, ret; u16 buf[18] = { ((COMTYPE_AUDIODAC << 8) + SendDiSEqC), 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; dprintk(4, "%p\n", av7110); if (len > 10) len = 10; buf[1] = len + 2; buf[2] = len; if (burst != -1) buf[3] = burst ? 0x01 : 0x00; else buf[3] = 0xffff; for (i = 0; i < len; i++) buf[i + 4] = msg[i]; ret = av7110_send_fw_cmd(av7110, buf, 18); if (ret && ret!=-ERESTARTSYS) printk(KERN_ERR "dvb-ttpci: av7110_diseqc_send error %d\n", ret); return ret;}#ifdef CONFIG_DVB_AV7110_OSDstatic inline int SetColorBlend(struct av7110 *av7110, u8 windownr){ return av7110_fw_cmd(av7110, COMTYPE_OSD, SetCBlend, 1, windownr);}static inline int SetBlend_(struct av7110 *av7110, u8 windownr, enum av7110_osd_palette_type colordepth, u16 index, u8 blending){ return av7110_fw_cmd(av7110, COMTYPE_OSD, SetBlend, 4, windownr, colordepth, index, blending);}static inline int SetColor_(struct av7110 *av7110, u8 windownr, enum av7110_osd_palette_type colordepth, u16 index, u16 colorhi, u16 colorlo){ return av7110_fw_cmd(av7110, COMTYPE_OSD, SetColor, 5, windownr, colordepth, index, colorhi, colorlo);}static inline int SetFont(struct av7110 *av7110, u8 windownr, u8 fontsize, u16 colorfg, u16 colorbg){ return av7110_fw_cmd(av7110, COMTYPE_OSD, Set_Font, 4, windownr, fontsize, colorfg, colorbg);}static int FlushText(struct av7110 *av7110){ unsigned long start; int err; if (down_interruptible(&av7110->dcomlock)) return -ERESTARTSYS; start = jiffies; while (1) { err = time_after(jiffies, start + ARM_WAIT_OSD); if (rdebi(av7110, DEBINOSWAP, BUFF1_BASE, 0, 2) == 0) break; if (err) { printk(KERN_ERR "dvb-ttpci: %s(): timeout waiting for BUFF1_BASE == 0\n", __FUNCTION__); up(&av7110->dcomlock); return -ETIMEDOUT; } msleep(1); } up(&av7110->dcomlock); return 0;}static int WriteText(struct av7110 *av7110, u8 win, u16 x, u16 y, u8* buf){ int i, ret; unsigned long start; int length = strlen(buf) + 1; u16 cbuf[5] = { (COMTYPE_OSD << 8) + DText, 3, win, x, y }; if (down_interruptible(&av7110->dcomlock)) return -ERESTARTSYS; start = jiffies; while (1) { ret = time_after(jiffies, start + ARM_WAIT_OSD); if (rdebi(av7110, DEBINOSWAP, BUFF1_BASE, 0, 2) == 0) break; if (ret) { printk(KERN_ERR "dvb-ttpci: %s: timeout waiting for BUFF1_BASE == 0\n", __FUNCTION__); up(&av7110->dcomlock); return -ETIMEDOUT; } msleep(1); }#ifndef _NOHANDSHAKE start = jiffies; while (1) { ret = time_after(jiffies, start + ARM_WAIT_SHAKE); if (rdebi(av7110, DEBINOSWAP, HANDSHAKE_REG, 0, 2) == 0) break; if (ret) { printk(KERN_ERR "dvb-ttpci: %s: timeout waiting for HANDSHAKE_REG\n", __FUNCTION__); up(&av7110->dcomlock); return -ETIMEDOUT; } msleep(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 = __av7110_send_fw_cmd(av7110, cbuf, 5); up(&av7110->dcomlock); if (ret && ret!=-ERESTARTSYS) printk(KERN_ERR "dvb-ttpci: WriteText error %d\n", ret); return ret;}static inline int DrawLine(struct av7110 *av7110, u8 windownr, u16 x, u16 y, u16 dx, u16 dy, u16 color){ return av7110_fw_cmd(av7110, COMTYPE_OSD, DLine, 6, windownr, x, y, dx, dy, color);}static inline int DrawBlock(struct av7110 *av7110, u8 windownr, u16 x, u16 y, u16 dx, u16 dy, u16 color){ return av7110_fw_cmd(av7110, COMTYPE_OSD, DBox, 6, windownr, x, y, dx, dy, color);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -