av7110_av.c revision ef226d00dd041f753163fd3b69c7790496ab8384
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); 92fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endrissstatic int write_ts_to_decoder(struct av7110 *av7110, int type, const u8 *buf, size_t len); 931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint av7110_record_cb(struct dvb_filter_pes2ts *p2t, u8 *buf, size_t len) 961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *) p2t->priv; 981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!(dvbdmxfeed->ts_type & TS_PACKET)) 1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (buf[3] == 0xe0) // video PES do not have a length in TS 1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buf[4] = buf[5] = 0; 1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (dvbdmxfeed->ts_type & TS_PAYLOAD_ONLY) 1041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return dvbdmxfeed->cb.ts(buf, len, NULL, 0, 1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds &dvbdmxfeed->feed.ts, DMX_OK); 1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return dvb_filter_pes2ts(p2t, buf, len, 1); 1081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int dvb_filter_pes2ts_cb(void *priv, unsigned char *data) 1111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *) priv; 1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dvbdmxfeed->cb.ts(data, 188, NULL, 0, 1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds &dvbdmxfeed->feed.ts, DMX_OK); 1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint av7110_av_start_record(struct av7110 *av7110, int av, 1201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct dvb_demux_feed *dvbdmxfeed) 1211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 122ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald int ret = 0; 1231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct dvb_demux *dvbdmx = dvbdmxfeed->demux; 1241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dprintk(2, "av7110:%p, , dvb_demux_feed:%p\n", av7110, dvbdmxfeed); 1261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->playing || (av7110->rec_mode & av)) 1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EBUSY; 1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Stop, 0); 1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dvbdmx->recording = 1; 1311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->rec_mode |= av; 1321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (av7110->rec_mode) { 1341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case RP_AUDIO: 1351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dvb_filter_pes2ts_init(&av7110->p2t[0], 1361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dvbdmx->pesfilter[0]->pid, 1371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dvb_filter_pes2ts_cb, 1381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (void *) dvbdmx->pesfilter[0]); 139ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Record, 2, AudioPES, 0); 1401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 1411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case RP_VIDEO: 1431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dvb_filter_pes2ts_init(&av7110->p2t[1], 1441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dvbdmx->pesfilter[1]->pid, 1451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dvb_filter_pes2ts_cb, 1461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (void *) dvbdmx->pesfilter[1]); 147ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Record, 2, VideoPES, 0); 1481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 1491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case RP_AV: 1511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dvb_filter_pes2ts_init(&av7110->p2t[0], 1521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dvbdmx->pesfilter[0]->pid, 1531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dvb_filter_pes2ts_cb, 1541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (void *) dvbdmx->pesfilter[0]); 1551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dvb_filter_pes2ts_init(&av7110->p2t[1], 1561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dvbdmx->pesfilter[1]->pid, 1571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dvb_filter_pes2ts_cb, 1581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (void *) dvbdmx->pesfilter[1]); 159ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Record, 2, AV_PES, 0); 1601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 1611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 162ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald return ret; 1631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint av7110_av_start_play(struct av7110 *av7110, int av) 1661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 167ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald int ret = 0; 1681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dprintk(2, "av7110:%p, \n", av7110); 1691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->rec_mode) 1711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EBUSY; 1721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->playing & av) 1731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EBUSY; 1741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Stop, 0); 1761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->playing == RP_NONE) { 1781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110_ipack_reset(&av7110->ipack[0]); 1791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110_ipack_reset(&av7110->ipack[1]); 1801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->playing |= av; 1831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (av7110->playing) { 1841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case RP_AUDIO: 185ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Play, 2, AudioPES, 0); 1861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 1871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case RP_VIDEO: 188ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Play, 2, VideoPES, 0); 1891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->sinfo = 0; 1901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 1911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case RP_AV: 1921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->sinfo = 0; 193ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Play, 2, AV_PES, 0); 1941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 1951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 196ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (!ret) 197ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = av7110->playing; 198ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald return ret; 1991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 201ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewaldint av7110_av_stop(struct av7110 *av7110, int av) 2021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 203ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald int ret = 0; 2041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dprintk(2, "av7110:%p, \n", av7110); 2051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!(av7110->playing & av) && !(av7110->rec_mode & av)) 207ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald return 0; 2081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Stop, 0); 2091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->playing) { 2101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->playing &= ~av; 2111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (av7110->playing) { 2121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case RP_AUDIO: 213ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Play, 2, AudioPES, 0); 2141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 2151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case RP_VIDEO: 216ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Play, 2, VideoPES, 0); 2171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 2181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case RP_NONE: 219ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = av7110_set_vidmode(av7110, av7110->vidmode); 2201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 2211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 2231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->rec_mode &= ~av; 2241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (av7110->rec_mode) { 2251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case RP_AUDIO: 226ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Record, 2, AudioPES, 0); 2271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 2281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case RP_VIDEO: 229ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Record, 2, VideoPES, 0); 2301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 2311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case RP_NONE: 2321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 2331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 235ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald return ret; 2361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint av7110_pes_play(void *dest, struct dvb_ringbuffer *buf, int dlen) 2401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int len; 2421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u32 sync; 2431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u16 blen; 2441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!dlen) { 2461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds wake_up(&buf->queue); 2471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -1; 2481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (1) { 2501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((len = dvb_ringbuffer_avail(buf)) < 6) 2511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -1; 2521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sync = DVB_RINGBUFFER_PEEK(buf, 0) << 24; 2531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sync |= DVB_RINGBUFFER_PEEK(buf, 1) << 16; 2541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sync |= DVB_RINGBUFFER_PEEK(buf, 2) << 8; 2551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sync |= DVB_RINGBUFFER_PEEK(buf, 3); 2561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (((sync &~ 0x0f) == 0x000001e0) || 2581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ((sync &~ 0x1f) == 0x000001c0) || 2591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (sync == 0x000001bd)) 2601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 2611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk("resync\n"); 2621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DVB_RINGBUFFER_SKIP(buf, 1); 2631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds blen = DVB_RINGBUFFER_PEEK(buf, 4) << 8; 2651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds blen |= DVB_RINGBUFFER_PEEK(buf, 5); 2661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds blen += 6; 2671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (len < blen || blen > dlen) { 2681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds //printk("buffer empty - avail %d blen %u dlen %d\n", len, blen, dlen); 2691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds wake_up(&buf->queue); 2701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -1; 2711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 273b0ba0e3ab6f452321771325b7b5578f9a804f69eAl Viro dvb_ringbuffer_read(buf, dest, (size_t) blen); 2741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dprintk(2, "pread=0x%08lx, pwrite=0x%08lx\n", 2761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (unsigned long) buf->pread, (unsigned long) buf->pwrite); 2771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds wake_up(&buf->queue); 2781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return blen; 2791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint av7110_set_volume(struct av7110 *av7110, int volleft, int volright) 2831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int err, vol, val, balance = 0; 2851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dprintk(2, "av7110:%p, \n", av7110); 2871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->mixer.volume_left = volleft; 2891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->mixer.volume_right = volright; 2901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (av7110->adac_type) { 2921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case DVB_ADAC_TI: 2931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds volleft = (volleft * 256) / 1036; 2941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds volright = (volright * 256) / 1036; 2951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (volleft > 0x3f) 2961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds volleft = 0x3f; 2971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (volright > 0x3f) 2981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds volright = 0x3f; 2991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((err = SendDAC(av7110, 3, 0x80 + volleft))) 3001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return err; 3011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return SendDAC(av7110, 4, volright); 3021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case DVB_ADAC_CRYSTAL: 3041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds volleft = 127 - volleft / 2; 3051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds volright = 127 - volright / 2; 3061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds i2c_writereg(av7110, 0x20, 0x03, volleft); 3071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds i2c_writereg(av7110, 0x20, 0x04, volright); 3081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 3091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3101c13b95c7d22d5c552246b465da4b364ba00ba65Marco Schluessler case DVB_ADAC_MSP34x0: 3111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds vol = (volleft > volright) ? volleft : volright; 3121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds val = (vol * 0x73 / 255) << 8; 3131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (vol > 0) 3141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds balance = ((volright - volleft) * 127) / vol; 3151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds msp_writereg(av7110, MSP_WR_DSP, 0x0001, balance << 8); 3161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds msp_writereg(av7110, MSP_WR_DSP, 0x0000, val); /* loudspeaker */ 3171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds msp_writereg(av7110, MSP_WR_DSP, 0x0006, val); /* headphonesr */ 3181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 31961391e0446e97bea44d93bd1624e5b32d3cc8474Tim Kaiser 32061391e0446e97bea44d93bd1624e5b32d3cc8474Tim Kaiser case DVB_ADAC_MSP34x5: 32161391e0446e97bea44d93bd1624e5b32d3cc8474Tim Kaiser vol = (volleft > volright) ? volleft : volright; 32261391e0446e97bea44d93bd1624e5b32d3cc8474Tim Kaiser val = (vol * 0x73 / 255) << 8; 32361391e0446e97bea44d93bd1624e5b32d3cc8474Tim Kaiser if (vol > 0) 32461391e0446e97bea44d93bd1624e5b32d3cc8474Tim Kaiser balance = ((volright - volleft) * 127) / vol; 32561391e0446e97bea44d93bd1624e5b32d3cc8474Tim Kaiser msp_writereg(av7110, MSP_WR_DSP, 0x0001, balance << 8); 32661391e0446e97bea44d93bd1624e5b32d3cc8474Tim Kaiser msp_writereg(av7110, MSP_WR_DSP, 0x0000, val); /* loudspeaker */ 32761391e0446e97bea44d93bd1624e5b32d3cc8474Tim Kaiser return 0; 3281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 32961391e0446e97bea44d93bd1624e5b32d3cc8474Tim Kaiser 3301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 3311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 33358a44040b4937c7d16b79a1b3048992eeac9853bMarco Schluesslerint av7110_set_vidmode(struct av7110 *av7110, enum av7110_video_mode mode) 3341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 335ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald int ret; 3361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dprintk(2, "av7110:%p, \n", av7110); 3371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 338ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = av7110_fw_cmd(av7110, COMTYPE_ENCODER, LoadVidCode, 1, mode); 3391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 340ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (!ret && !av7110->playing) { 341ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = ChangePIDs(av7110, av7110->pids[DMX_PES_VIDEO], 3421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->pids[DMX_PES_AUDIO], 3431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->pids[DMX_PES_TELETEXT], 3441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0, av7110->pids[DMX_PES_PCR]); 345ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (!ret) 346ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, Scan, 0); 3471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 348ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald return ret; 3491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 35258a44040b4937c7d16b79a1b3048992eeac9853bMarco Schluesslerstatic enum av7110_video_mode sw2mode[16] = { 35358a44040b4937c7d16b79a1b3048992eeac9853bMarco Schluessler AV7110_VIDEO_MODE_PAL, AV7110_VIDEO_MODE_NTSC, 35458a44040b4937c7d16b79a1b3048992eeac9853bMarco Schluessler AV7110_VIDEO_MODE_NTSC, AV7110_VIDEO_MODE_PAL, 35558a44040b4937c7d16b79a1b3048992eeac9853bMarco Schluessler AV7110_VIDEO_MODE_NTSC, AV7110_VIDEO_MODE_NTSC, 35658a44040b4937c7d16b79a1b3048992eeac9853bMarco Schluessler AV7110_VIDEO_MODE_PAL, AV7110_VIDEO_MODE_NTSC, 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, 36058a44040b4937c7d16b79a1b3048992eeac9853bMarco Schluessler AV7110_VIDEO_MODE_PAL, AV7110_VIDEO_MODE_PAL, 3611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 3621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 363ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewaldstatic int get_video_format(struct av7110 *av7110, u8 *buf, int count) 3641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 3661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int hsize, vsize; 3671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int sw; 3681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 *p; 369ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald int ret = 0; 3701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dprintk(2, "av7110:%p, \n", av7110); 3721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->sinfo) 374ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald return 0; 3751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 7; i < count - 10; i++) { 3761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p = buf + i; 3771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (p[0] || p[1] || p[2] != 0x01 || p[3] != 0xb3) 3781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds continue; 3791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p += 4; 3801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hsize = ((p[1] &0xF0) >> 4) | (p[0] << 4); 3811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds vsize = ((p[1] &0x0F) << 8) | (p[2]); 3821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sw = (p[3] & 0x0F); 383ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = av7110_set_vidmode(av7110, sw2mode[sw]); 384ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (!ret) { 385ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald dprintk(2, "playback %dx%d fr=%d\n", hsize, vsize, sw); 386ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald av7110->sinfo = 1; 387ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald } 3881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 3891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 390ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald return ret; 3911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/**************************************************************************** 3951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * I/O buffer management and control 3961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ****************************************************************************/ 3971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline long aux_ring_buffer_write(struct dvb_ringbuffer *rbuf, 399804b4458943f14bf144d3c3ba50097ced9b27b29Oliver Endriss const u8 *buf, unsigned long count) 4001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long todo = count; 4021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int free; 4031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (todo > 0) { 4051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (dvb_ringbuffer_free(rbuf) < 2048) { 4061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (wait_event_interruptible(rbuf->queue, 4071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (dvb_ringbuffer_free(rbuf) >= 2048))) 4081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count - todo; 4091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds free = dvb_ringbuffer_free(rbuf); 4111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (free > todo) 4121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds free = todo; 4131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dvb_ringbuffer_write(rbuf, buf, free); 4141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds todo -= free; 4151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buf += free; 4161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count - todo; 4191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void play_video_cb(u8 *buf, int count, void *priv) 4221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct av7110 *av7110 = (struct av7110 *) priv; 4241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dprintk(2, "av7110:%p, \n", av7110); 4251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((buf[3] & 0xe0) == 0xe0) { 4271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds get_video_format(av7110, buf, count); 4281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds aux_ring_buffer_write(&av7110->avout, buf, count); 4291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else 4301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds aux_ring_buffer_write(&av7110->aout, buf, count); 4311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void play_audio_cb(u8 *buf, int count, void *priv) 4341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct av7110 *av7110 = (struct av7110 *) priv; 4361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dprintk(2, "av7110:%p, \n", av7110); 4371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds aux_ring_buffer_write(&av7110->aout, buf, count); 4391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 441fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss 442fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss#define FREE_COND_TS (dvb_ringbuffer_free(rb) >= 4096) 443fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss 444fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endrissstatic ssize_t ts_play(struct av7110 *av7110, const char __user *buf, 445fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss unsigned long count, int nonblock, int type) 446fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss{ 447fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss struct dvb_ringbuffer *rb; 448fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss u8 *kb; 449fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss unsigned long todo = count; 450fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss 451fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss dprintk(2, "%s: type %d cnt %lu\n", __func__, type, count); 452fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss 453fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss rb = (type) ? &av7110->avout : &av7110->aout; 454fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss kb = av7110->kbuf[type]; 455fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss 456fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss if (!kb) 457fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss return -ENOBUFS; 458fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss 459fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss if (nonblock && !FREE_COND_TS) 460fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss return -EWOULDBLOCK; 461fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss 462fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss while (todo >= TS_SIZE) { 463fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss if (!FREE_COND_TS) { 464fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss if (nonblock) 465fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss return count - todo; 466fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss if (wait_event_interruptible(rb->queue, FREE_COND_TS)) 467fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss return count - todo; 468fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss } 469fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss if (copy_from_user(kb, buf, TS_SIZE)) 470fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss return -EFAULT; 471fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss write_ts_to_decoder(av7110, type, kb, TS_SIZE); 472fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss todo -= TS_SIZE; 473fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss buf += TS_SIZE; 474fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss } 475fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss 476fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss return count - todo; 477fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss} 478fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss 479fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss 4801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define FREE_COND (dvb_ringbuffer_free(&av7110->avout) >= 20 * 1024 && \ 4811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dvb_ringbuffer_free(&av7110->aout) >= 20 * 1024) 4821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 483804b4458943f14bf144d3c3ba50097ced9b27b29Oliver Endrissstatic ssize_t dvb_play(struct av7110 *av7110, const char __user *buf, 4841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long count, int nonblock, int type) 4851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long todo = count, n; 4871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dprintk(2, "av7110:%p, \n", av7110); 4881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!av7110->kbuf[type]) 4901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -ENOBUFS; 4911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (nonblock && !FREE_COND) 4931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EWOULDBLOCK; 4941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (todo > 0) { 4961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!FREE_COND) { 4971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (nonblock) 4981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count - todo; 4991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (wait_event_interruptible(av7110->avout.queue, 5001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FREE_COND)) 5011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count - todo; 5021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds n = todo; 5041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (n > IPACKS * 2) 5051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds n = IPACKS * 2; 5061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (copy_from_user(av7110->kbuf[type], buf, n)) 5071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EFAULT; 5081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110_ipack_instant_repack(av7110->kbuf[type], n, 5091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds &av7110->ipack[type]); 5101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds todo -= n; 5111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buf += n; 5121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count - todo; 5141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic ssize_t dvb_play_kernel(struct av7110 *av7110, const u8 *buf, 5171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long count, int nonblock, int type) 5181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 5191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long todo = count, n; 5201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dprintk(2, "av7110:%p, \n", av7110); 5211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!av7110->kbuf[type]) 5231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -ENOBUFS; 5241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (nonblock && !FREE_COND) 5261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EWOULDBLOCK; 5271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (todo > 0) { 5291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!FREE_COND) { 5301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (nonblock) 5311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count - todo; 5321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (wait_event_interruptible(av7110->avout.queue, 5331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FREE_COND)) 5341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count - todo; 5351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds n = todo; 5371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (n > IPACKS * 2) 5381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds n = IPACKS * 2; 5391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110_ipack_instant_repack(buf, n, &av7110->ipack[type]); 5401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds todo -= n; 5411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buf += n; 5421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count - todo; 5441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 546804b4458943f14bf144d3c3ba50097ced9b27b29Oliver Endrissstatic ssize_t dvb_aplay(struct av7110 *av7110, const char __user *buf, 5471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long count, int nonblock, int type) 5481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 5491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long todo = count, n; 5501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dprintk(2, "av7110:%p, \n", av7110); 5511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!av7110->kbuf[type]) 5531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -ENOBUFS; 5541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (nonblock && dvb_ringbuffer_free(&av7110->aout) < 20 * 1024) 5551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EWOULDBLOCK; 5561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (todo > 0) { 5581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (dvb_ringbuffer_free(&av7110->aout) < 20 * 1024) { 5591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (nonblock) 5601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count - todo; 5611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (wait_event_interruptible(av7110->aout.queue, 5621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (dvb_ringbuffer_free(&av7110->aout) >= 20 * 1024))) 5631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count-todo; 5641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds n = todo; 5661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (n > IPACKS * 2) 5671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds n = IPACKS * 2; 5681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (copy_from_user(av7110->kbuf[type], buf, n)) 5691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EFAULT; 5701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110_ipack_instant_repack(av7110->kbuf[type], n, 5711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds &av7110->ipack[type]); 5721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds todo -= n; 5731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buf += n; 5741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count - todo; 5761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid av7110_p2t_init(struct av7110_p2t *p, struct dvb_demux_feed *feed) 5791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 5801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memset(p->pes, 0, TS_SIZE); 5811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->counter = 0; 5821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->pos = 0; 5831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->frags = 0; 5841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (feed) 5851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->feed = feed; 5861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void clear_p2t(struct av7110_p2t *p) 5891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 5901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memset(p->pes, 0, TS_SIZE); 5911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds// p->counter = 0; 5921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->pos = 0; 5931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->frags = 0; 5941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int find_pes_header(u8 const *buf, long int length, int *frags) 5981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 5991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int c = 0; 6001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int found = 0; 6011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *frags = 0; 6031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (c < length - 3 && !found) { 6051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (buf[c] == 0x00 && buf[c + 1] == 0x00 && 6061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buf[c + 2] == 0x01) { 6071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch ( buf[c + 3] ) { 6081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case PROG_STREAM_MAP: 6091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case PRIVATE_STREAM2: 6101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case PROG_STREAM_DIR: 6111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case ECM_STREAM : 6121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case EMM_STREAM : 6131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case PADDING_STREAM : 6141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case DSM_CC_STREAM : 6151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case ISO13522_STREAM: 6161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case PRIVATE_STREAM1: 6171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case AUDIO_STREAM_S ... AUDIO_STREAM_E: 6181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case VIDEO_STREAM_S ... VIDEO_STREAM_E: 6191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds found = 1; 6201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 6211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 6231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c++; 6241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 6251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else 6271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c++; 6281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (c == length - 3 && !found) { 6301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (buf[length - 1] == 0x00) 6311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *frags = 1; 6321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (buf[length - 2] == 0x00 && 6331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buf[length - 1] == 0x00) 6341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *frags = 2; 6351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (buf[length - 3] == 0x00 && 6361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buf[length - 2] == 0x00 && 6371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buf[length - 1] == 0x01) 6381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *frags = 3; 6391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -1; 6401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return c; 6431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid av7110_p2t_write(u8 const *buf, long int length, u16 pid, struct av7110_p2t *p) 6461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 6471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int c, c2, l, add; 6481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int check, rest; 6491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c = 0; 6511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c2 = 0; 6521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (p->frags){ 6531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds check = 0; 6541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch(p->frags) { 6551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 1: 6561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (buf[c] == 0x00 && buf[c + 1] == 0x01) { 6571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds check = 1; 6581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c += 2; 6591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 6611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 2: 6621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (buf[c] == 0x01) { 6631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds check = 1; 6641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c++; 6651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 6671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 3: 6681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds check = 1; 6691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (check) { 6711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (buf[c]) { 6721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case PROG_STREAM_MAP: 6731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case PRIVATE_STREAM2: 6741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case PROG_STREAM_DIR: 6751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case ECM_STREAM : 6761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case EMM_STREAM : 6771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case PADDING_STREAM : 6781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case DSM_CC_STREAM : 6791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case ISO13522_STREAM: 6801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case PRIVATE_STREAM1: 6811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case AUDIO_STREAM_S ... AUDIO_STREAM_E: 6821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case VIDEO_STREAM_S ... VIDEO_STREAM_E: 6831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->pes[0] = 0x00; 6841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->pes[1] = 0x00; 6851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->pes[2] = 0x01; 6861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->pes[3] = buf[c]; 6871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->pos = 4; 6881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(p->pes + p->pos, buf + c, (TS_SIZE - 4) - p->pos); 6891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c += (TS_SIZE - 4) - p->pos; 6901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p_to_t(p->pes, (TS_SIZE - 4), pid, &p->counter, p->feed); 6911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds clear_p2t(p); 6921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 6931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 6951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c = 0; 6961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 6971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->frags = 0; 7001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (p->pos) { 7031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c2 = find_pes_header(buf + c, length - c, &p->frags); 7041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (c2 >= 0 && c2 < (TS_SIZE - 4) - p->pos) 7051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds l = c2+c; 7061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 7071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds l = (TS_SIZE - 4) - p->pos; 7081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(p->pes + p->pos, buf, l); 7091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c += l; 7101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->pos += l; 7111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p_to_t(p->pes, p->pos, pid, &p->counter, p->feed); 7121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds clear_p2t(p); 7131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds add = 0; 7161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (c < length) { 7171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c2 = find_pes_header(buf + c + add, length - c - add, &p->frags); 7181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (c2 >= 0) { 7191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c2 += c + add; 7201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (c2 > c){ 7211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p_to_t(buf + c, c2 - c, pid, &p->counter, p->feed); 7221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c = c2; 7231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds clear_p2t(p); 7241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds add = 0; 7251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else 7261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds add = 1; 7271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 7281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds l = length - c; 7291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rest = l % (TS_SIZE - 4); 7301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds l -= rest; 7311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p_to_t(buf + c, l, pid, &p->counter, p->feed); 7321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(p->pes, buf + c + l, rest); 7331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->pos = rest; 7341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c = length; 7351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int write_ts_header2(u16 pid, u8 *counter, int pes_start, u8 *buf, u8 length) 7411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 7421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 7431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int c = 0; 7441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int fill; 7451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 tshead[4] = { 0x47, 0x00, 0x00, 0x10 }; 7461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fill = (TS_SIZE - 4) - length; 7481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (pes_start) 7491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tshead[1] = 0x40; 7501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (fill) 7511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tshead[3] = 0x30; 7521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tshead[1] |= (u8)((pid & 0x1F00) >> 8); 7531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tshead[2] |= (u8)(pid & 0x00FF); 7541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tshead[3] |= ((*counter)++ & 0x0F); 7551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(buf, tshead, 4); 7561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c += 4; 7571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (fill) { 7591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buf[4] = fill - 1; 7601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c++; 7611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (fill > 1) { 7621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buf[5] = 0x00; 7631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c++; 7641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 6; i < fill + 4; i++) { 7661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buf[i] = 0xFF; 7671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c++; 7681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return c; 7721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void p_to_t(u8 const *buf, long int length, u16 pid, u8 *counter, 7761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct dvb_demux_feed *feed) 7771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 7781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int l, pes_start; 7791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 obuf[TS_SIZE]; 7801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds long c = 0; 7811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pes_start = 0; 7831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (length > 3 && 7841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buf[0] == 0x00 && buf[1] == 0x00 && buf[2] == 0x01) 7851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (buf[3]) { 7861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case PROG_STREAM_MAP: 7871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case PRIVATE_STREAM2: 7881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case PROG_STREAM_DIR: 7891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case ECM_STREAM : 7901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case EMM_STREAM : 7911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case PADDING_STREAM : 7921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case DSM_CC_STREAM : 7931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case ISO13522_STREAM: 7941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case PRIVATE_STREAM1: 7951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case AUDIO_STREAM_S ... AUDIO_STREAM_E: 7961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case VIDEO_STREAM_S ... VIDEO_STREAM_E: 7971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pes_start = 1; 7981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 7991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 8011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 8021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (c < length) { 8051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memset(obuf, 0, TS_SIZE); 8061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (length - c >= (TS_SIZE - 4)){ 8071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds l = write_ts_header2(pid, counter, pes_start, 8081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds obuf, (TS_SIZE - 4)); 8091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(obuf + l, buf + c, TS_SIZE - l); 8101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c += TS_SIZE - l; 8111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 8121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds l = write_ts_header2(pid, counter, pes_start, 8131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds obuf, length - c); 8141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(obuf + l, buf + c, TS_SIZE - l); 8151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c = length; 8161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds feed->cb.ts(obuf, 188, NULL, 0, &feed->feed.ts, DMX_OK); 8181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pes_start = 0; 8191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 8211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 823fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endrissstatic int write_ts_to_decoder(struct av7110 *av7110, int type, const u8 *buf, size_t len) 824fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss{ 825fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss struct ipack *ipack = &av7110->ipack[type]; 826fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss 827ef226d00dd041f753163fd3b69c7790496ab8384Oliver Endriss if (buf[1] & TRANS_ERROR) { 828ef226d00dd041f753163fd3b69c7790496ab8384Oliver Endriss av7110_ipack_reset(ipack); 829ef226d00dd041f753163fd3b69c7790496ab8384Oliver Endriss return -1; 830ef226d00dd041f753163fd3b69c7790496ab8384Oliver Endriss } 831ef226d00dd041f753163fd3b69c7790496ab8384Oliver Endriss 832fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss if (!(buf[3] & PAYLOAD)) 833fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss return -1; 834fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss 835fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss if (buf[1] & PAY_START) 836fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss av7110_ipack_flush(ipack); 837fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss 838fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss if (buf[3] & ADAPT_FIELD) { 839fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss len -= buf[4] + 1; 840fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss buf += buf[4] + 1; 841fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss if (!len) 842fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss return 0; 843fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss } 844fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss 845fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss av7110_ipack_instant_repack(buf + 4, len - 4, ipack); 846fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss return 0; 847fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss} 848fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss 849fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss 8501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint av7110_write_to_decoder(struct dvb_demux_feed *feed, const u8 *buf, size_t len) 8511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 8521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct dvb_demux *demux = feed->demux; 8531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct av7110 *av7110 = (struct av7110 *) demux->priv; 8541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dprintk(2, "av7110:%p, \n", av7110); 8561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8579e615eac827094147401c44c9ff955b468d4fa79Oliver Endriss if (av7110->full_ts && demux->dmx.frontend->source != DMX_MEMORY_FE) 8589e615eac827094147401c44c9ff955b468d4fa79Oliver Endriss return 0; 8599e615eac827094147401c44c9ff955b468d4fa79Oliver Endriss 8601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (feed->pes_type) { 8611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 0: 8621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->audiostate.stream_source == AUDIO_SOURCE_MEMORY) 8631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EINVAL; 8641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 8651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 1: 8661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->videostate.stream_source == VIDEO_SOURCE_MEMORY) 8671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EINVAL; 8681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 8691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 8701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -1; 8711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 873fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss return write_ts_to_decoder(av7110, feed->pes_type, buf, len); 8741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 8751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/****************************************************************************** 8791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Video MPEG decoder events 8801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ******************************************************************************/ 8811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid dvb_video_add_event(struct av7110 *av7110, struct video_event *event) 8821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 8831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct dvb_video_events *events = &av7110->video_events; 8841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int wp; 8851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_lock_bh(&events->lock); 8871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds wp = (events->eventw + 1) % MAX_VIDEO_EVENT; 8891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (wp == events->eventr) { 8901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds events->overflow = 1; 8911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds events->eventr = (events->eventr + 1) % MAX_VIDEO_EVENT; 8921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds //FIXME: timestamp? 8951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(&events->events[events->eventw], event, sizeof(struct video_event)); 8961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds events->eventw = wp; 8971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_unlock_bh(&events->lock); 8991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds wake_up_interruptible(&events->wait_queue); 9011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 9021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int dvb_video_get_event (struct av7110 *av7110, struct video_event *event, int flags) 9051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 9061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct dvb_video_events *events = &av7110->video_events; 9071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (events->overflow) { 9091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds events->overflow = 0; 9101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EOVERFLOW; 9111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 9121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (events->eventw == events->eventr) { 9131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int ret; 9141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (flags & O_NONBLOCK) 9161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EWOULDBLOCK; 9171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ret = wait_event_interruptible(events->wait_queue, 9191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds events->eventw != events->eventr); 9201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ret < 0) 9211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ret; 9221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 9231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_lock_bh(&events->lock); 9251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(event, &events->events[events->eventr], 9271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sizeof(struct video_event)); 9281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds events->eventr = (events->eventr + 1) % MAX_VIDEO_EVENT; 9291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_unlock_bh(&events->lock); 9311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 9331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 9341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/****************************************************************************** 9371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * DVB device file operations 9381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ******************************************************************************/ 9391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic unsigned int dvb_video_poll(struct file *file, poll_table *wait) 9411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 942d9bdf77296a00538faff95f29bf238857daea2e7Tobias Klauser struct dvb_device *dvbdev = file->private_data; 943d9bdf77296a00538faff95f29bf238857daea2e7Tobias Klauser struct av7110 *av7110 = dvbdev->priv; 9441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int mask = 0; 9451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dprintk(2, "av7110:%p, \n", av7110); 9471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((file->f_flags & O_ACCMODE) != O_RDONLY) 9491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds poll_wait(file, &av7110->avout.queue, wait); 9501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds poll_wait(file, &av7110->video_events.wait_queue, wait); 9521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->video_events.eventw != av7110->video_events.eventr) 9541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mask = POLLPRI; 9551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((file->f_flags & O_ACCMODE) != O_RDONLY) { 9571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->playing) { 9581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (FREE_COND) 9591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mask |= (POLLOUT | POLLWRNORM); 9601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else /* if not playing: may play if asked for */ 9611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mask |= (POLLOUT | POLLWRNORM); 9621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 9631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return mask; 9651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 9661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic ssize_t dvb_video_write(struct file *file, const char __user *buf, 9681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds size_t count, loff_t *ppos) 9691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 970d9bdf77296a00538faff95f29bf238857daea2e7Tobias Klauser struct dvb_device *dvbdev = file->private_data; 971d9bdf77296a00538faff95f29bf238857daea2e7Tobias Klauser struct av7110 *av7110 = dvbdev->priv; 972fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss unsigned char c; 9731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dprintk(2, "av7110:%p, \n", av7110); 9751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((file->f_flags & O_ACCMODE) == O_RDONLY) 9771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EPERM; 9781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->videostate.stream_source != VIDEO_SOURCE_MEMORY) 9801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EPERM; 9811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 982fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss if (get_user(c, buf)) 983fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss return -EFAULT; 984fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss if (c == 0x47 && count % TS_SIZE == 0) 985fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss return ts_play(av7110, buf, count, file->f_flags & O_NONBLOCK, 1); 986fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss else 987fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss return dvb_play(av7110, buf, count, file->f_flags & O_NONBLOCK, 1); 9881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 9891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic unsigned int dvb_audio_poll(struct file *file, poll_table *wait) 9911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 992d9bdf77296a00538faff95f29bf238857daea2e7Tobias Klauser struct dvb_device *dvbdev = file->private_data; 993d9bdf77296a00538faff95f29bf238857daea2e7Tobias Klauser struct av7110 *av7110 = dvbdev->priv; 9941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int mask = 0; 9951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dprintk(2, "av7110:%p, \n", av7110); 9971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds poll_wait(file, &av7110->aout.queue, wait); 9991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->playing) { 10011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (dvb_ringbuffer_free(&av7110->aout) >= 20 * 1024) 10021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mask |= (POLLOUT | POLLWRNORM); 10031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else /* if not playing: may play if asked for */ 10041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mask = (POLLOUT | POLLWRNORM); 10051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return mask; 10071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 10081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic ssize_t dvb_audio_write(struct file *file, const char __user *buf, 10101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds size_t count, loff_t *ppos) 10111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1012d9bdf77296a00538faff95f29bf238857daea2e7Tobias Klauser struct dvb_device *dvbdev = file->private_data; 1013d9bdf77296a00538faff95f29bf238857daea2e7Tobias Klauser struct av7110 *av7110 = dvbdev->priv; 1014fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss unsigned char c; 10151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dprintk(2, "av7110:%p, \n", av7110); 10171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->audiostate.stream_source != AUDIO_SOURCE_MEMORY) { 10191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_ERR "not audio source memory\n"); 10201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EPERM; 10211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1022fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss 1023fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss if (get_user(c, buf)) 1024fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss return -EFAULT; 1025fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss if (c == 0x47 && count % TS_SIZE == 0) 1026fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss return ts_play(av7110, buf, count, file->f_flags & O_NONBLOCK, 0); 1027fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss else 1028fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss return dvb_aplay(av7110, buf, count, file->f_flags & O_NONBLOCK, 0); 10291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 10301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic u8 iframe_header[] = { 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x80, 0x00, 0x00 }; 10321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define MIN_IFRAME 400000 10341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1035804b4458943f14bf144d3c3ba50097ced9b27b29Oliver Endrissstatic int play_iframe(struct av7110 *av7110, char __user *buf, unsigned int len, int nonblock) 10361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1037a230e55d92347e09d9ba2e97096df114b2dfaf2dAl Viro unsigned i, n; 10380ed4a6ea9dbd9f5b77ce594f7f46be022d2c49ecOliver Endriss int progressive = 0; 1039a230e55d92347e09d9ba2e97096df114b2dfaf2dAl Viro int match = 0; 10401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dprintk(2, "av7110:%p, \n", av7110); 10421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!(av7110->playing & RP_VIDEO)) { 10441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110_av_start_play(av7110, RP_VIDEO) < 0) 10451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EBUSY; 10461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 10471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1048a230e55d92347e09d9ba2e97096df114b2dfaf2dAl Viro /* search in buf for instances of 00 00 01 b5 1? */ 1049a230e55d92347e09d9ba2e97096df114b2dfaf2dAl Viro for (i = 0; i < len; i++) { 1050a230e55d92347e09d9ba2e97096df114b2dfaf2dAl Viro unsigned char c; 1051a230e55d92347e09d9ba2e97096df114b2dfaf2dAl Viro if (get_user(c, buf + i)) 1052a230e55d92347e09d9ba2e97096df114b2dfaf2dAl Viro return -EFAULT; 1053a230e55d92347e09d9ba2e97096df114b2dfaf2dAl Viro if (match == 5) { 1054a230e55d92347e09d9ba2e97096df114b2dfaf2dAl Viro progressive = c & 0x08; 1055a230e55d92347e09d9ba2e97096df114b2dfaf2dAl Viro match = 0; 1056a230e55d92347e09d9ba2e97096df114b2dfaf2dAl Viro } 1057a230e55d92347e09d9ba2e97096df114b2dfaf2dAl Viro if (c == 0x00) { 1058a230e55d92347e09d9ba2e97096df114b2dfaf2dAl Viro match = (match == 1 || match == 2) ? 2 : 1; 1059a230e55d92347e09d9ba2e97096df114b2dfaf2dAl Viro continue; 1060a230e55d92347e09d9ba2e97096df114b2dfaf2dAl Viro } 1061a230e55d92347e09d9ba2e97096df114b2dfaf2dAl Viro switch (match++) { 1062a230e55d92347e09d9ba2e97096df114b2dfaf2dAl Viro case 2: if (c == 0x01) 1063a230e55d92347e09d9ba2e97096df114b2dfaf2dAl Viro continue; 1064a230e55d92347e09d9ba2e97096df114b2dfaf2dAl Viro break; 1065a230e55d92347e09d9ba2e97096df114b2dfaf2dAl Viro case 3: if (c == 0xb5) 1066a230e55d92347e09d9ba2e97096df114b2dfaf2dAl Viro continue; 1067a230e55d92347e09d9ba2e97096df114b2dfaf2dAl Viro break; 1068a230e55d92347e09d9ba2e97096df114b2dfaf2dAl Viro case 4: if ((c & 0xf0) == 0x10) 1069a230e55d92347e09d9ba2e97096df114b2dfaf2dAl Viro continue; 1070a230e55d92347e09d9ba2e97096df114b2dfaf2dAl Viro break; 1071a230e55d92347e09d9ba2e97096df114b2dfaf2dAl Viro } 1072a230e55d92347e09d9ba2e97096df114b2dfaf2dAl Viro match = 0; 10730ed4a6ea9dbd9f5b77ce594f7f46be022d2c49ecOliver Endriss } 10740ed4a6ea9dbd9f5b77ce594f7f46be022d2c49ecOliver Endriss 10751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* setting n always > 1, fixes problems when playing stillframes 10761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds consisting of I- and P-Frames */ 10771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds n = MIN_IFRAME / len + 1; 10781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* FIXME: nonblock? */ 10801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dvb_play_kernel(av7110, iframe_header, sizeof(iframe_header), 0, 1); 10811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < n; i++) 10831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dvb_play(av7110, buf, len, 0, 1); 10841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110_ipack_flush(&av7110->ipack[1]); 10860ed4a6ea9dbd9f5b77ce594f7f46be022d2c49ecOliver Endriss 10870ed4a6ea9dbd9f5b77ce594f7f46be022d2c49ecOliver Endriss if (progressive) 10880ed4a6ea9dbd9f5b77ce594f7f46be022d2c49ecOliver Endriss return vidcom(av7110, AV_VIDEO_CMD_FREEZE, 1); 10890ed4a6ea9dbd9f5b77ce594f7f46be022d2c49ecOliver Endriss else 10900ed4a6ea9dbd9f5b77ce594f7f46be022d2c49ecOliver Endriss return 0; 10911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 10921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int dvb_video_ioctl(struct inode *inode, struct file *file, 10951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int cmd, void *parg) 10961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1097d9bdf77296a00538faff95f29bf238857daea2e7Tobias Klauser struct dvb_device *dvbdev = file->private_data; 1098d9bdf77296a00538faff95f29bf238857daea2e7Tobias Klauser struct av7110 *av7110 = dvbdev->priv; 10991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long arg = (unsigned long) parg; 11001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int ret = 0; 11011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1102ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald dprintk(1, "av7110:%p, cmd=%04x\n", av7110,cmd); 11031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((file->f_flags & O_ACCMODE) == O_RDONLY) { 11051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ( cmd != VIDEO_GET_STATUS && cmd != VIDEO_GET_EVENT && 11061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cmd != VIDEO_GET_SIZE ) { 11071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EPERM; 11081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 11091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 11101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (cmd) { 11121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case VIDEO_STOP: 11131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->videostate.play_state = VIDEO_STOPPED; 11141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->videostate.stream_source == VIDEO_SOURCE_MEMORY) 1115ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = av7110_av_stop(av7110, RP_VIDEO); 11161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 11172435be11ae1afb64ac7dfb25e10b6e3037ab0522Hans Verkuil ret = vidcom(av7110, AV_VIDEO_CMD_STOP, 11181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->videostate.video_blank ? 0 : 1); 1119ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (!ret) 1120ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald av7110->trickmode = TRICK_NONE; 11211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 11221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case VIDEO_PLAY: 11241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->trickmode = TRICK_NONE; 11251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->videostate.play_state == VIDEO_FREEZED) { 11261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->videostate.play_state = VIDEO_PLAYING; 11272435be11ae1afb64ac7dfb25e10b6e3037ab0522Hans Verkuil ret = vidcom(av7110, AV_VIDEO_CMD_PLAY, 0); 1128ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (ret) 1129ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald break; 11301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 11311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->videostate.stream_source == VIDEO_SOURCE_MEMORY) { 11331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->playing == RP_AV) { 1134ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Stop, 0); 1135ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (ret) 1136ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald break; 11371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->playing &= ~RP_VIDEO; 11381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1139ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = av7110_av_start_play(av7110, RP_VIDEO); 11401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1141ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (!ret) 11422435be11ae1afb64ac7dfb25e10b6e3037ab0522Hans Verkuil ret = vidcom(av7110, AV_VIDEO_CMD_PLAY, 0); 1143ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (!ret) 1144ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald av7110->videostate.play_state = VIDEO_PLAYING; 11451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 11461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case VIDEO_FREEZE: 11481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->videostate.play_state = VIDEO_FREEZED; 11491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->playing & RP_VIDEO) 1150ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Pause, 0); 11511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 11522435be11ae1afb64ac7dfb25e10b6e3037ab0522Hans Verkuil ret = vidcom(av7110, AV_VIDEO_CMD_FREEZE, 1); 1153ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (!ret) 1154ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald av7110->trickmode = TRICK_FREEZE; 11551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 11561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case VIDEO_CONTINUE: 11581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->playing & RP_VIDEO) 1159ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Continue, 0); 1160ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (!ret) 11612435be11ae1afb64ac7dfb25e10b6e3037ab0522Hans Verkuil ret = vidcom(av7110, AV_VIDEO_CMD_PLAY, 0); 1162ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (!ret) { 1163ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald av7110->videostate.play_state = VIDEO_PLAYING; 1164ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald av7110->trickmode = TRICK_NONE; 1165ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald } 11661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 11671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case VIDEO_SELECT_SOURCE: 11691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->videostate.stream_source = (video_stream_source_t) arg; 11701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 11711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case VIDEO_SET_BLANK: 11731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->videostate.video_blank = (int) arg; 11741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 11751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case VIDEO_GET_STATUS: 11771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(parg, &av7110->videostate, sizeof(struct video_status)); 11781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 11791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case VIDEO_GET_EVENT: 1181ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = dvb_video_get_event(av7110, parg, file->f_flags); 11821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 11831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case VIDEO_GET_SIZE: 11851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(parg, &av7110->video_size, sizeof(video_size_t)); 11861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 11871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case VIDEO_SET_DISPLAY_FORMAT: 11891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 11901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds video_displayformat_t format = (video_displayformat_t) arg; 11911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (format) { 11931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case VIDEO_PAN_SCAN: 1194defd574ec07edaa1587da144d03b18495ab484b1Oliver Endriss av7110->display_panscan = VID_PAN_SCAN_PREF; 11951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 11961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case VIDEO_LETTER_BOX: 1198defd574ec07edaa1587da144d03b18495ab484b1Oliver Endriss av7110->display_panscan = VID_VC_AND_PS_PREF; 11991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 12001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case VIDEO_CENTER_CUT_OUT: 1202defd574ec07edaa1587da144d03b18495ab484b1Oliver Endriss av7110->display_panscan = VID_CENTRE_CUT_PREF; 12031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 12041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 12061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ret = -EINVAL; 12071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 12081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ret < 0) 12091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 1210a65d3bb7177cbab1fca69dd97537766c2817b6b2Johannes Stezenbach av7110->videostate.display_format = format; 12111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ret = av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetPanScanType, 1212defd574ec07edaa1587da144d03b18495ab484b1Oliver Endriss 1, av7110->display_panscan); 12131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 12141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 12151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case VIDEO_SET_FORMAT: 12171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (arg > 1) { 12181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ret = -EINVAL; 12191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 12201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 12211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->display_ar = arg; 12221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ret = av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetMonitorType, 12231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1, (u16) arg); 12241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 12251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case VIDEO_STILLPICTURE: 12271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 12281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct video_still_picture *pic = 12291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (struct video_still_picture *) parg; 12301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->videostate.stream_source = VIDEO_SOURCE_MEMORY; 12311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dvb_ringbuffer_flush_spinlock_wakeup(&av7110->avout); 12321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ret = play_iframe(av7110, pic->iFrame, pic->size, 12331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds file->f_flags & O_NONBLOCK); 12341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 12351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 12361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case VIDEO_FAST_FORWARD: 12381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds //note: arg is ignored by firmware 12391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->playing & RP_VIDEO) 1240ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, 12417a2fa90fa8084846937aa194f8a40abfa99c692fJohannes Stezenbach __Scan_I, 2, AV_PES, 0); 12421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 12432435be11ae1afb64ac7dfb25e10b6e3037ab0522Hans Verkuil ret = vidcom(av7110, AV_VIDEO_CMD_FFWD, arg); 1244ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (!ret) { 1245ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald av7110->trickmode = TRICK_FAST; 1246ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald av7110->videostate.play_state = VIDEO_PLAYING; 1247ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald } 12481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 12491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case VIDEO_SLOWMOTION: 12511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->playing&RP_VIDEO) { 1252ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Slow, 2, 0, 0); 1253ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (!ret) 12542435be11ae1afb64ac7dfb25e10b6e3037ab0522Hans Verkuil ret = vidcom(av7110, AV_VIDEO_CMD_SLOW, arg); 12551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 12562435be11ae1afb64ac7dfb25e10b6e3037ab0522Hans Verkuil ret = vidcom(av7110, AV_VIDEO_CMD_PLAY, 0); 1257ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (!ret) 12582435be11ae1afb64ac7dfb25e10b6e3037ab0522Hans Verkuil ret = vidcom(av7110, AV_VIDEO_CMD_STOP, 0); 1259ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (!ret) 12602435be11ae1afb64ac7dfb25e10b6e3037ab0522Hans Verkuil ret = vidcom(av7110, AV_VIDEO_CMD_SLOW, arg); 1261ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald } 1262ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (!ret) { 1263ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald av7110->trickmode = TRICK_SLOW; 1264ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald av7110->videostate.play_state = VIDEO_PLAYING; 12651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 12661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 12671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case VIDEO_GET_CAPABILITIES: 12691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *(int *)parg = VIDEO_CAP_MPEG1 | VIDEO_CAP_MPEG2 | 12701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds VIDEO_CAP_SYS | VIDEO_CAP_PROG; 12711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 12721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case VIDEO_CLEAR_BUFFER: 12741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dvb_ringbuffer_flush_spinlock_wakeup(&av7110->avout); 12751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110_ipack_reset(&av7110->ipack[1]); 12761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->playing == RP_AV) { 1278ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, 12797a2fa90fa8084846937aa194f8a40abfa99c692fJohannes Stezenbach __Play, 2, AV_PES, 0); 1280ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (ret) 1281ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald break; 12821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->trickmode == TRICK_FAST) 1283ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, 12847a2fa90fa8084846937aa194f8a40abfa99c692fJohannes Stezenbach __Scan_I, 2, AV_PES, 0); 12851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->trickmode == TRICK_SLOW) { 1286ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, 12877a2fa90fa8084846937aa194f8a40abfa99c692fJohannes Stezenbach __Slow, 2, 0, 0); 1288ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (!ret) 12892435be11ae1afb64ac7dfb25e10b6e3037ab0522Hans Verkuil ret = vidcom(av7110, AV_VIDEO_CMD_SLOW, arg); 12901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 12911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->trickmode == TRICK_FREEZE) 12922435be11ae1afb64ac7dfb25e10b6e3037ab0522Hans Verkuil ret = vidcom(av7110, AV_VIDEO_CMD_STOP, 1); 12931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 12941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 12951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case VIDEO_SET_STREAMTYPE: 12971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 12991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 13011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ret = -ENOIOCTLCMD; 13021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 13031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 13041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ret; 13051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 13061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int dvb_audio_ioctl(struct inode *inode, struct file *file, 13081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int cmd, void *parg) 13091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1310d9bdf77296a00538faff95f29bf238857daea2e7Tobias Klauser struct dvb_device *dvbdev = file->private_data; 1311d9bdf77296a00538faff95f29bf238857daea2e7Tobias Klauser struct av7110 *av7110 = dvbdev->priv; 13121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long arg = (unsigned long) parg; 13131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int ret = 0; 13141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1315ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald dprintk(1, "av7110:%p, cmd=%04x\n", av7110,cmd); 13161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (((file->f_flags & O_ACCMODE) == O_RDONLY) && 13181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (cmd != AUDIO_GET_STATUS)) 13191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EPERM; 13201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (cmd) { 13221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case AUDIO_STOP: 13231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->audiostate.stream_source == AUDIO_SOURCE_MEMORY) 1324ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = av7110_av_stop(av7110, RP_AUDIO); 13251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 1326ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = audcom(av7110, AUDIO_CMD_MUTE); 1327ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (!ret) 1328ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald av7110->audiostate.play_state = AUDIO_STOPPED; 13291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 13301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case AUDIO_PLAY: 13321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->audiostate.stream_source == AUDIO_SOURCE_MEMORY) 1333ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = av7110_av_start_play(av7110, RP_AUDIO); 1334ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (!ret) 1335ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = audcom(av7110, AUDIO_CMD_UNMUTE); 1336ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (!ret) 1337ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald av7110->audiostate.play_state = AUDIO_PLAYING; 13381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 13391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case AUDIO_PAUSE: 1341ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = audcom(av7110, AUDIO_CMD_MUTE); 1342ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (!ret) 1343ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald av7110->audiostate.play_state = AUDIO_PAUSED; 13441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 13451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case AUDIO_CONTINUE: 13471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->audiostate.play_state == AUDIO_PAUSED) { 13481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->audiostate.play_state = AUDIO_PLAYING; 1349ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = audcom(av7110, AUDIO_CMD_UNMUTE | AUDIO_CMD_PCM16); 13501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 13511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 13521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case AUDIO_SELECT_SOURCE: 13541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->audiostate.stream_source = (audio_stream_source_t) arg; 13551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 13561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case AUDIO_SET_MUTE: 13581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 1359ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = audcom(av7110, arg ? AUDIO_CMD_MUTE : AUDIO_CMD_UNMUTE); 1360ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (!ret) 1361ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald av7110->audiostate.mute_state = (int) arg; 13621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 13631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 13641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case AUDIO_SET_AV_SYNC: 13661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->audiostate.AV_sync_state = (int) arg; 1367ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = audcom(av7110, arg ? AUDIO_CMD_SYNC_ON : AUDIO_CMD_SYNC_OFF); 13681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 13691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case AUDIO_SET_BYPASS_MODE: 137147f3692096eef208d8cb455bfa2b3308cdfc40deDr. Werner Fink if (FW_VERSION(av7110->arm_app) < 0x2621) 137247f3692096eef208d8cb455bfa2b3308cdfc40deDr. Werner Fink ret = -EINVAL; 137347f3692096eef208d8cb455bfa2b3308cdfc40deDr. Werner Fink av7110->audiostate.bypass_mode = (int)arg; 13741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 13751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case AUDIO_CHANNEL_SELECT: 13771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->audiostate.channel_select = (audio_channel_select_t) arg; 13781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch(av7110->audiostate.channel_select) { 13801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case AUDIO_STEREO: 1381ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = audcom(av7110, AUDIO_CMD_STEREO); 138261391e0446e97bea44d93bd1624e5b32d3cc8474Tim Kaiser if (!ret) { 1383ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (av7110->adac_type == DVB_ADAC_CRYSTAL) 1384ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald i2c_writereg(av7110, 0x20, 0x02, 0x49); 138561391e0446e97bea44d93bd1624e5b32d3cc8474Tim Kaiser else if (av7110->adac_type == DVB_ADAC_MSP34x5) 138661391e0446e97bea44d93bd1624e5b32d3cc8474Tim Kaiser msp_writereg(av7110, MSP_WR_DSP, 0x0008, 0x0220); 138761391e0446e97bea44d93bd1624e5b32d3cc8474Tim Kaiser } 13881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 13891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case AUDIO_MONO_LEFT: 1391ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = audcom(av7110, AUDIO_CMD_MONO_L); 139261391e0446e97bea44d93bd1624e5b32d3cc8474Tim Kaiser if (!ret) { 1393ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (av7110->adac_type == DVB_ADAC_CRYSTAL) 1394ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald i2c_writereg(av7110, 0x20, 0x02, 0x4a); 139561391e0446e97bea44d93bd1624e5b32d3cc8474Tim Kaiser else if (av7110->adac_type == DVB_ADAC_MSP34x5) 139661391e0446e97bea44d93bd1624e5b32d3cc8474Tim Kaiser msp_writereg(av7110, MSP_WR_DSP, 0x0008, 0x0200); 139761391e0446e97bea44d93bd1624e5b32d3cc8474Tim Kaiser } 13981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 13991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case AUDIO_MONO_RIGHT: 1401ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = audcom(av7110, AUDIO_CMD_MONO_R); 140261391e0446e97bea44d93bd1624e5b32d3cc8474Tim Kaiser if (!ret) { 1403ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (av7110->adac_type == DVB_ADAC_CRYSTAL) 1404ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald i2c_writereg(av7110, 0x20, 0x02, 0x45); 140561391e0446e97bea44d93bd1624e5b32d3cc8474Tim Kaiser else if (av7110->adac_type == DVB_ADAC_MSP34x5) 140661391e0446e97bea44d93bd1624e5b32d3cc8474Tim Kaiser msp_writereg(av7110, MSP_WR_DSP, 0x0008, 0x0210); 140761391e0446e97bea44d93bd1624e5b32d3cc8474Tim Kaiser } 14081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 14091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 14111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ret = -EINVAL; 14121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 14131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 14141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 14151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case AUDIO_GET_STATUS: 14171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(parg, &av7110->audiostate, sizeof(struct audio_status)); 14181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 14191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case AUDIO_GET_CAPABILITIES: 142147f3692096eef208d8cb455bfa2b3308cdfc40deDr. Werner Fink if (FW_VERSION(av7110->arm_app) < 0x2621) 142247f3692096eef208d8cb455bfa2b3308cdfc40deDr. Werner Fink *(unsigned int *)parg = AUDIO_CAP_LPCM | AUDIO_CAP_MP1 | AUDIO_CAP_MP2; 142347f3692096eef208d8cb455bfa2b3308cdfc40deDr. Werner Fink else 142447f3692096eef208d8cb455bfa2b3308cdfc40deDr. Werner Fink *(unsigned int *)parg = AUDIO_CAP_LPCM | AUDIO_CAP_DTS | AUDIO_CAP_AC3 | 142547f3692096eef208d8cb455bfa2b3308cdfc40deDr. Werner Fink AUDIO_CAP_MP1 | AUDIO_CAP_MP2; 14261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 14271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case AUDIO_CLEAR_BUFFER: 14291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dvb_ringbuffer_flush_spinlock_wakeup(&av7110->aout); 14301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110_ipack_reset(&av7110->ipack[0]); 14311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->playing == RP_AV) 1432ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, 14337a2fa90fa8084846937aa194f8a40abfa99c692fJohannes Stezenbach __Play, 2, AV_PES, 0); 14341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 14351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case AUDIO_SET_ID: 14361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 14381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case AUDIO_SET_MIXER: 14391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 14401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct audio_mixer *amix = (struct audio_mixer *)parg; 14411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1442ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = av7110_set_volume(av7110, amix->volume_left, amix->volume_right); 14431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 14441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 14451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case AUDIO_SET_STREAMTYPE: 14461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 14471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 14481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ret = -ENOIOCTLCMD; 14491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 14501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ret; 14511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 14521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int dvb_video_open(struct inode *inode, struct file *file) 14551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1456d9bdf77296a00538faff95f29bf238857daea2e7Tobias Klauser struct dvb_device *dvbdev = file->private_data; 1457d9bdf77296a00538faff95f29bf238857daea2e7Tobias Klauser struct av7110 *av7110 = dvbdev->priv; 14581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int err; 14591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dprintk(2, "av7110:%p, \n", av7110); 14611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((err = dvb_generic_open(inode, file)) < 0) 14631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return err; 14641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((file->f_flags & O_ACCMODE) != O_RDONLY) { 14661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dvb_ringbuffer_flush_spinlock_wakeup(&av7110->aout); 14671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dvb_ringbuffer_flush_spinlock_wakeup(&av7110->avout); 14681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->video_blank = 1; 14691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->audiostate.AV_sync_state = 1; 14701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->videostate.stream_source = VIDEO_SOURCE_DEMUX; 14711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* empty event queue */ 14731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->video_events.eventr = av7110->video_events.eventw = 0; 14741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 14751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 14771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 14781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int dvb_video_release(struct inode *inode, struct file *file) 14801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1481d9bdf77296a00538faff95f29bf238857daea2e7Tobias Klauser struct dvb_device *dvbdev = file->private_data; 1482d9bdf77296a00538faff95f29bf238857daea2e7Tobias Klauser struct av7110 *av7110 = dvbdev->priv; 14831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dprintk(2, "av7110:%p, \n", av7110); 14851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((file->f_flags & O_ACCMODE) != O_RDONLY) { 14871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110_av_stop(av7110, RP_VIDEO); 14881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 14891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return dvb_generic_release(inode, file); 14911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 14921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int dvb_audio_open(struct inode *inode, struct file *file) 14941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1495d9bdf77296a00538faff95f29bf238857daea2e7Tobias Klauser struct dvb_device *dvbdev = file->private_data; 1496d9bdf77296a00538faff95f29bf238857daea2e7Tobias Klauser struct av7110 *av7110 = dvbdev->priv; 1497d9bdf77296a00538faff95f29bf238857daea2e7Tobias Klauser int err = dvb_generic_open(inode, file); 14981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dprintk(2, "av7110:%p, \n", av7110); 15001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (err < 0) 15021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return err; 15031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dvb_ringbuffer_flush_spinlock_wakeup(&av7110->aout); 15041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->audiostate.stream_source = AUDIO_SOURCE_DEMUX; 15051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 15061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 15071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int dvb_audio_release(struct inode *inode, struct file *file) 15091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1510d9bdf77296a00538faff95f29bf238857daea2e7Tobias Klauser struct dvb_device *dvbdev = file->private_data; 1511d9bdf77296a00538faff95f29bf238857daea2e7Tobias Klauser struct av7110 *av7110 = dvbdev->priv; 15121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dprintk(2, "av7110:%p, \n", av7110); 15141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110_av_stop(av7110, RP_AUDIO); 15161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return dvb_generic_release(inode, file); 15171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 15181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/****************************************************************************** 15221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * driver registration 15231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ******************************************************************************/ 15241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1525784e29d2031b535637f65a8b81fb0871c7c51b3fJan Engelhardtstatic const struct file_operations dvb_video_fops = { 15261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .owner = THIS_MODULE, 15271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .write = dvb_video_write, 15281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .ioctl = dvb_generic_ioctl, 15291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .open = dvb_video_open, 15301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .release = dvb_video_release, 15311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .poll = dvb_video_poll, 15321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 15331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct dvb_device dvbdev_video = { 15351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .priv = NULL, 15361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .users = 6, 15371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .readers = 5, /* arbitrary */ 15381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .writers = 1, 15391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .fops = &dvb_video_fops, 15401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .kernel_ioctl = dvb_video_ioctl, 15411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 15421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1543784e29d2031b535637f65a8b81fb0871c7c51b3fJan Engelhardtstatic const struct file_operations dvb_audio_fops = { 15441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .owner = THIS_MODULE, 15451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .write = dvb_audio_write, 15461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .ioctl = dvb_generic_ioctl, 15471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .open = dvb_audio_open, 15481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .release = dvb_audio_release, 15491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .poll = dvb_audio_poll, 15501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 15511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct dvb_device dvbdev_audio = { 15531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .priv = NULL, 15541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .users = 1, 15551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .writers = 1, 15561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .fops = &dvb_audio_fops, 15571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .kernel_ioctl = dvb_audio_ioctl, 15581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 15591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint av7110_av_register(struct av7110 *av7110) 15621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 15631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->audiostate.AV_sync_state = 0; 15641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->audiostate.mute_state = 0; 15651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->audiostate.play_state = AUDIO_STOPPED; 15661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->audiostate.stream_source = AUDIO_SOURCE_DEMUX; 15671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->audiostate.channel_select = AUDIO_STEREO; 15681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->audiostate.bypass_mode = 0; 15691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->videostate.video_blank = 0; 15711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->videostate.play_state = VIDEO_STOPPED; 15721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->videostate.stream_source = VIDEO_SOURCE_DEMUX; 15731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->videostate.video_format = VIDEO_FORMAT_4_3; 1574defd574ec07edaa1587da144d03b18495ab484b1Oliver Endriss av7110->videostate.display_format = VIDEO_LETTER_BOX; 15751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->display_ar = VIDEO_FORMAT_4_3; 1576defd574ec07edaa1587da144d03b18495ab484b1Oliver Endriss av7110->display_panscan = VID_VC_AND_PS_PREF; 15771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds init_waitqueue_head(&av7110->video_events.wait_queue); 15791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_lock_init(&av7110->video_events.lock); 15801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->video_events.eventw = av7110->video_events.eventr = 0; 15811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->video_events.overflow = 0; 15821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memset(&av7110->video_size, 0, sizeof (video_size_t)); 15831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1584fdc53a6dbfea18e621dd23ed5cfb160837d7ce52Johannes Stezenbach dvb_register_device(&av7110->dvb_adapter, &av7110->video_dev, 15851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds &dvbdev_video, av7110, DVB_DEVICE_VIDEO); 15861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1587fdc53a6dbfea18e621dd23ed5cfb160837d7ce52Johannes Stezenbach dvb_register_device(&av7110->dvb_adapter, &av7110->audio_dev, 15881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds &dvbdev_audio, av7110, DVB_DEVICE_AUDIO); 15891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 15911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 15921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid av7110_av_unregister(struct av7110 *av7110) 15941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 15951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dvb_unregister_device(av7110->audio_dev); 15961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dvb_unregister_device(av7110->video_dev); 15971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 15981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint av7110_av_init(struct av7110 *av7110) 16001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 16011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds void (*play[])(u8 *, int, void *) = { play_audio_cb, play_video_cb }; 16021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i, ret; 16031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < 2; i++) { 16051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct ipack *ipack = av7110->ipack + i; 16061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ret = av7110_ipack_init(ipack, IPACKS, play[i]); 16081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ret < 0) { 16091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (i) 16101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110_ipack_free(--ipack); 16111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out; 16121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 16131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ipack->data = av7110; 16141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 16151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dvb_ringbuffer_init(&av7110->avout, av7110->iobuf, AVOUTLEN); 16171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dvb_ringbuffer_init(&av7110->aout, av7110->iobuf + AVOUTLEN, AOUTLEN); 16181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->kbuf[0] = (u8 *)(av7110->iobuf + AVOUTLEN + AOUTLEN + BMPLEN); 16201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->kbuf[1] = av7110->kbuf[0] + 2 * IPACKS; 16211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsout: 16221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ret; 16231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 16241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid av7110_av_exit(struct av7110 *av7110) 16261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 16271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110_ipack_free(&av7110->ipack[0]); 16281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110_ipack_free(&av7110->ipack[1]); 16291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1630