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