linux/drivers/media/pci/ttpci/av7110_av.c
<<
>>
Prefs
   1/*
   2 * av7110_av.c: audio and video MPEG decoder stuff
   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 *
  16 * This program is distributed in the hope that it will be useful,
  17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19 * GNU General Public License for more details.
  20 *
  21 *
  22 * You should have received a copy of the GNU General Public License
  23 * along with this program; if not, write to the Free Software
  24 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  25 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
  26 *
  27 *
  28 * the project's page is at http://www.linuxtv.org/ 
  29 */
  30
  31#include <linux/types.h>
  32#include <linux/kernel.h>
  33#include <linux/string.h>
  34#include <linux/delay.h>
  35#include <linux/fs.h>
  36
  37#include "av7110.h"
  38#include "av7110_hw.h"
  39#include "av7110_av.h"
  40#include "av7110_ipack.h"
  41
  42/* MPEG-2 (ISO 13818 / H.222.0) stream types */
  43#define PROG_STREAM_MAP  0xBC
  44#define PRIVATE_STREAM1  0xBD
  45#define PADDING_STREAM   0xBE
  46#define PRIVATE_STREAM2  0xBF
  47#define AUDIO_STREAM_S   0xC0
  48#define AUDIO_STREAM_E   0xDF
  49#define VIDEO_STREAM_S   0xE0
  50#define VIDEO_STREAM_E   0xEF
  51#define ECM_STREAM       0xF0
  52#define EMM_STREAM       0xF1
  53#define DSM_CC_STREAM    0xF2
  54#define ISO13522_STREAM  0xF3
  55#define PROG_STREAM_DIR  0xFF
  56
  57#define PTS_DTS_FLAGS    0xC0
  58
  59//pts_dts flags
  60#define PTS_ONLY         0x80
  61#define PTS_DTS          0xC0
  62#define TS_SIZE          188
  63#define TRANS_ERROR      0x80
  64#define PAY_START        0x40
  65#define TRANS_PRIO       0x20
  66#define PID_MASK_HI      0x1F
  67//flags
  68#define TRANS_SCRMBL1    0x80
  69#define TRANS_SCRMBL2    0x40
  70#define ADAPT_FIELD      0x20
  71#define PAYLOAD          0x10
  72#define COUNT_MASK       0x0F
  73
  74// adaptation flags
  75#define DISCON_IND       0x80
  76#define RAND_ACC_IND     0x40
  77#define ES_PRI_IND       0x20
  78#define PCR_FLAG         0x10
  79#define OPCR_FLAG        0x08
  80#define SPLICE_FLAG      0x04
  81#define TRANS_PRIV       0x02
  82#define ADAP_EXT_FLAG    0x01
  83
  84// adaptation extension flags
  85#define LTW_FLAG         0x80
  86#define PIECE_RATE       0x40
  87#define SEAM_SPLICE      0x20
  88
  89
  90static void p_to_t(u8 const *buf, long int length, u16 pid,
  91                   u8 *counter, struct dvb_demux_feed *feed);
  92static int write_ts_to_decoder(struct av7110 *av7110, int type, const u8 *buf, size_t len);
  93
  94
  95int av7110_record_cb(struct dvb_filter_pes2ts *p2t, u8 *buf, size_t len)
  96{
  97        struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *) p2t->priv;
  98
  99        if (!(dvbdmxfeed->ts_type & TS_PACKET))
 100                return 0;
 101        if (buf[3] == 0xe0)      // video PES do not have a length in TS
 102                buf[4] = buf[5] = 0;
 103        if (dvbdmxfeed->ts_type & TS_PAYLOAD_ONLY)
 104                return dvbdmxfeed->cb.ts(buf, len, NULL, 0,
 105                                         &dvbdmxfeed->feed.ts, DMX_OK);
 106        else
 107                return dvb_filter_pes2ts(p2t, buf, len, 1);
 108}
 109
 110static int dvb_filter_pes2ts_cb(void *priv, unsigned char *data)
 111{
 112        struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *) priv;
 113
 114        dvbdmxfeed->cb.ts(data, 188, NULL, 0,
 115                          &dvbdmxfeed->feed.ts, DMX_OK);
 116        return 0;
 117}
 118
 119int av7110_av_start_record(struct av7110 *av7110, int av,
 120                           struct dvb_demux_feed *dvbdmxfeed)
 121{
 122        int ret = 0;
 123        struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
 124
 125        dprintk(2, "av7110:%p, , dvb_demux_feed:%p\n", av7110, dvbdmxfeed);
 126
 127        if (av7110->playing || (av7110->rec_mode & av))
 128                return -EBUSY;
 129        av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Stop, 0);
 130        dvbdmx->recording = 1;
 131        av7110->rec_mode |= av;
 132
 133        switch (av7110->rec_mode) {
 134        case RP_AUDIO:
 135                dvb_filter_pes2ts_init(&av7110->p2t[0],
 136                                       dvbdmx->pesfilter[0]->pid,
 137                                       dvb_filter_pes2ts_cb,
 138                                       (void *) dvbdmx->pesfilter[0]);
 139                ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Record, 2, AudioPES, 0);
 140                break;
 141
 142        case RP_VIDEO:
 143                dvb_filter_pes2ts_init(&av7110->p2t[1],
 144                                       dvbdmx->pesfilter[1]->pid,
 145                                       dvb_filter_pes2ts_cb,
 146                                       (void *) dvbdmx->pesfilter[1]);
 147                ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Record, 2, VideoPES, 0);
 148                break;
 149
 150        case RP_AV:
 151                dvb_filter_pes2ts_init(&av7110->p2t[0],
 152                                       dvbdmx->pesfilter[0]->pid,
 153                                       dvb_filter_pes2ts_cb,
 154                                       (void *) dvbdmx->pesfilter[0]);
 155                dvb_filter_pes2ts_init(&av7110->p2t[1],
 156                                       dvbdmx->pesfilter[1]->pid,
 157                                       dvb_filter_pes2ts_cb,
 158                                       (void *) dvbdmx->pesfilter[1]);
 159                ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Record, 2, AV_PES, 0);
 160                break;
 161        }
 162        return ret;
 163}
 164
 165int av7110_av_start_play(struct av7110 *av7110, int av)
 166{
 167        int ret = 0;
 168        dprintk(2, "av7110:%p, \n", av7110);
 169
 170        if (av7110->rec_mode)
 171                return -EBUSY;
 172        if (av7110->playing & av)
 173                return -EBUSY;
 174
 175        av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Stop, 0);
 176
 177        if (av7110->playing == RP_NONE) {
 178                av7110_ipack_reset(&av7110->ipack[0]);
 179                av7110_ipack_reset(&av7110->ipack[1]);
 180        }
 181
 182        av7110->playing |= av;
 183        switch (av7110->playing) {
 184        case RP_AUDIO:
 185                ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Play, 2, AudioPES, 0);
 186                break;
 187        case RP_VIDEO:
 188                ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Play, 2, VideoPES, 0);
 189                av7110->sinfo = 0;
 190                break;
 191        case RP_AV:
 192                av7110->sinfo = 0;
 193                ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Play, 2, AV_PES, 0);
 194                break;
 195        }
 196        return ret;
 197}
 198
 199int av7110_av_stop(struct av7110 *av7110, int av)
 200{
 201        int ret = 0;
 202        dprintk(2, "av7110:%p, \n", av7110);
 203
 204        if (!(av7110->playing & av) && !(av7110->rec_mode & av))
 205                return 0;
 206        av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Stop, 0);
 207        if (av7110->playing) {
 208                av7110->playing &= ~av;
 209                switch (av7110->playing) {
 210                case RP_AUDIO:
 211                        ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Play, 2, AudioPES, 0);
 212                        break;
 213                case RP_VIDEO:
 214                        ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Play, 2, VideoPES, 0);
 215                        break;
 216                case RP_NONE:
 217                        ret = av7110_set_vidmode(av7110, av7110->vidmode);
 218                        break;
 219                }
 220        } else {
 221                av7110->rec_mode &= ~av;
 222                switch (av7110->rec_mode) {
 223                case RP_AUDIO:
 224                        ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Record, 2, AudioPES, 0);
 225                        break;
 226                case RP_VIDEO:
 227                        ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Record, 2, VideoPES, 0);
 228                        break;
 229                case RP_NONE:
 230                        break;
 231                }
 232        }
 233        return ret;
 234}
 235
 236
 237int av7110_pes_play(void *dest, struct dvb_ringbuffer *buf, int dlen)
 238{
 239        int len;
 240        u32 sync;
 241        u16 blen;
 242
 243        if (!dlen) {
 244                wake_up(&buf->queue);
 245                return -1;
 246        }
 247        while (1) {
 248                len = dvb_ringbuffer_avail(buf);
 249                if (len < 6) {
 250                        wake_up(&buf->queue);
 251                        return -1;
 252                }
 253                sync =  DVB_RINGBUFFER_PEEK(buf, 0) << 24;
 254                sync |= DVB_RINGBUFFER_PEEK(buf, 1) << 16;
 255                sync |= DVB_RINGBUFFER_PEEK(buf, 2) << 8;
 256                sync |= DVB_RINGBUFFER_PEEK(buf, 3);
 257
 258                if (((sync &~ 0x0f) == 0x000001e0) ||
 259                    ((sync &~ 0x1f) == 0x000001c0) ||
 260                    (sync == 0x000001bd))
 261                        break;
 262                printk("resync\n");
 263                DVB_RINGBUFFER_SKIP(buf, 1);
 264        }
 265        blen =  DVB_RINGBUFFER_PEEK(buf, 4) << 8;
 266        blen |= DVB_RINGBUFFER_PEEK(buf, 5);
 267        blen += 6;
 268        if (len < blen || blen > dlen) {
 269                //printk("buffer empty - avail %d blen %u dlen %d\n", len, blen, dlen);
 270                wake_up(&buf->queue);
 271                return -1;
 272        }
 273
 274        dvb_ringbuffer_read(buf, dest, (size_t) blen);
 275
 276        dprintk(2, "pread=0x%08lx, pwrite=0x%08lx\n",
 277               (unsigned long) buf->pread, (unsigned long) buf->pwrite);
 278        wake_up(&buf->queue);
 279        return blen;
 280}
 281
 282
 283int av7110_set_volume(struct av7110 *av7110, int volleft, int volright)
 284{
 285        int err, vol, val, balance = 0;
 286
 287        dprintk(2, "av7110:%p, \n", av7110);
 288
 289        av7110->mixer.volume_left = volleft;
 290        av7110->mixer.volume_right = volright;
 291
 292        switch (av7110->adac_type) {
 293        case DVB_ADAC_TI:
 294                volleft = (volleft * 256) / 1036;
 295                volright = (volright * 256) / 1036;
 296                if (volleft > 0x3f)
 297                        volleft = 0x3f;
 298                if (volright > 0x3f)
 299                        volright = 0x3f;
 300                if ((err = SendDAC(av7110, 3, 0x80 + volleft)))
 301                        return err;
 302                return SendDAC(av7110, 4, volright);
 303
 304        case DVB_ADAC_CRYSTAL:
 305                volleft = 127 - volleft / 2;
 306                volright = 127 - volright / 2;
 307                i2c_writereg(av7110, 0x20, 0x03, volleft);
 308                i2c_writereg(av7110, 0x20, 0x04, volright);
 309                return 0;
 310
 311        case DVB_ADAC_MSP34x0:
 312                vol  = (volleft > volright) ? volleft : volright;
 313                val     = (vol * 0x73 / 255) << 8;
 314                if (vol > 0)
 315                       balance = ((volright - volleft) * 127) / vol;
 316                msp_writereg(av7110, MSP_WR_DSP, 0x0001, balance << 8);
 317                msp_writereg(av7110, MSP_WR_DSP, 0x0000, val); /* loudspeaker */
 318                msp_writereg(av7110, MSP_WR_DSP, 0x0006, val); /* headphonesr */
 319                return 0;
 320
 321        case DVB_ADAC_MSP34x5:
 322                vol = (volleft > volright) ? volleft : volright;
 323                val = (vol * 0x73 / 255) << 8;
 324                if (vol > 0)
 325                        balance = ((volright - volleft) * 127) / vol;
 326                msp_writereg(av7110, MSP_WR_DSP, 0x0001, balance << 8);
 327                msp_writereg(av7110, MSP_WR_DSP, 0x0000, val); /* loudspeaker */
 328                return 0;
 329        }
 330
 331        return 0;
 332}
 333
 334int av7110_set_vidmode(struct av7110 *av7110, enum av7110_video_mode mode)
 335{
 336        int ret;
 337        dprintk(2, "av7110:%p, \n", av7110);
 338
 339        ret = av7110_fw_cmd(av7110, COMTYPE_ENCODER, LoadVidCode, 1, mode);
 340
 341        if (!ret && !av7110->playing) {
 342                ret = ChangePIDs(av7110, av7110->pids[DMX_PES_VIDEO],
 343                           av7110->pids[DMX_PES_AUDIO],
 344                           av7110->pids[DMX_PES_TELETEXT],
 345                           0, av7110->pids[DMX_PES_PCR]);
 346                if (!ret)
 347                        ret = av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, Scan, 0);
 348        }
 349        return ret;
 350}
 351
 352
 353static enum av7110_video_mode sw2mode[16] = {
 354        AV7110_VIDEO_MODE_PAL, AV7110_VIDEO_MODE_NTSC,
 355        AV7110_VIDEO_MODE_NTSC, AV7110_VIDEO_MODE_PAL,
 356        AV7110_VIDEO_MODE_NTSC, AV7110_VIDEO_MODE_NTSC,
 357        AV7110_VIDEO_MODE_PAL, AV7110_VIDEO_MODE_NTSC,
 358        AV7110_VIDEO_MODE_PAL, AV7110_VIDEO_MODE_PAL,
 359        AV7110_VIDEO_MODE_PAL, AV7110_VIDEO_MODE_PAL,
 360        AV7110_VIDEO_MODE_PAL, AV7110_VIDEO_MODE_PAL,
 361        AV7110_VIDEO_MODE_PAL, AV7110_VIDEO_MODE_PAL,
 362};
 363
 364static int get_video_format(struct av7110 *av7110, u8 *buf, int count)
 365{
 366        int i;
 367        int hsize, vsize;
 368        int sw;
 369        u8 *p;
 370        int ret = 0;
 371
 372        dprintk(2, "av7110:%p, \n", av7110);
 373
 374        if (av7110->sinfo)
 375                return 0;
 376        for (i = 7; i < count - 10; i++) {
 377                p = buf + i;
 378                if (p[0] || p[1] || p[2] != 0x01 || p[3] != 0xb3)
 379                        continue;
 380                p += 4;
 381                hsize = ((p[1] &0xF0) >> 4) | (p[0] << 4);
 382                vsize = ((p[1] &0x0F) << 8) | (p[2]);
 383                sw = (p[3] & 0x0F);
 384                ret = av7110_set_vidmode(av7110, sw2mode[sw]);
 385                if (!ret) {
 386                        dprintk(2, "playback %dx%d fr=%d\n", hsize, vsize, sw);
 387                        av7110->sinfo = 1;
 388                }
 389                break;
 390        }
 391        return ret;
 392}
 393
 394
 395/****************************************************************************
 396 * I/O buffer management and control
 397 ****************************************************************************/
 398
 399static inline long aux_ring_buffer_write(struct dvb_ringbuffer *rbuf,
 400                                         const u8 *buf, unsigned long count)
 401{
 402        unsigned long todo = count;
 403        int free;
 404
 405        while (todo > 0) {
 406                if (dvb_ringbuffer_free(rbuf) < 2048) {
 407                        if (wait_event_interruptible(rbuf->queue,
 408                                                     (dvb_ringbuffer_free(rbuf) >= 2048)))
 409                                return count - todo;
 410                }
 411                free = dvb_ringbuffer_free(rbuf);
 412                if (free > todo)
 413                        free = todo;
 414                dvb_ringbuffer_write(rbuf, buf, free);
 415                todo -= free;
 416                buf += free;
 417        }
 418
 419        return count - todo;
 420}
 421
 422static void play_video_cb(u8 *buf, int count, void *priv)
 423{
 424        struct av7110 *av7110 = (struct av7110 *) priv;
 425        dprintk(2, "av7110:%p, \n", av7110);
 426
 427        if ((buf[3] & 0xe0) == 0xe0) {
 428                get_video_format(av7110, buf, count);
 429                aux_ring_buffer_write(&av7110->avout, buf, count);
 430        } else
 431                aux_ring_buffer_write(&av7110->aout, buf, count);
 432}
 433
 434static void play_audio_cb(u8 *buf, int count, void *priv)
 435{
 436        struct av7110 *av7110 = (struct av7110 *) priv;
 437        dprintk(2, "av7110:%p, \n", av7110);
 438
 439        aux_ring_buffer_write(&av7110->aout, buf, count);
 440}
 441
 442
 443#define FREE_COND_TS (dvb_ringbuffer_free(rb) >= 4096)
 444
 445static ssize_t ts_play(struct av7110 *av7110, const char __user *buf,
 446                       unsigned long count, int nonblock, int type)
 447{
 448        struct dvb_ringbuffer *rb;
 449        u8 *kb;
 450        unsigned long todo = count;
 451
 452        dprintk(2, "%s: type %d cnt %lu\n", __func__, type, count);
 453
 454        rb = (type) ? &av7110->avout : &av7110->aout;
 455        kb = av7110->kbuf[type];
 456
 457        if (!kb)
 458                return -ENOBUFS;
 459
 460        if (nonblock && !FREE_COND_TS)
 461                return -EWOULDBLOCK;
 462
 463        while (todo >= TS_SIZE) {
 464                if (!FREE_COND_TS) {
 465                        if (nonblock)
 466                                return count - todo;
 467                        if (wait_event_interruptible(rb->queue, FREE_COND_TS))
 468                                return count - todo;
 469                }
 470                if (copy_from_user(kb, buf, TS_SIZE))
 471                        return -EFAULT;
 472                write_ts_to_decoder(av7110, type, kb, TS_SIZE);
 473                todo -= TS_SIZE;
 474                buf += TS_SIZE;
 475        }
 476
 477        return count - todo;
 478}
 479
 480
 481#define FREE_COND (dvb_ringbuffer_free(&av7110->avout) >= 20 * 1024 && \
 482                   dvb_ringbuffer_free(&av7110->aout) >= 20 * 1024)
 483
 484static ssize_t dvb_play(struct av7110 *av7110, const char __user *buf,
 485                        unsigned long count, int nonblock, int type)
 486{
 487        unsigned long todo = count, n;
 488        dprintk(2, "av7110:%p, \n", av7110);
 489
 490        if (!av7110->kbuf[type])
 491                return -ENOBUFS;
 492
 493        if (nonblock && !FREE_COND)
 494                return -EWOULDBLOCK;
 495
 496        while (todo > 0) {
 497                if (!FREE_COND) {
 498                        if (nonblock)
 499                                return count - todo;
 500                        if (wait_event_interruptible(av7110->avout.queue,
 501                                                     FREE_COND))
 502                                return count - todo;
 503                }
 504                n = todo;
 505                if (n > IPACKS * 2)
 506                        n = IPACKS * 2;
 507                if (copy_from_user(av7110->kbuf[type], buf, n))
 508                        return -EFAULT;
 509                av7110_ipack_instant_repack(av7110->kbuf[type], n,
 510                                            &av7110->ipack[type]);
 511                todo -= n;
 512                buf += n;
 513        }
 514        return count - todo;
 515}
 516
 517static ssize_t dvb_play_kernel(struct av7110 *av7110, const u8 *buf,
 518                        unsigned long count, int nonblock, int type)
 519{
 520        unsigned long todo = count, n;
 521        dprintk(2, "av7110:%p, \n", av7110);
 522
 523        if (!av7110->kbuf[type])
 524                return -ENOBUFS;
 525
 526        if (nonblock && !FREE_COND)
 527                return -EWOULDBLOCK;
 528
 529        while (todo > 0) {
 530                if (!FREE_COND) {
 531                        if (nonblock)
 532                                return count - todo;
 533                        if (wait_event_interruptible(av7110->avout.queue,
 534                                                     FREE_COND))
 535                                return count - todo;
 536                }
 537                n = todo;
 538                if (n > IPACKS * 2)
 539                        n = IPACKS * 2;
 540                av7110_ipack_instant_repack(buf, n, &av7110->ipack[type]);
 541                todo -= n;
 542                buf += n;
 543        }
 544        return count - todo;
 545}
 546
 547static ssize_t dvb_aplay(struct av7110 *av7110, const char __user *buf,
 548                         unsigned long count, int nonblock, int type)
 549{
 550        unsigned long todo = count, n;
 551        dprintk(2, "av7110:%p, \n", av7110);
 552
 553        if (!av7110->kbuf[type])
 554                return -ENOBUFS;
 555        if (nonblock && dvb_ringbuffer_free(&av7110->aout) < 20 * 1024)
 556                return -EWOULDBLOCK;
 557
 558        while (todo > 0) {
 559                if (dvb_ringbuffer_free(&av7110->aout) < 20 * 1024) {
 560                        if (nonblock)
 561                                return count - todo;
 562                        if (wait_event_interruptible(av7110->aout.queue,
 563                                        (dvb_ringbuffer_free(&av7110->aout) >= 20 * 1024)))
 564                                return count-todo;
 565                }
 566                n = todo;
 567                if (n > IPACKS * 2)
 568                        n = IPACKS * 2;
 569                if (copy_from_user(av7110->kbuf[type], buf, n))
 570                        return -EFAULT;
 571                av7110_ipack_instant_repack(av7110->kbuf[type], n,
 572                                            &av7110->ipack[type]);
 573                todo -= n;
 574                buf += n;
 575        }
 576        return count - todo;
 577}
 578
 579void av7110_p2t_init(struct av7110_p2t *p, struct dvb_demux_feed *feed)
 580{
 581        memset(p->pes, 0, TS_SIZE);
 582        p->counter = 0;
 583        p->pos = 0;
 584        p->frags = 0;
 585        if (feed)
 586                p->feed = feed;
 587}
 588
 589static void clear_p2t(struct av7110_p2t *p)
 590{
 591        memset(p->pes, 0, TS_SIZE);
 592//      p->counter = 0;
 593        p->pos = 0;
 594        p->frags = 0;
 595}
 596
 597
 598static int find_pes_header(u8 const *buf, long int length, int *frags)
 599{
 600        int c = 0;
 601        int found = 0;
 602
 603        *frags = 0;
 604
 605        while (c < length - 3 && !found) {
 606                if (buf[c] == 0x00 && buf[c + 1] == 0x00 &&
 607                    buf[c + 2] == 0x01) {
 608                        switch ( buf[c + 3] ) {
 609                        case PROG_STREAM_MAP:
 610                        case PRIVATE_STREAM2:
 611                        case PROG_STREAM_DIR:
 612                        case ECM_STREAM     :
 613                        case EMM_STREAM     :
 614                        case PADDING_STREAM :
 615                        case DSM_CC_STREAM  :
 616                        case ISO13522_STREAM:
 617                        case PRIVATE_STREAM1:
 618                        case AUDIO_STREAM_S ... AUDIO_STREAM_E:
 619                        case VIDEO_STREAM_S ... VIDEO_STREAM_E:
 620                                found = 1;
 621                                break;
 622
 623                        default:
 624                                c++;
 625                                break;
 626                        }
 627                } else
 628                        c++;
 629        }
 630        if (c == length - 3 && !found) {
 631                if (buf[length - 1] == 0x00)
 632                        *frags = 1;
 633                if (buf[length - 2] == 0x00 &&
 634                    buf[length - 1] == 0x00)
 635                        *frags = 2;
 636                if (buf[length - 3] == 0x00 &&
 637                    buf[length - 2] == 0x00 &&
 638                    buf[length - 1] == 0x01)
 639                        *frags = 3;
 640                return -1;
 641        }
 642
 643        return c;
 644}
 645
 646void av7110_p2t_write(u8 const *buf, long int length, u16 pid, struct av7110_p2t *p)
 647{
 648        int c, c2, l, add;
 649        int check, rest;
 650
 651        c = 0;
 652        c2 = 0;
 653        if (p->frags){
 654                check = 0;
 655                switch(p->frags) {
 656                case 1:
 657                        if (buf[c] == 0x00 && buf[c + 1] == 0x01) {
 658                                check = 1;
 659                                c += 2;
 660                        }
 661                        break;
 662                case 2:
 663                        if (buf[c] == 0x01) {
 664                                check = 1;
 665                                c++;
 666                        }
 667                        break;
 668                case 3:
 669                        check = 1;
 670                }
 671                if (check) {
 672                        switch (buf[c]) {
 673                        case PROG_STREAM_MAP:
 674                        case PRIVATE_STREAM2:
 675                        case PROG_STREAM_DIR:
 676                        case ECM_STREAM     :
 677                        case EMM_STREAM     :
 678                        case PADDING_STREAM :
 679                        case DSM_CC_STREAM  :
 680                        case ISO13522_STREAM:
 681                        case PRIVATE_STREAM1:
 682                        case AUDIO_STREAM_S ... AUDIO_STREAM_E:
 683                        case VIDEO_STREAM_S ... VIDEO_STREAM_E:
 684                                p->pes[0] = 0x00;
 685                                p->pes[1] = 0x00;
 686                                p->pes[2] = 0x01;
 687                                p->pes[3] = buf[c];
 688                                p->pos = 4;
 689                                memcpy(p->pes + p->pos, buf + c, (TS_SIZE - 4) - p->pos);
 690                                c += (TS_SIZE - 4) - p->pos;
 691                                p_to_t(p->pes, (TS_SIZE - 4), pid, &p->counter, p->feed);
 692                                clear_p2t(p);
 693                                break;
 694
 695                        default:
 696                                c = 0;
 697                                break;
 698                        }
 699                }
 700                p->frags = 0;
 701        }
 702
 703        if (p->pos) {
 704                c2 = find_pes_header(buf + c, length - c, &p->frags);
 705                if (c2 >= 0 && c2 < (TS_SIZE - 4) - p->pos)
 706                        l = c2+c;
 707                else
 708                        l = (TS_SIZE - 4) - p->pos;
 709                memcpy(p->pes + p->pos, buf, l);
 710                c += l;
 711                p->pos += l;
 712                p_to_t(p->pes, p->pos, pid, &p->counter, p->feed);
 713                clear_p2t(p);
 714        }
 715
 716        add = 0;
 717        while (c < length) {
 718                c2 = find_pes_header(buf + c + add, length - c - add, &p->frags);
 719                if (c2 >= 0) {
 720                        c2 += c + add;
 721                        if (c2 > c){
 722                                p_to_t(buf + c, c2 - c, pid, &p->counter, p->feed);
 723                                c = c2;
 724                                clear_p2t(p);
 725                                add = 0;
 726                        } else
 727                                add = 1;
 728                } else {
 729                        l = length - c;
 730                        rest = l % (TS_SIZE - 4);
 731                        l -= rest;
 732                        p_to_t(buf + c, l, pid, &p->counter, p->feed);
 733                        memcpy(p->pes, buf + c + l, rest);
 734                        p->pos = rest;
 735                        c = length;
 736                }
 737        }
 738}
 739
 740
 741static int write_ts_header2(u16 pid, u8 *counter, int pes_start, u8 *buf, u8 length)
 742{
 743        int i;
 744        int c = 0;
 745        int fill;
 746        u8 tshead[4] = { 0x47, 0x00, 0x00, 0x10 };
 747
 748        fill = (TS_SIZE - 4) - length;
 749        if (pes_start)
 750                tshead[1] = 0x40;
 751        if (fill)
 752                tshead[3] = 0x30;
 753        tshead[1] |= (u8)((pid & 0x1F00) >> 8);
 754        tshead[2] |= (u8)(pid & 0x00FF);
 755        tshead[3] |= ((*counter)++ & 0x0F);
 756        memcpy(buf, tshead, 4);
 757        c += 4;
 758
 759        if (fill) {
 760                buf[4] = fill - 1;
 761                c++;
 762                if (fill > 1) {
 763                        buf[5] = 0x00;
 764                        c++;
 765                }
 766                for (i = 6; i < fill + 4; i++) {
 767                        buf[i] = 0xFF;
 768                        c++;
 769                }
 770        }
 771
 772        return c;
 773}
 774
 775
 776static void p_to_t(u8 const *buf, long int length, u16 pid, u8 *counter,
 777                   struct dvb_demux_feed *feed)
 778{
 779        int l, pes_start;
 780        u8 obuf[TS_SIZE];
 781        long c = 0;
 782
 783        pes_start = 0;
 784        if (length > 3 &&
 785             buf[0] == 0x00 && buf[1] == 0x00 && buf[2] == 0x01)
 786                switch (buf[3]) {
 787                        case PROG_STREAM_MAP:
 788                        case PRIVATE_STREAM2:
 789                        case PROG_STREAM_DIR:
 790                        case ECM_STREAM     :
 791                        case EMM_STREAM     :
 792                        case PADDING_STREAM :
 793                        case DSM_CC_STREAM  :
 794                        case ISO13522_STREAM:
 795                        case PRIVATE_STREAM1:
 796                        case AUDIO_STREAM_S ... AUDIO_STREAM_E:
 797                        case VIDEO_STREAM_S ... VIDEO_STREAM_E:
 798                                pes_start = 1;
 799                                break;
 800
 801                        default:
 802                                break;
 803                }
 804
 805        while (c < length) {
 806                memset(obuf, 0, TS_SIZE);
 807                if (length - c >= (TS_SIZE - 4)){
 808                        l = write_ts_header2(pid, counter, pes_start,
 809                                             obuf, (TS_SIZE - 4));
 810                        memcpy(obuf + l, buf + c, TS_SIZE - l);
 811                        c += TS_SIZE - l;
 812                } else {
 813                        l = write_ts_header2(pid, counter, pes_start,
 814                                             obuf, length - c);
 815                        memcpy(obuf + l, buf + c, TS_SIZE - l);
 816                        c = length;
 817                }
 818                feed->cb.ts(obuf, 188, NULL, 0, &feed->feed.ts, DMX_OK);
 819                pes_start = 0;
 820        }
 821}
 822
 823
 824static int write_ts_to_decoder(struct av7110 *av7110, int type, const u8 *buf, size_t len)
 825{
 826        struct ipack *ipack = &av7110->ipack[type];
 827
 828        if (buf[1] & TRANS_ERROR) {
 829                av7110_ipack_reset(ipack);
 830                return -1;
 831        }
 832
 833        if (!(buf[3] & PAYLOAD))
 834                return -1;
 835
 836        if (buf[1] & PAY_START)
 837                av7110_ipack_flush(ipack);
 838
 839        if (buf[3] & ADAPT_FIELD) {
 840                len -= buf[4] + 1;
 841                buf += buf[4] + 1;
 842                if (!len)
 843                        return 0;
 844        }
 845
 846        av7110_ipack_instant_repack(buf + 4, len - 4, ipack);
 847        return 0;
 848}
 849
 850
 851int av7110_write_to_decoder(struct dvb_demux_feed *feed, const u8 *buf, size_t len)
 852{
 853        struct dvb_demux *demux = feed->demux;
 854        struct av7110 *av7110 = (struct av7110 *) demux->priv;
 855
 856        dprintk(2, "av7110:%p, \n", av7110);
 857
 858        if (av7110->full_ts && demux->dmx.frontend->source != DMX_MEMORY_FE)
 859                return 0;
 860
 861        switch (feed->pes_type) {
 862        case 0:
 863                if (av7110->audiostate.stream_source == AUDIO_SOURCE_MEMORY)
 864                        return -EINVAL;
 865                break;
 866        case 1:
 867                if (av7110->videostate.stream_source == VIDEO_SOURCE_MEMORY)
 868                        return -EINVAL;
 869                break;
 870        default:
 871                return -1;
 872        }
 873
 874        return write_ts_to_decoder(av7110, feed->pes_type, buf, len);
 875}
 876
 877
 878
 879/******************************************************************************
 880 * Video MPEG decoder events
 881 ******************************************************************************/
 882void dvb_video_add_event(struct av7110 *av7110, struct video_event *event)
 883{
 884        struct dvb_video_events *events = &av7110->video_events;
 885        int wp;
 886
 887        spin_lock_bh(&events->lock);
 888
 889        wp = (events->eventw + 1) % MAX_VIDEO_EVENT;
 890        if (wp == events->eventr) {
 891                events->overflow = 1;
 892                events->eventr = (events->eventr + 1) % MAX_VIDEO_EVENT;
 893        }
 894
 895        //FIXME: timestamp?
 896        memcpy(&events->events[events->eventw], event, sizeof(struct video_event));
 897        events->eventw = wp;
 898
 899        spin_unlock_bh(&events->lock);
 900
 901        wake_up_interruptible(&events->wait_queue);
 902}
 903
 904
 905static int dvb_video_get_event (struct av7110 *av7110, struct video_event *event, int flags)
 906{
 907        struct dvb_video_events *events = &av7110->video_events;
 908
 909        if (events->overflow) {
 910                events->overflow = 0;
 911                return -EOVERFLOW;
 912        }
 913        if (events->eventw == events->eventr) {
 914                int ret;
 915
 916                if (flags & O_NONBLOCK)
 917                        return -EWOULDBLOCK;
 918
 919                ret = wait_event_interruptible(events->wait_queue,
 920                                               events->eventw != events->eventr);
 921                if (ret < 0)
 922                        return ret;
 923        }
 924
 925        spin_lock_bh(&events->lock);
 926
 927        memcpy(event, &events->events[events->eventr],
 928               sizeof(struct video_event));
 929        events->eventr = (events->eventr + 1) % MAX_VIDEO_EVENT;
 930
 931        spin_unlock_bh(&events->lock);
 932
 933        return 0;
 934}
 935
 936
 937/******************************************************************************
 938 * DVB device file operations
 939 ******************************************************************************/
 940
 941static unsigned int dvb_video_poll(struct file *file, poll_table *wait)
 942{
 943        struct dvb_device *dvbdev = file->private_data;
 944        struct av7110 *av7110 = dvbdev->priv;
 945        unsigned int mask = 0;
 946
 947        dprintk(2, "av7110:%p, \n", av7110);
 948
 949        if ((file->f_flags & O_ACCMODE) != O_RDONLY)
 950                poll_wait(file, &av7110->avout.queue, wait);
 951
 952        poll_wait(file, &av7110->video_events.wait_queue, wait);
 953
 954        if (av7110->video_events.eventw != av7110->video_events.eventr)
 955                mask = POLLPRI;
 956
 957        if ((file->f_flags & O_ACCMODE) != O_RDONLY) {
 958                if (av7110->playing) {
 959                        if (FREE_COND)
 960                                mask |= (POLLOUT | POLLWRNORM);
 961                } else {
 962                        /* if not playing: may play if asked for */
 963                        mask |= (POLLOUT | POLLWRNORM);
 964                }
 965        }
 966
 967        return mask;
 968}
 969
 970static ssize_t dvb_video_write(struct file *file, const char __user *buf,
 971                               size_t count, loff_t *ppos)
 972{
 973        struct dvb_device *dvbdev = file->private_data;
 974        struct av7110 *av7110 = dvbdev->priv;
 975        unsigned char c;
 976
 977        dprintk(2, "av7110:%p, \n", av7110);
 978
 979        if ((file->f_flags & O_ACCMODE) == O_RDONLY)
 980                return -EPERM;
 981
 982        if (av7110->videostate.stream_source != VIDEO_SOURCE_MEMORY)
 983                return -EPERM;
 984
 985        if (get_user(c, buf))
 986                return -EFAULT;
 987        if (c == 0x47 && count % TS_SIZE == 0)
 988                return ts_play(av7110, buf, count, file->f_flags & O_NONBLOCK, 1);
 989        else
 990                return dvb_play(av7110, buf, count, file->f_flags & O_NONBLOCK, 1);
 991}
 992
 993static unsigned int dvb_audio_poll(struct file *file, poll_table *wait)
 994{
 995        struct dvb_device *dvbdev = file->private_data;
 996        struct av7110 *av7110 = dvbdev->priv;
 997        unsigned int mask = 0;
 998
 999        dprintk(2, "av7110:%p, \n", av7110);
1000
1001        poll_wait(file, &av7110->aout.queue, wait);
1002
1003        if (av7110->playing) {
1004                if (dvb_ringbuffer_free(&av7110->aout) >= 20 * 1024)
1005                        mask |= (POLLOUT | POLLWRNORM);
1006        } else /* if not playing: may play if asked for */
1007                mask = (POLLOUT | POLLWRNORM);
1008
1009        return mask;
1010}
1011
1012static ssize_t dvb_audio_write(struct file *file, const char __user *buf,
1013                               size_t count, loff_t *ppos)
1014{
1015        struct dvb_device *dvbdev = file->private_data;
1016        struct av7110 *av7110 = dvbdev->priv;
1017        unsigned char c;
1018
1019        dprintk(2, "av7110:%p, \n", av7110);
1020
1021        if (av7110->audiostate.stream_source != AUDIO_SOURCE_MEMORY) {
1022                printk(KERN_ERR "not audio source memory\n");
1023                return -EPERM;
1024        }
1025
1026        if (get_user(c, buf))
1027                return -EFAULT;
1028        if (c == 0x47 && count % TS_SIZE == 0)
1029                return ts_play(av7110, buf, count, file->f_flags & O_NONBLOCK, 0);
1030        else
1031                return dvb_aplay(av7110, buf, count, file->f_flags & O_NONBLOCK, 0);
1032}
1033
1034static u8 iframe_header[] = { 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x80, 0x00, 0x00 };
1035
1036#define MIN_IFRAME 400000
1037
1038static int play_iframe(struct av7110 *av7110, char __user *buf, unsigned int len, int nonblock)
1039{
1040        unsigned i, n;
1041        int progressive = 0;
1042        int match = 0;
1043
1044        dprintk(2, "av7110:%p, \n", av7110);
1045
1046        if (!(av7110->playing & RP_VIDEO)) {
1047                if (av7110_av_start_play(av7110, RP_VIDEO) < 0)
1048                        return -EBUSY;
1049        }
1050
1051        /* search in buf for instances of 00 00 01 b5 1? */
1052        for (i = 0; i < len; i++) {
1053                unsigned char c;
1054                if (get_user(c, buf + i))
1055                        return -EFAULT;
1056                if (match == 5) {
1057                        progressive = c & 0x08;
1058                        match = 0;
1059                }
1060                if (c == 0x00) {
1061                        match = (match == 1 || match == 2) ? 2 : 1;
1062                        continue;
1063                }
1064                switch (match++) {
1065                case 2: if (c == 0x01)
1066                                continue;
1067                        break;
1068                case 3: if (c == 0xb5)
1069                                continue;
1070                        break;
1071                case 4: if ((c & 0xf0) == 0x10)
1072                                continue;
1073                        break;
1074                }
1075                match = 0;
1076        }
1077
1078        /* setting n always > 1, fixes problems when playing stillframes
1079           consisting of I- and P-Frames */
1080        n = MIN_IFRAME / len + 1;
1081
1082        /* FIXME: nonblock? */
1083        dvb_play_kernel(av7110, iframe_header, sizeof(iframe_header), 0, 1);
1084
1085        for (i = 0; i < n; i++)
1086                dvb_play(av7110, buf, len, 0, 1);
1087
1088        av7110_ipack_flush(&av7110->ipack[1]);
1089
1090        if (progressive)
1091                return vidcom(av7110, AV_VIDEO_CMD_FREEZE, 1);
1092        else
1093                return 0;
1094}
1095
1096
1097static int dvb_video_ioctl(struct file *file,
1098                           unsigned int cmd, void *parg)
1099{
1100        struct dvb_device *dvbdev = file->private_data;
1101        struct av7110 *av7110 = dvbdev->priv;
1102        unsigned long arg = (unsigned long) parg;
1103        int ret = 0;
1104
1105        dprintk(1, "av7110:%p, cmd=%04x\n", av7110,cmd);
1106
1107        if ((file->f_flags & O_ACCMODE) == O_RDONLY) {
1108                if ( cmd != VIDEO_GET_STATUS && cmd != VIDEO_GET_EVENT &&
1109                     cmd != VIDEO_GET_SIZE ) {
1110                        return -EPERM;
1111                }
1112        }
1113
1114        if (mutex_lock_interruptible(&av7110->ioctl_mutex))
1115                return -ERESTARTSYS;
1116
1117        switch (cmd) {
1118        case VIDEO_STOP:
1119                av7110->videostate.play_state = VIDEO_STOPPED;
1120                if (av7110->videostate.stream_source == VIDEO_SOURCE_MEMORY)
1121                        ret = av7110_av_stop(av7110, RP_VIDEO);
1122                else
1123                        ret = vidcom(av7110, AV_VIDEO_CMD_STOP,
1124                               av7110->videostate.video_blank ? 0 : 1);
1125                if (!ret)
1126                        av7110->trickmode = TRICK_NONE;
1127                break;
1128
1129        case VIDEO_PLAY:
1130                av7110->trickmode = TRICK_NONE;
1131                if (av7110->videostate.play_state == VIDEO_FREEZED) {
1132                        av7110->videostate.play_state = VIDEO_PLAYING;
1133                        ret = vidcom(av7110, AV_VIDEO_CMD_PLAY, 0);
1134                        if (ret)
1135                                break;
1136                }
1137                if (av7110->videostate.stream_source == VIDEO_SOURCE_MEMORY) {
1138                        if (av7110->playing == RP_AV) {
1139                                ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Stop, 0);
1140                                if (ret)
1141                                        break;
1142                                av7110->playing &= ~RP_VIDEO;
1143                        }
1144                        ret = av7110_av_start_play(av7110, RP_VIDEO);
1145                }
1146                if (!ret)
1147                        ret = vidcom(av7110, AV_VIDEO_CMD_PLAY, 0);
1148                if (!ret)
1149                        av7110->videostate.play_state = VIDEO_PLAYING;
1150                break;
1151
1152        case VIDEO_FREEZE:
1153                av7110->videostate.play_state = VIDEO_FREEZED;
1154                if (av7110->playing & RP_VIDEO)
1155                        ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Pause, 0);
1156                else
1157                        ret = vidcom(av7110, AV_VIDEO_CMD_FREEZE, 1);
1158                if (!ret)
1159                        av7110->trickmode = TRICK_FREEZE;
1160                break;
1161
1162        case VIDEO_CONTINUE:
1163                if (av7110->playing & RP_VIDEO)
1164                        ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Continue, 0);
1165                if (!ret)
1166                        ret = vidcom(av7110, AV_VIDEO_CMD_PLAY, 0);
1167                if (!ret) {
1168                        av7110->videostate.play_state = VIDEO_PLAYING;
1169                        av7110->trickmode = TRICK_NONE;
1170                }
1171                break;
1172
1173        case VIDEO_SELECT_SOURCE:
1174                av7110->videostate.stream_source = (video_stream_source_t) arg;
1175                break;
1176
1177        case VIDEO_SET_BLANK:
1178                av7110->videostate.video_blank = (int) arg;
1179                break;
1180
1181        case VIDEO_GET_STATUS:
1182                memcpy(parg, &av7110->videostate, sizeof(struct video_status));
1183                break;
1184
1185        case VIDEO_GET_EVENT:
1186                ret = dvb_video_get_event(av7110, parg, file->f_flags);
1187                break;
1188
1189        case VIDEO_GET_SIZE:
1190                memcpy(parg, &av7110->video_size, sizeof(video_size_t));
1191                break;
1192
1193        case VIDEO_SET_DISPLAY_FORMAT:
1194        {
1195                video_displayformat_t format = (video_displayformat_t) arg;
1196                switch (format) {
1197                case VIDEO_PAN_SCAN:
1198                        av7110->display_panscan = VID_PAN_SCAN_PREF;
1199                        break;
1200                case VIDEO_LETTER_BOX:
1201                        av7110->display_panscan = VID_VC_AND_PS_PREF;
1202                        break;
1203                case VIDEO_CENTER_CUT_OUT:
1204                        av7110->display_panscan = VID_CENTRE_CUT_PREF;
1205                        break;
1206                default:
1207                        ret = -EINVAL;
1208                }
1209                if (ret < 0)
1210                        break;
1211                av7110->videostate.display_format = format;
1212                ret = av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetPanScanType,
1213                                    1, av7110->display_panscan);
1214                break;
1215        }
1216
1217        case VIDEO_SET_FORMAT:
1218                if (arg > 1) {
1219                        ret = -EINVAL;
1220                        break;
1221                }
1222                av7110->display_ar = arg;
1223                ret = av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetMonitorType,
1224                                    1, (u16) arg);
1225                break;
1226
1227        case VIDEO_STILLPICTURE:
1228        {
1229                struct video_still_picture *pic =
1230                        (struct video_still_picture *) parg;
1231                av7110->videostate.stream_source = VIDEO_SOURCE_MEMORY;
1232                dvb_ringbuffer_flush_spinlock_wakeup(&av7110->avout);
1233                ret = play_iframe(av7110, pic->iFrame, pic->size,
1234                                  file->f_flags & O_NONBLOCK);
1235                break;
1236        }
1237
1238        case VIDEO_FAST_FORWARD:
1239                //note: arg is ignored by firmware
1240                if (av7110->playing & RP_VIDEO)
1241                        ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY,
1242                                            __Scan_I, 2, AV_PES, 0);
1243                else
1244                        ret = vidcom(av7110, AV_VIDEO_CMD_FFWD, arg);
1245                if (!ret) {
1246                        av7110->trickmode = TRICK_FAST;
1247                        av7110->videostate.play_state = VIDEO_PLAYING;
1248                }
1249                break;
1250
1251        case VIDEO_SLOWMOTION:
1252                if (av7110->playing&RP_VIDEO) {
1253                        if (av7110->trickmode != TRICK_SLOW)
1254                                ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Slow, 2, 0, 0);
1255                        if (!ret)
1256                                ret = vidcom(av7110, AV_VIDEO_CMD_SLOW, arg);
1257                } else {
1258                        ret = vidcom(av7110, AV_VIDEO_CMD_PLAY, 0);
1259                        if (!ret)
1260                                ret = vidcom(av7110, AV_VIDEO_CMD_STOP, 0);
1261                        if (!ret)
1262                                ret = vidcom(av7110, AV_VIDEO_CMD_SLOW, arg);
1263                }
1264                if (!ret) {
1265                        av7110->trickmode = TRICK_SLOW;
1266                        av7110->videostate.play_state = VIDEO_PLAYING;
1267                }
1268                break;
1269
1270        case VIDEO_GET_CAPABILITIES:
1271                *(int *)parg = VIDEO_CAP_MPEG1 | VIDEO_CAP_MPEG2 |
1272                        VIDEO_CAP_SYS | VIDEO_CAP_PROG;
1273                break;
1274
1275        case VIDEO_CLEAR_BUFFER:
1276                dvb_ringbuffer_flush_spinlock_wakeup(&av7110->avout);
1277                av7110_ipack_reset(&av7110->ipack[1]);
1278                if (av7110->playing == RP_AV) {
1279                        ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY,
1280                                            __Play, 2, AV_PES, 0);
1281                        if (ret)
1282                                break;
1283                        if (av7110->trickmode == TRICK_FAST)
1284                                ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY,
1285                                                    __Scan_I, 2, AV_PES, 0);
1286                        if (av7110->trickmode == TRICK_SLOW) {
1287                                ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY,
1288                                                    __Slow, 2, 0, 0);
1289                                if (!ret)
1290                                        ret = vidcom(av7110, AV_VIDEO_CMD_SLOW, arg);
1291                        }
1292                        if (av7110->trickmode == TRICK_FREEZE)
1293                                ret = vidcom(av7110, AV_VIDEO_CMD_STOP, 1);
1294                }
1295                break;
1296
1297        case VIDEO_SET_STREAMTYPE:
1298                break;
1299
1300        default:
1301                ret = -ENOIOCTLCMD;
1302                break;
1303        }
1304
1305        mutex_unlock(&av7110->ioctl_mutex);
1306        return ret;
1307}
1308
1309static int dvb_audio_ioctl(struct file *file,
1310                           unsigned int cmd, void *parg)
1311{
1312        struct dvb_device *dvbdev = file->private_data;
1313        struct av7110 *av7110 = dvbdev->priv;
1314        unsigned long arg = (unsigned long) parg;
1315        int ret = 0;
1316
1317        dprintk(1, "av7110:%p, cmd=%04x\n", av7110,cmd);
1318
1319        if (((file->f_flags & O_ACCMODE) == O_RDONLY) &&
1320            (cmd != AUDIO_GET_STATUS))
1321                return -EPERM;
1322
1323        if (mutex_lock_interruptible(&av7110->ioctl_mutex))
1324                return -ERESTARTSYS;
1325
1326        switch (cmd) {
1327        case AUDIO_STOP:
1328                if (av7110->audiostate.stream_source == AUDIO_SOURCE_MEMORY)
1329                        ret = av7110_av_stop(av7110, RP_AUDIO);
1330                else
1331                        ret = audcom(av7110, AUDIO_CMD_MUTE);
1332                if (!ret)
1333                        av7110->audiostate.play_state = AUDIO_STOPPED;
1334                break;
1335
1336        case AUDIO_PLAY:
1337                if (av7110->audiostate.stream_source == AUDIO_SOURCE_MEMORY)
1338                        ret = av7110_av_start_play(av7110, RP_AUDIO);
1339                if (!ret)
1340                        ret = audcom(av7110, AUDIO_CMD_UNMUTE);
1341                if (!ret)
1342                        av7110->audiostate.play_state = AUDIO_PLAYING;
1343                break;
1344
1345        case AUDIO_PAUSE:
1346                ret = audcom(av7110, AUDIO_CMD_MUTE);
1347                if (!ret)
1348                        av7110->audiostate.play_state = AUDIO_PAUSED;
1349                break;
1350
1351        case AUDIO_CONTINUE:
1352                if (av7110->audiostate.play_state == AUDIO_PAUSED) {
1353                        av7110->audiostate.play_state = AUDIO_PLAYING;
1354                        ret = audcom(av7110, AUDIO_CMD_UNMUTE | AUDIO_CMD_PCM16);
1355                }
1356                break;
1357
1358        case AUDIO_SELECT_SOURCE:
1359                av7110->audiostate.stream_source = (audio_stream_source_t) arg;
1360                break;
1361
1362        case AUDIO_SET_MUTE:
1363        {
1364                ret = audcom(av7110, arg ? AUDIO_CMD_MUTE : AUDIO_CMD_UNMUTE);
1365                if (!ret)
1366                        av7110->audiostate.mute_state = (int) arg;
1367                break;
1368        }
1369
1370        case AUDIO_SET_AV_SYNC:
1371                av7110->audiostate.AV_sync_state = (int) arg;
1372                ret = audcom(av7110, arg ? AUDIO_CMD_SYNC_ON : AUDIO_CMD_SYNC_OFF);
1373                break;
1374
1375        case AUDIO_SET_BYPASS_MODE:
1376                if (FW_VERSION(av7110->arm_app) < 0x2621)
1377                        ret = -EINVAL;
1378                av7110->audiostate.bypass_mode = (int)arg;
1379                break;
1380
1381        case AUDIO_CHANNEL_SELECT:
1382                av7110->audiostate.channel_select = (audio_channel_select_t) arg;
1383                switch(av7110->audiostate.channel_select) {
1384                case AUDIO_STEREO:
1385                        ret = audcom(av7110, AUDIO_CMD_STEREO);
1386                        if (!ret) {
1387                                if (av7110->adac_type == DVB_ADAC_CRYSTAL)
1388                                        i2c_writereg(av7110, 0x20, 0x02, 0x49);
1389                                else if (av7110->adac_type == DVB_ADAC_MSP34x5)
1390                                        msp_writereg(av7110, MSP_WR_DSP, 0x0008, 0x0220);
1391                        }
1392                        break;
1393                case AUDIO_MONO_LEFT:
1394                        ret = audcom(av7110, AUDIO_CMD_MONO_L);
1395                        if (!ret) {
1396                                if (av7110->adac_type == DVB_ADAC_CRYSTAL)
1397                                        i2c_writereg(av7110, 0x20, 0x02, 0x4a);
1398                                else if (av7110->adac_type == DVB_ADAC_MSP34x5)
1399                                        msp_writereg(av7110, MSP_WR_DSP, 0x0008, 0x0200);
1400                        }
1401                        break;
1402                case AUDIO_MONO_RIGHT:
1403                        ret = audcom(av7110, AUDIO_CMD_MONO_R);
1404                        if (!ret) {
1405                                if (av7110->adac_type == DVB_ADAC_CRYSTAL)
1406                                        i2c_writereg(av7110, 0x20, 0x02, 0x45);
1407                                else if (av7110->adac_type == DVB_ADAC_MSP34x5)
1408                                        msp_writereg(av7110, MSP_WR_DSP, 0x0008, 0x0210);
1409                        }
1410                        break;
1411                default:
1412                        ret = -EINVAL;
1413                        break;
1414                }
1415                break;
1416
1417        case AUDIO_GET_STATUS:
1418                memcpy(parg, &av7110->audiostate, sizeof(struct audio_status));
1419                break;
1420
1421        case AUDIO_GET_CAPABILITIES:
1422                if (FW_VERSION(av7110->arm_app) < 0x2621)
1423                        *(unsigned int *)parg = AUDIO_CAP_LPCM | AUDIO_CAP_MP1 | AUDIO_CAP_MP2;
1424                else
1425                        *(unsigned int *)parg = AUDIO_CAP_LPCM | AUDIO_CAP_DTS | AUDIO_CAP_AC3 |
1426                                                AUDIO_CAP_MP1 | AUDIO_CAP_MP2;
1427                break;
1428
1429        case AUDIO_CLEAR_BUFFER:
1430                dvb_ringbuffer_flush_spinlock_wakeup(&av7110->aout);
1431                av7110_ipack_reset(&av7110->ipack[0]);
1432                if (av7110->playing == RP_AV)
1433                        ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY,
1434                                            __Play, 2, AV_PES, 0);
1435                break;
1436
1437        case AUDIO_SET_ID:
1438                break;
1439
1440        case AUDIO_SET_MIXER:
1441        {
1442                struct audio_mixer *amix = (struct audio_mixer *)parg;
1443                ret = av7110_set_volume(av7110, amix->volume_left, amix->volume_right);
1444                break;
1445        }
1446
1447        case AUDIO_SET_STREAMTYPE:
1448                break;
1449
1450        default:
1451                ret = -ENOIOCTLCMD;
1452        }
1453
1454        mutex_unlock(&av7110->ioctl_mutex);
1455        return ret;
1456}
1457
1458
1459static int dvb_video_open(struct inode *inode, struct file *file)
1460{
1461        struct dvb_device *dvbdev = file->private_data;
1462        struct av7110 *av7110 = dvbdev->priv;
1463        int err;
1464
1465        dprintk(2, "av7110:%p, \n", av7110);
1466
1467        if ((err = dvb_generic_open(inode, file)) < 0)
1468                return err;
1469
1470        if ((file->f_flags & O_ACCMODE) != O_RDONLY) {
1471                dvb_ringbuffer_flush_spinlock_wakeup(&av7110->aout);
1472                dvb_ringbuffer_flush_spinlock_wakeup(&av7110->avout);
1473                av7110->video_blank = 1;
1474                av7110->audiostate.AV_sync_state = 1;
1475                av7110->videostate.stream_source = VIDEO_SOURCE_DEMUX;
1476
1477                /*  empty event queue */
1478                av7110->video_events.eventr = av7110->video_events.eventw = 0;
1479        }
1480
1481        return 0;
1482}
1483
1484static int dvb_video_release(struct inode *inode, struct file *file)
1485{
1486        struct dvb_device *dvbdev = file->private_data;
1487        struct av7110 *av7110 = dvbdev->priv;
1488
1489        dprintk(2, "av7110:%p, \n", av7110);
1490
1491        if ((file->f_flags & O_ACCMODE) != O_RDONLY) {
1492                av7110_av_stop(av7110, RP_VIDEO);
1493        }
1494
1495        return dvb_generic_release(inode, file);
1496}
1497
1498static int dvb_audio_open(struct inode *inode, struct file *file)
1499{
1500        struct dvb_device *dvbdev = file->private_data;
1501        struct av7110 *av7110 = dvbdev->priv;
1502        int err = dvb_generic_open(inode, file);
1503
1504        dprintk(2, "av7110:%p, \n", av7110);
1505
1506        if (err < 0)
1507                return err;
1508        dvb_ringbuffer_flush_spinlock_wakeup(&av7110->aout);
1509        av7110->audiostate.stream_source = AUDIO_SOURCE_DEMUX;
1510        return 0;
1511}
1512
1513static int dvb_audio_release(struct inode *inode, struct file *file)
1514{
1515        struct dvb_device *dvbdev = file->private_data;
1516        struct av7110 *av7110 = dvbdev->priv;
1517
1518        dprintk(2, "av7110:%p, \n", av7110);
1519
1520        av7110_av_stop(av7110, RP_AUDIO);
1521        return dvb_generic_release(inode, file);
1522}
1523
1524
1525
1526/******************************************************************************
1527 * driver registration
1528 ******************************************************************************/
1529
1530static const struct file_operations dvb_video_fops = {
1531        .owner          = THIS_MODULE,
1532        .write          = dvb_video_write,
1533        .unlocked_ioctl = dvb_generic_ioctl,
1534        .open           = dvb_video_open,
1535        .release        = dvb_video_release,
1536        .poll           = dvb_video_poll,
1537        .llseek         = noop_llseek,
1538};
1539
1540static struct dvb_device dvbdev_video = {
1541        .priv           = NULL,
1542        .users          = 6,
1543        .readers        = 5,    /* arbitrary */
1544        .writers        = 1,
1545        .fops           = &dvb_video_fops,
1546        .kernel_ioctl   = dvb_video_ioctl,
1547};
1548
1549static const struct file_operations dvb_audio_fops = {
1550        .owner          = THIS_MODULE,
1551        .write          = dvb_audio_write,
1552        .unlocked_ioctl = dvb_generic_ioctl,
1553        .open           = dvb_audio_open,
1554        .release        = dvb_audio_release,
1555        .poll           = dvb_audio_poll,
1556        .llseek         = noop_llseek,
1557};
1558
1559static struct dvb_device dvbdev_audio = {
1560        .priv           = NULL,
1561        .users          = 1,
1562        .writers        = 1,
1563        .fops           = &dvb_audio_fops,
1564        .kernel_ioctl   = dvb_audio_ioctl,
1565};
1566
1567
1568int av7110_av_register(struct av7110 *av7110)
1569{
1570        av7110->audiostate.AV_sync_state = 0;
1571        av7110->audiostate.mute_state = 0;
1572        av7110->audiostate.play_state = AUDIO_STOPPED;
1573        av7110->audiostate.stream_source = AUDIO_SOURCE_DEMUX;
1574        av7110->audiostate.channel_select = AUDIO_STEREO;
1575        av7110->audiostate.bypass_mode = 0;
1576
1577        av7110->videostate.video_blank = 0;
1578        av7110->videostate.play_state = VIDEO_STOPPED;
1579        av7110->videostate.stream_source = VIDEO_SOURCE_DEMUX;
1580        av7110->videostate.video_format = VIDEO_FORMAT_4_3;
1581        av7110->videostate.display_format = VIDEO_LETTER_BOX;
1582        av7110->display_ar = VIDEO_FORMAT_4_3;
1583        av7110->display_panscan = VID_VC_AND_PS_PREF;
1584
1585        init_waitqueue_head(&av7110->video_events.wait_queue);
1586        spin_lock_init(&av7110->video_events.lock);
1587        av7110->video_events.eventw = av7110->video_events.eventr = 0;
1588        av7110->video_events.overflow = 0;
1589        memset(&av7110->video_size, 0, sizeof (video_size_t));
1590
1591        dvb_register_device(&av7110->dvb_adapter, &av7110->video_dev,
1592                            &dvbdev_video, av7110, DVB_DEVICE_VIDEO);
1593
1594        dvb_register_device(&av7110->dvb_adapter, &av7110->audio_dev,
1595                            &dvbdev_audio, av7110, DVB_DEVICE_AUDIO);
1596
1597        return 0;
1598}
1599
1600void av7110_av_unregister(struct av7110 *av7110)
1601{
1602        dvb_unregister_device(av7110->audio_dev);
1603        dvb_unregister_device(av7110->video_dev);
1604}
1605
1606int av7110_av_init(struct av7110 *av7110)
1607{
1608        void (*play[])(u8 *, int, void *) = { play_audio_cb, play_video_cb };
1609        int i, ret;
1610
1611        for (i = 0; i < 2; i++) {
1612                struct ipack *ipack = av7110->ipack + i;
1613
1614                ret = av7110_ipack_init(ipack, IPACKS, play[i]);
1615                if (ret < 0) {
1616                        if (i)
1617                                av7110_ipack_free(--ipack);
1618                        goto out;
1619                }
1620                ipack->data = av7110;
1621        }
1622
1623        dvb_ringbuffer_init(&av7110->avout, av7110->iobuf, AVOUTLEN);
1624        dvb_ringbuffer_init(&av7110->aout, av7110->iobuf + AVOUTLEN, AOUTLEN);
1625
1626        av7110->kbuf[0] = (u8 *)(av7110->iobuf + AVOUTLEN + AOUTLEN + BMPLEN);
1627        av7110->kbuf[1] = av7110->kbuf[0] + 2 * IPACKS;
1628out:
1629        return ret;
1630}
1631
1632void av7110_av_exit(struct av7110 *av7110)
1633{
1634        av7110_ipack_free(&av7110->ipack[0]);
1635        av7110_ipack_free(&av7110->ipack[1]);
1636}
1637