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