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 * 28631dd1a885b6d7e9f6f51b4e5b311c2bb04c323cJustin P. Mattock * the project's page is at http://www.linuxtv.org/ 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 return ret; 1971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 199ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewaldint av7110_av_stop(struct av7110 *av7110, int av) 2001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 201ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald int ret = 0; 2021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dprintk(2, "av7110:%p, \n", av7110); 2031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!(av7110->playing & av) && !(av7110->rec_mode & av)) 205ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald return 0; 2061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Stop, 0); 2071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->playing) { 2081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->playing &= ~av; 2091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (av7110->playing) { 2101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case RP_AUDIO: 211ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Play, 2, AudioPES, 0); 2121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 2131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case RP_VIDEO: 214ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Play, 2, VideoPES, 0); 2151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 2161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case RP_NONE: 217ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = av7110_set_vidmode(av7110, av7110->vidmode); 2181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 2191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 2211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->rec_mode &= ~av; 2221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (av7110->rec_mode) { 2231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case RP_AUDIO: 224ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Record, 2, AudioPES, 0); 2251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 2261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case RP_VIDEO: 227ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Record, 2, VideoPES, 0); 2281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 2291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case RP_NONE: 2301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 2311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 233ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald return ret; 2341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint av7110_pes_play(void *dest, struct dvb_ringbuffer *buf, int dlen) 2381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int len; 2401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u32 sync; 2411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u16 blen; 2421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!dlen) { 2441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds wake_up(&buf->queue); 2451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -1; 2461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (1) { 24892d0d66c1515c8ee3b700ab3d610587c71fe497fJulia Lawall len = dvb_ringbuffer_avail(buf); 24992d0d66c1515c8ee3b700ab3d610587c71fe497fJulia Lawall if (len < 6) { 25092d0d66c1515c8ee3b700ab3d610587c71fe497fJulia Lawall wake_up(&buf->queue); 2511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -1; 25292d0d66c1515c8ee3b700ab3d610587c71fe497fJulia Lawall } 2531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sync = DVB_RINGBUFFER_PEEK(buf, 0) << 24; 2541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sync |= DVB_RINGBUFFER_PEEK(buf, 1) << 16; 2551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sync |= DVB_RINGBUFFER_PEEK(buf, 2) << 8; 2561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sync |= DVB_RINGBUFFER_PEEK(buf, 3); 2571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (((sync &~ 0x0f) == 0x000001e0) || 2591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ((sync &~ 0x1f) == 0x000001c0) || 2601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (sync == 0x000001bd)) 2611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 2621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk("resync\n"); 2631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DVB_RINGBUFFER_SKIP(buf, 1); 2641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds blen = DVB_RINGBUFFER_PEEK(buf, 4) << 8; 2661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds blen |= DVB_RINGBUFFER_PEEK(buf, 5); 2671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds blen += 6; 2681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (len < blen || blen > dlen) { 2691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds //printk("buffer empty - avail %d blen %u dlen %d\n", len, blen, dlen); 2701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds wake_up(&buf->queue); 2711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -1; 2721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 274b0ba0e3ab6f452321771325b7b5578f9a804f69eAl Viro dvb_ringbuffer_read(buf, dest, (size_t) blen); 2751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dprintk(2, "pread=0x%08lx, pwrite=0x%08lx\n", 2771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (unsigned long) buf->pread, (unsigned long) buf->pwrite); 2781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds wake_up(&buf->queue); 2791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return blen; 2801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint av7110_set_volume(struct av7110 *av7110, int volleft, int volright) 2841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int err, vol, val, balance = 0; 2861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dprintk(2, "av7110:%p, \n", av7110); 2881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->mixer.volume_left = volleft; 2901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->mixer.volume_right = volright; 2911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (av7110->adac_type) { 2931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case DVB_ADAC_TI: 2941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds volleft = (volleft * 256) / 1036; 2951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds volright = (volright * 256) / 1036; 2961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (volleft > 0x3f) 2971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds volleft = 0x3f; 2981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (volright > 0x3f) 2991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds volright = 0x3f; 3001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((err = SendDAC(av7110, 3, 0x80 + volleft))) 3011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return err; 3021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return SendDAC(av7110, 4, volright); 3031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case DVB_ADAC_CRYSTAL: 3051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds volleft = 127 - volleft / 2; 3061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds volright = 127 - volright / 2; 3071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds i2c_writereg(av7110, 0x20, 0x03, volleft); 3081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds i2c_writereg(av7110, 0x20, 0x04, volright); 3091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 3101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3111c13b95c7d22d5c552246b465da4b364ba00ba65Marco Schluessler case DVB_ADAC_MSP34x0: 3121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds vol = (volleft > volright) ? volleft : volright; 3131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds val = (vol * 0x73 / 255) << 8; 3141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (vol > 0) 3151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds balance = ((volright - volleft) * 127) / vol; 3161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds msp_writereg(av7110, MSP_WR_DSP, 0x0001, balance << 8); 3171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds msp_writereg(av7110, MSP_WR_DSP, 0x0000, val); /* loudspeaker */ 3181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds msp_writereg(av7110, MSP_WR_DSP, 0x0006, val); /* headphonesr */ 3191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 32061391e0446e97bea44d93bd1624e5b32d3cc8474Tim Kaiser 32161391e0446e97bea44d93bd1624e5b32d3cc8474Tim Kaiser case DVB_ADAC_MSP34x5: 32261391e0446e97bea44d93bd1624e5b32d3cc8474Tim Kaiser vol = (volleft > volright) ? volleft : volright; 32361391e0446e97bea44d93bd1624e5b32d3cc8474Tim Kaiser val = (vol * 0x73 / 255) << 8; 32461391e0446e97bea44d93bd1624e5b32d3cc8474Tim Kaiser if (vol > 0) 32561391e0446e97bea44d93bd1624e5b32d3cc8474Tim Kaiser balance = ((volright - volleft) * 127) / vol; 32661391e0446e97bea44d93bd1624e5b32d3cc8474Tim Kaiser msp_writereg(av7110, MSP_WR_DSP, 0x0001, balance << 8); 32761391e0446e97bea44d93bd1624e5b32d3cc8474Tim Kaiser msp_writereg(av7110, MSP_WR_DSP, 0x0000, val); /* loudspeaker */ 32861391e0446e97bea44d93bd1624e5b32d3cc8474Tim Kaiser return 0; 3291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 33061391e0446e97bea44d93bd1624e5b32d3cc8474Tim Kaiser 3311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 3321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 33458a44040b4937c7d16b79a1b3048992eeac9853bMarco Schluesslerint av7110_set_vidmode(struct av7110 *av7110, enum av7110_video_mode mode) 3351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 336ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald int ret; 3371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dprintk(2, "av7110:%p, \n", av7110); 3381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 339ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = av7110_fw_cmd(av7110, COMTYPE_ENCODER, LoadVidCode, 1, mode); 3401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 341ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (!ret && !av7110->playing) { 342ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = ChangePIDs(av7110, av7110->pids[DMX_PES_VIDEO], 3431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->pids[DMX_PES_AUDIO], 3441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->pids[DMX_PES_TELETEXT], 3451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0, av7110->pids[DMX_PES_PCR]); 346ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (!ret) 347ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, Scan, 0); 3481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 349ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald return ret; 3501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 35358a44040b4937c7d16b79a1b3048992eeac9853bMarco Schluesslerstatic enum av7110_video_mode sw2mode[16] = { 35458a44040b4937c7d16b79a1b3048992eeac9853bMarco Schluessler AV7110_VIDEO_MODE_PAL, AV7110_VIDEO_MODE_NTSC, 35558a44040b4937c7d16b79a1b3048992eeac9853bMarco Schluessler AV7110_VIDEO_MODE_NTSC, AV7110_VIDEO_MODE_PAL, 35658a44040b4937c7d16b79a1b3048992eeac9853bMarco Schluessler AV7110_VIDEO_MODE_NTSC, AV7110_VIDEO_MODE_NTSC, 35758a44040b4937c7d16b79a1b3048992eeac9853bMarco Schluessler AV7110_VIDEO_MODE_PAL, AV7110_VIDEO_MODE_NTSC, 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, 36158a44040b4937c7d16b79a1b3048992eeac9853bMarco Schluessler AV7110_VIDEO_MODE_PAL, AV7110_VIDEO_MODE_PAL, 3621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 3631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 364ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewaldstatic int get_video_format(struct av7110 *av7110, u8 *buf, int count) 3651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 3671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int hsize, vsize; 3681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int sw; 3691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 *p; 370ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald int ret = 0; 3711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dprintk(2, "av7110:%p, \n", av7110); 3731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->sinfo) 375ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald return 0; 3761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 7; i < count - 10; i++) { 3771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p = buf + i; 3781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (p[0] || p[1] || p[2] != 0x01 || p[3] != 0xb3) 3791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds continue; 3801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p += 4; 3811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hsize = ((p[1] &0xF0) >> 4) | (p[0] << 4); 3821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds vsize = ((p[1] &0x0F) << 8) | (p[2]); 3831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sw = (p[3] & 0x0F); 384ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = av7110_set_vidmode(av7110, sw2mode[sw]); 385ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (!ret) { 386ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald dprintk(2, "playback %dx%d fr=%d\n", hsize, vsize, sw); 387ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald av7110->sinfo = 1; 388ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald } 3891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 3901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 391ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald return ret; 3921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/**************************************************************************** 3961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * I/O buffer management and control 3971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ****************************************************************************/ 3981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline long aux_ring_buffer_write(struct dvb_ringbuffer *rbuf, 400804b4458943f14bf144d3c3ba50097ced9b27b29Oliver Endriss const u8 *buf, unsigned long count) 4011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long todo = count; 4031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int free; 4041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (todo > 0) { 4061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (dvb_ringbuffer_free(rbuf) < 2048) { 4071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (wait_event_interruptible(rbuf->queue, 4081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (dvb_ringbuffer_free(rbuf) >= 2048))) 4091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count - todo; 4101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds free = dvb_ringbuffer_free(rbuf); 4121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (free > todo) 4131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds free = todo; 4141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dvb_ringbuffer_write(rbuf, buf, free); 4151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds todo -= free; 4161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buf += free; 4171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count - todo; 4201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void play_video_cb(u8 *buf, int count, void *priv) 4231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct av7110 *av7110 = (struct av7110 *) priv; 4251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dprintk(2, "av7110:%p, \n", av7110); 4261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((buf[3] & 0xe0) == 0xe0) { 4281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds get_video_format(av7110, buf, count); 4291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds aux_ring_buffer_write(&av7110->avout, buf, count); 4301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else 4311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds aux_ring_buffer_write(&av7110->aout, buf, count); 4321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void play_audio_cb(u8 *buf, int count, void *priv) 4351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct av7110 *av7110 = (struct av7110 *) priv; 4371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dprintk(2, "av7110:%p, \n", av7110); 4381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds aux_ring_buffer_write(&av7110->aout, buf, count); 4401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 442fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss 443fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss#define FREE_COND_TS (dvb_ringbuffer_free(rb) >= 4096) 444fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss 445fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endrissstatic ssize_t ts_play(struct av7110 *av7110, const char __user *buf, 446fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss unsigned long count, int nonblock, int type) 447fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss{ 448fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss struct dvb_ringbuffer *rb; 449fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss u8 *kb; 450fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss unsigned long todo = count; 451fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss 452fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss dprintk(2, "%s: type %d cnt %lu\n", __func__, type, count); 453fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss 454fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss rb = (type) ? &av7110->avout : &av7110->aout; 455fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss kb = av7110->kbuf[type]; 456fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss 457fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss if (!kb) 458fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss return -ENOBUFS; 459fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss 460fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss if (nonblock && !FREE_COND_TS) 461fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss return -EWOULDBLOCK; 462fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss 463fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss while (todo >= TS_SIZE) { 464fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss if (!FREE_COND_TS) { 465fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss if (nonblock) 466fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss return count - todo; 467fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss if (wait_event_interruptible(rb->queue, FREE_COND_TS)) 468fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss return count - todo; 469fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss } 470fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss if (copy_from_user(kb, buf, TS_SIZE)) 471fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss return -EFAULT; 472fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss write_ts_to_decoder(av7110, type, kb, TS_SIZE); 473fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss todo -= TS_SIZE; 474fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss buf += TS_SIZE; 475fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss } 476fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss 477fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss return count - todo; 478fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss} 479fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss 480fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss 4811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define FREE_COND (dvb_ringbuffer_free(&av7110->avout) >= 20 * 1024 && \ 4821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dvb_ringbuffer_free(&av7110->aout) >= 20 * 1024) 4831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 484804b4458943f14bf144d3c3ba50097ced9b27b29Oliver Endrissstatic ssize_t dvb_play(struct av7110 *av7110, const char __user *buf, 4851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long count, int nonblock, int type) 4861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long todo = count, n; 4881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dprintk(2, "av7110:%p, \n", av7110); 4891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!av7110->kbuf[type]) 4911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -ENOBUFS; 4921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (nonblock && !FREE_COND) 4941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EWOULDBLOCK; 4951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (todo > 0) { 4971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!FREE_COND) { 4981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (nonblock) 4991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count - todo; 5001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (wait_event_interruptible(av7110->avout.queue, 5011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FREE_COND)) 5021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count - todo; 5031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds n = todo; 5051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (n > IPACKS * 2) 5061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds n = IPACKS * 2; 5071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (copy_from_user(av7110->kbuf[type], buf, n)) 5081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EFAULT; 5091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110_ipack_instant_repack(av7110->kbuf[type], n, 5101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds &av7110->ipack[type]); 5111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds todo -= n; 5121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buf += n; 5131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count - todo; 5151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic ssize_t dvb_play_kernel(struct av7110 *av7110, const u8 *buf, 5181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long count, int nonblock, int type) 5191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 5201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long todo = count, n; 5211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dprintk(2, "av7110:%p, \n", av7110); 5221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!av7110->kbuf[type]) 5241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -ENOBUFS; 5251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (nonblock && !FREE_COND) 5271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EWOULDBLOCK; 5281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (todo > 0) { 5301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!FREE_COND) { 5311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (nonblock) 5321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count - todo; 5331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (wait_event_interruptible(av7110->avout.queue, 5341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FREE_COND)) 5351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count - todo; 5361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds n = todo; 5381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (n > IPACKS * 2) 5391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds n = IPACKS * 2; 5401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110_ipack_instant_repack(buf, n, &av7110->ipack[type]); 5411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds todo -= n; 5421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buf += n; 5431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count - todo; 5451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 547804b4458943f14bf144d3c3ba50097ced9b27b29Oliver Endrissstatic ssize_t dvb_aplay(struct av7110 *av7110, const char __user *buf, 5481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long count, int nonblock, int type) 5491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 5501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long todo = count, n; 5511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dprintk(2, "av7110:%p, \n", av7110); 5521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!av7110->kbuf[type]) 5541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -ENOBUFS; 5551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (nonblock && dvb_ringbuffer_free(&av7110->aout) < 20 * 1024) 5561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EWOULDBLOCK; 5571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (todo > 0) { 5591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (dvb_ringbuffer_free(&av7110->aout) < 20 * 1024) { 5601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (nonblock) 5611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count - todo; 5621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (wait_event_interruptible(av7110->aout.queue, 5631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (dvb_ringbuffer_free(&av7110->aout) >= 20 * 1024))) 5641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count-todo; 5651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds n = todo; 5671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (n > IPACKS * 2) 5681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds n = IPACKS * 2; 5691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (copy_from_user(av7110->kbuf[type], buf, n)) 5701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EFAULT; 5711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110_ipack_instant_repack(av7110->kbuf[type], n, 5721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds &av7110->ipack[type]); 5731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds todo -= n; 5741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buf += n; 5751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count - todo; 5771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid av7110_p2t_init(struct av7110_p2t *p, struct dvb_demux_feed *feed) 5801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 5811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memset(p->pes, 0, TS_SIZE); 5821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->counter = 0; 5831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->pos = 0; 5841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->frags = 0; 5851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (feed) 5861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->feed = feed; 5871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void clear_p2t(struct av7110_p2t *p) 5901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 5911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memset(p->pes, 0, TS_SIZE); 5921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds// p->counter = 0; 5931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->pos = 0; 5941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->frags = 0; 5951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int find_pes_header(u8 const *buf, long int length, int *frags) 5991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 6001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int c = 0; 6011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int found = 0; 6021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *frags = 0; 6041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (c < length - 3 && !found) { 6061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (buf[c] == 0x00 && buf[c + 1] == 0x00 && 6071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buf[c + 2] == 0x01) { 6081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch ( buf[c + 3] ) { 6091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case PROG_STREAM_MAP: 6101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case PRIVATE_STREAM2: 6111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case PROG_STREAM_DIR: 6121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case ECM_STREAM : 6131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case EMM_STREAM : 6141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case PADDING_STREAM : 6151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case DSM_CC_STREAM : 6161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case ISO13522_STREAM: 6171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case PRIVATE_STREAM1: 6181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case AUDIO_STREAM_S ... AUDIO_STREAM_E: 6191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case VIDEO_STREAM_S ... VIDEO_STREAM_E: 6201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds found = 1; 6211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 6221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 6241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c++; 6251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 6261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else 6281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c++; 6291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (c == length - 3 && !found) { 6311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (buf[length - 1] == 0x00) 6321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *frags = 1; 6331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (buf[length - 2] == 0x00 && 6341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buf[length - 1] == 0x00) 6351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *frags = 2; 6361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (buf[length - 3] == 0x00 && 6371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buf[length - 2] == 0x00 && 6381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buf[length - 1] == 0x01) 6391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *frags = 3; 6401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -1; 6411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return c; 6441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid av7110_p2t_write(u8 const *buf, long int length, u16 pid, struct av7110_p2t *p) 6471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 6481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int c, c2, l, add; 6491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int check, rest; 6501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c = 0; 6521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c2 = 0; 6531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (p->frags){ 6541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds check = 0; 6551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch(p->frags) { 6561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 1: 6571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (buf[c] == 0x00 && buf[c + 1] == 0x01) { 6581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds check = 1; 6591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c += 2; 6601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 6621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 2: 6631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (buf[c] == 0x01) { 6641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds check = 1; 6651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c++; 6661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 6681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 3: 6691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds check = 1; 6701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (check) { 6721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (buf[c]) { 6731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case PROG_STREAM_MAP: 6741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case PRIVATE_STREAM2: 6751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case PROG_STREAM_DIR: 6761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case ECM_STREAM : 6771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case EMM_STREAM : 6781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case PADDING_STREAM : 6791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case DSM_CC_STREAM : 6801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case ISO13522_STREAM: 6811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case PRIVATE_STREAM1: 6821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case AUDIO_STREAM_S ... AUDIO_STREAM_E: 6831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case VIDEO_STREAM_S ... VIDEO_STREAM_E: 6841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->pes[0] = 0x00; 6851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->pes[1] = 0x00; 6861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->pes[2] = 0x01; 6871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->pes[3] = buf[c]; 6881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->pos = 4; 6891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(p->pes + p->pos, buf + c, (TS_SIZE - 4) - p->pos); 6901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c += (TS_SIZE - 4) - p->pos; 6911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p_to_t(p->pes, (TS_SIZE - 4), pid, &p->counter, p->feed); 6921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds clear_p2t(p); 6931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 6941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 6961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c = 0; 6971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 6981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->frags = 0; 7011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (p->pos) { 7041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c2 = find_pes_header(buf + c, length - c, &p->frags); 7051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (c2 >= 0 && c2 < (TS_SIZE - 4) - p->pos) 7061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds l = c2+c; 7071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 7081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds l = (TS_SIZE - 4) - p->pos; 7091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(p->pes + p->pos, buf, l); 7101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c += l; 7111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->pos += l; 7121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p_to_t(p->pes, p->pos, pid, &p->counter, p->feed); 7131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds clear_p2t(p); 7141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds add = 0; 7171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (c < length) { 7181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c2 = find_pes_header(buf + c + add, length - c - add, &p->frags); 7191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (c2 >= 0) { 7201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c2 += c + add; 7211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (c2 > c){ 7221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p_to_t(buf + c, c2 - c, pid, &p->counter, p->feed); 7231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c = c2; 7241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds clear_p2t(p); 7251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds add = 0; 7261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else 7271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds add = 1; 7281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 7291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds l = length - c; 7301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rest = l % (TS_SIZE - 4); 7311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds l -= rest; 7321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p_to_t(buf + c, l, pid, &p->counter, p->feed); 7331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(p->pes, buf + c + l, rest); 7341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->pos = rest; 7351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c = length; 7361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int write_ts_header2(u16 pid, u8 *counter, int pes_start, u8 *buf, u8 length) 7421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 7431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 7441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int c = 0; 7451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int fill; 7461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 tshead[4] = { 0x47, 0x00, 0x00, 0x10 }; 7471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fill = (TS_SIZE - 4) - length; 7491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (pes_start) 7501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tshead[1] = 0x40; 7511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (fill) 7521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tshead[3] = 0x30; 7531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tshead[1] |= (u8)((pid & 0x1F00) >> 8); 7541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tshead[2] |= (u8)(pid & 0x00FF); 7551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tshead[3] |= ((*counter)++ & 0x0F); 7561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(buf, tshead, 4); 7571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c += 4; 7581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (fill) { 7601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buf[4] = fill - 1; 7611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c++; 7621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (fill > 1) { 7631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buf[5] = 0x00; 7641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c++; 7651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 6; i < fill + 4; i++) { 7671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buf[i] = 0xFF; 7681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c++; 7691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return c; 7731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void p_to_t(u8 const *buf, long int length, u16 pid, u8 *counter, 7771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct dvb_demux_feed *feed) 7781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 7791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int l, pes_start; 7801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 obuf[TS_SIZE]; 7811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds long c = 0; 7821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pes_start = 0; 7841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (length > 3 && 7851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buf[0] == 0x00 && buf[1] == 0x00 && buf[2] == 0x01) 7861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (buf[3]) { 7871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case PROG_STREAM_MAP: 7881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case PRIVATE_STREAM2: 7891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case PROG_STREAM_DIR: 7901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case ECM_STREAM : 7911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case EMM_STREAM : 7921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case PADDING_STREAM : 7931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case DSM_CC_STREAM : 7941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case ISO13522_STREAM: 7951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case PRIVATE_STREAM1: 7961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case AUDIO_STREAM_S ... AUDIO_STREAM_E: 7971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case VIDEO_STREAM_S ... VIDEO_STREAM_E: 7981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pes_start = 1; 7991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 8001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 8021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 8031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (c < length) { 8061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memset(obuf, 0, TS_SIZE); 8071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (length - c >= (TS_SIZE - 4)){ 8081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds l = write_ts_header2(pid, counter, pes_start, 8091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds obuf, (TS_SIZE - 4)); 8101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(obuf + l, buf + c, TS_SIZE - l); 8111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c += TS_SIZE - l; 8121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 8131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds l = write_ts_header2(pid, counter, pes_start, 8141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds obuf, length - c); 8151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(obuf + l, buf + c, TS_SIZE - l); 8161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c = length; 8171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds feed->cb.ts(obuf, 188, NULL, 0, &feed->feed.ts, DMX_OK); 8191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pes_start = 0; 8201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 8221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 824fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endrissstatic int write_ts_to_decoder(struct av7110 *av7110, int type, const u8 *buf, size_t len) 825fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss{ 826fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss struct ipack *ipack = &av7110->ipack[type]; 827fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss 828ef226d00dd041f753163fd3b69c7790496ab8384Oliver Endriss if (buf[1] & TRANS_ERROR) { 829ef226d00dd041f753163fd3b69c7790496ab8384Oliver Endriss av7110_ipack_reset(ipack); 830ef226d00dd041f753163fd3b69c7790496ab8384Oliver Endriss return -1; 831ef226d00dd041f753163fd3b69c7790496ab8384Oliver Endriss } 832ef226d00dd041f753163fd3b69c7790496ab8384Oliver Endriss 833fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss if (!(buf[3] & PAYLOAD)) 834fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss return -1; 835fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss 836fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss if (buf[1] & PAY_START) 837fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss av7110_ipack_flush(ipack); 838fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss 839fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss if (buf[3] & ADAPT_FIELD) { 840fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss len -= buf[4] + 1; 841fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss buf += buf[4] + 1; 842fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss if (!len) 843fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss return 0; 844fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss } 845fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss 846fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss av7110_ipack_instant_repack(buf + 4, len - 4, ipack); 847fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss return 0; 848fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss} 849fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss 850fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss 8511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint av7110_write_to_decoder(struct dvb_demux_feed *feed, const u8 *buf, size_t len) 8521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 8531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct dvb_demux *demux = feed->demux; 8541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct av7110 *av7110 = (struct av7110 *) demux->priv; 8551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dprintk(2, "av7110:%p, \n", av7110); 8571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8589e615eac827094147401c44c9ff955b468d4fa79Oliver Endriss if (av7110->full_ts && demux->dmx.frontend->source != DMX_MEMORY_FE) 8599e615eac827094147401c44c9ff955b468d4fa79Oliver Endriss return 0; 8609e615eac827094147401c44c9ff955b468d4fa79Oliver Endriss 8611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (feed->pes_type) { 8621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 0: 8631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->audiostate.stream_source == AUDIO_SOURCE_MEMORY) 8641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EINVAL; 8651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 8661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 1: 8671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->videostate.stream_source == VIDEO_SOURCE_MEMORY) 8681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EINVAL; 8691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 8701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 8711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -1; 8721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 874fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss return write_ts_to_decoder(av7110, feed->pes_type, buf, len); 8751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 8761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/****************************************************************************** 8801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Video MPEG decoder events 8811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ******************************************************************************/ 8821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid dvb_video_add_event(struct av7110 *av7110, struct video_event *event) 8831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 8841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct dvb_video_events *events = &av7110->video_events; 8851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int wp; 8861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_lock_bh(&events->lock); 8881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds wp = (events->eventw + 1) % MAX_VIDEO_EVENT; 8901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (wp == events->eventr) { 8911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds events->overflow = 1; 8921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds events->eventr = (events->eventr + 1) % MAX_VIDEO_EVENT; 8931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds //FIXME: timestamp? 8961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(&events->events[events->eventw], event, sizeof(struct video_event)); 8971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds events->eventw = wp; 8981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_unlock_bh(&events->lock); 9001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds wake_up_interruptible(&events->wait_queue); 9021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 9031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int dvb_video_get_event (struct av7110 *av7110, struct video_event *event, int flags) 9061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 9071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct dvb_video_events *events = &av7110->video_events; 9081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (events->overflow) { 9101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds events->overflow = 0; 9111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EOVERFLOW; 9121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 9131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (events->eventw == events->eventr) { 9141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int ret; 9151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (flags & O_NONBLOCK) 9171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EWOULDBLOCK; 9181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ret = wait_event_interruptible(events->wait_queue, 9201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds events->eventw != events->eventr); 9211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ret < 0) 9221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ret; 9231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 9241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_lock_bh(&events->lock); 9261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(event, &events->events[events->eventr], 9281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sizeof(struct video_event)); 9291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds events->eventr = (events->eventr + 1) % MAX_VIDEO_EVENT; 9301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_unlock_bh(&events->lock); 9321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 9341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 9351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/****************************************************************************** 9381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * DVB device file operations 9391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ******************************************************************************/ 9401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic unsigned int dvb_video_poll(struct file *file, poll_table *wait) 9421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 943d9bdf77296a00538faff95f29bf238857daea2e7Tobias Klauser struct dvb_device *dvbdev = file->private_data; 944d9bdf77296a00538faff95f29bf238857daea2e7Tobias Klauser struct av7110 *av7110 = dvbdev->priv; 9451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int mask = 0; 9461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dprintk(2, "av7110:%p, \n", av7110); 9481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((file->f_flags & O_ACCMODE) != O_RDONLY) 9501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds poll_wait(file, &av7110->avout.queue, wait); 9511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds poll_wait(file, &av7110->video_events.wait_queue, wait); 9531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->video_events.eventw != av7110->video_events.eventr) 9551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mask = POLLPRI; 9561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((file->f_flags & O_ACCMODE) != O_RDONLY) { 9581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->playing) { 9591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (FREE_COND) 9601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mask |= (POLLOUT | POLLWRNORM); 961bc8aacecf22922062e283b3032d5985af51e006aDan Carpenter } else { 962bc8aacecf22922062e283b3032d5985af51e006aDan Carpenter /* if not playing: may play if asked for */ 963bc8aacecf22922062e283b3032d5985af51e006aDan Carpenter mask |= (POLLOUT | POLLWRNORM); 964bc8aacecf22922062e283b3032d5985af51e006aDan Carpenter } 9651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 9661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return mask; 9681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 9691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic ssize_t dvb_video_write(struct file *file, const char __user *buf, 9711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds size_t count, loff_t *ppos) 9721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 973d9bdf77296a00538faff95f29bf238857daea2e7Tobias Klauser struct dvb_device *dvbdev = file->private_data; 974d9bdf77296a00538faff95f29bf238857daea2e7Tobias Klauser struct av7110 *av7110 = dvbdev->priv; 975fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss unsigned char c; 9761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dprintk(2, "av7110:%p, \n", av7110); 9781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((file->f_flags & O_ACCMODE) == O_RDONLY) 9801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EPERM; 9811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->videostate.stream_source != VIDEO_SOURCE_MEMORY) 9831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EPERM; 9841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 985fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss if (get_user(c, buf)) 986fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss return -EFAULT; 987fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss if (c == 0x47 && count % TS_SIZE == 0) 988fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss return ts_play(av7110, buf, count, file->f_flags & O_NONBLOCK, 1); 989fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss else 990fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss return dvb_play(av7110, buf, count, file->f_flags & O_NONBLOCK, 1); 9911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 9921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic unsigned int dvb_audio_poll(struct file *file, poll_table *wait) 9941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 995d9bdf77296a00538faff95f29bf238857daea2e7Tobias Klauser struct dvb_device *dvbdev = file->private_data; 996d9bdf77296a00538faff95f29bf238857daea2e7Tobias Klauser struct av7110 *av7110 = dvbdev->priv; 9971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int mask = 0; 9981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dprintk(2, "av7110:%p, \n", av7110); 10001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds poll_wait(file, &av7110->aout.queue, wait); 10021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->playing) { 10041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (dvb_ringbuffer_free(&av7110->aout) >= 20 * 1024) 10051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mask |= (POLLOUT | POLLWRNORM); 10061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else /* if not playing: may play if asked for */ 10071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mask = (POLLOUT | POLLWRNORM); 10081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return mask; 10101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 10111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic ssize_t dvb_audio_write(struct file *file, const char __user *buf, 10131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds size_t count, loff_t *ppos) 10141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1015d9bdf77296a00538faff95f29bf238857daea2e7Tobias Klauser struct dvb_device *dvbdev = file->private_data; 1016d9bdf77296a00538faff95f29bf238857daea2e7Tobias Klauser struct av7110 *av7110 = dvbdev->priv; 1017fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss unsigned char c; 10181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dprintk(2, "av7110:%p, \n", av7110); 10201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->audiostate.stream_source != AUDIO_SOURCE_MEMORY) { 10221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_ERR "not audio source memory\n"); 10231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EPERM; 10241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1025fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss 1026fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss if (get_user(c, buf)) 1027fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss return -EFAULT; 1028fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss if (c == 0x47 && count % TS_SIZE == 0) 1029fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss return ts_play(av7110, buf, count, file->f_flags & O_NONBLOCK, 0); 1030fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss else 1031fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bfOliver Endriss return dvb_aplay(av7110, buf, count, file->f_flags & O_NONBLOCK, 0); 10321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 10331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic u8 iframe_header[] = { 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x80, 0x00, 0x00 }; 10351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define MIN_IFRAME 400000 10371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1038804b4458943f14bf144d3c3ba50097ced9b27b29Oliver Endrissstatic int play_iframe(struct av7110 *av7110, char __user *buf, unsigned int len, int nonblock) 10391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1040a230e55d92347e09d9ba2e97096df114b2dfaf2dAl Viro unsigned i, n; 10410ed4a6ea9dbd9f5b77ce594f7f46be022d2c49ecOliver Endriss int progressive = 0; 1042a230e55d92347e09d9ba2e97096df114b2dfaf2dAl Viro int match = 0; 10431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dprintk(2, "av7110:%p, \n", av7110); 10451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!(av7110->playing & RP_VIDEO)) { 10471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110_av_start_play(av7110, RP_VIDEO) < 0) 10481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EBUSY; 10491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 10501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1051a230e55d92347e09d9ba2e97096df114b2dfaf2dAl Viro /* search in buf for instances of 00 00 01 b5 1? */ 1052a230e55d92347e09d9ba2e97096df114b2dfaf2dAl Viro for (i = 0; i < len; i++) { 1053a230e55d92347e09d9ba2e97096df114b2dfaf2dAl Viro unsigned char c; 1054a230e55d92347e09d9ba2e97096df114b2dfaf2dAl Viro if (get_user(c, buf + i)) 1055a230e55d92347e09d9ba2e97096df114b2dfaf2dAl Viro return -EFAULT; 1056a230e55d92347e09d9ba2e97096df114b2dfaf2dAl Viro if (match == 5) { 1057a230e55d92347e09d9ba2e97096df114b2dfaf2dAl Viro progressive = c & 0x08; 1058a230e55d92347e09d9ba2e97096df114b2dfaf2dAl Viro match = 0; 1059a230e55d92347e09d9ba2e97096df114b2dfaf2dAl Viro } 1060a230e55d92347e09d9ba2e97096df114b2dfaf2dAl Viro if (c == 0x00) { 1061a230e55d92347e09d9ba2e97096df114b2dfaf2dAl Viro match = (match == 1 || match == 2) ? 2 : 1; 1062a230e55d92347e09d9ba2e97096df114b2dfaf2dAl Viro continue; 1063a230e55d92347e09d9ba2e97096df114b2dfaf2dAl Viro } 1064a230e55d92347e09d9ba2e97096df114b2dfaf2dAl Viro switch (match++) { 1065a230e55d92347e09d9ba2e97096df114b2dfaf2dAl Viro case 2: if (c == 0x01) 1066a230e55d92347e09d9ba2e97096df114b2dfaf2dAl Viro continue; 1067a230e55d92347e09d9ba2e97096df114b2dfaf2dAl Viro break; 1068a230e55d92347e09d9ba2e97096df114b2dfaf2dAl Viro case 3: if (c == 0xb5) 1069a230e55d92347e09d9ba2e97096df114b2dfaf2dAl Viro continue; 1070a230e55d92347e09d9ba2e97096df114b2dfaf2dAl Viro break; 1071a230e55d92347e09d9ba2e97096df114b2dfaf2dAl Viro case 4: if ((c & 0xf0) == 0x10) 1072a230e55d92347e09d9ba2e97096df114b2dfaf2dAl Viro continue; 1073a230e55d92347e09d9ba2e97096df114b2dfaf2dAl Viro break; 1074a230e55d92347e09d9ba2e97096df114b2dfaf2dAl Viro } 1075a230e55d92347e09d9ba2e97096df114b2dfaf2dAl Viro match = 0; 10760ed4a6ea9dbd9f5b77ce594f7f46be022d2c49ecOliver Endriss } 10770ed4a6ea9dbd9f5b77ce594f7f46be022d2c49ecOliver Endriss 10781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* setting n always > 1, fixes problems when playing stillframes 10791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds consisting of I- and P-Frames */ 10801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds n = MIN_IFRAME / len + 1; 10811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* FIXME: nonblock? */ 10831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dvb_play_kernel(av7110, iframe_header, sizeof(iframe_header), 0, 1); 10841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < n; i++) 10861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dvb_play(av7110, buf, len, 0, 1); 10871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110_ipack_flush(&av7110->ipack[1]); 10890ed4a6ea9dbd9f5b77ce594f7f46be022d2c49ecOliver Endriss 10900ed4a6ea9dbd9f5b77ce594f7f46be022d2c49ecOliver Endriss if (progressive) 10910ed4a6ea9dbd9f5b77ce594f7f46be022d2c49ecOliver Endriss return vidcom(av7110, AV_VIDEO_CMD_FREEZE, 1); 10920ed4a6ea9dbd9f5b77ce594f7f46be022d2c49ecOliver Endriss else 10930ed4a6ea9dbd9f5b77ce594f7f46be022d2c49ecOliver Endriss return 0; 10941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 10951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 109716ef8def80ea97c3cacdcaa765bdf62b2d94f86dArnd Bergmannstatic int dvb_video_ioctl(struct file *file, 10981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int cmd, void *parg) 10991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1100d9bdf77296a00538faff95f29bf238857daea2e7Tobias Klauser struct dvb_device *dvbdev = file->private_data; 1101d9bdf77296a00538faff95f29bf238857daea2e7Tobias Klauser struct av7110 *av7110 = dvbdev->priv; 11021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long arg = (unsigned long) parg; 11031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int ret = 0; 11041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1105ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald dprintk(1, "av7110:%p, cmd=%04x\n", av7110,cmd); 11061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((file->f_flags & O_ACCMODE) == O_RDONLY) { 11081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ( cmd != VIDEO_GET_STATUS && cmd != VIDEO_GET_EVENT && 11091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cmd != VIDEO_GET_SIZE ) { 11101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EPERM; 11111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 11121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 11131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 111430ad64b8ac539459f8975aa186421ef3db0bb5cbNikolaus Schulz if (mutex_lock_interruptible(&av7110->ioctl_mutex)) 111530ad64b8ac539459f8975aa186421ef3db0bb5cbNikolaus Schulz return -ERESTARTSYS; 111630ad64b8ac539459f8975aa186421ef3db0bb5cbNikolaus Schulz 11171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (cmd) { 11181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case VIDEO_STOP: 11191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->videostate.play_state = VIDEO_STOPPED; 11201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->videostate.stream_source == VIDEO_SOURCE_MEMORY) 1121ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = av7110_av_stop(av7110, RP_VIDEO); 11221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 11232435be11ae1afb64ac7dfb25e10b6e3037ab0522Hans Verkuil ret = vidcom(av7110, AV_VIDEO_CMD_STOP, 11241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->videostate.video_blank ? 0 : 1); 1125ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (!ret) 1126ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald av7110->trickmode = TRICK_NONE; 11271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 11281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case VIDEO_PLAY: 11301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->trickmode = TRICK_NONE; 11311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->videostate.play_state == VIDEO_FREEZED) { 11321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->videostate.play_state = VIDEO_PLAYING; 11332435be11ae1afb64ac7dfb25e10b6e3037ab0522Hans Verkuil ret = vidcom(av7110, AV_VIDEO_CMD_PLAY, 0); 1134ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (ret) 1135ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald break; 11361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 11371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->videostate.stream_source == VIDEO_SOURCE_MEMORY) { 11381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->playing == RP_AV) { 1139ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Stop, 0); 1140ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (ret) 1141ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald break; 11421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->playing &= ~RP_VIDEO; 11431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1144ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = av7110_av_start_play(av7110, RP_VIDEO); 11451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1146ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (!ret) 11472435be11ae1afb64ac7dfb25e10b6e3037ab0522Hans Verkuil ret = vidcom(av7110, AV_VIDEO_CMD_PLAY, 0); 1148ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (!ret) 1149ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald av7110->videostate.play_state = VIDEO_PLAYING; 11501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 11511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case VIDEO_FREEZE: 11531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->videostate.play_state = VIDEO_FREEZED; 11541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->playing & RP_VIDEO) 1155ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Pause, 0); 11561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 11572435be11ae1afb64ac7dfb25e10b6e3037ab0522Hans Verkuil ret = vidcom(av7110, AV_VIDEO_CMD_FREEZE, 1); 1158ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (!ret) 1159ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald av7110->trickmode = TRICK_FREEZE; 11601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 11611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case VIDEO_CONTINUE: 11631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->playing & RP_VIDEO) 1164ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Continue, 0); 1165ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (!ret) 11662435be11ae1afb64ac7dfb25e10b6e3037ab0522Hans Verkuil ret = vidcom(av7110, AV_VIDEO_CMD_PLAY, 0); 1167ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (!ret) { 1168ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald av7110->videostate.play_state = VIDEO_PLAYING; 1169ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald av7110->trickmode = TRICK_NONE; 1170ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald } 11711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 11721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case VIDEO_SELECT_SOURCE: 11741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->videostate.stream_source = (video_stream_source_t) arg; 11751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 11761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case VIDEO_SET_BLANK: 11781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->videostate.video_blank = (int) arg; 11791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 11801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case VIDEO_GET_STATUS: 11821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(parg, &av7110->videostate, sizeof(struct video_status)); 11831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 11841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case VIDEO_GET_EVENT: 1186ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = dvb_video_get_event(av7110, parg, file->f_flags); 11871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 11881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case VIDEO_GET_SIZE: 11901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(parg, &av7110->video_size, sizeof(video_size_t)); 11911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 11921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case VIDEO_SET_DISPLAY_FORMAT: 11941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 11951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds video_displayformat_t format = (video_displayformat_t) arg; 11961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (format) { 11971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case VIDEO_PAN_SCAN: 1198defd574ec07edaa1587da144d03b18495ab484b1Oliver Endriss av7110->display_panscan = VID_PAN_SCAN_PREF; 11991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 12001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case VIDEO_LETTER_BOX: 1201defd574ec07edaa1587da144d03b18495ab484b1Oliver Endriss av7110->display_panscan = VID_VC_AND_PS_PREF; 12021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 12031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case VIDEO_CENTER_CUT_OUT: 1204defd574ec07edaa1587da144d03b18495ab484b1Oliver Endriss av7110->display_panscan = VID_CENTRE_CUT_PREF; 12051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 12061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 12071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ret = -EINVAL; 12081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 12091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ret < 0) 12101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 1211a65d3bb7177cbab1fca69dd97537766c2817b6b2Johannes Stezenbach av7110->videostate.display_format = format; 12121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ret = av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetPanScanType, 1213defd574ec07edaa1587da144d03b18495ab484b1Oliver Endriss 1, av7110->display_panscan); 12141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 12151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 12161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case VIDEO_SET_FORMAT: 12181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (arg > 1) { 12191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ret = -EINVAL; 12201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 12211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 12221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->display_ar = arg; 12231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ret = av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetMonitorType, 12241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1, (u16) arg); 12251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 12261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case VIDEO_STILLPICTURE: 12281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 12291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct video_still_picture *pic = 12301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (struct video_still_picture *) parg; 12311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->videostate.stream_source = VIDEO_SOURCE_MEMORY; 12321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dvb_ringbuffer_flush_spinlock_wakeup(&av7110->avout); 12331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ret = play_iframe(av7110, pic->iFrame, pic->size, 12341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds file->f_flags & O_NONBLOCK); 12351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 12361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 12371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case VIDEO_FAST_FORWARD: 12391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds //note: arg is ignored by firmware 12401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->playing & RP_VIDEO) 1241ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, 12427a2fa90fa8084846937aa194f8a40abfa99c692fJohannes Stezenbach __Scan_I, 2, AV_PES, 0); 12431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 12442435be11ae1afb64ac7dfb25e10b6e3037ab0522Hans Verkuil ret = vidcom(av7110, AV_VIDEO_CMD_FFWD, arg); 1245ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (!ret) { 1246ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald av7110->trickmode = TRICK_FAST; 1247ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald av7110->videostate.play_state = VIDEO_PLAYING; 1248ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald } 12491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 12501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case VIDEO_SLOWMOTION: 12521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->playing&RP_VIDEO) { 1253452dac4550f757ef263c324d967414aa6c6122d7Oliver Endriss if (av7110->trickmode != TRICK_SLOW) 1254452dac4550f757ef263c324d967414aa6c6122d7Oliver Endriss ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Slow, 2, 0, 0); 1255ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (!ret) 12562435be11ae1afb64ac7dfb25e10b6e3037ab0522Hans Verkuil ret = vidcom(av7110, AV_VIDEO_CMD_SLOW, arg); 12571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 12582435be11ae1afb64ac7dfb25e10b6e3037ab0522Hans Verkuil ret = vidcom(av7110, AV_VIDEO_CMD_PLAY, 0); 1259ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (!ret) 12602435be11ae1afb64ac7dfb25e10b6e3037ab0522Hans Verkuil ret = vidcom(av7110, AV_VIDEO_CMD_STOP, 0); 1261ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (!ret) 12622435be11ae1afb64ac7dfb25e10b6e3037ab0522Hans Verkuil ret = vidcom(av7110, AV_VIDEO_CMD_SLOW, arg); 1263ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald } 1264ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (!ret) { 1265ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald av7110->trickmode = TRICK_SLOW; 1266ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald av7110->videostate.play_state = VIDEO_PLAYING; 12671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 12681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 12691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case VIDEO_GET_CAPABILITIES: 12711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *(int *)parg = VIDEO_CAP_MPEG1 | VIDEO_CAP_MPEG2 | 12721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds VIDEO_CAP_SYS | VIDEO_CAP_PROG; 12731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 12741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case VIDEO_CLEAR_BUFFER: 12761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dvb_ringbuffer_flush_spinlock_wakeup(&av7110->avout); 12771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110_ipack_reset(&av7110->ipack[1]); 12781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->playing == RP_AV) { 1279ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, 12807a2fa90fa8084846937aa194f8a40abfa99c692fJohannes Stezenbach __Play, 2, AV_PES, 0); 1281ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (ret) 1282ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald break; 12831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->trickmode == TRICK_FAST) 1284ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, 12857a2fa90fa8084846937aa194f8a40abfa99c692fJohannes Stezenbach __Scan_I, 2, AV_PES, 0); 12861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->trickmode == TRICK_SLOW) { 1287ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, 12887a2fa90fa8084846937aa194f8a40abfa99c692fJohannes Stezenbach __Slow, 2, 0, 0); 1289ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (!ret) 12902435be11ae1afb64ac7dfb25e10b6e3037ab0522Hans Verkuil ret = vidcom(av7110, AV_VIDEO_CMD_SLOW, arg); 12911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 12921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->trickmode == TRICK_FREEZE) 12932435be11ae1afb64ac7dfb25e10b6e3037ab0522Hans Verkuil ret = vidcom(av7110, AV_VIDEO_CMD_STOP, 1); 12941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 12951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 12961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case VIDEO_SET_STREAMTYPE: 12981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 12991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 13011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ret = -ENOIOCTLCMD; 13021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 13031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1304ea3b73dc13d87d92e805f439f3d7bfcb5865db06Oliver Endriss 130530ad64b8ac539459f8975aa186421ef3db0bb5cbNikolaus Schulz mutex_unlock(&av7110->ioctl_mutex); 13061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ret; 13071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 13081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 130916ef8def80ea97c3cacdcaa765bdf62b2d94f86dArnd Bergmannstatic int dvb_audio_ioctl(struct file *file, 13101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int cmd, void *parg) 13111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1312d9bdf77296a00538faff95f29bf238857daea2e7Tobias Klauser struct dvb_device *dvbdev = file->private_data; 1313d9bdf77296a00538faff95f29bf238857daea2e7Tobias Klauser struct av7110 *av7110 = dvbdev->priv; 13141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long arg = (unsigned long) parg; 13151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int ret = 0; 13161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1317ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald dprintk(1, "av7110:%p, cmd=%04x\n", av7110,cmd); 13181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (((file->f_flags & O_ACCMODE) == O_RDONLY) && 13201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (cmd != AUDIO_GET_STATUS)) 13211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EPERM; 13221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 132330ad64b8ac539459f8975aa186421ef3db0bb5cbNikolaus Schulz if (mutex_lock_interruptible(&av7110->ioctl_mutex)) 132430ad64b8ac539459f8975aa186421ef3db0bb5cbNikolaus Schulz return -ERESTARTSYS; 132530ad64b8ac539459f8975aa186421ef3db0bb5cbNikolaus Schulz 13261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (cmd) { 13271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case AUDIO_STOP: 13281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->audiostate.stream_source == AUDIO_SOURCE_MEMORY) 1329ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = av7110_av_stop(av7110, RP_AUDIO); 13301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 1331ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = audcom(av7110, AUDIO_CMD_MUTE); 1332ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (!ret) 1333ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald av7110->audiostate.play_state = AUDIO_STOPPED; 13341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 13351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case AUDIO_PLAY: 13371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->audiostate.stream_source == AUDIO_SOURCE_MEMORY) 1338ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = av7110_av_start_play(av7110, RP_AUDIO); 1339ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (!ret) 1340ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = audcom(av7110, AUDIO_CMD_UNMUTE); 1341ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (!ret) 1342ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald av7110->audiostate.play_state = AUDIO_PLAYING; 13431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 13441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case AUDIO_PAUSE: 1346ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = audcom(av7110, AUDIO_CMD_MUTE); 1347ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (!ret) 1348ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald av7110->audiostate.play_state = AUDIO_PAUSED; 13491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 13501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case AUDIO_CONTINUE: 13521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->audiostate.play_state == AUDIO_PAUSED) { 13531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->audiostate.play_state = AUDIO_PLAYING; 1354ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = audcom(av7110, AUDIO_CMD_UNMUTE | AUDIO_CMD_PCM16); 13551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 13561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 13571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case AUDIO_SELECT_SOURCE: 13591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->audiostate.stream_source = (audio_stream_source_t) arg; 13601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 13611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case AUDIO_SET_MUTE: 13631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 1364ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = audcom(av7110, arg ? AUDIO_CMD_MUTE : AUDIO_CMD_UNMUTE); 1365ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (!ret) 1366ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald av7110->audiostate.mute_state = (int) arg; 13671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 13681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 13691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case AUDIO_SET_AV_SYNC: 13711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->audiostate.AV_sync_state = (int) arg; 1372ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = audcom(av7110, arg ? AUDIO_CMD_SYNC_ON : AUDIO_CMD_SYNC_OFF); 13731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 13741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case AUDIO_SET_BYPASS_MODE: 137647f3692096eef208d8cb455bfa2b3308cdfc40deDr. Werner Fink if (FW_VERSION(av7110->arm_app) < 0x2621) 137747f3692096eef208d8cb455bfa2b3308cdfc40deDr. Werner Fink ret = -EINVAL; 137847f3692096eef208d8cb455bfa2b3308cdfc40deDr. Werner Fink av7110->audiostate.bypass_mode = (int)arg; 13791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 13801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case AUDIO_CHANNEL_SELECT: 13821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->audiostate.channel_select = (audio_channel_select_t) arg; 13831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch(av7110->audiostate.channel_select) { 13841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case AUDIO_STEREO: 1385ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = audcom(av7110, AUDIO_CMD_STEREO); 138661391e0446e97bea44d93bd1624e5b32d3cc8474Tim Kaiser if (!ret) { 1387ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (av7110->adac_type == DVB_ADAC_CRYSTAL) 1388ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald i2c_writereg(av7110, 0x20, 0x02, 0x49); 138961391e0446e97bea44d93bd1624e5b32d3cc8474Tim Kaiser else if (av7110->adac_type == DVB_ADAC_MSP34x5) 139061391e0446e97bea44d93bd1624e5b32d3cc8474Tim Kaiser msp_writereg(av7110, MSP_WR_DSP, 0x0008, 0x0220); 139161391e0446e97bea44d93bd1624e5b32d3cc8474Tim Kaiser } 13921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 13931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case AUDIO_MONO_LEFT: 1394ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = audcom(av7110, AUDIO_CMD_MONO_L); 139561391e0446e97bea44d93bd1624e5b32d3cc8474Tim Kaiser if (!ret) { 1396ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (av7110->adac_type == DVB_ADAC_CRYSTAL) 1397ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald i2c_writereg(av7110, 0x20, 0x02, 0x4a); 139861391e0446e97bea44d93bd1624e5b32d3cc8474Tim Kaiser else if (av7110->adac_type == DVB_ADAC_MSP34x5) 139961391e0446e97bea44d93bd1624e5b32d3cc8474Tim Kaiser msp_writereg(av7110, MSP_WR_DSP, 0x0008, 0x0200); 140061391e0446e97bea44d93bd1624e5b32d3cc8474Tim Kaiser } 14011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 14021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case AUDIO_MONO_RIGHT: 1403ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = audcom(av7110, AUDIO_CMD_MONO_R); 140461391e0446e97bea44d93bd1624e5b32d3cc8474Tim Kaiser if (!ret) { 1405ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald if (av7110->adac_type == DVB_ADAC_CRYSTAL) 1406ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald i2c_writereg(av7110, 0x20, 0x02, 0x45); 140761391e0446e97bea44d93bd1624e5b32d3cc8474Tim Kaiser else if (av7110->adac_type == DVB_ADAC_MSP34x5) 140861391e0446e97bea44d93bd1624e5b32d3cc8474Tim Kaiser msp_writereg(av7110, MSP_WR_DSP, 0x0008, 0x0210); 140961391e0446e97bea44d93bd1624e5b32d3cc8474Tim Kaiser } 14101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 14111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 14121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ret = -EINVAL; 14131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 14141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 14151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 14161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case AUDIO_GET_STATUS: 14181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(parg, &av7110->audiostate, sizeof(struct audio_status)); 14191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 14201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case AUDIO_GET_CAPABILITIES: 142247f3692096eef208d8cb455bfa2b3308cdfc40deDr. Werner Fink if (FW_VERSION(av7110->arm_app) < 0x2621) 142347f3692096eef208d8cb455bfa2b3308cdfc40deDr. Werner Fink *(unsigned int *)parg = AUDIO_CAP_LPCM | AUDIO_CAP_MP1 | AUDIO_CAP_MP2; 142447f3692096eef208d8cb455bfa2b3308cdfc40deDr. Werner Fink else 142547f3692096eef208d8cb455bfa2b3308cdfc40deDr. Werner Fink *(unsigned int *)parg = AUDIO_CAP_LPCM | AUDIO_CAP_DTS | AUDIO_CAP_AC3 | 142647f3692096eef208d8cb455bfa2b3308cdfc40deDr. Werner Fink AUDIO_CAP_MP1 | AUDIO_CAP_MP2; 14271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 14281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case AUDIO_CLEAR_BUFFER: 14301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dvb_ringbuffer_flush_spinlock_wakeup(&av7110->aout); 14311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110_ipack_reset(&av7110->ipack[0]); 14321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (av7110->playing == RP_AV) 1433ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, 14347a2fa90fa8084846937aa194f8a40abfa99c692fJohannes Stezenbach __Play, 2, AV_PES, 0); 14351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 14361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1437ea3b73dc13d87d92e805f439f3d7bfcb5865db06Oliver Endriss case AUDIO_SET_ID: 14381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 1439ea3b73dc13d87d92e805f439f3d7bfcb5865db06Oliver Endriss 14401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case AUDIO_SET_MIXER: 14411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 14421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct audio_mixer *amix = (struct audio_mixer *)parg; 1443ce18a223607b0e8cc9a8375abc64281a13ac423cWolfgang Rohdewald ret = av7110_set_volume(av7110, amix->volume_left, amix->volume_right); 14441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 14451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1446ea3b73dc13d87d92e805f439f3d7bfcb5865db06Oliver Endriss 14471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case AUDIO_SET_STREAMTYPE: 14481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 1449ea3b73dc13d87d92e805f439f3d7bfcb5865db06Oliver Endriss 14501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 14511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ret = -ENOIOCTLCMD; 14521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1453ea3b73dc13d87d92e805f439f3d7bfcb5865db06Oliver Endriss 145430ad64b8ac539459f8975aa186421ef3db0bb5cbNikolaus Schulz mutex_unlock(&av7110->ioctl_mutex); 14551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ret; 14561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 14571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int dvb_video_open(struct inode *inode, struct file *file) 14601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1461d9bdf77296a00538faff95f29bf238857daea2e7Tobias Klauser struct dvb_device *dvbdev = file->private_data; 1462d9bdf77296a00538faff95f29bf238857daea2e7Tobias Klauser struct av7110 *av7110 = dvbdev->priv; 14631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int err; 14641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dprintk(2, "av7110:%p, \n", av7110); 14661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((err = dvb_generic_open(inode, file)) < 0) 14681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return err; 14691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((file->f_flags & O_ACCMODE) != O_RDONLY) { 14711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dvb_ringbuffer_flush_spinlock_wakeup(&av7110->aout); 14721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dvb_ringbuffer_flush_spinlock_wakeup(&av7110->avout); 14731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->video_blank = 1; 14741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->audiostate.AV_sync_state = 1; 14751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->videostate.stream_source = VIDEO_SOURCE_DEMUX; 14761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* empty event queue */ 14781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->video_events.eventr = av7110->video_events.eventw = 0; 14791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 14801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 14821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 14831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int dvb_video_release(struct inode *inode, struct file *file) 14851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1486d9bdf77296a00538faff95f29bf238857daea2e7Tobias Klauser struct dvb_device *dvbdev = file->private_data; 1487d9bdf77296a00538faff95f29bf238857daea2e7Tobias Klauser struct av7110 *av7110 = dvbdev->priv; 14881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dprintk(2, "av7110:%p, \n", av7110); 14901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((file->f_flags & O_ACCMODE) != O_RDONLY) { 14921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110_av_stop(av7110, RP_VIDEO); 14931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 14941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return dvb_generic_release(inode, file); 14961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 14971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int dvb_audio_open(struct inode *inode, struct file *file) 14991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1500d9bdf77296a00538faff95f29bf238857daea2e7Tobias Klauser struct dvb_device *dvbdev = file->private_data; 1501d9bdf77296a00538faff95f29bf238857daea2e7Tobias Klauser struct av7110 *av7110 = dvbdev->priv; 1502d9bdf77296a00538faff95f29bf238857daea2e7Tobias Klauser int err = dvb_generic_open(inode, file); 15031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dprintk(2, "av7110:%p, \n", av7110); 15051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (err < 0) 15071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return err; 15081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dvb_ringbuffer_flush_spinlock_wakeup(&av7110->aout); 15091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->audiostate.stream_source = AUDIO_SOURCE_DEMUX; 15101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 15111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 15121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int dvb_audio_release(struct inode *inode, struct file *file) 15141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1515d9bdf77296a00538faff95f29bf238857daea2e7Tobias Klauser struct dvb_device *dvbdev = file->private_data; 1516d9bdf77296a00538faff95f29bf238857daea2e7Tobias Klauser struct av7110 *av7110 = dvbdev->priv; 15171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dprintk(2, "av7110:%p, \n", av7110); 15191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110_av_stop(av7110, RP_AUDIO); 15211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return dvb_generic_release(inode, file); 15221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 15231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/****************************************************************************** 15271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * driver registration 15281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ******************************************************************************/ 15291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1530784e29d2031b535637f65a8b81fb0871c7c51b3fJan Engelhardtstatic const struct file_operations dvb_video_fops = { 15311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .owner = THIS_MODULE, 15321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .write = dvb_video_write, 153316ef8def80ea97c3cacdcaa765bdf62b2d94f86dArnd Bergmann .unlocked_ioctl = dvb_generic_ioctl, 15341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .open = dvb_video_open, 15351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .release = dvb_video_release, 15361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .poll = dvb_video_poll, 15376038f373a3dc1f1c26496e60b6c40b164716f07eArnd Bergmann .llseek = noop_llseek, 15381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 15391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct dvb_device dvbdev_video = { 15411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .priv = NULL, 15421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .users = 6, 15431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .readers = 5, /* arbitrary */ 15441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .writers = 1, 15451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .fops = &dvb_video_fops, 15461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .kernel_ioctl = dvb_video_ioctl, 15471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 15481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1549784e29d2031b535637f65a8b81fb0871c7c51b3fJan Engelhardtstatic const struct file_operations dvb_audio_fops = { 15501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .owner = THIS_MODULE, 15511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .write = dvb_audio_write, 155216ef8def80ea97c3cacdcaa765bdf62b2d94f86dArnd Bergmann .unlocked_ioctl = dvb_generic_ioctl, 15531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .open = dvb_audio_open, 15541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .release = dvb_audio_release, 15551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .poll = dvb_audio_poll, 15566038f373a3dc1f1c26496e60b6c40b164716f07eArnd Bergmann .llseek = noop_llseek, 15571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 15581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct dvb_device dvbdev_audio = { 15601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .priv = NULL, 15611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .users = 1, 15621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .writers = 1, 15631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .fops = &dvb_audio_fops, 15641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .kernel_ioctl = dvb_audio_ioctl, 15651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 15661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint av7110_av_register(struct av7110 *av7110) 15691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 15701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->audiostate.AV_sync_state = 0; 15711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->audiostate.mute_state = 0; 15721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->audiostate.play_state = AUDIO_STOPPED; 15731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->audiostate.stream_source = AUDIO_SOURCE_DEMUX; 15741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->audiostate.channel_select = AUDIO_STEREO; 15751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->audiostate.bypass_mode = 0; 15761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->videostate.video_blank = 0; 15781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->videostate.play_state = VIDEO_STOPPED; 15791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->videostate.stream_source = VIDEO_SOURCE_DEMUX; 15801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->videostate.video_format = VIDEO_FORMAT_4_3; 1581defd574ec07edaa1587da144d03b18495ab484b1Oliver Endriss av7110->videostate.display_format = VIDEO_LETTER_BOX; 15821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->display_ar = VIDEO_FORMAT_4_3; 1583defd574ec07edaa1587da144d03b18495ab484b1Oliver Endriss av7110->display_panscan = VID_VC_AND_PS_PREF; 15841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds init_waitqueue_head(&av7110->video_events.wait_queue); 15861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_lock_init(&av7110->video_events.lock); 15871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->video_events.eventw = av7110->video_events.eventr = 0; 15881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->video_events.overflow = 0; 15891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memset(&av7110->video_size, 0, sizeof (video_size_t)); 15901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1591fdc53a6dbfea18e621dd23ed5cfb160837d7ce52Johannes Stezenbach dvb_register_device(&av7110->dvb_adapter, &av7110->video_dev, 15921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds &dvbdev_video, av7110, DVB_DEVICE_VIDEO); 15931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1594fdc53a6dbfea18e621dd23ed5cfb160837d7ce52Johannes Stezenbach dvb_register_device(&av7110->dvb_adapter, &av7110->audio_dev, 15951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds &dvbdev_audio, av7110, DVB_DEVICE_AUDIO); 15961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 15981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 15991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid av7110_av_unregister(struct av7110 *av7110) 16011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 16021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dvb_unregister_device(av7110->audio_dev); 16031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dvb_unregister_device(av7110->video_dev); 16041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 16051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint av7110_av_init(struct av7110 *av7110) 16071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 16081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds void (*play[])(u8 *, int, void *) = { play_audio_cb, play_video_cb }; 16091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i, ret; 16101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < 2; i++) { 16121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct ipack *ipack = av7110->ipack + i; 16131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ret = av7110_ipack_init(ipack, IPACKS, play[i]); 16151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ret < 0) { 16161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (i) 16171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110_ipack_free(--ipack); 16181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out; 16191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 16201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ipack->data = av7110; 16211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 16221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dvb_ringbuffer_init(&av7110->avout, av7110->iobuf, AVOUTLEN); 16241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dvb_ringbuffer_init(&av7110->aout, av7110->iobuf + AVOUTLEN, AOUTLEN); 16251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->kbuf[0] = (u8 *)(av7110->iobuf + AVOUTLEN + AOUTLEN + BMPLEN); 16271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110->kbuf[1] = av7110->kbuf[0] + 2 * IPACKS; 16281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsout: 16291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ret; 16301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 16311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid av7110_av_exit(struct av7110 *av7110) 16331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 16341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110_ipack_free(&av7110->ipack[0]); 16351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110_ipack_free(&av7110->ipack[1]); 16361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1637