root/drivers/media/pci/ttpci/av7110_hw.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. av7110_debiwrite
  2. av7110_debiread
  3. av7110_reset_arm
  4. waitdebi
  5. load_dram
  6. av7110_bootarm
  7. av7110_wait_msgstate
  8. __av7110_send_fw_cmd
  9. av7110_send_fw_cmd
  10. av7110_fw_cmd
  11. av7110_send_ci_cmd
  12. av7110_fw_request
  13. av7110_fw_query
  14. av7110_firmversion
  15. av7110_diseqc_send
  16. SetColorBlend
  17. SetBlend_
  18. SetColor_
  19. SetFont
  20. FlushText
  21. WriteText
  22. DrawLine
  23. DrawBlock
  24. HideWindow
  25. MoveWindowRel
  26. MoveWindowAbs
  27. DestroyOSDWindow
  28. CreateOSDWindow
  29. WaitUntilBmpLoaded
  30. LoadBitmap
  31. BlitBitmap
  32. ReleaseBitmap
  33. RGB2YUV
  34. OSDSetColor
  35. OSDSetPalette
  36. OSDSetBlock
  37. av7110_osd_cmd
  38. av7110_osd_capability

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  * av7110_hw.c: av7110 low level hardware access and firmware interface
   4  *
   5  * Copyright (C) 1999-2002 Ralph  Metzler
   6  *                       & Marcus Metzler for convergence integrated media GmbH
   7  *
   8  * originally based on code by:
   9  * Copyright (C) 1998,1999 Christian Theiss <mistert@rz.fh-augsburg.de>
  10  *
  11  * the project's page is at https://linuxtv.org
  12  */
  13 
  14 /* for debugging ARM communication: */
  15 //#define COM_DEBUG
  16 
  17 #include <linux/types.h>
  18 #include <linux/kernel.h>
  19 #include <linux/string.h>
  20 #include <linux/delay.h>
  21 #include <linux/fs.h>
  22 
  23 #include "av7110.h"
  24 #include "av7110_hw.h"
  25 
  26 #define _NOHANDSHAKE
  27 
  28 /*
  29  * Max transfer size done by av7110_fw_cmd()
  30  *
  31  * The maximum size passed to this function is 6 bytes. The buffer also
  32  * uses two additional ones for type and size. So, 8 bytes is enough.
  33  */
  34 #define MAX_XFER_SIZE  8
  35 
  36 /****************************************************************************
  37  * DEBI functions
  38  ****************************************************************************/
  39 
  40 /* This DEBI code is based on the Stradis driver
  41    by Nathan Laredo <laredo@gnu.org> */
  42 
  43 int av7110_debiwrite(struct av7110 *av7110, u32 config,
  44                      int addr, u32 val, unsigned int count)
  45 {
  46         struct saa7146_dev *dev = av7110->dev;
  47 
  48         if (count > 32764) {
  49                 printk("%s: invalid count %d\n", __func__, count);
  50                 return -1;
  51         }
  52         if (saa7146_wait_for_debi_done(av7110->dev, 0) < 0) {
  53                 printk("%s: wait_for_debi_done failed\n", __func__);
  54                 return -1;
  55         }
  56         saa7146_write(dev, DEBI_CONFIG, config);
  57         if (count <= 4)         /* immediate transfer */
  58                 saa7146_write(dev, DEBI_AD, val);
  59         else                    /* block transfer */
  60                 saa7146_write(dev, DEBI_AD, av7110->debi_bus);
  61         saa7146_write(dev, DEBI_COMMAND, (count << 17) | (addr & 0xffff));
  62         saa7146_write(dev, MC2, (2 << 16) | 2);
  63         return 0;
  64 }
  65 
  66 u32 av7110_debiread(struct av7110 *av7110, u32 config, int addr, unsigned int count)
  67 {
  68         struct saa7146_dev *dev = av7110->dev;
  69         u32 result = 0;
  70 
  71         if (count > 32764) {
  72                 printk("%s: invalid count %d\n", __func__, count);
  73                 return 0;
  74         }
  75         if (saa7146_wait_for_debi_done(av7110->dev, 0) < 0) {
  76                 printk("%s: wait_for_debi_done #1 failed\n", __func__);
  77                 return 0;
  78         }
  79         saa7146_write(dev, DEBI_AD, av7110->debi_bus);
  80         saa7146_write(dev, DEBI_COMMAND, (count << 17) | 0x10000 | (addr & 0xffff));
  81 
  82         saa7146_write(dev, DEBI_CONFIG, config);
  83         saa7146_write(dev, MC2, (2 << 16) | 2);
  84         if (count > 4)
  85                 return count;
  86         if (saa7146_wait_for_debi_done(av7110->dev, 0) < 0) {
  87                 printk("%s: wait_for_debi_done #2 failed\n", __func__);
  88                 return 0;
  89         }
  90 
  91         result = saa7146_read(dev, DEBI_AD);
  92         result &= (0xffffffffUL >> ((4 - count) * 8));
  93         return result;
  94 }
  95 
  96 
  97 
  98 /* av7110 ARM core boot stuff */
  99 #if 0
 100 void av7110_reset_arm(struct av7110 *av7110)
 101 {
 102         saa7146_setgpio(av7110->dev, RESET_LINE, SAA7146_GPIO_OUTLO);
 103 
 104         /* Disable DEBI and GPIO irq */
 105         SAA7146_IER_DISABLE(av7110->dev, MASK_19 | MASK_03);
 106         SAA7146_ISR_CLEAR(av7110->dev, MASK_19 | MASK_03);
 107 
 108         saa7146_setgpio(av7110->dev, RESET_LINE, SAA7146_GPIO_OUTHI);
 109         msleep(30);     /* the firmware needs some time to initialize */
 110 
 111         ARM_ResetMailBox(av7110);
 112 
 113         SAA7146_ISR_CLEAR(av7110->dev, MASK_19 | MASK_03);
 114         SAA7146_IER_ENABLE(av7110->dev, MASK_03);
 115 
 116         av7110->arm_ready = 1;
 117         dprintk(1, "reset ARM\n");
 118 }
 119 #endif  /*  0  */
 120 
 121 static int waitdebi(struct av7110 *av7110, int adr, int state)
 122 {
 123         int k;
 124 
 125         dprintk(4, "%p\n", av7110);
 126 
 127         for (k = 0; k < 100; k++) {
 128                 if (irdebi(av7110, DEBINOSWAP, adr, 0, 2) == state)
 129                         return 0;
 130                 udelay(5);
 131         }
 132         return -ETIMEDOUT;
 133 }
 134 
 135 static int load_dram(struct av7110 *av7110, u32 *data, int len)
 136 {
 137         int i;
 138         int blocks, rest;
 139         u32 base, bootblock = AV7110_BOOT_BLOCK;
 140 
 141         dprintk(4, "%p\n", av7110);
 142 
 143         blocks = len / AV7110_BOOT_MAX_SIZE;
 144         rest = len % AV7110_BOOT_MAX_SIZE;
 145         base = DRAM_START_CODE;
 146 
 147         for (i = 0; i < blocks; i++) {
 148                 if (waitdebi(av7110, AV7110_BOOT_STATE, BOOTSTATE_BUFFER_EMPTY) < 0) {
 149                         printk(KERN_ERR "dvb-ttpci: load_dram(): timeout at block %d\n", i);
 150                         return -ETIMEDOUT;
 151                 }
 152                 dprintk(4, "writing DRAM block %d\n", i);
 153                 mwdebi(av7110, DEBISWAB, bootblock,
 154                        ((u8 *)data) + i * AV7110_BOOT_MAX_SIZE, AV7110_BOOT_MAX_SIZE);
 155                 bootblock ^= 0x1400;
 156                 iwdebi(av7110, DEBISWAB, AV7110_BOOT_BASE, swab32(base), 4);
 157                 iwdebi(av7110, DEBINOSWAP, AV7110_BOOT_SIZE, AV7110_BOOT_MAX_SIZE, 2);
 158                 iwdebi(av7110, DEBINOSWAP, AV7110_BOOT_STATE, BOOTSTATE_BUFFER_FULL, 2);
 159                 base += AV7110_BOOT_MAX_SIZE;
 160         }
 161 
 162         if (rest > 0) {
 163                 if (waitdebi(av7110, AV7110_BOOT_STATE, BOOTSTATE_BUFFER_EMPTY) < 0) {
 164                         printk(KERN_ERR "dvb-ttpci: load_dram(): timeout at last block\n");
 165                         return -ETIMEDOUT;
 166                 }
 167                 if (rest > 4)
 168                         mwdebi(av7110, DEBISWAB, bootblock,
 169                                ((u8 *)data) + i * AV7110_BOOT_MAX_SIZE, rest);
 170                 else
 171                         mwdebi(av7110, DEBISWAB, bootblock,
 172                                ((u8 *)data) + i * AV7110_BOOT_MAX_SIZE - 4, rest + 4);
 173 
 174                 iwdebi(av7110, DEBISWAB, AV7110_BOOT_BASE, swab32(base), 4);
 175                 iwdebi(av7110, DEBINOSWAP, AV7110_BOOT_SIZE, rest, 2);
 176                 iwdebi(av7110, DEBINOSWAP, AV7110_BOOT_STATE, BOOTSTATE_BUFFER_FULL, 2);
 177         }
 178         if (waitdebi(av7110, AV7110_BOOT_STATE, BOOTSTATE_BUFFER_EMPTY) < 0) {
 179                 printk(KERN_ERR "dvb-ttpci: load_dram(): timeout after last block\n");
 180                 return -ETIMEDOUT;
 181         }
 182         iwdebi(av7110, DEBINOSWAP, AV7110_BOOT_SIZE, 0, 2);
 183         iwdebi(av7110, DEBINOSWAP, AV7110_BOOT_STATE, BOOTSTATE_BUFFER_FULL, 2);
 184         if (waitdebi(av7110, AV7110_BOOT_STATE, BOOTSTATE_AV7110_BOOT_COMPLETE) < 0) {
 185                 printk(KERN_ERR "dvb-ttpci: load_dram(): final handshake timeout\n");
 186                 return -ETIMEDOUT;
 187         }
 188         return 0;
 189 }
 190 
 191 
 192 /* we cannot write av7110 DRAM directly, so load a bootloader into
 193  * the DPRAM which implements a simple boot protocol */
 194 int av7110_bootarm(struct av7110 *av7110)
 195 {
 196         const struct firmware *fw;
 197         const char *fw_name = "av7110/bootcode.bin";
 198         struct saa7146_dev *dev = av7110->dev;
 199         u32 ret;
 200         int i;
 201 
 202         dprintk(4, "%p\n", av7110);
 203 
 204         av7110->arm_ready = 0;
 205 
 206         saa7146_setgpio(dev, RESET_LINE, SAA7146_GPIO_OUTLO);
 207 
 208         /* Disable DEBI and GPIO irq */
 209         SAA7146_IER_DISABLE(av7110->dev, MASK_03 | MASK_19);
 210         SAA7146_ISR_CLEAR(av7110->dev, MASK_19 | MASK_03);
 211 
 212         /* enable DEBI */
 213         saa7146_write(av7110->dev, MC1, 0x08800880);
 214         saa7146_write(av7110->dev, DD1_STREAM_B, 0x00000000);
 215         saa7146_write(av7110->dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
 216 
 217         /* test DEBI */
 218         iwdebi(av7110, DEBISWAP, DPRAM_BASE, 0x76543210, 4);
 219         /* FIXME: Why does Nexus CA require 2x iwdebi for first init? */
 220         iwdebi(av7110, DEBISWAP, DPRAM_BASE, 0x76543210, 4);
 221 
 222         if ((ret=irdebi(av7110, DEBINOSWAP, DPRAM_BASE, 0, 4)) != 0x10325476) {
 223                 printk(KERN_ERR "dvb-ttpci: debi test in av7110_bootarm() failed: %08x != %08x (check your BIOS 'Plug&Play OS' settings)\n",
 224                        ret, 0x10325476);
 225                 return -1;
 226         }
 227         for (i = 0; i < 8192; i += 4)
 228                 iwdebi(av7110, DEBISWAP, DPRAM_BASE + i, 0x00, 4);
 229         dprintk(2, "debi test OK\n");
 230 
 231         /* boot */
 232         dprintk(1, "load boot code\n");
 233         saa7146_setgpio(dev, ARM_IRQ_LINE, SAA7146_GPIO_IRQLO);
 234         //saa7146_setgpio(dev, DEBI_DONE_LINE, SAA7146_GPIO_INPUT);
 235         //saa7146_setgpio(dev, 3, SAA7146_GPIO_INPUT);
 236 
 237         ret = request_firmware(&fw, fw_name, &dev->pci->dev);
 238         if (ret) {
 239                 printk(KERN_ERR "dvb-ttpci: Failed to load firmware \"%s\"\n",
 240                         fw_name);
 241                 return ret;
 242         }
 243 
 244         mwdebi(av7110, DEBISWAB, DPRAM_BASE, fw->data, fw->size);
 245         release_firmware(fw);
 246         iwdebi(av7110, DEBINOSWAP, AV7110_BOOT_STATE, BOOTSTATE_BUFFER_FULL, 2);
 247 
 248         if (saa7146_wait_for_debi_done(av7110->dev, 1)) {
 249                 printk(KERN_ERR "dvb-ttpci: av7110_bootarm(): saa7146_wait_for_debi_done() timed out\n");
 250                 return -ETIMEDOUT;
 251         }
 252         saa7146_setgpio(dev, RESET_LINE, SAA7146_GPIO_OUTHI);
 253         mdelay(1);
 254 
 255         dprintk(1, "load dram code\n");
 256         if (load_dram(av7110, (u32 *)av7110->bin_root, av7110->size_root) < 0) {
 257                 printk(KERN_ERR "dvb-ttpci: av7110_bootarm(): load_dram() failed\n");
 258                 return -1;
 259         }
 260 
 261         saa7146_setgpio(dev, RESET_LINE, SAA7146_GPIO_OUTLO);
 262         mdelay(1);
 263 
 264         dprintk(1, "load dpram code\n");
 265         mwdebi(av7110, DEBISWAB, DPRAM_BASE, av7110->bin_dpram, av7110->size_dpram);
 266 
 267         if (saa7146_wait_for_debi_done(av7110->dev, 1)) {
 268                 printk(KERN_ERR "dvb-ttpci: av7110_bootarm(): saa7146_wait_for_debi_done() timed out after loading DRAM\n");
 269                 return -ETIMEDOUT;
 270         }
 271         saa7146_setgpio(dev, RESET_LINE, SAA7146_GPIO_OUTHI);
 272         msleep(30);     /* the firmware needs some time to initialize */
 273 
 274         //ARM_ClearIrq(av7110);
 275         ARM_ResetMailBox(av7110);
 276         SAA7146_ISR_CLEAR(av7110->dev, MASK_19 | MASK_03);
 277         SAA7146_IER_ENABLE(av7110->dev, MASK_03);
 278 
 279         av7110->arm_errors = 0;
 280         av7110->arm_ready = 1;
 281         return 0;
 282 }
 283 MODULE_FIRMWARE("av7110/bootcode.bin");
 284 
 285 /****************************************************************************
 286  * DEBI command polling
 287  ****************************************************************************/
 288 
 289 int av7110_wait_msgstate(struct av7110 *av7110, u16 flags)
 290 {
 291         unsigned long start;
 292         u32 stat;
 293         int err;
 294 
 295         if (FW_VERSION(av7110->arm_app) <= 0x261c) {
 296                 /* not supported by old firmware */
 297                 msleep(50);
 298                 return 0;
 299         }
 300 
 301         /* new firmware */
 302         start = jiffies;
 303         for (;;) {
 304                 err = time_after(jiffies, start + ARM_WAIT_FREE);
 305                 if (mutex_lock_interruptible(&av7110->dcomlock))
 306                         return -ERESTARTSYS;
 307                 stat = rdebi(av7110, DEBINOSWAP, MSGSTATE, 0, 2);
 308                 mutex_unlock(&av7110->dcomlock);
 309                 if ((stat & flags) == 0)
 310                         break;
 311                 if (err) {
 312                         printk(KERN_ERR "%s: timeout waiting for MSGSTATE %04x\n",
 313                                 __func__, stat & flags);
 314                         return -ETIMEDOUT;
 315                 }
 316                 msleep(1);
 317         }
 318         return 0;
 319 }
 320 
 321 static int __av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length)
 322 {
 323         int i;
 324         unsigned long start;
 325         char *type = NULL;
 326         u16 flags[2] = {0, 0};
 327         u32 stat;
 328         int err;
 329 
 330 //      dprintk(4, "%p\n", av7110);
 331 
 332         if (!av7110->arm_ready) {
 333                 dprintk(1, "arm not ready.\n");
 334                 return -ENXIO;
 335         }
 336 
 337         start = jiffies;
 338         while (1) {
 339                 err = time_after(jiffies, start + ARM_WAIT_FREE);
 340                 if (rdebi(av7110, DEBINOSWAP, COMMAND, 0, 2) == 0)
 341                         break;
 342                 if (err) {
 343                         printk(KERN_ERR "dvb-ttpci: %s(): timeout waiting for COMMAND idle\n", __func__);
 344                         av7110->arm_errors++;
 345                         return -ETIMEDOUT;
 346                 }
 347                 msleep(1);
 348         }
 349 
 350         if (FW_VERSION(av7110->arm_app) <= 0x261f)
 351                 wdebi(av7110, DEBINOSWAP, COM_IF_LOCK, 0xffff, 2);
 352 
 353 #ifndef _NOHANDSHAKE
 354         start = jiffies;
 355         while (1) {
 356                 err = time_after(jiffies, start + ARM_WAIT_SHAKE);
 357                 if (rdebi(av7110, DEBINOSWAP, HANDSHAKE_REG, 0, 2) == 0)
 358                         break;
 359                 if (err) {
 360                         printk(KERN_ERR "dvb-ttpci: %s(): timeout waiting for HANDSHAKE_REG\n", __func__);
 361                         return -ETIMEDOUT;
 362                 }
 363                 msleep(1);
 364         }
 365 #endif
 366 
 367         switch ((buf[0] >> 8) & 0xff) {
 368         case COMTYPE_PIDFILTER:
 369         case COMTYPE_ENCODER:
 370         case COMTYPE_REC_PLAY:
 371         case COMTYPE_MPEGDECODER:
 372                 type = "MSG";
 373                 flags[0] = GPMQOver;
 374                 flags[1] = GPMQFull;
 375                 break;
 376         case COMTYPE_OSD:
 377                 type = "OSD";
 378                 flags[0] = OSDQOver;
 379                 flags[1] = OSDQFull;
 380                 break;
 381         case COMTYPE_MISC:
 382                 if (FW_VERSION(av7110->arm_app) >= 0x261d) {
 383                         type = "MSG";
 384                         flags[0] = GPMQOver;
 385                         flags[1] = GPMQBusy;
 386                 }
 387                 break;
 388         default:
 389                 break;
 390         }
 391 
 392         if (type != NULL) {
 393                 /* non-immediate COMMAND type */
 394                 start = jiffies;
 395                 for (;;) {
 396                         err = time_after(jiffies, start + ARM_WAIT_FREE);
 397                         stat = rdebi(av7110, DEBINOSWAP, MSGSTATE, 0, 2);
 398                         if (stat & flags[0]) {
 399                                 printk(KERN_ERR "%s: %s QUEUE overflow\n",
 400                                         __func__, type);
 401                                 return -1;
 402                         }
 403                         if ((stat & flags[1]) == 0)
 404                                 break;
 405                         if (err) {
 406                                 printk(KERN_ERR "%s: timeout waiting on busy %s QUEUE\n",
 407                                         __func__, type);
 408                                 av7110->arm_errors++;
 409                                 return -ETIMEDOUT;
 410                         }
 411                         msleep(1);
 412                 }
 413         }
 414 
 415         for (i = 2; i < length; i++)
 416                 wdebi(av7110, DEBINOSWAP, COMMAND + 2 * i, (u32) buf[i], 2);
 417 
 418         if (length)
 419                 wdebi(av7110, DEBINOSWAP, COMMAND + 2, (u32) buf[1], 2);
 420         else
 421                 wdebi(av7110, DEBINOSWAP, COMMAND + 2, 0, 2);
 422 
 423         wdebi(av7110, DEBINOSWAP, COMMAND, (u32) buf[0], 2);
 424 
 425         if (FW_VERSION(av7110->arm_app) <= 0x261f)
 426                 wdebi(av7110, DEBINOSWAP, COM_IF_LOCK, 0x0000, 2);
 427 
 428 #ifdef COM_DEBUG
 429         start = jiffies;
 430         while (1) {
 431                 err = time_after(jiffies, start + ARM_WAIT_FREE);
 432                 if (rdebi(av7110, DEBINOSWAP, COMMAND, 0, 2) == 0)
 433                         break;
 434                 if (err) {
 435                         printk(KERN_ERR "dvb-ttpci: %s(): timeout waiting for COMMAND %d to complete\n",
 436                                __func__, (buf[0] >> 8) & 0xff);
 437                         return -ETIMEDOUT;
 438                 }
 439                 msleep(1);
 440         }
 441 
 442         stat = rdebi(av7110, DEBINOSWAP, MSGSTATE, 0, 2);
 443         if (stat & GPMQOver) {
 444                 printk(KERN_ERR "dvb-ttpci: %s(): GPMQOver\n", __func__);
 445                 return -ENOSPC;
 446         }
 447         else if (stat & OSDQOver) {
 448                 printk(KERN_ERR "dvb-ttpci: %s(): OSDQOver\n", __func__);
 449                 return -ENOSPC;
 450         }
 451 #endif
 452 
 453         return 0;
 454 }
 455 
 456 static int av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length)
 457 {
 458         int ret;
 459 
 460 //      dprintk(4, "%p\n", av7110);
 461 
 462         if (!av7110->arm_ready) {
 463                 dprintk(1, "arm not ready.\n");
 464                 return -1;
 465         }
 466         if (mutex_lock_interruptible(&av7110->dcomlock))
 467                 return -ERESTARTSYS;
 468 
 469         ret = __av7110_send_fw_cmd(av7110, buf, length);
 470         mutex_unlock(&av7110->dcomlock);
 471         if (ret && ret!=-ERESTARTSYS)
 472                 printk(KERN_ERR "dvb-ttpci: %s(): av7110_send_fw_cmd error %d\n",
 473                        __func__, ret);
 474         return ret;
 475 }
 476 
 477 int av7110_fw_cmd(struct av7110 *av7110, int type, int com, int num, ...)
 478 {
 479         va_list args;
 480         u16 buf[MAX_XFER_SIZE];
 481         int i, ret;
 482 
 483 //      dprintk(4, "%p\n", av7110);
 484 
 485         if (2 + num > ARRAY_SIZE(buf)) {
 486                 printk(KERN_WARNING
 487                        "%s: %s len=%d is too big!\n",
 488                        KBUILD_MODNAME, __func__, num);
 489                 return -EINVAL;
 490         }
 491 
 492         buf[0] = ((type << 8) | com);
 493         buf[1] = num;
 494 
 495         if (num) {
 496                 va_start(args, num);
 497                 for (i = 0; i < num; i++)
 498                         buf[i + 2] = va_arg(args, u32);
 499                 va_end(args);
 500         }
 501 
 502         ret = av7110_send_fw_cmd(av7110, buf, num + 2);
 503         if (ret && ret != -ERESTARTSYS)
 504                 printk(KERN_ERR "dvb-ttpci: av7110_fw_cmd error %d\n", ret);
 505         return ret;
 506 }
 507 
 508 #if 0
 509 int av7110_send_ci_cmd(struct av7110 *av7110, u8 subcom, u8 *buf, u8 len)
 510 {
 511         int i, ret;
 512         u16 cmd[18] = { ((COMTYPE_COMMON_IF << 8) + subcom),
 513                 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
 514 
 515         dprintk(4, "%p\n", av7110);
 516 
 517         for(i = 0; i < len && i < 32; i++)
 518         {
 519                 if(i % 2 == 0)
 520                         cmd[(i / 2) + 2] = (u16)(buf[i]) << 8;
 521                 else
 522                         cmd[(i / 2) + 2] |= buf[i];
 523         }
 524 
 525         ret = av7110_send_fw_cmd(av7110, cmd, 18);
 526         if (ret && ret != -ERESTARTSYS)
 527                 printk(KERN_ERR "dvb-ttpci: av7110_send_ci_cmd error %d\n", ret);
 528         return ret;
 529 }
 530 #endif  /*  0  */
 531 
 532 int av7110_fw_request(struct av7110 *av7110, u16 *request_buf,
 533                       int request_buf_len, u16 *reply_buf, int reply_buf_len)
 534 {
 535         int err;
 536         s16 i;
 537         unsigned long start;
 538 #ifdef COM_DEBUG
 539         u32 stat;
 540 #endif
 541 
 542         dprintk(4, "%p\n", av7110);
 543 
 544         if (!av7110->arm_ready) {
 545                 dprintk(1, "arm not ready.\n");
 546                 return -1;
 547         }
 548 
 549         if (mutex_lock_interruptible(&av7110->dcomlock))
 550                 return -ERESTARTSYS;
 551 
 552         if ((err = __av7110_send_fw_cmd(av7110, request_buf, request_buf_len)) < 0) {
 553                 mutex_unlock(&av7110->dcomlock);
 554                 printk(KERN_ERR "dvb-ttpci: av7110_fw_request error %d\n", err);
 555                 return err;
 556         }
 557 
 558         start = jiffies;
 559         while (1) {
 560                 err = time_after(jiffies, start + ARM_WAIT_FREE);
 561                 if (rdebi(av7110, DEBINOSWAP, COMMAND, 0, 2) == 0)
 562                         break;
 563                 if (err) {
 564                         printk(KERN_ERR "%s: timeout waiting for COMMAND to complete\n", __func__);
 565                         mutex_unlock(&av7110->dcomlock);
 566                         return -ETIMEDOUT;
 567                 }
 568 #ifdef _NOHANDSHAKE
 569                 msleep(1);
 570 #endif
 571         }
 572 
 573 #ifndef _NOHANDSHAKE
 574         start = jiffies;
 575         while (1) {
 576                 err = time_after(jiffies, start + ARM_WAIT_SHAKE);
 577                 if (rdebi(av7110, DEBINOSWAP, HANDSHAKE_REG, 0, 2) == 0)
 578                         break;
 579                 if (err) {
 580                         printk(KERN_ERR "%s: timeout waiting for HANDSHAKE_REG\n", __func__);
 581                         mutex_unlock(&av7110->dcomlock);
 582                         return -ETIMEDOUT;
 583                 }
 584                 msleep(1);
 585         }
 586 #endif
 587 
 588 #ifdef COM_DEBUG
 589         stat = rdebi(av7110, DEBINOSWAP, MSGSTATE, 0, 2);
 590         if (stat & GPMQOver) {
 591                 printk(KERN_ERR "%s: GPMQOver\n", __func__);
 592                 mutex_unlock(&av7110->dcomlock);
 593                 return -1;
 594         }
 595         else if (stat & OSDQOver) {
 596                 printk(KERN_ERR "%s: OSDQOver\n", __func__);
 597                 mutex_unlock(&av7110->dcomlock);
 598                 return -1;
 599         }
 600 #endif
 601 
 602         for (i = 0; i < reply_buf_len; i++)
 603                 reply_buf[i] = rdebi(av7110, DEBINOSWAP, COM_BUFF + 2 * i, 0, 2);
 604 
 605         mutex_unlock(&av7110->dcomlock);
 606         return 0;
 607 }
 608 
 609 static int av7110_fw_query(struct av7110 *av7110, u16 tag, u16* buf, s16 length)
 610 {
 611         int ret;
 612         ret = av7110_fw_request(av7110, &tag, 0, buf, length);
 613         if (ret)
 614                 printk(KERN_ERR "dvb-ttpci: av7110_fw_query error %d\n", ret);
 615         return ret;
 616 }
 617 
 618 
 619 /****************************************************************************
 620  * Firmware commands
 621  ****************************************************************************/
 622 
 623 /* get version of the firmware ROM, RTSL, video ucode and ARM application  */
 624 int av7110_firmversion(struct av7110 *av7110)
 625 {
 626         u16 buf[20];
 627         u16 tag = ((COMTYPE_REQUEST << 8) + ReqVersion);
 628 
 629         dprintk(4, "%p\n", av7110);
 630 
 631         if (av7110_fw_query(av7110, tag, buf, 16)) {
 632                 printk("dvb-ttpci: failed to boot firmware @ card %d\n",
 633                        av7110->dvb_adapter.num);
 634                 return -EIO;
 635         }
 636 
 637         av7110->arm_fw = (buf[0] << 16) + buf[1];
 638         av7110->arm_rtsl = (buf[2] << 16) + buf[3];
 639         av7110->arm_vid = (buf[4] << 16) + buf[5];
 640         av7110->arm_app = (buf[6] << 16) + buf[7];
 641         av7110->avtype = (buf[8] << 16) + buf[9];
 642 
 643         printk("dvb-ttpci: info @ card %d: firm %08x, rtsl %08x, vid %08x, app %08x\n",
 644                av7110->dvb_adapter.num, av7110->arm_fw,
 645                av7110->arm_rtsl, av7110->arm_vid, av7110->arm_app);
 646 
 647         /* print firmware capabilities */
 648         if (FW_CI_LL_SUPPORT(av7110->arm_app))
 649                 printk("dvb-ttpci: firmware @ card %d supports CI link layer interface\n",
 650                        av7110->dvb_adapter.num);
 651         else
 652                 printk("dvb-ttpci: no firmware support for CI link layer interface @ card %d\n",
 653                        av7110->dvb_adapter.num);
 654 
 655         return 0;
 656 }
 657 
 658 
 659 int av7110_diseqc_send(struct av7110 *av7110, int len, u8 *msg, unsigned long burst)
 660 {
 661         int i, ret;
 662         u16 buf[18] = { ((COMTYPE_AUDIODAC << 8) + SendDiSEqC),
 663                         16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
 664 
 665         dprintk(4, "%p\n", av7110);
 666 
 667         if (len > 10)
 668                 len = 10;
 669 
 670         buf[1] = len + 2;
 671         buf[2] = len;
 672 
 673         if (burst != -1)
 674                 buf[3] = burst ? 0x01 : 0x00;
 675         else
 676                 buf[3] = 0xffff;
 677 
 678         for (i = 0; i < len; i++)
 679                 buf[i + 4] = msg[i];
 680 
 681         ret = av7110_send_fw_cmd(av7110, buf, 18);
 682         if (ret && ret!=-ERESTARTSYS)
 683                 printk(KERN_ERR "dvb-ttpci: av7110_diseqc_send error %d\n", ret);
 684         return ret;
 685 }
 686 
 687 
 688 #ifdef CONFIG_DVB_AV7110_OSD
 689 
 690 static inline int SetColorBlend(struct av7110 *av7110, u8 windownr)
 691 {
 692         return av7110_fw_cmd(av7110, COMTYPE_OSD, SetCBlend, 1, windownr);
 693 }
 694 
 695 static inline int SetBlend_(struct av7110 *av7110, u8 windownr,
 696                      enum av7110_osd_palette_type colordepth, u16 index, u8 blending)
 697 {
 698         return av7110_fw_cmd(av7110, COMTYPE_OSD, SetBlend, 4,
 699                              windownr, colordepth, index, blending);
 700 }
 701 
 702 static inline int SetColor_(struct av7110 *av7110, u8 windownr,
 703                      enum av7110_osd_palette_type colordepth, u16 index, u16 colorhi, u16 colorlo)
 704 {
 705         return av7110_fw_cmd(av7110, COMTYPE_OSD, SetColor, 5,
 706                              windownr, colordepth, index, colorhi, colorlo);
 707 }
 708 
 709 static inline int SetFont(struct av7110 *av7110, u8 windownr, u8 fontsize,
 710                           u16 colorfg, u16 colorbg)
 711 {
 712         return av7110_fw_cmd(av7110, COMTYPE_OSD, Set_Font, 4,
 713                              windownr, fontsize, colorfg, colorbg);
 714 }
 715 
 716 static int FlushText(struct av7110 *av7110)
 717 {
 718         unsigned long start;
 719         int err;
 720 
 721         if (mutex_lock_interruptible(&av7110->dcomlock))
 722                 return -ERESTARTSYS;
 723         start = jiffies;
 724         while (1) {
 725                 err = time_after(jiffies, start + ARM_WAIT_OSD);
 726                 if (rdebi(av7110, DEBINOSWAP, BUFF1_BASE, 0, 2) == 0)
 727                         break;
 728                 if (err) {
 729                         printk(KERN_ERR "dvb-ttpci: %s(): timeout waiting for BUFF1_BASE == 0\n",
 730                                __func__);
 731                         mutex_unlock(&av7110->dcomlock);
 732                         return -ETIMEDOUT;
 733                 }
 734                 msleep(1);
 735         }
 736         mutex_unlock(&av7110->dcomlock);
 737         return 0;
 738 }
 739 
 740 static int WriteText(struct av7110 *av7110, u8 win, u16 x, u16 y, char *buf)
 741 {
 742         int i, ret;
 743         unsigned long start;
 744         int length = strlen(buf) + 1;
 745         u16 cbuf[5] = { (COMTYPE_OSD << 8) + DText, 3, win, x, y };
 746 
 747         if (mutex_lock_interruptible(&av7110->dcomlock))
 748                 return -ERESTARTSYS;
 749 
 750         start = jiffies;
 751         while (1) {
 752                 ret = time_after(jiffies, start + ARM_WAIT_OSD);
 753                 if (rdebi(av7110, DEBINOSWAP, BUFF1_BASE, 0, 2) == 0)
 754                         break;
 755                 if (ret) {
 756                         printk(KERN_ERR "dvb-ttpci: %s: timeout waiting for BUFF1_BASE == 0\n",
 757                                __func__);
 758                         mutex_unlock(&av7110->dcomlock);
 759                         return -ETIMEDOUT;
 760                 }
 761                 msleep(1);
 762         }
 763 #ifndef _NOHANDSHAKE
 764         start = jiffies;
 765         while (1) {
 766                 ret = time_after(jiffies, start + ARM_WAIT_SHAKE);
 767                 if (rdebi(av7110, DEBINOSWAP, HANDSHAKE_REG, 0, 2) == 0)
 768                         break;
 769                 if (ret) {
 770                         printk(KERN_ERR "dvb-ttpci: %s: timeout waiting for HANDSHAKE_REG\n",
 771                                __func__);
 772                         mutex_unlock(&av7110->dcomlock);
 773                         return -ETIMEDOUT;
 774                 }
 775                 msleep(1);
 776         }
 777 #endif
 778         for (i = 0; i < length / 2; i++)
 779                 wdebi(av7110, DEBINOSWAP, BUFF1_BASE + i * 2,
 780                       swab16(*(u16 *)(buf + 2 * i)), 2);
 781         if (length & 1)
 782                 wdebi(av7110, DEBINOSWAP, BUFF1_BASE + i * 2, 0, 2);
 783         ret = __av7110_send_fw_cmd(av7110, cbuf, 5);
 784         mutex_unlock(&av7110->dcomlock);
 785         if (ret && ret!=-ERESTARTSYS)
 786                 printk(KERN_ERR "dvb-ttpci: WriteText error %d\n", ret);
 787         return ret;
 788 }
 789 
 790 static inline int DrawLine(struct av7110 *av7110, u8 windownr,
 791                            u16 x, u16 y, u16 dx, u16 dy, u16 color)
 792 {
 793         return av7110_fw_cmd(av7110, COMTYPE_OSD, DLine, 6,
 794                              windownr, x, y, dx, dy, color);
 795 }
 796 
 797 static inline int DrawBlock(struct av7110 *av7110, u8 windownr,
 798                             u16 x, u16 y, u16 dx, u16 dy, u16 color)
 799 {
 800         return av7110_fw_cmd(av7110, COMTYPE_OSD, DBox, 6,
 801                              windownr, x, y, dx, dy, color);
 802 }
 803 
 804 static inline int HideWindow(struct av7110 *av7110, u8 windownr)
 805 {
 806         return av7110_fw_cmd(av7110, COMTYPE_OSD, WHide, 1, windownr);
 807 }
 808 
 809 static inline int MoveWindowRel(struct av7110 *av7110, u8 windownr, u16 x, u16 y)
 810 {
 811         return av7110_fw_cmd(av7110, COMTYPE_OSD, WMoveD, 3, windownr, x, y);
 812 }
 813 
 814 static inline int MoveWindowAbs(struct av7110 *av7110, u8 windownr, u16 x, u16 y)
 815 {
 816         return av7110_fw_cmd(av7110, COMTYPE_OSD, WMoveA, 3, windownr, x, y);
 817 }
 818 
 819 static inline int DestroyOSDWindow(struct av7110 *av7110, u8 windownr)
 820 {
 821         return av7110_fw_cmd(av7110, COMTYPE_OSD, WDestroy, 1, windownr);
 822 }
 823 
 824 static inline int CreateOSDWindow(struct av7110 *av7110, u8 windownr,
 825                                   osd_raw_window_t disptype,
 826                                   u16 width, u16 height)
 827 {
 828         return av7110_fw_cmd(av7110, COMTYPE_OSD, WCreate, 4,
 829                              windownr, disptype, width, height);
 830 }
 831 
 832 
 833 static enum av7110_osd_palette_type bpp2pal[8] = {
 834         Pal1Bit, Pal2Bit, 0, Pal4Bit, 0, 0, 0, Pal8Bit
 835 };
 836 static osd_raw_window_t bpp2bit[8] = {
 837         OSD_BITMAP1, OSD_BITMAP2, 0, OSD_BITMAP4, 0, 0, 0, OSD_BITMAP8
 838 };
 839 
 840 static inline int WaitUntilBmpLoaded(struct av7110 *av7110)
 841 {
 842         int ret = wait_event_timeout(av7110->bmpq,
 843                                 av7110->bmp_state != BMP_LOADING, 10*HZ);
 844         if (ret == 0) {
 845                 printk("dvb-ttpci: warning: timeout waiting in LoadBitmap: %d, %d\n",
 846                        ret, av7110->bmp_state);
 847                 av7110->bmp_state = BMP_NONE;
 848                 return -ETIMEDOUT;
 849         }
 850         return 0;
 851 }
 852 
 853 static inline int LoadBitmap(struct av7110 *av7110,
 854                              u16 dx, u16 dy, int inc, u8 __user * data)
 855 {
 856         u16 format;
 857         int bpp;
 858         int i;
 859         int d, delta;
 860         u8 c;
 861         int ret;
 862 
 863         dprintk(4, "%p\n", av7110);
 864 
 865         format = bpp2bit[av7110->osdbpp[av7110->osdwin]];
 866 
 867         av7110->bmp_state = BMP_LOADING;
 868         if      (format == OSD_BITMAP8) {
 869                 bpp=8; delta = 1;
 870         } else if (format == OSD_BITMAP4) {
 871                 bpp=4; delta = 2;
 872         } else if (format == OSD_BITMAP2) {
 873                 bpp=2; delta = 4;
 874         } else if (format == OSD_BITMAP1) {
 875                 bpp=1; delta = 8;
 876         } else {
 877                 av7110->bmp_state = BMP_NONE;
 878                 return -EINVAL;
 879         }
 880         av7110->bmplen = ((dx * dy * bpp + 7) & ~7) / 8;
 881         av7110->bmpp = 0;
 882         if (av7110->bmplen > 32768) {
 883                 av7110->bmp_state = BMP_NONE;
 884                 return -EINVAL;
 885         }
 886         for (i = 0; i < dy; i++) {
 887                 if (copy_from_user(av7110->bmpbuf + 1024 + i * dx, data + i * inc, dx)) {
 888                         av7110->bmp_state = BMP_NONE;
 889                         return -EINVAL;
 890                 }
 891         }
 892         if (format != OSD_BITMAP8) {
 893                 for (i = 0; i < dx * dy / delta; i++) {
 894                         c = ((u8 *)av7110->bmpbuf)[1024 + i * delta + delta - 1];
 895                         for (d = delta - 2; d >= 0; d--) {
 896                                 c |= (((u8 *)av7110->bmpbuf)[1024 + i * delta + d]
 897                                       << ((delta - d - 1) * bpp));
 898                                 ((u8 *)av7110->bmpbuf)[1024 + i] = c;
 899                         }
 900                 }
 901         }
 902         av7110->bmplen += 1024;
 903         dprintk(4, "av7110_fw_cmd: LoadBmp size %d\n", av7110->bmplen);
 904         ret = av7110_fw_cmd(av7110, COMTYPE_OSD, LoadBmp, 3, format, dx, dy);
 905         if (!ret)
 906                 ret = WaitUntilBmpLoaded(av7110);
 907         return ret;
 908 }
 909 
 910 static int BlitBitmap(struct av7110 *av7110, u16 x, u16 y)
 911 {
 912         dprintk(4, "%p\n", av7110);
 913 
 914         return av7110_fw_cmd(av7110, COMTYPE_OSD, BlitBmp, 4, av7110->osdwin, x, y, 0);
 915 }
 916 
 917 static inline int ReleaseBitmap(struct av7110 *av7110)
 918 {
 919         dprintk(4, "%p\n", av7110);
 920 
 921         if (av7110->bmp_state != BMP_LOADED && FW_VERSION(av7110->arm_app) < 0x261e)
 922                 return -1;
 923         if (av7110->bmp_state == BMP_LOADING)
 924                 dprintk(1,"ReleaseBitmap called while BMP_LOADING\n");
 925         av7110->bmp_state = BMP_NONE;
 926         return av7110_fw_cmd(av7110, COMTYPE_OSD, ReleaseBmp, 0);
 927 }
 928 
 929 static u32 RGB2YUV(u16 R, u16 G, u16 B)
 930 {
 931         u16 y, u, v;
 932         u16 Y, Cr, Cb;
 933 
 934         y = R * 77 + G * 150 + B * 29;  /* Luma=0.299R+0.587G+0.114B 0..65535 */
 935         u = 2048 + B * 8 -(y >> 5);     /* Cr 0..4095 */
 936         v = 2048 + R * 8 -(y >> 5);     /* Cb 0..4095 */
 937 
 938         Y = y / 256;
 939         Cb = u / 16;
 940         Cr = v / 16;
 941 
 942         return Cr | (Cb << 16) | (Y << 8);
 943 }
 944 
 945 static int OSDSetColor(struct av7110 *av7110, u8 color, u8 r, u8 g, u8 b, u8 blend)
 946 {
 947         int ret;
 948 
 949         u16 ch, cl;
 950         u32 yuv;
 951 
 952         yuv = blend ? RGB2YUV(r,g,b) : 0;
 953         cl = (yuv & 0xffff);
 954         ch = ((yuv >> 16) & 0xffff);
 955         ret = SetColor_(av7110, av7110->osdwin, bpp2pal[av7110->osdbpp[av7110->osdwin]],
 956                         color, ch, cl);
 957         if (!ret)
 958                 ret = SetBlend_(av7110, av7110->osdwin, bpp2pal[av7110->osdbpp[av7110->osdwin]],
 959                                 color, ((blend >> 4) & 0x0f));
 960         return ret;
 961 }
 962 
 963 static int OSDSetPalette(struct av7110 *av7110, u32 __user * colors, u8 first, u8 last)
 964 {
 965         int i;
 966         int length = last - first + 1;
 967 
 968         if (length * 4 > DATA_BUFF3_SIZE)
 969                 return -EINVAL;
 970 
 971         for (i = 0; i < length; i++) {
 972                 u32 color, blend, yuv;
 973 
 974                 if (get_user(color, colors + i))
 975                         return -EFAULT;
 976                 blend = (color & 0xF0000000) >> 4;
 977                 yuv = blend ? RGB2YUV(color & 0xFF, (color >> 8) & 0xFF,
 978                                      (color >> 16) & 0xFF) | blend : 0;
 979                 yuv = ((yuv & 0xFFFF0000) >> 16) | ((yuv & 0x0000FFFF) << 16);
 980                 wdebi(av7110, DEBINOSWAP, DATA_BUFF3_BASE + i * 4, yuv, 4);
 981         }
 982         return av7110_fw_cmd(av7110, COMTYPE_OSD, Set_Palette, 4,
 983                             av7110->osdwin,
 984                             bpp2pal[av7110->osdbpp[av7110->osdwin]],
 985                             first, last);
 986 }
 987 
 988 static int OSDSetBlock(struct av7110 *av7110, int x0, int y0,
 989                        int x1, int y1, int inc, u8 __user * data)
 990 {
 991         uint w, h, bpp, bpl, size, lpb, bnum, brest;
 992         int i;
 993         int rc,release_rc;
 994 
 995         w = x1 - x0 + 1;
 996         h = y1 - y0 + 1;
 997         if (inc <= 0)
 998                 inc = w;
 999         if (w <= 0 || w > 720 || h <= 0 || h > 576)
1000                 return -EINVAL;
1001         bpp = av7110->osdbpp[av7110->osdwin] + 1;
1002         bpl = ((w * bpp + 7) & ~7) / 8;
1003         size = h * bpl;
1004         lpb = (32 * 1024) / bpl;
1005         bnum = size / (lpb * bpl);
1006         brest = size - bnum * lpb * bpl;
1007 
1008         if (av7110->bmp_state == BMP_LOADING) {
1009                 /* possible if syscall is repeated by -ERESTARTSYS and if firmware cannot abort */
1010                 BUG_ON (FW_VERSION(av7110->arm_app) >= 0x261e);
1011                 rc = WaitUntilBmpLoaded(av7110);
1012                 if (rc)
1013                         return rc;
1014                 /* just continue. This should work for all fw versions
1015                  * if bnum==1 && !brest && LoadBitmap was successful
1016                  */
1017         }
1018 
1019         rc = 0;
1020         for (i = 0; i < bnum; i++) {
1021                 rc = LoadBitmap(av7110, w, lpb, inc, data);
1022                 if (rc)
1023                         break;
1024                 rc = BlitBitmap(av7110, x0, y0 + i * lpb);
1025                 if (rc)
1026                         break;
1027                 data += lpb * inc;
1028         }
1029         if (!rc && brest) {
1030                 rc = LoadBitmap(av7110, w, brest / bpl, inc, data);
1031                 if (!rc)
1032                         rc = BlitBitmap(av7110, x0, y0 + bnum * lpb);
1033         }
1034         release_rc = ReleaseBitmap(av7110);
1035         if (!rc)
1036                 rc = release_rc;
1037         if (rc)
1038                 dprintk(1,"returns %d\n",rc);
1039         return rc;
1040 }
1041 
1042 int av7110_osd_cmd(struct av7110 *av7110, osd_cmd_t *dc)
1043 {
1044         int ret;
1045 
1046         if (mutex_lock_interruptible(&av7110->osd_mutex))
1047                 return -ERESTARTSYS;
1048 
1049         switch (dc->cmd) {
1050         case OSD_Close:
1051                 ret = DestroyOSDWindow(av7110, av7110->osdwin);
1052                 break;
1053         case OSD_Open:
1054                 av7110->osdbpp[av7110->osdwin] = (dc->color - 1) & 7;
1055                 ret = CreateOSDWindow(av7110, av7110->osdwin,
1056                                 bpp2bit[av7110->osdbpp[av7110->osdwin]],
1057                                 dc->x1 - dc->x0 + 1, dc->y1 - dc->y0 + 1);
1058                 if (ret)
1059                         break;
1060                 if (!dc->data) {
1061                         ret = MoveWindowAbs(av7110, av7110->osdwin, dc->x0, dc->y0);
1062                         if (ret)
1063                                 break;
1064                         ret = SetColorBlend(av7110, av7110->osdwin);
1065                 }
1066                 break;
1067         case OSD_Show:
1068                 ret = MoveWindowRel(av7110, av7110->osdwin, 0, 0);
1069                 break;
1070         case OSD_Hide:
1071                 ret = HideWindow(av7110, av7110->osdwin);
1072                 break;
1073         case OSD_Clear:
1074                 ret = DrawBlock(av7110, av7110->osdwin, 0, 0, 720, 576, 0);
1075                 break;
1076         case OSD_Fill:
1077                 ret = DrawBlock(av7110, av7110->osdwin, 0, 0, 720, 576, dc->color);
1078                 break;
1079         case OSD_SetColor:
1080                 ret = OSDSetColor(av7110, dc->color, dc->x0, dc->y0, dc->x1, dc->y1);
1081                 break;
1082         case OSD_SetPalette:
1083                 if (FW_VERSION(av7110->arm_app) >= 0x2618)
1084                         ret = OSDSetPalette(av7110, dc->data, dc->color, dc->x0);
1085                 else {
1086                         int i, len = dc->x0-dc->color+1;
1087                         u8 __user *colors = (u8 __user *)dc->data;
1088                         u8 r, g = 0, b = 0, blend = 0;
1089                         ret = 0;
1090                         for (i = 0; i<len; i++) {
1091                                 if (get_user(r, colors + i * 4) ||
1092                                     get_user(g, colors + i * 4 + 1) ||
1093                                     get_user(b, colors + i * 4 + 2) ||
1094                                     get_user(blend, colors + i * 4 + 3)) {
1095                                         ret = -EFAULT;
1096                                         break;
1097                                     }
1098                                 ret = OSDSetColor(av7110, dc->color + i, r, g, b, blend);
1099                                 if (ret)
1100                                         break;
1101                         }
1102                 }
1103                 break;
1104         case OSD_SetPixel:
1105                 ret = DrawLine(av7110, av7110->osdwin,
1106                          dc->x0, dc->y0, 0, 0, dc->color);
1107                 break;
1108         case OSD_SetRow:
1109                 dc->y1 = dc->y0;
1110                 /* fall through */
1111         case OSD_SetBlock:
1112                 ret = OSDSetBlock(av7110, dc->x0, dc->y0, dc->x1, dc->y1, dc->color, dc->data);
1113                 break;
1114         case OSD_FillRow:
1115                 ret = DrawBlock(av7110, av7110->osdwin, dc->x0, dc->y0,
1116                           dc->x1-dc->x0+1, dc->y1, dc->color);
1117                 break;
1118         case OSD_FillBlock:
1119                 ret = DrawBlock(av7110, av7110->osdwin, dc->x0, dc->y0,
1120                           dc->x1 - dc->x0 + 1, dc->y1 - dc->y0 + 1, dc->color);
1121                 break;
1122         case OSD_Line:
1123                 ret = DrawLine(av7110, av7110->osdwin,
1124                          dc->x0, dc->y0, dc->x1 - dc->x0, dc->y1 - dc->y0, dc->color);
1125                 break;
1126         case OSD_Text:
1127         {
1128                 char textbuf[240];
1129 
1130                 if (strncpy_from_user(textbuf, dc->data, 240) < 0) {
1131                         ret = -EFAULT;
1132                         break;
1133                 }
1134                 textbuf[239] = 0;
1135                 if (dc->x1 > 3)
1136                         dc->x1 = 3;
1137                 ret = SetFont(av7110, av7110->osdwin, dc->x1,
1138                         (u16) (dc->color & 0xffff), (u16) (dc->color >> 16));
1139                 if (!ret)
1140                         ret = FlushText(av7110);
1141                 if (!ret)
1142                         ret = WriteText(av7110, av7110->osdwin, dc->x0, dc->y0, textbuf);
1143                 break;
1144         }
1145         case OSD_SetWindow:
1146                 if (dc->x0 < 1 || dc->x0 > 7)
1147                         ret = -EINVAL;
1148                 else {
1149                         av7110->osdwin = dc->x0;
1150                         ret = 0;
1151                 }
1152                 break;
1153         case OSD_MoveWindow:
1154                 ret = MoveWindowAbs(av7110, av7110->osdwin, dc->x0, dc->y0);
1155                 if (!ret)
1156                         ret = SetColorBlend(av7110, av7110->osdwin);
1157                 break;
1158         case OSD_OpenRaw:
1159                 if (dc->color < OSD_BITMAP1 || dc->color > OSD_CURSOR) {
1160                         ret = -EINVAL;
1161                         break;
1162                 }
1163                 if (dc->color >= OSD_BITMAP1 && dc->color <= OSD_BITMAP8HR)
1164                         av7110->osdbpp[av7110->osdwin] = (1 << (dc->color & 3)) - 1;
1165                 else
1166                         av7110->osdbpp[av7110->osdwin] = 0;
1167                 ret = CreateOSDWindow(av7110, av7110->osdwin, (osd_raw_window_t)dc->color,
1168                                 dc->x1 - dc->x0 + 1, dc->y1 - dc->y0 + 1);
1169                 if (ret)
1170                         break;
1171                 if (!dc->data) {
1172                         ret = MoveWindowAbs(av7110, av7110->osdwin, dc->x0, dc->y0);
1173                         if (!ret)
1174                                 ret = SetColorBlend(av7110, av7110->osdwin);
1175                 }
1176                 break;
1177         default:
1178                 ret = -EINVAL;
1179                 break;
1180         }
1181 
1182         mutex_unlock(&av7110->osd_mutex);
1183         if (ret==-ERESTARTSYS)
1184                 dprintk(1, "av7110_osd_cmd(%d) returns with -ERESTARTSYS\n",dc->cmd);
1185         else if (ret)
1186                 dprintk(1, "av7110_osd_cmd(%d) returns with %d\n",dc->cmd,ret);
1187 
1188         return ret;
1189 }
1190 
1191 int av7110_osd_capability(struct av7110 *av7110, osd_cap_t *cap)
1192 {
1193         switch (cap->cmd) {
1194         case OSD_CAP_MEMSIZE:
1195                 if (FW_4M_SDRAM(av7110->arm_app))
1196                         cap->val = 1000000;
1197                 else
1198                         cap->val = 92000;
1199                 return 0;
1200         default:
1201                 return -EINVAL;
1202         }
1203 }
1204 #endif /* CONFIG_DVB_AV7110_OSD */

/* [<][>][^][v][top][bottom][index][help] */