av7110_av.c revision 804b4458943f14bf144d3c3ba50097ced9b27b29
11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * av7110_av.c: audio and video MPEG decoder stuff 31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (C) 1999-2002 Ralph Metzler 51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * & Marcus Metzler for convergence integrated media GmbH 61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * originally based on code by: 81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (C) 1998,1999 Christian Theiss <mistert@rz.fh-augsburg.de> 91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This program is free software; you can redistribute it and/or 111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * modify it under the terms of the GNU General Public License 121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * as published by the Free Software Foundation; either version 2 131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * of the License, or (at your option) any later version. 141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This program is distributed in the hope that it will be useful, 171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * but WITHOUT ANY WARRANTY; without even the implied warranty of 181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * GNU General Public License for more details. 201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * You should have received a copy of the GNU General Public License 231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * along with this program; if not, write to the Free Software 241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Or, point your browser to http://www.gnu.org/copyleft/gpl.html 261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * the project's page is at http://www.linuxtv.org/dvb/ 291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/types.h> 321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/kernel.h> 331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/string.h> 341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/delay.h> 351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/fs.h> 361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "av7110.h" 381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "av7110_hw.h" 391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "av7110_av.h" 401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "av7110_ipack.h" 411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* MPEG-2 (ISO 13818 / H.222.0) stream types */ 431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define PROG_STREAM_MAP 0xBC 441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define PRIVATE_STREAM1 0xBD 451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define PADDING_STREAM 0xBE 461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define PRIVATE_STREAM2 0xBF 471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define AUDIO_STREAM_S 0xC0 481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define AUDIO_STREAM_E 0xDF 491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define VIDEO_STREAM_S 0xE0 501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define VIDEO_STREAM_E 0xEF 511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define ECM_STREAM 0xF0 521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define EMM_STREAM 0xF1 531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define DSM_CC_STREAM 0xF2 541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define ISO13522_STREAM 0xF3 551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define PROG_STREAM_DIR 0xFF 561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define PTS_DTS_FLAGS 0xC0 581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds//pts_dts flags 601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define PTS_ONLY 0x80 611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define PTS_DTS 0xC0 621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define TS_SIZE 188 631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define TRANS_ERROR 0x80 641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define PAY_START 0x40 651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define TRANS_PRIO 0x20 661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define PID_MASK_HI 0x1F 671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds//flags 681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define TRANS_SCRMBL1 0x80 691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define TRANS_SCRMBL2 0x40 701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define ADAPT_FIELD 0x20 711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define PAYLOAD 0x10 721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define COUNT_MASK 0x0F 731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds// adaptation flags 751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define DISCON_IND 0x80 761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define RAND_ACC_IND 0x40 771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define ES_PRI_IND 0x20 781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define PCR_FLAG 0x10 791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define OPCR_FLAG 0x08 801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define SPLICE_FLAG 0x04 811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define TRANS_PRIV 0x02 821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define ADAP_EXT_FLAG 0x01 831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds// adaptation extension flags 851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define LTW_FLAG 0x80 861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define PIECE_RATE 0x40 871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define SEAM_SPLICE 0x20 881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void p_to_t(u8 const *buf, long int length, u16 pid, 911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 *counter, struct dvb_demux_feed *feed); 921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint av7110_record_cb(struct dvb_filter_pes2ts *p2t, u8 *buf, size_t len) 951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *) p2t->priv; 971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!(dvbdmxfeed->ts_type & TS_PACKET)) 991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (buf[3] == 0xe0) // video PES do not have a length in TS 1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buf[4] = buf[5] = 0; 1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (dvbdmxfeed->ts_type & TS_PAYLOAD_ONLY) 1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return dvbdmxfeed->cb.ts(buf, len, NULL, 0, 1041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds &dvbdmxfeed->feed.ts, DMX_OK); 1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return dvb_filter_pes2ts(p2t, buf, len, 1); 1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int dvb_filter_pes2ts_cb(void *priv, unsigned char *data) 1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *) priv; 1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dvbdmxfeed->cb.ts(data, 188, NULL, 0, 1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds &dvbdmxfeed->feed.ts, DMX_OK); 1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint av7110_av_start_record(struct av7110 *av7110, int av, 1191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct dvb_demux_feed *dvbdmxfeed) 1201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 121ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald int ret = 0; 1221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct dvb_demux *dvbdmx = dvbdmxfeed->demux; 1231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dprintk(2, "av7110:%p, , dvb_demux_feed:%p\n", av7110, dvbdmxfeed); 1251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->playing || (av7110->rec_mode & av)) 1271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EBUSY; 1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Stop, 0); 1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dvbdmx->recording = 1; 1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->rec_mode |= av; 1311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (av7110->rec_mode) { 1331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case RP_AUDIO: 1341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dvb_filter_pes2ts_init(&av7110->p2t[0], 1351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dvbdmx->pesfilter[0]->pid, 1361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dvb_filter_pes2ts_cb, 1371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (void *) dvbdmx->pesfilter[0]); 138ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Record, 2, AudioPES, 0); 1391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 1401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case RP_VIDEO: 1421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dvb_filter_pes2ts_init(&av7110->p2t[1], 1431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dvbdmx->pesfilter[1]->pid, 1441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dvb_filter_pes2ts_cb, 1451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (void *) dvbdmx->pesfilter[1]); 146ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Record, 2, VideoPES, 0); 1471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 1481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case RP_AV: 1501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dvb_filter_pes2ts_init(&av7110->p2t[0], 1511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dvbdmx->pesfilter[0]->pid, 1521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dvb_filter_pes2ts_cb, 1531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (void *) dvbdmx->pesfilter[0]); 1541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dvb_filter_pes2ts_init(&av7110->p2t[1], 1551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dvbdmx->pesfilter[1]->pid, 1561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dvb_filter_pes2ts_cb, 1571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (void *) dvbdmx->pesfilter[1]); 158ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Record, 2, AV_PES, 0); 1591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 1601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 161ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald return ret; 1621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint av7110_av_start_play(struct av7110 *av7110, int av) 1651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 166ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald int ret = 0; 1671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dprintk(2, "av7110:%p, \n", av7110); 1681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->rec_mode) 1701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EBUSY; 1711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->playing & av) 1721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EBUSY; 1731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Stop, 0); 1751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->playing == RP_NONE) { 1771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110_ipack_reset(&av7110->ipack[0]); 1781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110_ipack_reset(&av7110->ipack[1]); 1791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->playing |= av; 1821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (av7110->playing) { 1831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case RP_AUDIO: 184ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Play, 2, AudioPES, 0); 1851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 1861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case RP_VIDEO: 187ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Play, 2, VideoPES, 0); 1881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->sinfo = 0; 1891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 1901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case RP_AV: 1911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->sinfo = 0; 192ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Play, 2, AV_PES, 0); 1931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 1941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 195ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (!ret) 196ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = av7110->playing; 197ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald return ret; 1981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 200ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewaldint av7110_av_stop(struct av7110 *av7110, int av) 2011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 202ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald int ret = 0; 2031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dprintk(2, "av7110:%p, \n", av7110); 2041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!(av7110->playing & av) && !(av7110->rec_mode & av)) 206ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald return 0; 2071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Stop, 0); 2081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->playing) { 2091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->playing &= ~av; 2101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (av7110->playing) { 2111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case RP_AUDIO: 212ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Play, 2, AudioPES, 0); 2131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 2141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case RP_VIDEO: 215ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Play, 2, VideoPES, 0); 2161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 2171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case RP_NONE: 218ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = av7110_set_vidmode(av7110, av7110->vidmode); 2191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 2201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 2221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->rec_mode &= ~av; 2231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (av7110->rec_mode) { 2241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case RP_AUDIO: 225ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Record, 2, AudioPES, 0); 2261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 2271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case RP_VIDEO: 228ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Record, 2, VideoPES, 0); 2291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 2301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case RP_NONE: 2311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 2321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 234ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald return ret; 2351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint av7110_pes_play(void *dest, struct dvb_ringbuffer *buf, int dlen) 2391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int len; 2411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u32 sync; 2421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u16 blen; 2431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!dlen) { 2451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds wake_up(&buf->queue); 2461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -1; 2471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (1) { 2491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((len = dvb_ringbuffer_avail(buf)) < 6) 2501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -1; 2511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sync = DVB_RINGBUFFER_PEEK(buf, 0) << 24; 2521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sync |= DVB_RINGBUFFER_PEEK(buf, 1) << 16; 2531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sync |= DVB_RINGBUFFER_PEEK(buf, 2) << 8; 2541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sync |= DVB_RINGBUFFER_PEEK(buf, 3); 2551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (((sync &~ 0x0f) == 0x000001e0) || 2571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ((sync &~ 0x1f) == 0x000001c0) || 2581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (sync == 0x000001bd)) 2591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 2601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk("resync\n"); 2611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DVB_RINGBUFFER_SKIP(buf, 1); 2621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds blen = DVB_RINGBUFFER_PEEK(buf, 4) << 8; 2641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds blen |= DVB_RINGBUFFER_PEEK(buf, 5); 2651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds blen += 6; 2661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (len < blen || blen > dlen) { 2671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds //printk("buffer empty - avail %d blen %u dlen %d\n", len, blen, dlen); 2681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds wake_up(&buf->queue); 2691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -1; 2701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dvb_ringbuffer_read(buf, dest, (size_t) blen, 0); 2731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dprintk(2, "pread=0x%08lx, pwrite=0x%08lx\n", 2751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (unsigned long) buf->pread, (unsigned long) buf->pwrite); 2761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds wake_up(&buf->queue); 2771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return blen; 2781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint av7110_set_volume(struct av7110 *av7110, int volleft, int volright) 2821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int err, vol, val, balance = 0; 2841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dprintk(2, "av7110:%p, \n", av7110); 2861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->mixer.volume_left = volleft; 2881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->mixer.volume_right = volright; 2891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (av7110->adac_type) { 2911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case DVB_ADAC_TI: 2921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds volleft = (volleft * 256) / 1036; 2931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds volright = (volright * 256) / 1036; 2941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (volleft > 0x3f) 2951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds volleft = 0x3f; 2961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (volright > 0x3f) 2971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds volright = 0x3f; 2981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((err = SendDAC(av7110, 3, 0x80 + volleft))) 2991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return err; 3001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return SendDAC(av7110, 4, volright); 3011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case DVB_ADAC_CRYSTAL: 3031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds volleft = 127 - volleft / 2; 3041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds volright = 127 - volright / 2; 3051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds i2c_writereg(av7110, 0x20, 0x03, volleft); 3061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds i2c_writereg(av7110, 0x20, 0x04, volright); 3071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 3081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3091c13b95c7d22d5c552246b465da4b364ba00ba65Marco Schluessler case DVB_ADAC_MSP34x0: 3101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds vol = (volleft > volright) ? volleft : volright; 3111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds val = (vol * 0x73 / 255) << 8; 3121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (vol > 0) 3131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds balance = ((volright - volleft) * 127) / vol; 3141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds msp_writereg(av7110, MSP_WR_DSP, 0x0001, balance << 8); 3151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds msp_writereg(av7110, MSP_WR_DSP, 0x0000, val); /* loudspeaker */ 3161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds msp_writereg(av7110, MSP_WR_DSP, 0x0006, val); /* headphonesr */ 3171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 31861391e0446e97bea44d93bd1624e5b32d3cc8474Tim Kaiser 31961391e0446e97bea44d93bd1624e5b32d3cc8474Tim Kaiser case DVB_ADAC_MSP34x5: 32061391e0446e97bea44d93bd1624e5b32d3cc8474Tim Kaiser vol = (volleft > volright) ? volleft : volright; 32161391e0446e97bea44d93bd1624e5b32d3cc8474Tim Kaiser val = (vol * 0x73 / 255) << 8; 32261391e0446e97bea44d93bd1624e5b32d3cc8474Tim Kaiser if (vol > 0) 32361391e0446e97bea44d93bd1624e5b32d3cc8474Tim Kaiser balance = ((volright - volleft) * 127) / vol; 32461391e0446e97bea44d93bd1624e5b32d3cc8474Tim Kaiser msp_writereg(av7110, MSP_WR_DSP, 0x0001, balance << 8); 32561391e0446e97bea44d93bd1624e5b32d3cc8474Tim Kaiser msp_writereg(av7110, MSP_WR_DSP, 0x0000, val); /* loudspeaker */ 32661391e0446e97bea44d93bd1624e5b32d3cc8474Tim Kaiser return 0; 3271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 32861391e0446e97bea44d93bd1624e5b32d3cc8474Tim Kaiser 3291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 3301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 332ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewaldint av7110_set_vidmode(struct av7110 *av7110, int mode) 3331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 334ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald int ret; 3351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dprintk(2, "av7110:%p, \n", av7110); 3361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 337ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = av7110_fw_cmd(av7110, COMTYPE_ENCODER, LoadVidCode, 1, mode); 3381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 339ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (!ret && !av7110->playing) { 340ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = ChangePIDs(av7110, av7110->pids[DMX_PES_VIDEO], 3411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->pids[DMX_PES_AUDIO], 3421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->pids[DMX_PES_TELETEXT], 3431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0, av7110->pids[DMX_PES_PCR]); 344ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (!ret) 345ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, Scan, 0); 3461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 347ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald return ret; 3481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int sw2mode[16] = { 3521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds VIDEO_MODE_PAL, VIDEO_MODE_NTSC, VIDEO_MODE_NTSC, VIDEO_MODE_PAL, 3531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds VIDEO_MODE_NTSC, VIDEO_MODE_NTSC, VIDEO_MODE_PAL, VIDEO_MODE_NTSC, 3541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds VIDEO_MODE_PAL, VIDEO_MODE_PAL, VIDEO_MODE_PAL, VIDEO_MODE_PAL, 3551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds VIDEO_MODE_PAL, VIDEO_MODE_PAL, VIDEO_MODE_PAL, VIDEO_MODE_PAL, 3561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 3571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 358ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewaldstatic int get_video_format(struct av7110 *av7110, u8 *buf, int count) 3591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 3611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int hsize, vsize; 3621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int sw; 3631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 *p; 364ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald int ret = 0; 3651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dprintk(2, "av7110:%p, \n", av7110); 3671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->sinfo) 369ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald return 0; 3701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 7; i < count - 10; i++) { 3711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p = buf + i; 3721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (p[0] || p[1] || p[2] != 0x01 || p[3] != 0xb3) 3731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds continue; 3741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p += 4; 3751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hsize = ((p[1] &0xF0) >> 4) | (p[0] << 4); 3761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds vsize = ((p[1] &0x0F) << 8) | (p[2]); 3771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sw = (p[3] & 0x0F); 378ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = av7110_set_vidmode(av7110, sw2mode[sw]); 379ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (!ret) { 380ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald dprintk(2, "playback %dx%d fr=%d\n", hsize, vsize, sw); 381ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald av7110->sinfo = 1; 382ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald } 3831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 3841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 385ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald return ret; 3861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/**************************************************************************** 3901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * I/O buffer management and control 3911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ****************************************************************************/ 3921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline long aux_ring_buffer_write(struct dvb_ringbuffer *rbuf, 394804b4458943f14bf144d3c3ba50097ced9b27b29Oliver Endriss const u8 *buf, unsigned long count) 3951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long todo = count; 3971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int free; 3981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (todo > 0) { 4001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (dvb_ringbuffer_free(rbuf) < 2048) { 4011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (wait_event_interruptible(rbuf->queue, 4021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (dvb_ringbuffer_free(rbuf) >= 2048))) 4031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count - todo; 4041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds free = dvb_ringbuffer_free(rbuf); 4061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (free > todo) 4071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds free = todo; 4081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dvb_ringbuffer_write(rbuf, buf, free); 4091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds todo -= free; 4101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buf += free; 4111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count - todo; 4141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void play_video_cb(u8 *buf, int count, void *priv) 4171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct av7110 *av7110 = (struct av7110 *) priv; 4191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dprintk(2, "av7110:%p, \n", av7110); 4201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((buf[3] & 0xe0) == 0xe0) { 4221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds get_video_format(av7110, buf, count); 4231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds aux_ring_buffer_write(&av7110->avout, buf, count); 4241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else 4251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds aux_ring_buffer_write(&av7110->aout, buf, count); 4261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void play_audio_cb(u8 *buf, int count, void *priv) 4291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct av7110 *av7110 = (struct av7110 *) priv; 4311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dprintk(2, "av7110:%p, \n", av7110); 4321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds aux_ring_buffer_write(&av7110->aout, buf, count); 4341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define FREE_COND (dvb_ringbuffer_free(&av7110->avout) >= 20 * 1024 && \ 4371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dvb_ringbuffer_free(&av7110->aout) >= 20 * 1024) 4381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 439804b4458943f14bf144d3c3ba50097ced9b27b29Oliver Endrissstatic ssize_t dvb_play(struct av7110 *av7110, const char __user *buf, 4401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long count, int nonblock, int type) 4411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long todo = count, n; 4431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dprintk(2, "av7110:%p, \n", av7110); 4441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!av7110->kbuf[type]) 4461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -ENOBUFS; 4471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (nonblock && !FREE_COND) 4491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EWOULDBLOCK; 4501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (todo > 0) { 4521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!FREE_COND) { 4531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (nonblock) 4541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count - todo; 4551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (wait_event_interruptible(av7110->avout.queue, 4561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FREE_COND)) 4571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count - todo; 4581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds n = todo; 4601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (n > IPACKS * 2) 4611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds n = IPACKS * 2; 4621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (copy_from_user(av7110->kbuf[type], buf, n)) 4631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EFAULT; 4641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110_ipack_instant_repack(av7110->kbuf[type], n, 4651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds &av7110->ipack[type]); 4661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds todo -= n; 4671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buf += n; 4681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count - todo; 4701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic ssize_t dvb_play_kernel(struct av7110 *av7110, const u8 *buf, 4731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long count, int nonblock, int type) 4741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long todo = count, n; 4761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dprintk(2, "av7110:%p, \n", av7110); 4771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!av7110->kbuf[type]) 4791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -ENOBUFS; 4801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (nonblock && !FREE_COND) 4821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EWOULDBLOCK; 4831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (todo > 0) { 4851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!FREE_COND) { 4861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (nonblock) 4871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count - todo; 4881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (wait_event_interruptible(av7110->avout.queue, 4891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FREE_COND)) 4901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count - todo; 4911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds n = todo; 4931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (n > IPACKS * 2) 4941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds n = IPACKS * 2; 4951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110_ipack_instant_repack(buf, n, &av7110->ipack[type]); 4961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds todo -= n; 4971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buf += n; 4981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count - todo; 5001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 502804b4458943f14bf144d3c3ba50097ced9b27b29Oliver Endrissstatic ssize_t dvb_aplay(struct av7110 *av7110, const char __user *buf, 5031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long count, int nonblock, int type) 5041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 5051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long todo = count, n; 5061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dprintk(2, "av7110:%p, \n", av7110); 5071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!av7110->kbuf[type]) 5091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -ENOBUFS; 5101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (nonblock && dvb_ringbuffer_free(&av7110->aout) < 20 * 1024) 5111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EWOULDBLOCK; 5121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (todo > 0) { 5141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (dvb_ringbuffer_free(&av7110->aout) < 20 * 1024) { 5151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (nonblock) 5161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count - todo; 5171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (wait_event_interruptible(av7110->aout.queue, 5181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (dvb_ringbuffer_free(&av7110->aout) >= 20 * 1024))) 5191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count-todo; 5201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds n = todo; 5221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (n > IPACKS * 2) 5231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds n = IPACKS * 2; 5241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (copy_from_user(av7110->kbuf[type], buf, n)) 5251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EFAULT; 5261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110_ipack_instant_repack(av7110->kbuf[type], n, 5271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds &av7110->ipack[type]); 5281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds todo -= n; 5291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buf += n; 5301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count - todo; 5321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid av7110_p2t_init(struct av7110_p2t *p, struct dvb_demux_feed *feed) 5351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 5361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memset(p->pes, 0, TS_SIZE); 5371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->counter = 0; 5381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->pos = 0; 5391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->frags = 0; 5401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (feed) 5411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->feed = feed; 5421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void clear_p2t(struct av7110_p2t *p) 5451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 5461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memset(p->pes, 0, TS_SIZE); 5471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds// p->counter = 0; 5481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->pos = 0; 5491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->frags = 0; 5501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int find_pes_header(u8 const *buf, long int length, int *frags) 5541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 5551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int c = 0; 5561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int found = 0; 5571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *frags = 0; 5591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (c < length - 3 && !found) { 5611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (buf[c] == 0x00 && buf[c + 1] == 0x00 && 5621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buf[c + 2] == 0x01) { 5631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch ( buf[c + 3] ) { 5641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case PROG_STREAM_MAP: 5651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case PRIVATE_STREAM2: 5661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case PROG_STREAM_DIR: 5671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case ECM_STREAM : 5681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case EMM_STREAM : 5691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case PADDING_STREAM : 5701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case DSM_CC_STREAM : 5711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case ISO13522_STREAM: 5721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case PRIVATE_STREAM1: 5731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case AUDIO_STREAM_S ... AUDIO_STREAM_E: 5741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case VIDEO_STREAM_S ... VIDEO_STREAM_E: 5751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds found = 1; 5761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 5771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 5791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c++; 5801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 5811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else 5831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c++; 5841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (c == length - 3 && !found) { 5861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (buf[length - 1] == 0x00) 5871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *frags = 1; 5881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (buf[length - 2] == 0x00 && 5891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buf[length - 1] == 0x00) 5901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *frags = 2; 5911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (buf[length - 3] == 0x00 && 5921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buf[length - 2] == 0x00 && 5931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buf[length - 1] == 0x01) 5941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *frags = 3; 5951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -1; 5961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return c; 5991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid av7110_p2t_write(u8 const *buf, long int length, u16 pid, struct av7110_p2t *p) 6021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 6031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int c, c2, l, add; 6041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int check, rest; 6051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c = 0; 6071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c2 = 0; 6081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (p->frags){ 6091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds check = 0; 6101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch(p->frags) { 6111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 1: 6121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (buf[c] == 0x00 && buf[c + 1] == 0x01) { 6131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds check = 1; 6141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c += 2; 6151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 6171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 2: 6181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (buf[c] == 0x01) { 6191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds check = 1; 6201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c++; 6211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 6231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 3: 6241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds check = 1; 6251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (check) { 6271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (buf[c]) { 6281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case PROG_STREAM_MAP: 6291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case PRIVATE_STREAM2: 6301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case PROG_STREAM_DIR: 6311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case ECM_STREAM : 6321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case EMM_STREAM : 6331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case PADDING_STREAM : 6341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case DSM_CC_STREAM : 6351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case ISO13522_STREAM: 6361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case PRIVATE_STREAM1: 6371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case AUDIO_STREAM_S ... AUDIO_STREAM_E: 6381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case VIDEO_STREAM_S ... VIDEO_STREAM_E: 6391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->pes[0] = 0x00; 6401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->pes[1] = 0x00; 6411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->pes[2] = 0x01; 6421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->pes[3] = buf[c]; 6431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->pos = 4; 6441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(p->pes + p->pos, buf + c, (TS_SIZE - 4) - p->pos); 6451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c += (TS_SIZE - 4) - p->pos; 6461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p_to_t(p->pes, (TS_SIZE - 4), pid, &p->counter, p->feed); 6471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds clear_p2t(p); 6481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 6491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 6511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c = 0; 6521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 6531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->frags = 0; 6561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (p->pos) { 6591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c2 = find_pes_header(buf + c, length - c, &p->frags); 6601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (c2 >= 0 && c2 < (TS_SIZE - 4) - p->pos) 6611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds l = c2+c; 6621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 6631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds l = (TS_SIZE - 4) - p->pos; 6641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(p->pes + p->pos, buf, l); 6651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c += l; 6661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->pos += l; 6671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p_to_t(p->pes, p->pos, pid, &p->counter, p->feed); 6681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds clear_p2t(p); 6691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds add = 0; 6721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (c < length) { 6731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c2 = find_pes_header(buf + c + add, length - c - add, &p->frags); 6741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (c2 >= 0) { 6751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c2 += c + add; 6761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (c2 > c){ 6771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p_to_t(buf + c, c2 - c, pid, &p->counter, p->feed); 6781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c = c2; 6791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds clear_p2t(p); 6801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds add = 0; 6811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else 6821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds add = 1; 6831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 6841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds l = length - c; 6851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rest = l % (TS_SIZE - 4); 6861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds l -= rest; 6871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p_to_t(buf + c, l, pid, &p->counter, p->feed); 6881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(p->pes, buf + c + l, rest); 6891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->pos = rest; 6901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c = length; 6911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int write_ts_header2(u16 pid, u8 *counter, int pes_start, u8 *buf, u8 length) 6971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 6981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 6991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int c = 0; 7001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int fill; 7011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 tshead[4] = { 0x47, 0x00, 0x00, 0x10 }; 7021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fill = (TS_SIZE - 4) - length; 7041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (pes_start) 7051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tshead[1] = 0x40; 7061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (fill) 7071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tshead[3] = 0x30; 7081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tshead[1] |= (u8)((pid & 0x1F00) >> 8); 7091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tshead[2] |= (u8)(pid & 0x00FF); 7101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tshead[3] |= ((*counter)++ & 0x0F); 7111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(buf, tshead, 4); 7121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c += 4; 7131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (fill) { 7151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buf[4] = fill - 1; 7161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c++; 7171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (fill > 1) { 7181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buf[5] = 0x00; 7191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c++; 7201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 6; i < fill + 4; i++) { 7221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buf[i] = 0xFF; 7231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c++; 7241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return c; 7281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void p_to_t(u8 const *buf, long int length, u16 pid, u8 *counter, 7321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct dvb_demux_feed *feed) 7331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 7341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int l, pes_start; 7351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 obuf[TS_SIZE]; 7361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds long c = 0; 7371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pes_start = 0; 7391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (length > 3 && 7401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buf[0] == 0x00 && buf[1] == 0x00 && buf[2] == 0x01) 7411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (buf[3]) { 7421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case PROG_STREAM_MAP: 7431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case PRIVATE_STREAM2: 7441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case PROG_STREAM_DIR: 7451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case ECM_STREAM : 7461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case EMM_STREAM : 7471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case PADDING_STREAM : 7481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case DSM_CC_STREAM : 7491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case ISO13522_STREAM: 7501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case PRIVATE_STREAM1: 7511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case AUDIO_STREAM_S ... AUDIO_STREAM_E: 7521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case VIDEO_STREAM_S ... VIDEO_STREAM_E: 7531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pes_start = 1; 7541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 7551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 7571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 7581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (c < length) { 7611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memset(obuf, 0, TS_SIZE); 7621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (length - c >= (TS_SIZE - 4)){ 7631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds l = write_ts_header2(pid, counter, pes_start, 7641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds obuf, (TS_SIZE - 4)); 7651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(obuf + l, buf + c, TS_SIZE - l); 7661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c += TS_SIZE - l; 7671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 7681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds l = write_ts_header2(pid, counter, pes_start, 7691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds obuf, length - c); 7701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(obuf + l, buf + c, TS_SIZE - l); 7711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c = length; 7721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds feed->cb.ts(obuf, 188, NULL, 0, &feed->feed.ts, DMX_OK); 7741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pes_start = 0; 7751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint av7110_write_to_decoder(struct dvb_demux_feed *feed, const u8 *buf, size_t len) 7801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 7811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct dvb_demux *demux = feed->demux; 7821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct av7110 *av7110 = (struct av7110 *) demux->priv; 7831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct ipack *ipack = &av7110->ipack[feed->pes_type]; 7841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dprintk(2, "av7110:%p, \n", av7110); 7861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (feed->pes_type) { 7881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 0: 7891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->audiostate.stream_source == AUDIO_SOURCE_MEMORY) 7901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EINVAL; 7911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 7921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 1: 7931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->videostate.stream_source == VIDEO_SOURCE_MEMORY) 7941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EINVAL; 7951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 7961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 7971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -1; 7981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!(buf[3] & 0x10)) /* no payload? */ 8011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -1; 8021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (buf[1] & 0x40) 8031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110_ipack_flush(ipack); 8041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (buf[3] & 0x20) { /* adaptation field? */ 8061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds len -= buf[4] + 1; 8071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buf += buf[4] + 1; 8081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!len) 8091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 8101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110_ipack_instant_repack(buf + 4, len - 4, &av7110->ipack[feed->pes_type]); 8131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 8141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 8151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/****************************************************************************** 8191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Video MPEG decoder events 8201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ******************************************************************************/ 8211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid dvb_video_add_event(struct av7110 *av7110, struct video_event *event) 8221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 8231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct dvb_video_events *events = &av7110->video_events; 8241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int wp; 8251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_lock_bh(&events->lock); 8271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds wp = (events->eventw + 1) % MAX_VIDEO_EVENT; 8291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (wp == events->eventr) { 8301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds events->overflow = 1; 8311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds events->eventr = (events->eventr + 1) % MAX_VIDEO_EVENT; 8321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds //FIXME: timestamp? 8351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(&events->events[events->eventw], event, sizeof(struct video_event)); 8361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds events->eventw = wp; 8371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_unlock_bh(&events->lock); 8391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds wake_up_interruptible(&events->wait_queue); 8411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 8421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int dvb_video_get_event (struct av7110 *av7110, struct video_event *event, int flags) 8451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 8461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct dvb_video_events *events = &av7110->video_events; 8471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (events->overflow) { 8491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds events->overflow = 0; 8501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EOVERFLOW; 8511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (events->eventw == events->eventr) { 8531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int ret; 8541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (flags & O_NONBLOCK) 8561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EWOULDBLOCK; 8571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ret = wait_event_interruptible(events->wait_queue, 8591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds events->eventw != events->eventr); 8601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ret < 0) 8611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ret; 8621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_lock_bh(&events->lock); 8651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(event, &events->events[events->eventr], 8671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sizeof(struct video_event)); 8681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds events->eventr = (events->eventr + 1) % MAX_VIDEO_EVENT; 8691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_unlock_bh(&events->lock); 8711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 8731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 8741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/****************************************************************************** 8771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * DVB device file operations 8781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ******************************************************************************/ 8791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic unsigned int dvb_video_poll(struct file *file, poll_table *wait) 8811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 882d9bdf77296a00538faff95f29bf238857daea2e7Tobias Klauser struct dvb_device *dvbdev = file->private_data; 883d9bdf77296a00538faff95f29bf238857daea2e7Tobias Klauser struct av7110 *av7110 = dvbdev->priv; 8841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int mask = 0; 8851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dprintk(2, "av7110:%p, \n", av7110); 8871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((file->f_flags & O_ACCMODE) != O_RDONLY) 8891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds poll_wait(file, &av7110->avout.queue, wait); 8901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds poll_wait(file, &av7110->video_events.wait_queue, wait); 8921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->video_events.eventw != av7110->video_events.eventr) 8941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mask = POLLPRI; 8951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((file->f_flags & O_ACCMODE) != O_RDONLY) { 8971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->playing) { 8981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (FREE_COND) 8991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mask |= (POLLOUT | POLLWRNORM); 9001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else /* if not playing: may play if asked for */ 9011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mask |= (POLLOUT | POLLWRNORM); 9021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 9031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return mask; 9051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 9061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic ssize_t dvb_video_write(struct file *file, const char __user *buf, 9081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds size_t count, loff_t *ppos) 9091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 910d9bdf77296a00538faff95f29bf238857daea2e7Tobias Klauser struct dvb_device *dvbdev = file->private_data; 911d9bdf77296a00538faff95f29bf238857daea2e7Tobias Klauser struct av7110 *av7110 = dvbdev->priv; 9121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dprintk(2, "av7110:%p, \n", av7110); 9141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((file->f_flags & O_ACCMODE) == O_RDONLY) 9161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EPERM; 9171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->videostate.stream_source != VIDEO_SOURCE_MEMORY) 9191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EPERM; 9201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return dvb_play(av7110, buf, count, file->f_flags & O_NONBLOCK, 1); 9221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 9231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic unsigned int dvb_audio_poll(struct file *file, poll_table *wait) 9251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 926d9bdf77296a00538faff95f29bf238857daea2e7Tobias Klauser struct dvb_device *dvbdev = file->private_data; 927d9bdf77296a00538faff95f29bf238857daea2e7Tobias Klauser struct av7110 *av7110 = dvbdev->priv; 9281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int mask = 0; 9291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dprintk(2, "av7110:%p, \n", av7110); 9311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds poll_wait(file, &av7110->aout.queue, wait); 9331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->playing) { 9351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (dvb_ringbuffer_free(&av7110->aout) >= 20 * 1024) 9361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mask |= (POLLOUT | POLLWRNORM); 9371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else /* if not playing: may play if asked for */ 9381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mask = (POLLOUT | POLLWRNORM); 9391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return mask; 9411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 9421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic ssize_t dvb_audio_write(struct file *file, const char __user *buf, 9441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds size_t count, loff_t *ppos) 9451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 946d9bdf77296a00538faff95f29bf238857daea2e7Tobias Klauser struct dvb_device *dvbdev = file->private_data; 947d9bdf77296a00538faff95f29bf238857daea2e7Tobias Klauser struct av7110 *av7110 = dvbdev->priv; 9481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dprintk(2, "av7110:%p, \n", av7110); 9501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->audiostate.stream_source != AUDIO_SOURCE_MEMORY) { 9521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_ERR "not audio source memory\n"); 9531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EPERM; 9541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 9551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return dvb_aplay(av7110, buf, count, file->f_flags & O_NONBLOCK, 0); 9561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 9571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic u8 iframe_header[] = { 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x80, 0x00, 0x00 }; 9591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define MIN_IFRAME 400000 9611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 962804b4458943f14bf144d3c3ba50097ced9b27b29Oliver Endrissstatic int play_iframe(struct av7110 *av7110, char __user *buf, unsigned int len, int nonblock) 9631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 9641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i, n; 9651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dprintk(2, "av7110:%p, \n", av7110); 9671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!(av7110->playing & RP_VIDEO)) { 9691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110_av_start_play(av7110, RP_VIDEO) < 0) 9701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EBUSY; 9711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 9721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* setting n always > 1, fixes problems when playing stillframes 9741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds consisting of I- and P-Frames */ 9751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds n = MIN_IFRAME / len + 1; 9761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* FIXME: nonblock? */ 9781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dvb_play_kernel(av7110, iframe_header, sizeof(iframe_header), 0, 1); 9791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < n; i++) 9811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dvb_play(av7110, buf, len, 0, 1); 9821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110_ipack_flush(&av7110->ipack[1]); 9841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 9851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 9861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int dvb_video_ioctl(struct inode *inode, struct file *file, 9891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int cmd, void *parg) 9901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 991d9bdf77296a00538faff95f29bf238857daea2e7Tobias Klauser struct dvb_device *dvbdev = file->private_data; 992d9bdf77296a00538faff95f29bf238857daea2e7Tobias Klauser struct av7110 *av7110 = dvbdev->priv; 9931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long arg = (unsigned long) parg; 9941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int ret = 0; 9951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 996ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald dprintk(1, "av7110:%p, cmd=%04x\n", av7110,cmd); 9971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((file->f_flags & O_ACCMODE) == O_RDONLY) { 9991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ( cmd != VIDEO_GET_STATUS && cmd != VIDEO_GET_EVENT && 10001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cmd != VIDEO_GET_SIZE ) { 10011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EPERM; 10021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 10031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 10041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (cmd) { 10061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case VIDEO_STOP: 10071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->videostate.play_state = VIDEO_STOPPED; 10081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->videostate.stream_source == VIDEO_SOURCE_MEMORY) 1009ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = av7110_av_stop(av7110, RP_VIDEO); 10101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 10112435be11ae1afb64ac7dfb25e10b6e3037ab0522Hans Verkuil ret = vidcom(av7110, AV_VIDEO_CMD_STOP, 10121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->videostate.video_blank ? 0 : 1); 1013ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (!ret) 1014ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald av7110->trickmode = TRICK_NONE; 10151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 10161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case VIDEO_PLAY: 10181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->trickmode = TRICK_NONE; 10191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->videostate.play_state == VIDEO_FREEZED) { 10201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->videostate.play_state = VIDEO_PLAYING; 10212435be11ae1afb64ac7dfb25e10b6e3037ab0522Hans Verkuil ret = vidcom(av7110, AV_VIDEO_CMD_PLAY, 0); 1022ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (ret) 1023ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald break; 10241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 10251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->videostate.stream_source == VIDEO_SOURCE_MEMORY) { 10271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->playing == RP_AV) { 1028ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Stop, 0); 1029ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (ret) 1030ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald break; 10311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->playing &= ~RP_VIDEO; 10321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1033ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = av7110_av_start_play(av7110, RP_VIDEO); 10341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1035ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (!ret) 10362435be11ae1afb64ac7dfb25e10b6e3037ab0522Hans Verkuil ret = vidcom(av7110, AV_VIDEO_CMD_PLAY, 0); 1037ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (!ret) 1038ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald av7110->videostate.play_state = VIDEO_PLAYING; 10391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 10401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case VIDEO_FREEZE: 10421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->videostate.play_state = VIDEO_FREEZED; 10431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->playing & RP_VIDEO) 1044ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Pause, 0); 10451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 10462435be11ae1afb64ac7dfb25e10b6e3037ab0522Hans Verkuil ret = vidcom(av7110, AV_VIDEO_CMD_FREEZE, 1); 1047ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (!ret) 1048ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald av7110->trickmode = TRICK_FREEZE; 10491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 10501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case VIDEO_CONTINUE: 10521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->playing & RP_VIDEO) 1053ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Continue, 0); 1054ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (!ret) 10552435be11ae1afb64ac7dfb25e10b6e3037ab0522Hans Verkuil ret = vidcom(av7110, AV_VIDEO_CMD_PLAY, 0); 1056ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (!ret) { 1057ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald av7110->videostate.play_state = VIDEO_PLAYING; 1058ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald av7110->trickmode = TRICK_NONE; 1059ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald } 10601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 10611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case VIDEO_SELECT_SOURCE: 10631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->videostate.stream_source = (video_stream_source_t) arg; 10641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 10651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case VIDEO_SET_BLANK: 10671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->videostate.video_blank = (int) arg; 10681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 10691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case VIDEO_GET_STATUS: 10711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(parg, &av7110->videostate, sizeof(struct video_status)); 10721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 10731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case VIDEO_GET_EVENT: 1075ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = dvb_video_get_event(av7110, parg, file->f_flags); 10761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 10771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case VIDEO_GET_SIZE: 10791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(parg, &av7110->video_size, sizeof(video_size_t)); 10801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 10811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case VIDEO_SET_DISPLAY_FORMAT: 10831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 10841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds video_displayformat_t format = (video_displayformat_t) arg; 10851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u16 val = 0; 10861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (format) { 10881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case VIDEO_PAN_SCAN: 10891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds val = VID_PAN_SCAN_PREF; 10901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 10911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case VIDEO_LETTER_BOX: 10931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds val = VID_VC_AND_PS_PREF; 10941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 10951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case VIDEO_CENTER_CUT_OUT: 10971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds val = VID_CENTRE_CUT_PREF; 10981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 10991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 11011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ret = -EINVAL; 11021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 11031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ret < 0) 11041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 1105a65d3bb7177cbab1fca69dd97537766c2817b6b2Johannes Stezenbach av7110->videostate.display_format = format; 11061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ret = av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetPanScanType, 11071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1, (u16) val); 11081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 11091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 11101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case VIDEO_SET_FORMAT: 11121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (arg > 1) { 11131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ret = -EINVAL; 11141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 11151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 11161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->display_ar = arg; 11171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ret = av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetMonitorType, 11181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1, (u16) arg); 11191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 11201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case VIDEO_STILLPICTURE: 11221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 11231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct video_still_picture *pic = 11241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (struct video_still_picture *) parg; 11251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->videostate.stream_source = VIDEO_SOURCE_MEMORY; 11261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dvb_ringbuffer_flush_spinlock_wakeup(&av7110->avout); 11271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ret = play_iframe(av7110, pic->iFrame, pic->size, 11281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds file->f_flags & O_NONBLOCK); 11291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 11301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 11311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case VIDEO_FAST_FORWARD: 11331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds //note: arg is ignored by firmware 11341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->playing & RP_VIDEO) 1135ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, 11367a2fa90fa8084846937aa194f8a40abfa99c692fJohannes Stezenbach __Scan_I, 2, AV_PES, 0); 11371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 11382435be11ae1afb64ac7dfb25e10b6e3037ab0522Hans Verkuil ret = vidcom(av7110, AV_VIDEO_CMD_FFWD, arg); 1139ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (!ret) { 1140ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald av7110->trickmode = TRICK_FAST; 1141ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald av7110->videostate.play_state = VIDEO_PLAYING; 1142ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald } 11431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 11441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case VIDEO_SLOWMOTION: 11461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->playing&RP_VIDEO) { 1147ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Slow, 2, 0, 0); 1148ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (!ret) 11492435be11ae1afb64ac7dfb25e10b6e3037ab0522Hans Verkuil ret = vidcom(av7110, AV_VIDEO_CMD_SLOW, arg); 11501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 11512435be11ae1afb64ac7dfb25e10b6e3037ab0522Hans Verkuil ret = vidcom(av7110, AV_VIDEO_CMD_PLAY, 0); 1152ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (!ret) 11532435be11ae1afb64ac7dfb25e10b6e3037ab0522Hans Verkuil ret = vidcom(av7110, AV_VIDEO_CMD_STOP, 0); 1154ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (!ret) 11552435be11ae1afb64ac7dfb25e10b6e3037ab0522Hans Verkuil ret = vidcom(av7110, AV_VIDEO_CMD_SLOW, arg); 1156ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald } 1157ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (!ret) { 1158ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald av7110->trickmode = TRICK_SLOW; 1159ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald av7110->videostate.play_state = VIDEO_PLAYING; 11601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 11611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 11621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case VIDEO_GET_CAPABILITIES: 11641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *(int *)parg = VIDEO_CAP_MPEG1 | VIDEO_CAP_MPEG2 | 11651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds VIDEO_CAP_SYS | VIDEO_CAP_PROG; 11661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 11671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case VIDEO_CLEAR_BUFFER: 11691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dvb_ringbuffer_flush_spinlock_wakeup(&av7110->avout); 11701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110_ipack_reset(&av7110->ipack[1]); 11711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->playing == RP_AV) { 1173ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, 11747a2fa90fa8084846937aa194f8a40abfa99c692fJohannes Stezenbach __Play, 2, AV_PES, 0); 1175ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (ret) 1176ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald break; 11771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->trickmode == TRICK_FAST) 1178ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, 11797a2fa90fa8084846937aa194f8a40abfa99c692fJohannes Stezenbach __Scan_I, 2, AV_PES, 0); 11801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->trickmode == TRICK_SLOW) { 1181ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, 11827a2fa90fa8084846937aa194f8a40abfa99c692fJohannes Stezenbach __Slow, 2, 0, 0); 1183ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (!ret) 11842435be11ae1afb64ac7dfb25e10b6e3037ab0522Hans Verkuil ret = vidcom(av7110, AV_VIDEO_CMD_SLOW, arg); 11851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 11861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->trickmode == TRICK_FREEZE) 11872435be11ae1afb64ac7dfb25e10b6e3037ab0522Hans Verkuil ret = vidcom(av7110, AV_VIDEO_CMD_STOP, 1); 11881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 11891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 11901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case VIDEO_SET_STREAMTYPE: 11921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 11941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 11961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ret = -ENOIOCTLCMD; 11971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 11981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 11991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ret; 12001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 12011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int dvb_audio_ioctl(struct inode *inode, struct file *file, 12031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int cmd, void *parg) 12041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1205d9bdf77296a00538faff95f29bf238857daea2e7Tobias Klauser struct dvb_device *dvbdev = file->private_data; 1206d9bdf77296a00538faff95f29bf238857daea2e7Tobias Klauser struct av7110 *av7110 = dvbdev->priv; 12071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long arg = (unsigned long) parg; 12081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int ret = 0; 12091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1210ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald dprintk(1, "av7110:%p, cmd=%04x\n", av7110,cmd); 12111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (((file->f_flags & O_ACCMODE) == O_RDONLY) && 12131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (cmd != AUDIO_GET_STATUS)) 12141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EPERM; 12151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (cmd) { 12171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case AUDIO_STOP: 12181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->audiostate.stream_source == AUDIO_SOURCE_MEMORY) 1219ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = av7110_av_stop(av7110, RP_AUDIO); 12201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 1221ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = audcom(av7110, AUDIO_CMD_MUTE); 1222ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (!ret) 1223ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald av7110->audiostate.play_state = AUDIO_STOPPED; 12241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 12251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case AUDIO_PLAY: 12271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->audiostate.stream_source == AUDIO_SOURCE_MEMORY) 1228ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = av7110_av_start_play(av7110, RP_AUDIO); 1229ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (!ret) 1230ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = audcom(av7110, AUDIO_CMD_UNMUTE); 1231ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (!ret) 1232ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald av7110->audiostate.play_state = AUDIO_PLAYING; 12331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 12341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case AUDIO_PAUSE: 1236ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = audcom(av7110, AUDIO_CMD_MUTE); 1237ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (!ret) 1238ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald av7110->audiostate.play_state = AUDIO_PAUSED; 12391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 12401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case AUDIO_CONTINUE: 12421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->audiostate.play_state == AUDIO_PAUSED) { 12431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->audiostate.play_state = AUDIO_PLAYING; 1244ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = audcom(av7110, AUDIO_CMD_UNMUTE | AUDIO_CMD_PCM16); 12451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 12461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 12471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case AUDIO_SELECT_SOURCE: 12491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->audiostate.stream_source = (audio_stream_source_t) arg; 12501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 12511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case AUDIO_SET_MUTE: 12531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 1254ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = audcom(av7110, arg ? AUDIO_CMD_MUTE : AUDIO_CMD_UNMUTE); 1255ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (!ret) 1256ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald av7110->audiostate.mute_state = (int) arg; 12571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 12581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 12591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case AUDIO_SET_AV_SYNC: 12611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->audiostate.AV_sync_state = (int) arg; 1262ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = audcom(av7110, arg ? AUDIO_CMD_SYNC_ON : AUDIO_CMD_SYNC_OFF); 12631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 12641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case AUDIO_SET_BYPASS_MODE: 126647f3692096eef208d8cb455bfa2b3308cdfc40deDr. Werner Fink if (FW_VERSION(av7110->arm_app) < 0x2621) 126747f3692096eef208d8cb455bfa2b3308cdfc40deDr. Werner Fink ret = -EINVAL; 126847f3692096eef208d8cb455bfa2b3308cdfc40deDr. Werner Fink av7110->audiostate.bypass_mode = (int)arg; 12691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 12701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case AUDIO_CHANNEL_SELECT: 12721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->audiostate.channel_select = (audio_channel_select_t) arg; 12731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch(av7110->audiostate.channel_select) { 12751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case AUDIO_STEREO: 1276ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = audcom(av7110, AUDIO_CMD_STEREO); 127761391e0446e97bea44d93bd1624e5b32d3cc8474Tim Kaiser if (!ret) { 1278ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (av7110->adac_type == DVB_ADAC_CRYSTAL) 1279ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald i2c_writereg(av7110, 0x20, 0x02, 0x49); 128061391e0446e97bea44d93bd1624e5b32d3cc8474Tim Kaiser else if (av7110->adac_type == DVB_ADAC_MSP34x5) 128161391e0446e97bea44d93bd1624e5b32d3cc8474Tim Kaiser msp_writereg(av7110, MSP_WR_DSP, 0x0008, 0x0220); 128261391e0446e97bea44d93bd1624e5b32d3cc8474Tim Kaiser } 12831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 12841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case AUDIO_MONO_LEFT: 1286ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = audcom(av7110, AUDIO_CMD_MONO_L); 128761391e0446e97bea44d93bd1624e5b32d3cc8474Tim Kaiser if (!ret) { 1288ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (av7110->adac_type == DVB_ADAC_CRYSTAL) 1289ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald i2c_writereg(av7110, 0x20, 0x02, 0x4a); 129061391e0446e97bea44d93bd1624e5b32d3cc8474Tim Kaiser else if (av7110->adac_type == DVB_ADAC_MSP34x5) 129161391e0446e97bea44d93bd1624e5b32d3cc8474Tim Kaiser msp_writereg(av7110, MSP_WR_DSP, 0x0008, 0x0200); 129261391e0446e97bea44d93bd1624e5b32d3cc8474Tim Kaiser } 12931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 12941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case AUDIO_MONO_RIGHT: 1296ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = audcom(av7110, AUDIO_CMD_MONO_R); 129761391e0446e97bea44d93bd1624e5b32d3cc8474Tim Kaiser if (!ret) { 1298ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (av7110->adac_type == DVB_ADAC_CRYSTAL) 1299ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald i2c_writereg(av7110, 0x20, 0x02, 0x45); 130061391e0446e97bea44d93bd1624e5b32d3cc8474Tim Kaiser else if (av7110->adac_type == DVB_ADAC_MSP34x5) 130161391e0446e97bea44d93bd1624e5b32d3cc8474Tim Kaiser msp_writereg(av7110, MSP_WR_DSP, 0x0008, 0x0210); 130261391e0446e97bea44d93bd1624e5b32d3cc8474Tim Kaiser } 13031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 13041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 13061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ret = -EINVAL; 13071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 13081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 13091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 13101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case AUDIO_GET_STATUS: 13121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(parg, &av7110->audiostate, sizeof(struct audio_status)); 13131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 13141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case AUDIO_GET_CAPABILITIES: 131647f3692096eef208d8cb455bfa2b3308cdfc40deDr. Werner Fink if (FW_VERSION(av7110->arm_app) < 0x2621) 131747f3692096eef208d8cb455bfa2b3308cdfc40deDr. Werner Fink *(unsigned int *)parg = AUDIO_CAP_LPCM | AUDIO_CAP_MP1 | AUDIO_CAP_MP2; 131847f3692096eef208d8cb455bfa2b3308cdfc40deDr. Werner Fink else 131947f3692096eef208d8cb455bfa2b3308cdfc40deDr. Werner Fink *(unsigned int *)parg = AUDIO_CAP_LPCM | AUDIO_CAP_DTS | AUDIO_CAP_AC3 | 132047f3692096eef208d8cb455bfa2b3308cdfc40deDr. Werner Fink AUDIO_CAP_MP1 | AUDIO_CAP_MP2; 13211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 13221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case AUDIO_CLEAR_BUFFER: 13241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dvb_ringbuffer_flush_spinlock_wakeup(&av7110->aout); 13251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110_ipack_reset(&av7110->ipack[0]); 13261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->playing == RP_AV) 1327ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, 13287a2fa90fa8084846937aa194f8a40abfa99c692fJohannes Stezenbach __Play, 2, AV_PES, 0); 13291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 13301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case AUDIO_SET_ID: 13311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 13331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case AUDIO_SET_MIXER: 13341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 13351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct audio_mixer *amix = (struct audio_mixer *)parg; 13361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1337ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = av7110_set_volume(av7110, amix->volume_left, amix->volume_right); 13381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 13391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 13401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case AUDIO_SET_STREAMTYPE: 13411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 13421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 13431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ret = -ENOIOCTLCMD; 13441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 13451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ret; 13461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 13471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int dvb_video_open(struct inode *inode, struct file *file) 13501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1351d9bdf77296a00538faff95f29bf238857daea2e7Tobias Klauser struct dvb_device *dvbdev = file->private_data; 1352d9bdf77296a00538faff95f29bf238857daea2e7Tobias Klauser struct av7110 *av7110 = dvbdev->priv; 13531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int err; 13541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dprintk(2, "av7110:%p, \n", av7110); 13561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((err = dvb_generic_open(inode, file)) < 0) 13581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return err; 13591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((file->f_flags & O_ACCMODE) != O_RDONLY) { 13611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dvb_ringbuffer_flush_spinlock_wakeup(&av7110->aout); 13621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dvb_ringbuffer_flush_spinlock_wakeup(&av7110->avout); 13631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->video_blank = 1; 13641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->audiostate.AV_sync_state = 1; 13651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->videostate.stream_source = VIDEO_SOURCE_DEMUX; 13661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* empty event queue */ 13681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->video_events.eventr = av7110->video_events.eventw = 0; 13691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 13701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 13721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 13731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int dvb_video_release(struct inode *inode, struct file *file) 13751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1376d9bdf77296a00538faff95f29bf238857daea2e7Tobias Klauser struct dvb_device *dvbdev = file->private_data; 1377d9bdf77296a00538faff95f29bf238857daea2e7Tobias Klauser struct av7110 *av7110 = dvbdev->priv; 13781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dprintk(2, "av7110:%p, \n", av7110); 13801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((file->f_flags & O_ACCMODE) != O_RDONLY) { 13821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110_av_stop(av7110, RP_VIDEO); 13831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 13841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return dvb_generic_release(inode, file); 13861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 13871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int dvb_audio_open(struct inode *inode, struct file *file) 13891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1390d9bdf77296a00538faff95f29bf238857daea2e7Tobias Klauser struct dvb_device *dvbdev = file->private_data; 1391d9bdf77296a00538faff95f29bf238857daea2e7Tobias Klauser struct av7110 *av7110 = dvbdev->priv; 1392d9bdf77296a00538faff95f29bf238857daea2e7Tobias Klauser int err = dvb_generic_open(inode, file); 13931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dprintk(2, "av7110:%p, \n", av7110); 13951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (err < 0) 13971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return err; 13981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dvb_ringbuffer_flush_spinlock_wakeup(&av7110->aout); 13991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->audiostate.stream_source = AUDIO_SOURCE_DEMUX; 14001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 14011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 14021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int dvb_audio_release(struct inode *inode, struct file *file) 14041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1405d9bdf77296a00538faff95f29bf238857daea2e7Tobias Klauser struct dvb_device *dvbdev = file->private_data; 1406d9bdf77296a00538faff95f29bf238857daea2e7Tobias Klauser struct av7110 *av7110 = dvbdev->priv; 14071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dprintk(2, "av7110:%p, \n", av7110); 14091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110_av_stop(av7110, RP_AUDIO); 14111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return dvb_generic_release(inode, file); 14121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 14131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/****************************************************************************** 14171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * driver registration 14181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ******************************************************************************/ 14191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct file_operations dvb_video_fops = { 14211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .owner = THIS_MODULE, 14221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .write = dvb_video_write, 14231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .ioctl = dvb_generic_ioctl, 14241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .open = dvb_video_open, 14251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .release = dvb_video_release, 14261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .poll = dvb_video_poll, 14271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 14281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct dvb_device dvbdev_video = { 14301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .priv = NULL, 14311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .users = 6, 14321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .readers = 5, /* arbitrary */ 14331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .writers = 1, 14341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .fops = &dvb_video_fops, 14351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .kernel_ioctl = dvb_video_ioctl, 14361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 14371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct file_operations dvb_audio_fops = { 14391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .owner = THIS_MODULE, 14401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .write = dvb_audio_write, 14411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .ioctl = dvb_generic_ioctl, 14421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .open = dvb_audio_open, 14431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .release = dvb_audio_release, 14441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .poll = dvb_audio_poll, 14451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 14461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct dvb_device dvbdev_audio = { 14481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .priv = NULL, 14491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .users = 1, 14501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .writers = 1, 14511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .fops = &dvb_audio_fops, 14521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .kernel_ioctl = dvb_audio_ioctl, 14531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 14541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint av7110_av_register(struct av7110 *av7110) 14571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 14581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->audiostate.AV_sync_state = 0; 14591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->audiostate.mute_state = 0; 14601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->audiostate.play_state = AUDIO_STOPPED; 14611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->audiostate.stream_source = AUDIO_SOURCE_DEMUX; 14621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->audiostate.channel_select = AUDIO_STEREO; 14631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->audiostate.bypass_mode = 0; 14641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->videostate.video_blank = 0; 14661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->videostate.play_state = VIDEO_STOPPED; 14671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->videostate.stream_source = VIDEO_SOURCE_DEMUX; 14681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->videostate.video_format = VIDEO_FORMAT_4_3; 14691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->videostate.display_format = VIDEO_CENTER_CUT_OUT; 14701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->display_ar = VIDEO_FORMAT_4_3; 14711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds init_waitqueue_head(&av7110->video_events.wait_queue); 14731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_lock_init(&av7110->video_events.lock); 14741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->video_events.eventw = av7110->video_events.eventr = 0; 14751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->video_events.overflow = 0; 14761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memset(&av7110->video_size, 0, sizeof (video_size_t)); 14771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1478fdc53a6dbfea18e621dd23ed5cfb160837d7ce52Johannes Stezenbach dvb_register_device(&av7110->dvb_adapter, &av7110->video_dev, 14791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds &dvbdev_video, av7110, DVB_DEVICE_VIDEO); 14801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1481fdc53a6dbfea18e621dd23ed5cfb160837d7ce52Johannes Stezenbach dvb_register_device(&av7110->dvb_adapter, &av7110->audio_dev, 14821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds &dvbdev_audio, av7110, DVB_DEVICE_AUDIO); 14831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 14851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 14861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid av7110_av_unregister(struct av7110 *av7110) 14881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 14891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dvb_unregister_device(av7110->audio_dev); 14901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dvb_unregister_device(av7110->video_dev); 14911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 14921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint av7110_av_init(struct av7110 *av7110) 14941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 14951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds void (*play[])(u8 *, int, void *) = { play_audio_cb, play_video_cb }; 14961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i, ret; 14971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < 2; i++) { 14991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct ipack *ipack = av7110->ipack + i; 15001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ret = av7110_ipack_init(ipack, IPACKS, play[i]); 15021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ret < 0) { 15031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (i) 15041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110_ipack_free(--ipack); 15051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out; 15061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 15071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ipack->data = av7110; 15081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 15091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dvb_ringbuffer_init(&av7110->avout, av7110->iobuf, AVOUTLEN); 15111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dvb_ringbuffer_init(&av7110->aout, av7110->iobuf + AVOUTLEN, AOUTLEN); 15121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->kbuf[0] = (u8 *)(av7110->iobuf + AVOUTLEN + AOUTLEN + BMPLEN); 15141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->kbuf[1] = av7110->kbuf[0] + 2 * IPACKS; 15151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsout: 15161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ret; 15171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 15181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid av7110_av_exit(struct av7110 *av7110) 15201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 15211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110_ipack_free(&av7110->ipack[0]); 15221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110_ipack_free(&av7110->ipack[1]); 15231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1524