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