av7110_av.c revision 0ed4a6ea9dbd9f5b77ce594f7f46be022d2c49ec
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 33258a44040b4937c7d16b79a1b3048992eeac9853bMarco Schluesslerint av7110_set_vidmode(struct av7110 *av7110, enum av7110_video_mode 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 35158a44040b4937c7d16b79a1b3048992eeac9853bMarco Schluesslerstatic enum av7110_video_mode sw2mode[16] = { 35258a44040b4937c7d16b79a1b3048992eeac9853bMarco Schluessler AV7110_VIDEO_MODE_PAL, AV7110_VIDEO_MODE_NTSC, 35358a44040b4937c7d16b79a1b3048992eeac9853bMarco Schluessler AV7110_VIDEO_MODE_NTSC, AV7110_VIDEO_MODE_PAL, 35458a44040b4937c7d16b79a1b3048992eeac9853bMarco Schluessler AV7110_VIDEO_MODE_NTSC, AV7110_VIDEO_MODE_NTSC, 35558a44040b4937c7d16b79a1b3048992eeac9853bMarco Schluessler AV7110_VIDEO_MODE_PAL, AV7110_VIDEO_MODE_NTSC, 35658a44040b4937c7d16b79a1b3048992eeac9853bMarco Schluessler AV7110_VIDEO_MODE_PAL, AV7110_VIDEO_MODE_PAL, 35758a44040b4937c7d16b79a1b3048992eeac9853bMarco Schluessler AV7110_VIDEO_MODE_PAL, AV7110_VIDEO_MODE_PAL, 35858a44040b4937c7d16b79a1b3048992eeac9853bMarco Schluessler AV7110_VIDEO_MODE_PAL, AV7110_VIDEO_MODE_PAL, 35958a44040b4937c7d16b79a1b3048992eeac9853bMarco Schluessler AV7110_VIDEO_MODE_PAL, AV7110_VIDEO_MODE_PAL, 3601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 3611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 362ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewaldstatic int get_video_format(struct av7110 *av7110, u8 *buf, int count) 3631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 3651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int hsize, vsize; 3661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int sw; 3671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 *p; 368ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald int ret = 0; 3691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dprintk(2, "av7110:%p, \n", av7110); 3711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->sinfo) 373ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald return 0; 3741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 7; i < count - 10; i++) { 3751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p = buf + i; 3761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (p[0] || p[1] || p[2] != 0x01 || p[3] != 0xb3) 3771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds continue; 3781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p += 4; 3791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hsize = ((p[1] &0xF0) >> 4) | (p[0] << 4); 3801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds vsize = ((p[1] &0x0F) << 8) | (p[2]); 3811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sw = (p[3] & 0x0F); 382ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = av7110_set_vidmode(av7110, sw2mode[sw]); 383ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (!ret) { 384ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald dprintk(2, "playback %dx%d fr=%d\n", hsize, vsize, sw); 385ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald av7110->sinfo = 1; 386ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald } 3871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 3881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 389ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald return ret; 3901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/**************************************************************************** 3941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * I/O buffer management and control 3951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ****************************************************************************/ 3961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline long aux_ring_buffer_write(struct dvb_ringbuffer *rbuf, 398804b4458943f14bf144d3c3ba50097ced9b27b29Oliver Endriss const u8 *buf, unsigned long count) 3991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long todo = count; 4011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int free; 4021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (todo > 0) { 4041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (dvb_ringbuffer_free(rbuf) < 2048) { 4051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (wait_event_interruptible(rbuf->queue, 4061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (dvb_ringbuffer_free(rbuf) >= 2048))) 4071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count - todo; 4081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds free = dvb_ringbuffer_free(rbuf); 4101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (free > todo) 4111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds free = todo; 4121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dvb_ringbuffer_write(rbuf, buf, free); 4131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds todo -= free; 4141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buf += free; 4151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count - todo; 4181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void play_video_cb(u8 *buf, int count, void *priv) 4211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct av7110 *av7110 = (struct av7110 *) priv; 4231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dprintk(2, "av7110:%p, \n", av7110); 4241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((buf[3] & 0xe0) == 0xe0) { 4261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds get_video_format(av7110, buf, count); 4271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds aux_ring_buffer_write(&av7110->avout, buf, count); 4281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else 4291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds aux_ring_buffer_write(&av7110->aout, buf, count); 4301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void play_audio_cb(u8 *buf, int count, void *priv) 4331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct av7110 *av7110 = (struct av7110 *) priv; 4351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dprintk(2, "av7110:%p, \n", av7110); 4361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds aux_ring_buffer_write(&av7110->aout, buf, count); 4381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define FREE_COND (dvb_ringbuffer_free(&av7110->avout) >= 20 * 1024 && \ 4411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dvb_ringbuffer_free(&av7110->aout) >= 20 * 1024) 4421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 443804b4458943f14bf144d3c3ba50097ced9b27b29Oliver Endrissstatic ssize_t dvb_play(struct av7110 *av7110, const char __user *buf, 4441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long count, int nonblock, int type) 4451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long todo = count, n; 4471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dprintk(2, "av7110:%p, \n", av7110); 4481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!av7110->kbuf[type]) 4501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -ENOBUFS; 4511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (nonblock && !FREE_COND) 4531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EWOULDBLOCK; 4541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (todo > 0) { 4561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!FREE_COND) { 4571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (nonblock) 4581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count - todo; 4591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (wait_event_interruptible(av7110->avout.queue, 4601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FREE_COND)) 4611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count - todo; 4621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds n = todo; 4641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (n > IPACKS * 2) 4651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds n = IPACKS * 2; 4661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (copy_from_user(av7110->kbuf[type], buf, n)) 4671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EFAULT; 4681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110_ipack_instant_repack(av7110->kbuf[type], n, 4691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds &av7110->ipack[type]); 4701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds todo -= n; 4711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buf += n; 4721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count - todo; 4741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic ssize_t dvb_play_kernel(struct av7110 *av7110, const u8 *buf, 4771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long count, int nonblock, int type) 4781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long todo = count, n; 4801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dprintk(2, "av7110:%p, \n", av7110); 4811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!av7110->kbuf[type]) 4831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -ENOBUFS; 4841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (nonblock && !FREE_COND) 4861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EWOULDBLOCK; 4871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (todo > 0) { 4891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!FREE_COND) { 4901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (nonblock) 4911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count - todo; 4921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (wait_event_interruptible(av7110->avout.queue, 4931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FREE_COND)) 4941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count - todo; 4951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds n = todo; 4971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (n > IPACKS * 2) 4981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds n = IPACKS * 2; 4991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110_ipack_instant_repack(buf, n, &av7110->ipack[type]); 5001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds todo -= n; 5011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buf += n; 5021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count - todo; 5041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 506804b4458943f14bf144d3c3ba50097ced9b27b29Oliver Endrissstatic ssize_t dvb_aplay(struct av7110 *av7110, const char __user *buf, 5071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long count, int nonblock, int type) 5081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 5091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long todo = count, n; 5101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dprintk(2, "av7110:%p, \n", av7110); 5111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!av7110->kbuf[type]) 5131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -ENOBUFS; 5141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (nonblock && dvb_ringbuffer_free(&av7110->aout) < 20 * 1024) 5151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EWOULDBLOCK; 5161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (todo > 0) { 5181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (dvb_ringbuffer_free(&av7110->aout) < 20 * 1024) { 5191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (nonblock) 5201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count - todo; 5211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (wait_event_interruptible(av7110->aout.queue, 5221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (dvb_ringbuffer_free(&av7110->aout) >= 20 * 1024))) 5231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count-todo; 5241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds n = todo; 5261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (n > IPACKS * 2) 5271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds n = IPACKS * 2; 5281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (copy_from_user(av7110->kbuf[type], buf, n)) 5291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EFAULT; 5301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110_ipack_instant_repack(av7110->kbuf[type], n, 5311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds &av7110->ipack[type]); 5321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds todo -= n; 5331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buf += n; 5341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count - todo; 5361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid av7110_p2t_init(struct av7110_p2t *p, struct dvb_demux_feed *feed) 5391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 5401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memset(p->pes, 0, TS_SIZE); 5411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->counter = 0; 5421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->pos = 0; 5431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->frags = 0; 5441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (feed) 5451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->feed = feed; 5461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void clear_p2t(struct av7110_p2t *p) 5491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 5501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memset(p->pes, 0, TS_SIZE); 5511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds// p->counter = 0; 5521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->pos = 0; 5531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->frags = 0; 5541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int find_pes_header(u8 const *buf, long int length, int *frags) 5581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 5591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int c = 0; 5601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int found = 0; 5611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *frags = 0; 5631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (c < length - 3 && !found) { 5651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (buf[c] == 0x00 && buf[c + 1] == 0x00 && 5661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buf[c + 2] == 0x01) { 5671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch ( buf[c + 3] ) { 5681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case PROG_STREAM_MAP: 5691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case PRIVATE_STREAM2: 5701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case PROG_STREAM_DIR: 5711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case ECM_STREAM : 5721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case EMM_STREAM : 5731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case PADDING_STREAM : 5741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case DSM_CC_STREAM : 5751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case ISO13522_STREAM: 5761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case PRIVATE_STREAM1: 5771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case AUDIO_STREAM_S ... AUDIO_STREAM_E: 5781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case VIDEO_STREAM_S ... VIDEO_STREAM_E: 5791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds found = 1; 5801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 5811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 5831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c++; 5841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 5851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else 5871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c++; 5881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (c == length - 3 && !found) { 5901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (buf[length - 1] == 0x00) 5911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *frags = 1; 5921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (buf[length - 2] == 0x00 && 5931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buf[length - 1] == 0x00) 5941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *frags = 2; 5951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (buf[length - 3] == 0x00 && 5961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buf[length - 2] == 0x00 && 5971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buf[length - 1] == 0x01) 5981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *frags = 3; 5991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -1; 6001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return c; 6031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid av7110_p2t_write(u8 const *buf, long int length, u16 pid, struct av7110_p2t *p) 6061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 6071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int c, c2, l, add; 6081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int check, rest; 6091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c = 0; 6111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c2 = 0; 6121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (p->frags){ 6131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds check = 0; 6141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch(p->frags) { 6151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 1: 6161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (buf[c] == 0x00 && buf[c + 1] == 0x01) { 6171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds check = 1; 6181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c += 2; 6191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 6211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 2: 6221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (buf[c] == 0x01) { 6231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds check = 1; 6241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c++; 6251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 6271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 3: 6281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds check = 1; 6291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (check) { 6311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (buf[c]) { 6321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case PROG_STREAM_MAP: 6331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case PRIVATE_STREAM2: 6341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case PROG_STREAM_DIR: 6351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case ECM_STREAM : 6361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case EMM_STREAM : 6371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case PADDING_STREAM : 6381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case DSM_CC_STREAM : 6391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case ISO13522_STREAM: 6401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case PRIVATE_STREAM1: 6411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case AUDIO_STREAM_S ... AUDIO_STREAM_E: 6421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case VIDEO_STREAM_S ... VIDEO_STREAM_E: 6431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->pes[0] = 0x00; 6441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->pes[1] = 0x00; 6451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->pes[2] = 0x01; 6461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->pes[3] = buf[c]; 6471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->pos = 4; 6481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(p->pes + p->pos, buf + c, (TS_SIZE - 4) - p->pos); 6491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c += (TS_SIZE - 4) - p->pos; 6501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p_to_t(p->pes, (TS_SIZE - 4), pid, &p->counter, p->feed); 6511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds clear_p2t(p); 6521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 6531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 6551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c = 0; 6561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 6571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->frags = 0; 6601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (p->pos) { 6631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c2 = find_pes_header(buf + c, length - c, &p->frags); 6641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (c2 >= 0 && c2 < (TS_SIZE - 4) - p->pos) 6651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds l = c2+c; 6661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 6671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds l = (TS_SIZE - 4) - p->pos; 6681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(p->pes + p->pos, buf, l); 6691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c += l; 6701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->pos += l; 6711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p_to_t(p->pes, p->pos, pid, &p->counter, p->feed); 6721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds clear_p2t(p); 6731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds add = 0; 6761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (c < length) { 6771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c2 = find_pes_header(buf + c + add, length - c - add, &p->frags); 6781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (c2 >= 0) { 6791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c2 += c + add; 6801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (c2 > c){ 6811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p_to_t(buf + c, c2 - c, pid, &p->counter, p->feed); 6821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c = c2; 6831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds clear_p2t(p); 6841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds add = 0; 6851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else 6861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds add = 1; 6871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 6881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds l = length - c; 6891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rest = l % (TS_SIZE - 4); 6901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds l -= rest; 6911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p_to_t(buf + c, l, pid, &p->counter, p->feed); 6921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(p->pes, buf + c + l, rest); 6931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->pos = rest; 6941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c = length; 6951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int write_ts_header2(u16 pid, u8 *counter, int pes_start, u8 *buf, u8 length) 7011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 7021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 7031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int c = 0; 7041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int fill; 7051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 tshead[4] = { 0x47, 0x00, 0x00, 0x10 }; 7061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fill = (TS_SIZE - 4) - length; 7081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (pes_start) 7091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tshead[1] = 0x40; 7101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (fill) 7111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tshead[3] = 0x30; 7121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tshead[1] |= (u8)((pid & 0x1F00) >> 8); 7131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tshead[2] |= (u8)(pid & 0x00FF); 7141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tshead[3] |= ((*counter)++ & 0x0F); 7151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(buf, tshead, 4); 7161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c += 4; 7171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (fill) { 7191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buf[4] = fill - 1; 7201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c++; 7211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (fill > 1) { 7221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buf[5] = 0x00; 7231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c++; 7241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 6; i < fill + 4; i++) { 7261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buf[i] = 0xFF; 7271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c++; 7281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return c; 7321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void p_to_t(u8 const *buf, long int length, u16 pid, u8 *counter, 7361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct dvb_demux_feed *feed) 7371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 7381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int l, pes_start; 7391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 obuf[TS_SIZE]; 7401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds long c = 0; 7411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pes_start = 0; 7431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (length > 3 && 7441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buf[0] == 0x00 && buf[1] == 0x00 && buf[2] == 0x01) 7451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (buf[3]) { 7461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case PROG_STREAM_MAP: 7471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case PRIVATE_STREAM2: 7481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case PROG_STREAM_DIR: 7491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case ECM_STREAM : 7501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case EMM_STREAM : 7511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case PADDING_STREAM : 7521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case DSM_CC_STREAM : 7531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case ISO13522_STREAM: 7541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case PRIVATE_STREAM1: 7551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case AUDIO_STREAM_S ... AUDIO_STREAM_E: 7561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case VIDEO_STREAM_S ... VIDEO_STREAM_E: 7571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pes_start = 1; 7581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 7591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 7611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 7621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (c < length) { 7651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memset(obuf, 0, TS_SIZE); 7661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (length - c >= (TS_SIZE - 4)){ 7671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds l = write_ts_header2(pid, counter, pes_start, 7681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds obuf, (TS_SIZE - 4)); 7691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(obuf + l, buf + c, TS_SIZE - l); 7701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c += TS_SIZE - l; 7711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 7721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds l = write_ts_header2(pid, counter, pes_start, 7731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds obuf, length - c); 7741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(obuf + l, buf + c, TS_SIZE - l); 7751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c = length; 7761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds feed->cb.ts(obuf, 188, NULL, 0, &feed->feed.ts, DMX_OK); 7781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pes_start = 0; 7791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint av7110_write_to_decoder(struct dvb_demux_feed *feed, const u8 *buf, size_t len) 7841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 7851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct dvb_demux *demux = feed->demux; 7861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct av7110 *av7110 = (struct av7110 *) demux->priv; 7871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct ipack *ipack = &av7110->ipack[feed->pes_type]; 7881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dprintk(2, "av7110:%p, \n", av7110); 7901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (feed->pes_type) { 7921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 0: 7931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->audiostate.stream_source == AUDIO_SOURCE_MEMORY) 7941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EINVAL; 7951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 7961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 1: 7971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->videostate.stream_source == VIDEO_SOURCE_MEMORY) 7981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EINVAL; 7991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 8001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 8011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -1; 8021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!(buf[3] & 0x10)) /* no payload? */ 8051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -1; 8061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (buf[1] & 0x40) 8071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110_ipack_flush(ipack); 8081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (buf[3] & 0x20) { /* adaptation field? */ 8101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds len -= buf[4] + 1; 8111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buf += buf[4] + 1; 8121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!len) 8131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 8141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110_ipack_instant_repack(buf + 4, len - 4, &av7110->ipack[feed->pes_type]); 8171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 8181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 8191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/****************************************************************************** 8231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Video MPEG decoder events 8241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ******************************************************************************/ 8251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid dvb_video_add_event(struct av7110 *av7110, struct video_event *event) 8261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 8271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct dvb_video_events *events = &av7110->video_events; 8281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int wp; 8291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_lock_bh(&events->lock); 8311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds wp = (events->eventw + 1) % MAX_VIDEO_EVENT; 8331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (wp == events->eventr) { 8341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds events->overflow = 1; 8351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds events->eventr = (events->eventr + 1) % MAX_VIDEO_EVENT; 8361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds //FIXME: timestamp? 8391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(&events->events[events->eventw], event, sizeof(struct video_event)); 8401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds events->eventw = wp; 8411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_unlock_bh(&events->lock); 8431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds wake_up_interruptible(&events->wait_queue); 8451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 8461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int dvb_video_get_event (struct av7110 *av7110, struct video_event *event, int flags) 8491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 8501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct dvb_video_events *events = &av7110->video_events; 8511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (events->overflow) { 8531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds events->overflow = 0; 8541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EOVERFLOW; 8551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (events->eventw == events->eventr) { 8571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int ret; 8581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (flags & O_NONBLOCK) 8601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EWOULDBLOCK; 8611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ret = wait_event_interruptible(events->wait_queue, 8631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds events->eventw != events->eventr); 8641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ret < 0) 8651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ret; 8661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_lock_bh(&events->lock); 8691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(event, &events->events[events->eventr], 8711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sizeof(struct video_event)); 8721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds events->eventr = (events->eventr + 1) % MAX_VIDEO_EVENT; 8731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_unlock_bh(&events->lock); 8751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 8771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 8781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/****************************************************************************** 8811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * DVB device file operations 8821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ******************************************************************************/ 8831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic unsigned int dvb_video_poll(struct file *file, poll_table *wait) 8851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 886d9bdf77296a00538faff95f29bf238857daea2e7Tobias Klauser struct dvb_device *dvbdev = file->private_data; 887d9bdf77296a00538faff95f29bf238857daea2e7Tobias Klauser struct av7110 *av7110 = dvbdev->priv; 8881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int mask = 0; 8891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dprintk(2, "av7110:%p, \n", av7110); 8911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((file->f_flags & O_ACCMODE) != O_RDONLY) 8931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds poll_wait(file, &av7110->avout.queue, wait); 8941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds poll_wait(file, &av7110->video_events.wait_queue, wait); 8961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->video_events.eventw != av7110->video_events.eventr) 8981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mask = POLLPRI; 8991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((file->f_flags & O_ACCMODE) != O_RDONLY) { 9011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->playing) { 9021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (FREE_COND) 9031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mask |= (POLLOUT | POLLWRNORM); 9041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else /* if not playing: may play if asked for */ 9051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mask |= (POLLOUT | POLLWRNORM); 9061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 9071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return mask; 9091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 9101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic ssize_t dvb_video_write(struct file *file, const char __user *buf, 9121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds size_t count, loff_t *ppos) 9131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 914d9bdf77296a00538faff95f29bf238857daea2e7Tobias Klauser struct dvb_device *dvbdev = file->private_data; 915d9bdf77296a00538faff95f29bf238857daea2e7Tobias Klauser struct av7110 *av7110 = dvbdev->priv; 9161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dprintk(2, "av7110:%p, \n", av7110); 9181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((file->f_flags & O_ACCMODE) == O_RDONLY) 9201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EPERM; 9211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->videostate.stream_source != VIDEO_SOURCE_MEMORY) 9231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EPERM; 9241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return dvb_play(av7110, buf, count, file->f_flags & O_NONBLOCK, 1); 9261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 9271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic unsigned int dvb_audio_poll(struct file *file, poll_table *wait) 9291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 930d9bdf77296a00538faff95f29bf238857daea2e7Tobias Klauser struct dvb_device *dvbdev = file->private_data; 931d9bdf77296a00538faff95f29bf238857daea2e7Tobias Klauser struct av7110 *av7110 = dvbdev->priv; 9321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int mask = 0; 9331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dprintk(2, "av7110:%p, \n", av7110); 9351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds poll_wait(file, &av7110->aout.queue, wait); 9371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->playing) { 9391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (dvb_ringbuffer_free(&av7110->aout) >= 20 * 1024) 9401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mask |= (POLLOUT | POLLWRNORM); 9411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else /* if not playing: may play if asked for */ 9421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mask = (POLLOUT | POLLWRNORM); 9431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return mask; 9451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 9461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic ssize_t dvb_audio_write(struct file *file, const char __user *buf, 9481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds size_t count, loff_t *ppos) 9491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 950d9bdf77296a00538faff95f29bf238857daea2e7Tobias Klauser struct dvb_device *dvbdev = file->private_data; 951d9bdf77296a00538faff95f29bf238857daea2e7Tobias Klauser struct av7110 *av7110 = dvbdev->priv; 9521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dprintk(2, "av7110:%p, \n", av7110); 9541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->audiostate.stream_source != AUDIO_SOURCE_MEMORY) { 9561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_ERR "not audio source memory\n"); 9571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EPERM; 9581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 9591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return dvb_aplay(av7110, buf, count, file->f_flags & O_NONBLOCK, 0); 9601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 9611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic u8 iframe_header[] = { 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x80, 0x00, 0x00 }; 9631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define MIN_IFRAME 400000 9651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 966804b4458943f14bf144d3c3ba50097ced9b27b29Oliver Endrissstatic int play_iframe(struct av7110 *av7110, char __user *buf, unsigned int len, int nonblock) 9671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 9681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i, n; 9690ed4a6ea9dbd9f5b77ce594f7f46be022d2c49ecOliver Endriss int progressive = 0; 9701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dprintk(2, "av7110:%p, \n", av7110); 9721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!(av7110->playing & RP_VIDEO)) { 9741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110_av_start_play(av7110, RP_VIDEO) < 0) 9751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EBUSY; 9761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 9771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9780ed4a6ea9dbd9f5b77ce594f7f46be022d2c49ecOliver Endriss for (i = 0; i < len - 5; i++) { 9790ed4a6ea9dbd9f5b77ce594f7f46be022d2c49ecOliver Endriss /* get progressive flag from picture extension */ 9800ed4a6ea9dbd9f5b77ce594f7f46be022d2c49ecOliver Endriss if (buf[i] == 0x00 && buf[i+1] == 0x00 && 9810ed4a6ea9dbd9f5b77ce594f7f46be022d2c49ecOliver Endriss buf[i+2] == 0x01 && (unsigned char)buf[i+3] == 0xb5 && 9820ed4a6ea9dbd9f5b77ce594f7f46be022d2c49ecOliver Endriss (buf[i+4] & 0xf0) == 0x10) 9830ed4a6ea9dbd9f5b77ce594f7f46be022d2c49ecOliver Endriss progressive = buf[i+5] & 0x08; 9840ed4a6ea9dbd9f5b77ce594f7f46be022d2c49ecOliver Endriss } 9850ed4a6ea9dbd9f5b77ce594f7f46be022d2c49ecOliver Endriss 9861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* setting n always > 1, fixes problems when playing stillframes 9871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds consisting of I- and P-Frames */ 9881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds n = MIN_IFRAME / len + 1; 9891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* FIXME: nonblock? */ 9911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dvb_play_kernel(av7110, iframe_header, sizeof(iframe_header), 0, 1); 9921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < n; i++) 9941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dvb_play(av7110, buf, len, 0, 1); 9951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110_ipack_flush(&av7110->ipack[1]); 9970ed4a6ea9dbd9f5b77ce594f7f46be022d2c49ecOliver Endriss 9980ed4a6ea9dbd9f5b77ce594f7f46be022d2c49ecOliver Endriss if (progressive) 9990ed4a6ea9dbd9f5b77ce594f7f46be022d2c49ecOliver Endriss return vidcom(av7110, AV_VIDEO_CMD_FREEZE, 1); 10000ed4a6ea9dbd9f5b77ce594f7f46be022d2c49ecOliver Endriss else 10010ed4a6ea9dbd9f5b77ce594f7f46be022d2c49ecOliver Endriss return 0; 10021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 10031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int dvb_video_ioctl(struct inode *inode, struct file *file, 10061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int cmd, void *parg) 10071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1008d9bdf77296a00538faff95f29bf238857daea2e7Tobias Klauser struct dvb_device *dvbdev = file->private_data; 1009d9bdf77296a00538faff95f29bf238857daea2e7Tobias Klauser struct av7110 *av7110 = dvbdev->priv; 10101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long arg = (unsigned long) parg; 10111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int ret = 0; 10121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1013ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald dprintk(1, "av7110:%p, cmd=%04x\n", av7110,cmd); 10141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((file->f_flags & O_ACCMODE) == O_RDONLY) { 10161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ( cmd != VIDEO_GET_STATUS && cmd != VIDEO_GET_EVENT && 10171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cmd != VIDEO_GET_SIZE ) { 10181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EPERM; 10191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 10201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 10211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (cmd) { 10231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case VIDEO_STOP: 10241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->videostate.play_state = VIDEO_STOPPED; 10251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->videostate.stream_source == VIDEO_SOURCE_MEMORY) 1026ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = av7110_av_stop(av7110, RP_VIDEO); 10271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 10282435be11ae1afb64ac7dfb25e10b6e3037ab0522Hans Verkuil ret = vidcom(av7110, AV_VIDEO_CMD_STOP, 10291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->videostate.video_blank ? 0 : 1); 1030ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (!ret) 1031ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald av7110->trickmode = TRICK_NONE; 10321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 10331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case VIDEO_PLAY: 10351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->trickmode = TRICK_NONE; 10361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->videostate.play_state == VIDEO_FREEZED) { 10371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->videostate.play_state = VIDEO_PLAYING; 10382435be11ae1afb64ac7dfb25e10b6e3037ab0522Hans Verkuil ret = vidcom(av7110, AV_VIDEO_CMD_PLAY, 0); 1039ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (ret) 1040ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald break; 10411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 10421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->videostate.stream_source == VIDEO_SOURCE_MEMORY) { 10441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->playing == RP_AV) { 1045ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Stop, 0); 1046ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (ret) 1047ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald break; 10481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->playing &= ~RP_VIDEO; 10491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1050ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = av7110_av_start_play(av7110, RP_VIDEO); 10511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1052ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (!ret) 10532435be11ae1afb64ac7dfb25e10b6e3037ab0522Hans Verkuil ret = vidcom(av7110, AV_VIDEO_CMD_PLAY, 0); 1054ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (!ret) 1055ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald av7110->videostate.play_state = VIDEO_PLAYING; 10561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 10571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case VIDEO_FREEZE: 10591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->videostate.play_state = VIDEO_FREEZED; 10601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->playing & RP_VIDEO) 1061ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Pause, 0); 10621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 10632435be11ae1afb64ac7dfb25e10b6e3037ab0522Hans Verkuil ret = vidcom(av7110, AV_VIDEO_CMD_FREEZE, 1); 1064ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (!ret) 1065ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald av7110->trickmode = TRICK_FREEZE; 10661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 10671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case VIDEO_CONTINUE: 10691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->playing & RP_VIDEO) 1070ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Continue, 0); 1071ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (!ret) 10722435be11ae1afb64ac7dfb25e10b6e3037ab0522Hans Verkuil ret = vidcom(av7110, AV_VIDEO_CMD_PLAY, 0); 1073ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (!ret) { 1074ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald av7110->videostate.play_state = VIDEO_PLAYING; 1075ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald av7110->trickmode = TRICK_NONE; 1076ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald } 10771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 10781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case VIDEO_SELECT_SOURCE: 10801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->videostate.stream_source = (video_stream_source_t) arg; 10811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 10821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case VIDEO_SET_BLANK: 10841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->videostate.video_blank = (int) arg; 10851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 10861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case VIDEO_GET_STATUS: 10881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(parg, &av7110->videostate, sizeof(struct video_status)); 10891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 10901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case VIDEO_GET_EVENT: 1092ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = dvb_video_get_event(av7110, parg, file->f_flags); 10931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 10941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case VIDEO_GET_SIZE: 10961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(parg, &av7110->video_size, sizeof(video_size_t)); 10971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 10981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case VIDEO_SET_DISPLAY_FORMAT: 11001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 11011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds video_displayformat_t format = (video_displayformat_t) arg; 11021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (format) { 11041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case VIDEO_PAN_SCAN: 1105defd574ec07edaa1587da144d03b18495ab484b1Oliver Endriss av7110->display_panscan = VID_PAN_SCAN_PREF; 11061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 11071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case VIDEO_LETTER_BOX: 1109defd574ec07edaa1587da144d03b18495ab484b1Oliver Endriss av7110->display_panscan = VID_VC_AND_PS_PREF; 11101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 11111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case VIDEO_CENTER_CUT_OUT: 1113defd574ec07edaa1587da144d03b18495ab484b1Oliver Endriss av7110->display_panscan = VID_CENTRE_CUT_PREF; 11141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 11151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 11171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ret = -EINVAL; 11181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 11191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ret < 0) 11201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 1121a65d3bb7177cbab1fca69dd97537766c2817b6b2Johannes Stezenbach av7110->videostate.display_format = format; 11221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ret = av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetPanScanType, 1123defd574ec07edaa1587da144d03b18495ab484b1Oliver Endriss 1, av7110->display_panscan); 11241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 11251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 11261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case VIDEO_SET_FORMAT: 11281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (arg > 1) { 11291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ret = -EINVAL; 11301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 11311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 11321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->display_ar = arg; 11331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ret = av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetMonitorType, 11341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1, (u16) arg); 11351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 11361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case VIDEO_STILLPICTURE: 11381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 11391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct video_still_picture *pic = 11401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (struct video_still_picture *) parg; 11411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->videostate.stream_source = VIDEO_SOURCE_MEMORY; 11421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dvb_ringbuffer_flush_spinlock_wakeup(&av7110->avout); 11431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ret = play_iframe(av7110, pic->iFrame, pic->size, 11441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds file->f_flags & O_NONBLOCK); 11451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 11461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 11471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case VIDEO_FAST_FORWARD: 11491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds //note: arg is ignored by firmware 11501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->playing & RP_VIDEO) 1151ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, 11527a2fa90fa8084846937aa194f8a40abfa99c692fJohannes Stezenbach __Scan_I, 2, AV_PES, 0); 11531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 11542435be11ae1afb64ac7dfb25e10b6e3037ab0522Hans Verkuil ret = vidcom(av7110, AV_VIDEO_CMD_FFWD, arg); 1155ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (!ret) { 1156ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald av7110->trickmode = TRICK_FAST; 1157ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald av7110->videostate.play_state = VIDEO_PLAYING; 1158ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald } 11591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 11601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case VIDEO_SLOWMOTION: 11621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->playing&RP_VIDEO) { 1163ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Slow, 2, 0, 0); 1164ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (!ret) 11652435be11ae1afb64ac7dfb25e10b6e3037ab0522Hans Verkuil ret = vidcom(av7110, AV_VIDEO_CMD_SLOW, arg); 11661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 11672435be11ae1afb64ac7dfb25e10b6e3037ab0522Hans Verkuil ret = vidcom(av7110, AV_VIDEO_CMD_PLAY, 0); 1168ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (!ret) 11692435be11ae1afb64ac7dfb25e10b6e3037ab0522Hans Verkuil ret = vidcom(av7110, AV_VIDEO_CMD_STOP, 0); 1170ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (!ret) 11712435be11ae1afb64ac7dfb25e10b6e3037ab0522Hans Verkuil ret = vidcom(av7110, AV_VIDEO_CMD_SLOW, arg); 1172ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald } 1173ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (!ret) { 1174ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald av7110->trickmode = TRICK_SLOW; 1175ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald av7110->videostate.play_state = VIDEO_PLAYING; 11761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 11771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 11781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case VIDEO_GET_CAPABILITIES: 11801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *(int *)parg = VIDEO_CAP_MPEG1 | VIDEO_CAP_MPEG2 | 11811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds VIDEO_CAP_SYS | VIDEO_CAP_PROG; 11821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 11831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case VIDEO_CLEAR_BUFFER: 11851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dvb_ringbuffer_flush_spinlock_wakeup(&av7110->avout); 11861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110_ipack_reset(&av7110->ipack[1]); 11871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->playing == RP_AV) { 1189ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, 11907a2fa90fa8084846937aa194f8a40abfa99c692fJohannes Stezenbach __Play, 2, AV_PES, 0); 1191ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (ret) 1192ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald break; 11931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->trickmode == TRICK_FAST) 1194ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, 11957a2fa90fa8084846937aa194f8a40abfa99c692fJohannes Stezenbach __Scan_I, 2, AV_PES, 0); 11961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->trickmode == TRICK_SLOW) { 1197ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, 11987a2fa90fa8084846937aa194f8a40abfa99c692fJohannes Stezenbach __Slow, 2, 0, 0); 1199ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (!ret) 12002435be11ae1afb64ac7dfb25e10b6e3037ab0522Hans Verkuil ret = vidcom(av7110, AV_VIDEO_CMD_SLOW, arg); 12011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 12021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->trickmode == TRICK_FREEZE) 12032435be11ae1afb64ac7dfb25e10b6e3037ab0522Hans Verkuil ret = vidcom(av7110, AV_VIDEO_CMD_STOP, 1); 12041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 12051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 12061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case VIDEO_SET_STREAMTYPE: 12081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 12101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 12121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ret = -ENOIOCTLCMD; 12131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 12141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 12151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ret; 12161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 12171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int dvb_audio_ioctl(struct inode *inode, struct file *file, 12191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int cmd, void *parg) 12201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1221d9bdf77296a00538faff95f29bf238857daea2e7Tobias Klauser struct dvb_device *dvbdev = file->private_data; 1222d9bdf77296a00538faff95f29bf238857daea2e7Tobias Klauser struct av7110 *av7110 = dvbdev->priv; 12231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long arg = (unsigned long) parg; 12241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int ret = 0; 12251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1226ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald dprintk(1, "av7110:%p, cmd=%04x\n", av7110,cmd); 12271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (((file->f_flags & O_ACCMODE) == O_RDONLY) && 12291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (cmd != AUDIO_GET_STATUS)) 12301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EPERM; 12311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (cmd) { 12331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case AUDIO_STOP: 12341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->audiostate.stream_source == AUDIO_SOURCE_MEMORY) 1235ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = av7110_av_stop(av7110, RP_AUDIO); 12361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 1237ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = audcom(av7110, AUDIO_CMD_MUTE); 1238ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (!ret) 1239ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald av7110->audiostate.play_state = AUDIO_STOPPED; 12401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 12411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case AUDIO_PLAY: 12431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->audiostate.stream_source == AUDIO_SOURCE_MEMORY) 1244ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = av7110_av_start_play(av7110, RP_AUDIO); 1245ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (!ret) 1246ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = audcom(av7110, AUDIO_CMD_UNMUTE); 1247ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (!ret) 1248ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald av7110->audiostate.play_state = AUDIO_PLAYING; 12491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 12501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case AUDIO_PAUSE: 1252ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = audcom(av7110, AUDIO_CMD_MUTE); 1253ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (!ret) 1254ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald av7110->audiostate.play_state = AUDIO_PAUSED; 12551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 12561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case AUDIO_CONTINUE: 12581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->audiostate.play_state == AUDIO_PAUSED) { 12591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->audiostate.play_state = AUDIO_PLAYING; 1260ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = audcom(av7110, AUDIO_CMD_UNMUTE | AUDIO_CMD_PCM16); 12611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 12621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 12631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case AUDIO_SELECT_SOURCE: 12651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->audiostate.stream_source = (audio_stream_source_t) arg; 12661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 12671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case AUDIO_SET_MUTE: 12691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 1270ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = audcom(av7110, arg ? AUDIO_CMD_MUTE : AUDIO_CMD_UNMUTE); 1271ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (!ret) 1272ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald av7110->audiostate.mute_state = (int) arg; 12731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 12741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 12751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case AUDIO_SET_AV_SYNC: 12771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->audiostate.AV_sync_state = (int) arg; 1278ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = audcom(av7110, arg ? AUDIO_CMD_SYNC_ON : AUDIO_CMD_SYNC_OFF); 12791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 12801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case AUDIO_SET_BYPASS_MODE: 128247f3692096eef208d8cb455bfa2b3308cdfc40deDr. Werner Fink if (FW_VERSION(av7110->arm_app) < 0x2621) 128347f3692096eef208d8cb455bfa2b3308cdfc40deDr. Werner Fink ret = -EINVAL; 128447f3692096eef208d8cb455bfa2b3308cdfc40deDr. Werner Fink av7110->audiostate.bypass_mode = (int)arg; 12851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 12861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case AUDIO_CHANNEL_SELECT: 12881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->audiostate.channel_select = (audio_channel_select_t) arg; 12891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch(av7110->audiostate.channel_select) { 12911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case AUDIO_STEREO: 1292ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = audcom(av7110, AUDIO_CMD_STEREO); 129361391e0446e97bea44d93bd1624e5b32d3cc8474Tim Kaiser if (!ret) { 1294ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (av7110->adac_type == DVB_ADAC_CRYSTAL) 1295ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald i2c_writereg(av7110, 0x20, 0x02, 0x49); 129661391e0446e97bea44d93bd1624e5b32d3cc8474Tim Kaiser else if (av7110->adac_type == DVB_ADAC_MSP34x5) 129761391e0446e97bea44d93bd1624e5b32d3cc8474Tim Kaiser msp_writereg(av7110, MSP_WR_DSP, 0x0008, 0x0220); 129861391e0446e97bea44d93bd1624e5b32d3cc8474Tim Kaiser } 12991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 13001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case AUDIO_MONO_LEFT: 1302ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = audcom(av7110, AUDIO_CMD_MONO_L); 130361391e0446e97bea44d93bd1624e5b32d3cc8474Tim Kaiser if (!ret) { 1304ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (av7110->adac_type == DVB_ADAC_CRYSTAL) 1305ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald i2c_writereg(av7110, 0x20, 0x02, 0x4a); 130661391e0446e97bea44d93bd1624e5b32d3cc8474Tim Kaiser else if (av7110->adac_type == DVB_ADAC_MSP34x5) 130761391e0446e97bea44d93bd1624e5b32d3cc8474Tim Kaiser msp_writereg(av7110, MSP_WR_DSP, 0x0008, 0x0200); 130861391e0446e97bea44d93bd1624e5b32d3cc8474Tim Kaiser } 13091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 13101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case AUDIO_MONO_RIGHT: 1312ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = audcom(av7110, AUDIO_CMD_MONO_R); 131361391e0446e97bea44d93bd1624e5b32d3cc8474Tim Kaiser if (!ret) { 1314ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (av7110->adac_type == DVB_ADAC_CRYSTAL) 1315ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald i2c_writereg(av7110, 0x20, 0x02, 0x45); 131661391e0446e97bea44d93bd1624e5b32d3cc8474Tim Kaiser else if (av7110->adac_type == DVB_ADAC_MSP34x5) 131761391e0446e97bea44d93bd1624e5b32d3cc8474Tim Kaiser msp_writereg(av7110, MSP_WR_DSP, 0x0008, 0x0210); 131861391e0446e97bea44d93bd1624e5b32d3cc8474Tim Kaiser } 13191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 13201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 13221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ret = -EINVAL; 13231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 13241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 13251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 13261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case AUDIO_GET_STATUS: 13281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(parg, &av7110->audiostate, sizeof(struct audio_status)); 13291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 13301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case AUDIO_GET_CAPABILITIES: 133247f3692096eef208d8cb455bfa2b3308cdfc40deDr. Werner Fink if (FW_VERSION(av7110->arm_app) < 0x2621) 133347f3692096eef208d8cb455bfa2b3308cdfc40deDr. Werner Fink *(unsigned int *)parg = AUDIO_CAP_LPCM | AUDIO_CAP_MP1 | AUDIO_CAP_MP2; 133447f3692096eef208d8cb455bfa2b3308cdfc40deDr. Werner Fink else 133547f3692096eef208d8cb455bfa2b3308cdfc40deDr. Werner Fink *(unsigned int *)parg = AUDIO_CAP_LPCM | AUDIO_CAP_DTS | AUDIO_CAP_AC3 | 133647f3692096eef208d8cb455bfa2b3308cdfc40deDr. Werner Fink AUDIO_CAP_MP1 | AUDIO_CAP_MP2; 13371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 13381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case AUDIO_CLEAR_BUFFER: 13401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dvb_ringbuffer_flush_spinlock_wakeup(&av7110->aout); 13411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110_ipack_reset(&av7110->ipack[0]); 13421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->playing == RP_AV) 1343ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, 13447a2fa90fa8084846937aa194f8a40abfa99c692fJohannes Stezenbach __Play, 2, AV_PES, 0); 13451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 13461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case AUDIO_SET_ID: 13471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 13491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case AUDIO_SET_MIXER: 13501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 13511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct audio_mixer *amix = (struct audio_mixer *)parg; 13521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1353ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = av7110_set_volume(av7110, amix->volume_left, amix->volume_right); 13541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 13551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 13561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case AUDIO_SET_STREAMTYPE: 13571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 13581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 13591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ret = -ENOIOCTLCMD; 13601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 13611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ret; 13621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 13631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int dvb_video_open(struct inode *inode, struct file *file) 13661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1367d9bdf77296a00538faff95f29bf238857daea2e7Tobias Klauser struct dvb_device *dvbdev = file->private_data; 1368d9bdf77296a00538faff95f29bf238857daea2e7Tobias Klauser struct av7110 *av7110 = dvbdev->priv; 13691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int err; 13701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dprintk(2, "av7110:%p, \n", av7110); 13721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((err = dvb_generic_open(inode, file)) < 0) 13741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return err; 13751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((file->f_flags & O_ACCMODE) != O_RDONLY) { 13771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dvb_ringbuffer_flush_spinlock_wakeup(&av7110->aout); 13781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dvb_ringbuffer_flush_spinlock_wakeup(&av7110->avout); 13791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->video_blank = 1; 13801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->audiostate.AV_sync_state = 1; 13811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->videostate.stream_source = VIDEO_SOURCE_DEMUX; 13821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* empty event queue */ 13841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->video_events.eventr = av7110->video_events.eventw = 0; 13851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 13861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 13881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 13891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int dvb_video_release(struct inode *inode, struct file *file) 13911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1392d9bdf77296a00538faff95f29bf238857daea2e7Tobias Klauser struct dvb_device *dvbdev = file->private_data; 1393d9bdf77296a00538faff95f29bf238857daea2e7Tobias Klauser struct av7110 *av7110 = dvbdev->priv; 13941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dprintk(2, "av7110:%p, \n", av7110); 13961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((file->f_flags & O_ACCMODE) != O_RDONLY) { 13981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110_av_stop(av7110, RP_VIDEO); 13991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 14001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return dvb_generic_release(inode, file); 14021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 14031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int dvb_audio_open(struct inode *inode, struct file *file) 14051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1406d9bdf77296a00538faff95f29bf238857daea2e7Tobias Klauser struct dvb_device *dvbdev = file->private_data; 1407d9bdf77296a00538faff95f29bf238857daea2e7Tobias Klauser struct av7110 *av7110 = dvbdev->priv; 1408d9bdf77296a00538faff95f29bf238857daea2e7Tobias Klauser int err = dvb_generic_open(inode, file); 14091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dprintk(2, "av7110:%p, \n", av7110); 14111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (err < 0) 14131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return err; 14141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dvb_ringbuffer_flush_spinlock_wakeup(&av7110->aout); 14151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->audiostate.stream_source = AUDIO_SOURCE_DEMUX; 14161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 14171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 14181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int dvb_audio_release(struct inode *inode, struct file *file) 14201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1421d9bdf77296a00538faff95f29bf238857daea2e7Tobias Klauser struct dvb_device *dvbdev = file->private_data; 1422d9bdf77296a00538faff95f29bf238857daea2e7Tobias Klauser struct av7110 *av7110 = dvbdev->priv; 14231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dprintk(2, "av7110:%p, \n", av7110); 14251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110_av_stop(av7110, RP_AUDIO); 14271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return dvb_generic_release(inode, file); 14281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 14291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/****************************************************************************** 14331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * driver registration 14341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ******************************************************************************/ 14351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct file_operations dvb_video_fops = { 14371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .owner = THIS_MODULE, 14381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .write = dvb_video_write, 14391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .ioctl = dvb_generic_ioctl, 14401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .open = dvb_video_open, 14411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .release = dvb_video_release, 14421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .poll = dvb_video_poll, 14431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 14441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct dvb_device dvbdev_video = { 14461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .priv = NULL, 14471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .users = 6, 14481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .readers = 5, /* arbitrary */ 14491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .writers = 1, 14501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .fops = &dvb_video_fops, 14511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .kernel_ioctl = dvb_video_ioctl, 14521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 14531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct file_operations dvb_audio_fops = { 14551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .owner = THIS_MODULE, 14561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .write = dvb_audio_write, 14571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .ioctl = dvb_generic_ioctl, 14581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .open = dvb_audio_open, 14591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .release = dvb_audio_release, 14601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .poll = dvb_audio_poll, 14611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 14621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct dvb_device dvbdev_audio = { 14641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .priv = NULL, 14651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .users = 1, 14661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .writers = 1, 14671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .fops = &dvb_audio_fops, 14681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .kernel_ioctl = dvb_audio_ioctl, 14691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 14701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint av7110_av_register(struct av7110 *av7110) 14731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 14741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->audiostate.AV_sync_state = 0; 14751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->audiostate.mute_state = 0; 14761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->audiostate.play_state = AUDIO_STOPPED; 14771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->audiostate.stream_source = AUDIO_SOURCE_DEMUX; 14781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->audiostate.channel_select = AUDIO_STEREO; 14791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->audiostate.bypass_mode = 0; 14801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->videostate.video_blank = 0; 14821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->videostate.play_state = VIDEO_STOPPED; 14831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->videostate.stream_source = VIDEO_SOURCE_DEMUX; 14841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->videostate.video_format = VIDEO_FORMAT_4_3; 1485defd574ec07edaa1587da144d03b18495ab484b1Oliver Endriss av7110->videostate.display_format = VIDEO_LETTER_BOX; 14861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->display_ar = VIDEO_FORMAT_4_3; 1487defd574ec07edaa1587da144d03b18495ab484b1Oliver Endriss av7110->display_panscan = VID_VC_AND_PS_PREF; 14881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds init_waitqueue_head(&av7110->video_events.wait_queue); 14901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_lock_init(&av7110->video_events.lock); 14911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->video_events.eventw = av7110->video_events.eventr = 0; 14921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->video_events.overflow = 0; 14931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memset(&av7110->video_size, 0, sizeof (video_size_t)); 14941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1495fdc53a6dbfea18e621dd23ed5cfb160837d7ce52Johannes Stezenbach dvb_register_device(&av7110->dvb_adapter, &av7110->video_dev, 14961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds &dvbdev_video, av7110, DVB_DEVICE_VIDEO); 14971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1498fdc53a6dbfea18e621dd23ed5cfb160837d7ce52Johannes Stezenbach dvb_register_device(&av7110->dvb_adapter, &av7110->audio_dev, 14991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds &dvbdev_audio, av7110, DVB_DEVICE_AUDIO); 15001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 15021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 15031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid av7110_av_unregister(struct av7110 *av7110) 15051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 15061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dvb_unregister_device(av7110->audio_dev); 15071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dvb_unregister_device(av7110->video_dev); 15081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 15091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint av7110_av_init(struct av7110 *av7110) 15111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 15121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds void (*play[])(u8 *, int, void *) = { play_audio_cb, play_video_cb }; 15131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i, ret; 15141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < 2; i++) { 15161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct ipack *ipack = av7110->ipack + i; 15171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ret = av7110_ipack_init(ipack, IPACKS, play[i]); 15191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ret < 0) { 15201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (i) 15211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110_ipack_free(--ipack); 15221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out; 15231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 15241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ipack->data = av7110; 15251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 15261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dvb_ringbuffer_init(&av7110->avout, av7110->iobuf, AVOUTLEN); 15281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dvb_ringbuffer_init(&av7110->aout, av7110->iobuf + AVOUTLEN, AOUTLEN); 15291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->kbuf[0] = (u8 *)(av7110->iobuf + AVOUTLEN + AOUTLEN + BMPLEN); 15311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->kbuf[1] = av7110->kbuf[0] + 2 * IPACKS; 15321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsout: 15331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ret; 15341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 15351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid av7110_av_exit(struct av7110 *av7110) 15371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 15381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110_ipack_free(&av7110->ipack[0]); 15391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110_ipack_free(&av7110->ipack[1]); 15401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1541