32 #include <linux/types.h>
33 #include <linux/kernel.h>
34 #include <linux/string.h>
55 if (count <= 0 || count > 32764) {
56 printk(
"%s: invalid count %d\n", __func__, count);
60 printk(
"%s: wait_for_debi_done failed\n", __func__);
78 if (count > 32764 || count <= 0) {
79 printk(
"%s: invalid count %d\n", __func__, count);
83 printk(
"%s: wait_for_debi_done #1 failed\n", __func__);
94 printk(
"%s: wait_for_debi_done #2 failed\n", __func__);
99 result &= (0xffffffff
UL >> ((4 -
count) * 8));
118 ARM_ResetMailBox(av7110);
134 for (k = 0; k < 100; k++) {
135 if (irdebi(av7110,
DEBINOSWAP, adr, 0, 2) == state)
142 static int load_dram(
struct av7110 *av7110,
u32 *
data,
int len)
154 for (i = 0; i < blocks; i++) {
156 printk(
KERN_ERR "dvb-ttpci: load_dram(): timeout at block %d\n", i);
159 dprintk(4,
"writing DRAM block %d\n", i);
171 printk(
KERN_ERR "dvb-ttpci: load_dram(): timeout at last block\n");
186 printk(
KERN_ERR "dvb-ttpci: load_dram(): timeout after last block\n");
192 printk(
KERN_ERR "dvb-ttpci: load_dram(): final handshake timeout\n");
204 const char *
fw_name =
"av7110/bootcode.bin";
230 printk(
KERN_ERR "dvb-ttpci: debi test in av7110_bootarm() failed: "
231 "%08x != %08x (check your BIOS 'Plug&Play OS' settings)\n",
235 for (i = 0; i < 8192; i += 4)
240 dprintk(1,
"load boot code\n");
258 "saa7146_wait_for_debi_done() timed out\n");
264 dprintk(1,
"load dram code\n");
267 "load_dram() failed\n");
274 dprintk(1,
"load dpram code\n");
279 "saa7146_wait_for_debi_done() timed out after loading DRAM\n");
286 ARM_ResetMailBox(av7110);
320 if ((stat & flags) == 0)
324 __func__, stat & flags);
332 static int __av7110_send_fw_cmd(
struct av7110 *av7110,
u16*
buf,
int length)
344 dprintk(1,
"arm not ready.\n");
354 printk(
KERN_ERR "dvb-ttpci: %s(): timeout waiting for COMMAND idle\n", __func__);
371 printk(
KERN_ERR "dvb-ttpci: %s(): timeout waiting for HANDSHAKE_REG\n", __func__);
378 switch ((buf[0] >> 8) & 0xff) {
409 if (stat & flags[0]) {
414 if ((stat & flags[1]) == 0)
426 for (i = 2; i <
length; i++)
446 printk(
KERN_ERR "dvb-ttpci: %s(): timeout waiting for COMMAND %d to complete\n",
447 __func__, (buf[0] >> 8) & 0xff);
467 static int av7110_send_fw_cmd(
struct av7110 *av7110,
u16* buf,
int length)
474 dprintk(1,
"arm not ready.\n");
480 ret = __av7110_send_fw_cmd(av7110, buf, length);
496 buf[0] = ((type << 8) | com);
501 for (i = 0; i < num; i++)
506 ret = av7110_send_fw_cmd(av7110, buf, num + 2);
513 int av7110_send_ci_cmd(
struct av7110 *av7110,
u8 subcom,
u8 *buf,
u8 len)
517 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
521 for(i = 0; i < len && i < 32; i++)
524 cmd[(i / 2) + 2] = (
u16)(buf[
i]) << 8;
526 cmd[(i / 2) + 2] |= buf[i];
529 ret = av7110_send_fw_cmd(av7110, cmd, 18);
549 dprintk(1,
"arm not ready.\n");
556 if ((err = __av7110_send_fw_cmd(av7110, request_buf, request_buf_len)) < 0) {
568 printk(
KERN_ERR "%s: timeout waiting for COMMAND to complete\n", __func__);
584 printk(
KERN_ERR "%s: timeout waiting for HANDSHAKE_REG\n", __func__);
594 if (stat & GPMQOver) {
613 static int av7110_fw_query(
struct av7110 *av7110,
u16 tag,
u16* buf,
s16 length)
635 if (av7110_fw_query(av7110, tag, buf, 16)) {
636 printk(
"dvb-ttpci: failed to boot firmware @ card %d\n",
641 av7110->
arm_fw = (buf[0] << 16) + buf[1];
642 av7110->
arm_rtsl = (buf[2] << 16) + buf[3];
643 av7110->
arm_vid = (buf[4] << 16) + buf[5];
644 av7110->
arm_app = (buf[6] << 16) + buf[7];
645 av7110->
avtype = (buf[8] << 16) + buf[9];
647 printk(
"dvb-ttpci: info @ card %d: firm %08x, rtsl %08x, vid %08x, app %08x\n",
653 printk(
"dvb-ttpci: firmware @ card %d supports CI link layer interface\n",
656 printk(
"dvb-ttpci: no firmware support for CI link layer interface @ card %d\n",
667 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
678 buf[3] = burst ? 0x01 : 0x00;
682 for (i = 0; i < len; i++)
685 ret = av7110_send_fw_cmd(av7110, buf, 18);
692 #ifdef CONFIG_DVB_AV7110_OSD
694 static inline int SetColorBlend(
struct av7110 *av7110,
u8 windownr)
699 static inline int SetBlend_(
struct av7110 *av7110,
u8 windownr,
703 windownr, colordepth, index, blending);
706 static inline int SetColor_(
struct av7110 *av7110,
u8 windownr,
710 windownr, colordepth, index, colorhi, colorlo);
713 static inline int SetFont(
struct av7110 *av7110,
u8 windownr,
u8 fontsize,
717 windownr, fontsize, colorfg, colorbg);
720 static int FlushText(
struct av7110 *av7110)
733 printk(
KERN_ERR "dvb-ttpci: %s(): timeout waiting for BUFF1_BASE == 0\n",
744 static int WriteText(
struct av7110 *av7110,
u8 win,
u16 x,
u16 y,
char *buf)
748 int length =
strlen(buf) + 1;
760 printk(
KERN_ERR "dvb-ttpci: %s: timeout waiting for BUFF1_BASE == 0\n",
774 printk(
KERN_ERR "dvb-ttpci: %s: timeout waiting for HANDSHAKE_REG\n",
782 for (i = 0; i < length / 2; i++)
787 ret = __av7110_send_fw_cmd(av7110, cbuf, 5);
794 static inline int DrawLine(
struct av7110 *av7110,
u8 windownr,
798 windownr, x, y, dx, dy, color);
801 static inline int DrawBlock(
struct av7110 *av7110,
u8 windownr,
805 windownr, x, y, dx, dy, color);
808 static inline int HideWindow(
struct av7110 *av7110,
u8 windownr)
813 static inline int MoveWindowRel(
struct av7110 *av7110,
u8 windownr,
u16 x,
u16 y)
818 static inline int MoveWindowAbs(
struct av7110 *av7110,
u8 windownr,
u16 x,
u16 y)
823 static inline int DestroyOSDWindow(
struct av7110 *av7110,
u8 windownr)
828 static inline int CreateOSDWindow(
struct av7110 *av7110,
u8 windownr,
833 windownr, disptype, width, height);
844 static inline int WaitUntilBmpLoaded(
struct av7110 *av7110)
849 printk(
"dvb-ttpci: warning: timeout waiting in LoadBitmap: %d, %d\n",
857 static inline int LoadBitmap(
struct av7110 *av7110,
884 av7110->
bmplen = ((dx * dy * bpp + 7) & ~7) / 8;
886 if (av7110->
bmplen > 32768) {
890 for (i = 0; i < dy; i++) {
897 for (i = 0; i < dx * dy /
delta; i++) {
898 c = ((
u8 *)av7110->
bmpbuf)[1024 + i * delta + delta - 1];
899 for (d = delta - 2; d >= 0; d--) {
900 c |= (((
u8 *)av7110->
bmpbuf)[1024 + i * delta +
d]
901 << ((delta - d - 1) * bpp));
907 dprintk(4,
"av7110_fw_cmd: LoadBmp size %d\n", av7110->
bmplen);
910 ret = WaitUntilBmpLoaded(av7110);
914 static int BlitBitmap(
struct av7110 *av7110,
u16 x,
u16 y)
921 static inline int ReleaseBitmap(
struct av7110 *av7110)
928 dprintk(1,
"ReleaseBitmap called while BMP_LOADING\n");
938 y = R * 77 + G * 150 + B * 29;
939 u = 2048 + B * 8 -(y >> 5);
940 v = 2048 + R * 8 -(y >> 5);
946 return Cr | (Cb << 16) | (Y << 8);
949 static int OSDSetColor(
struct av7110 *av7110,
u8 color,
u8 r,
u8 g,
u8 b,
u8 blend)
956 yuv = blend ? RGB2YUV(r,g,b) : 0;
958 ch = ((yuv >> 16) & 0xffff);
963 color, ((blend >> 4) & 0x0f));
967 static int OSDSetPalette(
struct av7110 *av7110,
u32 __user *
colors,
u8 first,
u8 last)
970 int length = last - first + 1;
975 for (i = 0; i <
length; i++) {
980 blend = (color & 0xF0000000) >> 4;
981 yuv = blend ? RGB2YUV(color & 0xFF, (color >> 8) & 0xFF,
982 (color >> 16) & 0xFF) | blend : 0;
983 yuv = ((yuv & 0xFFFF0000) >> 16) | ((yuv & 0x0000FFFF) << 16);
992 static int OSDSetBlock(
struct av7110 *av7110,
int x0,
int y0,
993 int x1,
int y1,
int inc,
u8 __user * data)
1003 if (w <= 0 || w > 720 || h <= 0 || h > 576)
1006 bpl = ((w * bpp + 7) & ~7) / 8;
1008 lpb = (32 * 1024) / bpl;
1009 bnum = size / (lpb * bpl);
1010 brest = size - bnum * lpb * bpl;
1015 rc = WaitUntilBmpLoaded(av7110);
1024 for (i = 0; i < bnum; i++) {
1025 rc = LoadBitmap(av7110, w, lpb, inc, data);
1028 rc = BlitBitmap(av7110, x0, y0 + i * lpb);
1034 rc = LoadBitmap(av7110, w, brest / bpl, inc, data);
1036 rc = BlitBitmap(av7110, x0, y0 + bnum * lpb);
1038 release_rc = ReleaseBitmap(av7110);
1046 int av7110_osd_cmd(
struct av7110 *av7110,
osd_cmd_t *
dc)
1055 ret = DestroyOSDWindow(av7110, av7110->
osdwin);
1059 ret = CreateOSDWindow(av7110, av7110->
osdwin,
1061 dc->
x1 - dc->
x0 + 1, dc->
y1 - dc->
y0 + 1);
1065 ret = MoveWindowAbs(av7110, av7110->
osdwin, dc->
x0, dc->
y0);
1068 ret = SetColorBlend(av7110, av7110->
osdwin);
1072 ret = MoveWindowRel(av7110, av7110->
osdwin, 0, 0);
1075 ret = HideWindow(av7110, av7110->
osdwin);
1078 ret = DrawBlock(av7110, av7110->
osdwin, 0, 0, 720, 576, 0);
1081 ret = DrawBlock(av7110, av7110->
osdwin, 0, 0, 720, 576, dc->
color);
1084 ret = OSDSetColor(av7110, dc->
color, dc->
x0, dc->
y0, dc->
x1, dc->
y1);
1088 ret = OSDSetPalette(av7110, dc->
data, dc->
color, dc->
x0);
1092 u8 r, g = 0, b = 0, blend = 0;
1094 for (i = 0; i<len; i++) {
1098 get_user(blend, colors + i * 4 + 3)) {
1102 ret = OSDSetColor(av7110, dc->
color + i, r, g, b, blend);
1109 ret = DrawLine(av7110, av7110->
osdwin,
1119 ret = DrawBlock(av7110, av7110->
osdwin, dc->
x0, dc->
y0,
1123 ret = DrawBlock(av7110, av7110->
osdwin, dc->
x0, dc->
y0,
1127 ret = DrawLine(av7110, av7110->
osdwin,
1141 ret = SetFont(av7110, av7110->
osdwin, dc->
x1,
1144 ret = FlushText(av7110);
1146 ret = WriteText(av7110, av7110->
osdwin, dc->
x0, dc->
y0, textbuf);
1150 if (dc->
x0 < 1 || dc->
x0 > 7)
1158 ret = MoveWindowAbs(av7110, av7110->
osdwin, dc->
x0, dc->
y0);
1160 ret = SetColorBlend(av7110, av7110->
osdwin);
1172 dc->
x1 - dc->
x0 + 1, dc->
y1 - dc->
y0 + 1);
1176 ret = MoveWindowAbs(av7110, av7110->
osdwin, dc->
x0, dc->
y0);
1178 ret = SetColorBlend(av7110, av7110->
osdwin);
1188 dprintk(1,
"av7110_osd_cmd(%d) returns with -ERESTARTSYS\n",dc->
cmd);
1190 dprintk(1,
"av7110_osd_cmd(%d) returns with %d\n",dc->
cmd,ret);
1195 int av7110_osd_capability(
struct av7110 *av7110,
osd_cap_t *
cap)