1*74a4d8c2SCharles.Forsyth /*
2*74a4d8c2SCharles.Forsyth * Boffin MPEG decoder
3*74a4d8c2SCharles.Forsyth */
4*74a4d8c2SCharles.Forsyth #include "u.h"
5*74a4d8c2SCharles.Forsyth #include "../port/lib.h"
6*74a4d8c2SCharles.Forsyth #include "mem.h"
7*74a4d8c2SCharles.Forsyth #include "dat.h"
8*74a4d8c2SCharles.Forsyth #include "fns.h"
9*74a4d8c2SCharles.Forsyth #include "../port/error.h"
10*74a4d8c2SCharles.Forsyth #include "zoran.h"
11*74a4d8c2SCharles.Forsyth #include "crystal.h"
12*74a4d8c2SCharles.Forsyth #include "io.h"
13*74a4d8c2SCharles.Forsyth
14*74a4d8c2SCharles.Forsyth enum
15*74a4d8c2SCharles.Forsyth {
16*74a4d8c2SCharles.Forsyth
17*74a4d8c2SCharles.Forsyth CPUACCCTRL = 0x20, /* Trident Window Chip control registers */
18*74a4d8c2SCharles.Forsyth CPUACCMD = 0x21,
19*74a4d8c2SCharles.Forsyth BNKADR = 0x22,
20*74a4d8c2SCharles.Forsyth SYSCONFIG = 0x23,
21*74a4d8c2SCharles.Forsyth VGACOMP = 0x24,
22*74a4d8c2SCharles.Forsyth VGAMASK = 0x25,
23*74a4d8c2SCharles.Forsyth VIDCOMPL = 0x26,
24*74a4d8c2SCharles.Forsyth VIDCOMPH = 0x27,
25*74a4d8c2SCharles.Forsyth MOS = 0x28,
26*74a4d8c2SCharles.Forsyth DISPCTRL = 0x29,
27*74a4d8c2SCharles.Forsyth CAPCTRL = 0x2a,
28*74a4d8c2SCharles.Forsyth OVLKT = 0x2b,
29*74a4d8c2SCharles.Forsyth OVLWINHSTRT = 0x2c,
30*74a4d8c2SCharles.Forsyth OVLWINVSTRT = 0x2d,
31*74a4d8c2SCharles.Forsyth OVLWINHEND = 0x2e,
32*74a4d8c2SCharles.Forsyth OVLWINVEND = 0x2f,
33*74a4d8c2SCharles.Forsyth RESERVED1 = 0x30,
34*74a4d8c2SCharles.Forsyth RESERVED2 = 0x31,
35*74a4d8c2SCharles.Forsyth DISPWINVSTRT1 = 0x32,
36*74a4d8c2SCharles.Forsyth DISPWINVSTRT2 = 0x33,
37*74a4d8c2SCharles.Forsyth DISPWINVEND = 0x34,
38*74a4d8c2SCharles.Forsyth DISPWINHSTRT1 = 0x35,
39*74a4d8c2SCharles.Forsyth DISPWINHSTRT2 = 0x36,
40*74a4d8c2SCharles.Forsyth DISPWINHEND = 0x37,
41*74a4d8c2SCharles.Forsyth CAPWINVSTRT = 0x38,
42*74a4d8c2SCharles.Forsyth CAPWINHSTRT = 0x39,
43*74a4d8c2SCharles.Forsyth CAPWINVMF = 0x3a,
44*74a4d8c2SCharles.Forsyth CAPWINHMF = 0x3b,
45*74a4d8c2SCharles.Forsyth RESERVED3 = 0x3c,
46*74a4d8c2SCharles.Forsyth CAPMASK = 0x3d,
47*74a4d8c2SCharles.Forsyth BNKPOLATION = 0x3e,
48*74a4d8c2SCharles.Forsyth SYNCPOL = 0x3f,
49*74a4d8c2SCharles.Forsyth DISPVTOTAL = 0x40,
50*74a4d8c2SCharles.Forsyth DISPHTOTAL = 0x41,
51*74a4d8c2SCharles.Forsyth DISPVSTRT = 0x42,
52*74a4d8c2SCharles.Forsyth DISPVEND = 0x43,
53*74a4d8c2SCharles.Forsyth DISPHSTRT = 0x44,
54*74a4d8c2SCharles.Forsyth DISPHEND = 0x45,
55*74a4d8c2SCharles.Forsyth DISPSYNCW = 0x46,
56*74a4d8c2SCharles.Forsyth DISPCRTCCTRL = 0x47,
57*74a4d8c2SCharles.Forsyth CAPVTOTAL = 0x48,
58*74a4d8c2SCharles.Forsyth CAPHTOTAL = 0x49,
59*74a4d8c2SCharles.Forsyth CAPVSTRT = 0x4a,
60*74a4d8c2SCharles.Forsyth CAPVEND = 0x4b,
61*74a4d8c2SCharles.Forsyth CAPHSTRT = 0x4c,
62*74a4d8c2SCharles.Forsyth CAPHEND = 0x4d,
63*74a4d8c2SCharles.Forsyth CAPSYNCW = 0x4e,
64*74a4d8c2SCharles.Forsyth CAPCRTCCTRL = 0x4f,
65*74a4d8c2SCharles.Forsyth VIDLUTDACRW = 0x50,
66*74a4d8c2SCharles.Forsyth VIDLUTDACRW0 = (VIDLUTDACRW),
67*74a4d8c2SCharles.Forsyth VIDLUTDACRW1 = (VIDLUTDACRW+1),
68*74a4d8c2SCharles.Forsyth VIDLUTDACRW2 = (VIDLUTDACRW+2),
69*74a4d8c2SCharles.Forsyth VIDLUTDACRW3 = (VIDLUTDACRW+3),
70*74a4d8c2SCharles.Forsyth VIDLUTDACRW4 = (VIDLUTDACRW+4),
71*74a4d8c2SCharles.Forsyth VIDLUTDACRW5 = (VIDLUTDACRW+5),
72*74a4d8c2SCharles.Forsyth VIDLUTDACRW6 = (VIDLUTDACRW+6),
73*74a4d8c2SCharles.Forsyth VIDLUTDACRW7 = (VIDLUTDACRW+7),
74*74a4d8c2SCharles.Forsyth VGALUTDACRW = 0x58,
75*74a4d8c2SCharles.Forsyth VGALUTDACRW0 = (VGALUTDACRW),
76*74a4d8c2SCharles.Forsyth VGALUTDACRW1 = (VGALUTDACRW+1),
77*74a4d8c2SCharles.Forsyth VGALUTDACRW2 = (VGALUTDACRW+2),
78*74a4d8c2SCharles.Forsyth VGALUTDACRW3 = (VGALUTDACRW+3),
79*74a4d8c2SCharles.Forsyth VGALUTDACRW4 = (VGALUTDACRW+4),
80*74a4d8c2SCharles.Forsyth VGALUTDACRW5 = (VGALUTDACRW+5),
81*74a4d8c2SCharles.Forsyth VGALUTDACRW6 = (VGALUTDACRW+6),
82*74a4d8c2SCharles.Forsyth VGALUTDACRW7 = (VGALUTDACRW+7),
83*74a4d8c2SCharles.Forsyth HZOOMF = 0x60,
84*74a4d8c2SCharles.Forsyth VZOOMF = 0x61,
85*74a4d8c2SCharles.Forsyth DELAY1 = 0x62,
86*74a4d8c2SCharles.Forsyth DELAY2 = 0x63,
87*74a4d8c2SCharles.Forsyth
88*74a4d8c2SCharles.Forsyth TRILO = 0,
89*74a4d8c2SCharles.Forsyth TRIHI = 1,
90*74a4d8c2SCharles.Forsyth TRIINDEX = 2,
91*74a4d8c2SCharles.Forsyth
92*74a4d8c2SCharles.Forsyth SCL = 0x02,
93*74a4d8c2SCharles.Forsyth SDA = 0x01,
94*74a4d8c2SCharles.Forsyth I2CR = 0x2B,
95*74a4d8c2SCharles.Forsyth SAA7110 = 0x9c,
96*74a4d8c2SCharles.Forsyth WRITE_C = 0x00,
97*74a4d8c2SCharles.Forsyth I2DLY = 5,
98*74a4d8c2SCharles.Forsyth };
99*74a4d8c2SCharles.Forsyth
100*74a4d8c2SCharles.Forsyth enum
101*74a4d8c2SCharles.Forsyth {
102*74a4d8c2SCharles.Forsyth ZR36100 = 0x1e0,
103*74a4d8c2SCharles.Forsyth ZRIRQ = 15,
104*74a4d8c2SCharles.Forsyth ZRDMA = 6,
105*74a4d8c2SCharles.Forsyth
106*74a4d8c2SCharles.Forsyth ZRIDREG = 4, /* offset */
107*74a4d8c2SCharles.Forsyth ZRMACH210 = 6, /* offset */
108*74a4d8c2SCharles.Forsyth ZRREG0 = 8, /* offset */
109*74a4d8c2SCharles.Forsyth ZRREG1 = 10, /* offset */
110*74a4d8c2SCharles.Forsyth ZRSR = ZRREG1, /* offset */
111*74a4d8c2SCharles.Forsyth ZRRDY = (1<<3),
112*74a4d8c2SCharles.Forsyth ZRIDLE = (1<<2),
113*74a4d8c2SCharles.Forsyth ZRREG2 = 12, /* offset */
114*74a4d8c2SCharles.Forsyth ZRREG3 = 14, /* offset */
115*74a4d8c2SCharles.Forsyth
116*74a4d8c2SCharles.Forsyth SIFwidth = 320,
117*74a4d8c2SCharles.Forsyth SIFheight = 240,
118*74a4d8c2SCharles.Forsyth
119*74a4d8c2SCharles.Forsyth IDPCOUNT = 3064,
120*74a4d8c2SCharles.Forsyth PMDPCOUNT = 2048,
121*74a4d8c2SCharles.Forsyth SVMDPCOUNT = 2048,
122*74a4d8c2SCharles.Forsyth
123*74a4d8c2SCharles.Forsyth HIWAT = 2*128*1024,
124*74a4d8c2SCharles.Forsyth DMABLK = 16384,
125*74a4d8c2SCharles.Forsyth };
126*74a4d8c2SCharles.Forsyth
127*74a4d8c2SCharles.Forsyth static struct {
128*74a4d8c2SCharles.Forsyth int zrport;
129*74a4d8c2SCharles.Forsyth int irq;
130*74a4d8c2SCharles.Forsyth int dma;
131*74a4d8c2SCharles.Forsyth int trport;
132*74a4d8c2SCharles.Forsyth } mpegconf;
133*74a4d8c2SCharles.Forsyth
134*74a4d8c2SCharles.Forsyth static char Evmode[] = "video format not supported";
135*74a4d8c2SCharles.Forsyth static char Eaudio[] = "invalid audio layer";
136*74a4d8c2SCharles.Forsyth static char Earate[] = "bad audio sample rate";
137*74a4d8c2SCharles.Forsyth
138*74a4d8c2SCharles.Forsyth /* Status bits depend on board revision */
139*74a4d8c2SCharles.Forsyth static short STDBY;
140*74a4d8c2SCharles.Forsyth static short VIDSEL;
141*74a4d8c2SCharles.Forsyth static short VSNIRQn;
142*74a4d8c2SCharles.Forsyth static short INTENAn;
143*74a4d8c2SCharles.Forsyth static short DSPBOOT;
144*74a4d8c2SCharles.Forsyth static short DSPRST;
145*74a4d8c2SCharles.Forsyth static short MPGRST;
146*74a4d8c2SCharles.Forsyth static int machsr;
147*74a4d8c2SCharles.Forsyth static int dopen;
148*74a4d8c2SCharles.Forsyth static int started;
149*74a4d8c2SCharles.Forsyth static int stop;
150*74a4d8c2SCharles.Forsyth static int pause;
151*74a4d8c2SCharles.Forsyth static int sp2br;
152*74a4d8c2SCharles.Forsyth static int sp2cd;
153*74a4d8c2SCharles.Forsyth static char properties[] = "video mpeg1,sif\naudio musicam,I musicam,II\n";
154*74a4d8c2SCharles.Forsyth static void inittrident(void);
155*74a4d8c2SCharles.Forsyth static int initzoran(void);
156*74a4d8c2SCharles.Forsyth static void initcrystal(void);
157*74a4d8c2SCharles.Forsyth static void mpegintr(Ureg*, void*);
158*74a4d8c2SCharles.Forsyth static void setwindow(int, char**);
159*74a4d8c2SCharles.Forsyth static void freebufs(void);
160*74a4d8c2SCharles.Forsyth static int mkbuf(char*, int);
161*74a4d8c2SCharles.Forsyth
162*74a4d8c2SCharles.Forsyth typedef struct Buf Buf;
163*74a4d8c2SCharles.Forsyth struct Buf
164*74a4d8c2SCharles.Forsyth {
165*74a4d8c2SCharles.Forsyth int nchar;
166*74a4d8c2SCharles.Forsyth uchar* ptr;
167*74a4d8c2SCharles.Forsyth Buf* link;
168*74a4d8c2SCharles.Forsyth uchar data[1];
169*74a4d8c2SCharles.Forsyth };
170*74a4d8c2SCharles.Forsyth
171*74a4d8c2SCharles.Forsyth static struct
172*74a4d8c2SCharles.Forsyth {
173*74a4d8c2SCharles.Forsyth Lock;
174*74a4d8c2SCharles.Forsyth int qlen;
175*74a4d8c2SCharles.Forsyth Buf* head;
176*74a4d8c2SCharles.Forsyth Buf* tail;
177*74a4d8c2SCharles.Forsyth Rendez flow;
178*74a4d8c2SCharles.Forsyth } bqueue;
179*74a4d8c2SCharles.Forsyth
180*74a4d8c2SCharles.Forsyth static int
zrstatus(void)181*74a4d8c2SCharles.Forsyth zrstatus(void)
182*74a4d8c2SCharles.Forsyth {
183*74a4d8c2SCharles.Forsyth return ins(mpegconf.zrport+ZRSR) & 0xf;
184*74a4d8c2SCharles.Forsyth }
185*74a4d8c2SCharles.Forsyth
186*74a4d8c2SCharles.Forsyth static int
zrwaitrdy(int timo,char * msg)187*74a4d8c2SCharles.Forsyth zrwaitrdy(int timo, char *msg)
188*74a4d8c2SCharles.Forsyth {
189*74a4d8c2SCharles.Forsyth int i;
190*74a4d8c2SCharles.Forsyth
191*74a4d8c2SCharles.Forsyth for(i = 0; i < timo; i++)
192*74a4d8c2SCharles.Forsyth if(ins(mpegconf.zrport+ZRSR) & ZRRDY)
193*74a4d8c2SCharles.Forsyth return 0;
194*74a4d8c2SCharles.Forsyth
195*74a4d8c2SCharles.Forsyth print("devmpeg: device not ready %s\n", msg);
196*74a4d8c2SCharles.Forsyth return 1;
197*74a4d8c2SCharles.Forsyth }
198*74a4d8c2SCharles.Forsyth
199*74a4d8c2SCharles.Forsyth static void
zrdma(Buf * b)200*74a4d8c2SCharles.Forsyth zrdma(Buf *b)
201*74a4d8c2SCharles.Forsyth {
202*74a4d8c2SCharles.Forsyth int n;
203*74a4d8c2SCharles.Forsyth
204*74a4d8c2SCharles.Forsyth n = dmasetup(mpegconf.dma, b->ptr, b->nchar, 0);
205*74a4d8c2SCharles.Forsyth b->ptr += n;
206*74a4d8c2SCharles.Forsyth b->nchar -= n;
207*74a4d8c2SCharles.Forsyth bqueue.qlen -= n;
208*74a4d8c2SCharles.Forsyth }
209*74a4d8c2SCharles.Forsyth
210*74a4d8c2SCharles.Forsyth static void
triwr(int reg,int val)211*74a4d8c2SCharles.Forsyth triwr(int reg, int val)
212*74a4d8c2SCharles.Forsyth {
213*74a4d8c2SCharles.Forsyth outb(mpegconf.trport+TRIINDEX, reg);
214*74a4d8c2SCharles.Forsyth outb(mpegconf.trport+TRILO, val);
215*74a4d8c2SCharles.Forsyth outb(mpegconf.trport+TRIHI, val>>8);
216*74a4d8c2SCharles.Forsyth }
217*74a4d8c2SCharles.Forsyth
218*74a4d8c2SCharles.Forsyth static int
trird(int reg)219*74a4d8c2SCharles.Forsyth trird(int reg)
220*74a4d8c2SCharles.Forsyth {
221*74a4d8c2SCharles.Forsyth int v;
222*74a4d8c2SCharles.Forsyth
223*74a4d8c2SCharles.Forsyth outb(mpegconf.trport+TRIINDEX, reg);
224*74a4d8c2SCharles.Forsyth v = inb(mpegconf.trport+TRILO);
225*74a4d8c2SCharles.Forsyth v |= inb(mpegconf.trport+TRIHI)<<8;
226*74a4d8c2SCharles.Forsyth
227*74a4d8c2SCharles.Forsyth return v;
228*74a4d8c2SCharles.Forsyth }
229*74a4d8c2SCharles.Forsyth
230*74a4d8c2SCharles.Forsyth enum
231*74a4d8c2SCharles.Forsyth {
232*74a4d8c2SCharles.Forsyth Qdir,
233*74a4d8c2SCharles.Forsyth Qdata,
234*74a4d8c2SCharles.Forsyth Qctl,
235*74a4d8c2SCharles.Forsyth };
236*74a4d8c2SCharles.Forsyth static Dirtab mpegtab[]=
237*74a4d8c2SCharles.Forsyth {
238*74a4d8c2SCharles.Forsyth "mpeg", {Qdata, 0}, 0, 0666,
239*74a4d8c2SCharles.Forsyth "mpegctl", {Qctl, 0}, 0, 0666,
240*74a4d8c2SCharles.Forsyth };
241*74a4d8c2SCharles.Forsyth
242*74a4d8c2SCharles.Forsyth static void
mpegreset(void)243*74a4d8c2SCharles.Forsyth mpegreset(void)
244*74a4d8c2SCharles.Forsyth {
245*74a4d8c2SCharles.Forsyth ISAConf isa;
246*74a4d8c2SCharles.Forsyth
247*74a4d8c2SCharles.Forsyth mpegconf.zrport = ZR36100;
248*74a4d8c2SCharles.Forsyth mpegconf.irq = ZRIRQ;
249*74a4d8c2SCharles.Forsyth mpegconf.dma = ZRDMA;
250*74a4d8c2SCharles.Forsyth
251*74a4d8c2SCharles.Forsyth memset(&isa, 0, sizeof(isa));
252*74a4d8c2SCharles.Forsyth if(isaconfig("mpeg", 0, &isa) == 0)
253*74a4d8c2SCharles.Forsyth return;
254*74a4d8c2SCharles.Forsyth if(isa.port)
255*74a4d8c2SCharles.Forsyth mpegconf.zrport = isa.port;
256*74a4d8c2SCharles.Forsyth if(isa.irq)
257*74a4d8c2SCharles.Forsyth mpegconf.irq = isa.irq;
258*74a4d8c2SCharles.Forsyth if(isa.dma)
259*74a4d8c2SCharles.Forsyth mpegconf.dma = isa.dma;
260*74a4d8c2SCharles.Forsyth dmainit(mpegconf.dma, 64*1024);
261*74a4d8c2SCharles.Forsyth print("mpeg0: port 0x%uX, irq %d, dma %d\n",
262*74a4d8c2SCharles.Forsyth mpegconf.zrport, mpegconf.irq, mpegconf.dma);
263*74a4d8c2SCharles.Forsyth mpegconf.trport = mpegconf.zrport+0x100;
264*74a4d8c2SCharles.Forsyth intrenable(VectorPIC+mpegconf.irq, mpegintr, 0, BUSUNKNOWN);
265*74a4d8c2SCharles.Forsyth }
266*74a4d8c2SCharles.Forsyth
267*74a4d8c2SCharles.Forsyth static void
mpeginit(void)268*74a4d8c2SCharles.Forsyth mpeginit(void)
269*74a4d8c2SCharles.Forsyth {
270*74a4d8c2SCharles.Forsyth if(mpegconf.trport == 0)
271*74a4d8c2SCharles.Forsyth return;
272*74a4d8c2SCharles.Forsyth
273*74a4d8c2SCharles.Forsyth inittrident();
274*74a4d8c2SCharles.Forsyth setwindow(0, 0);
275*74a4d8c2SCharles.Forsyth }
276*74a4d8c2SCharles.Forsyth
277*74a4d8c2SCharles.Forsyth static Chan*
mpegattach(char * spec)278*74a4d8c2SCharles.Forsyth mpegattach(char *spec)
279*74a4d8c2SCharles.Forsyth {
280*74a4d8c2SCharles.Forsyth if(mpegconf.trport == 0)
281*74a4d8c2SCharles.Forsyth error(Enodev);
282*74a4d8c2SCharles.Forsyth
283*74a4d8c2SCharles.Forsyth return devattach('E', spec);
284*74a4d8c2SCharles.Forsyth }
285*74a4d8c2SCharles.Forsyth
286*74a4d8c2SCharles.Forsyth static int
mpegwalk(Chan * c,char * name)287*74a4d8c2SCharles.Forsyth mpegwalk(Chan *c, char *name)
288*74a4d8c2SCharles.Forsyth {
289*74a4d8c2SCharles.Forsyth return devwalk(c, name, mpegtab, nelem(mpegtab), devgen);
290*74a4d8c2SCharles.Forsyth }
291*74a4d8c2SCharles.Forsyth
292*74a4d8c2SCharles.Forsyth static void
mpegstat(Chan * c,char * db)293*74a4d8c2SCharles.Forsyth mpegstat(Chan *c, char *db)
294*74a4d8c2SCharles.Forsyth {
295*74a4d8c2SCharles.Forsyth devstat(c, db, mpegtab, nelem(mpegtab), devgen);
296*74a4d8c2SCharles.Forsyth }
297*74a4d8c2SCharles.Forsyth
298*74a4d8c2SCharles.Forsyth static Chan*
mpegopen(Chan * c,int omode)299*74a4d8c2SCharles.Forsyth mpegopen(Chan *c, int omode)
300*74a4d8c2SCharles.Forsyth {
301*74a4d8c2SCharles.Forsyth switch(c->qid.path) {
302*74a4d8c2SCharles.Forsyth default:
303*74a4d8c2SCharles.Forsyth break;
304*74a4d8c2SCharles.Forsyth case Qdata:
305*74a4d8c2SCharles.Forsyth if(dopen)
306*74a4d8c2SCharles.Forsyth error(Einuse);
307*74a4d8c2SCharles.Forsyth dopen = 1;
308*74a4d8c2SCharles.Forsyth break;
309*74a4d8c2SCharles.Forsyth }
310*74a4d8c2SCharles.Forsyth return devopen(c, omode, mpegtab, nelem(mpegtab), devgen);
311*74a4d8c2SCharles.Forsyth }
312*74a4d8c2SCharles.Forsyth
313*74a4d8c2SCharles.Forsyth static void
mpegclose(Chan * c)314*74a4d8c2SCharles.Forsyth mpegclose(Chan *c)
315*74a4d8c2SCharles.Forsyth {
316*74a4d8c2SCharles.Forsyth int i;
317*74a4d8c2SCharles.Forsyth
318*74a4d8c2SCharles.Forsyth switch(c->qid.path) {
319*74a4d8c2SCharles.Forsyth default:
320*74a4d8c2SCharles.Forsyth break;
321*74a4d8c2SCharles.Forsyth case Qdata:
322*74a4d8c2SCharles.Forsyth if((c->flag & COPEN) == 0)
323*74a4d8c2SCharles.Forsyth break;
324*74a4d8c2SCharles.Forsyth if(started) {
325*74a4d8c2SCharles.Forsyth for(i = 0; i < 50; i++) {
326*74a4d8c2SCharles.Forsyth if(ins(mpegconf.zrport+ZRSR) & ZRIDLE)
327*74a4d8c2SCharles.Forsyth break;
328*74a4d8c2SCharles.Forsyth tsleep(&up->sleep, return0, 0, 100);
329*74a4d8c2SCharles.Forsyth }
330*74a4d8c2SCharles.Forsyth }
331*74a4d8c2SCharles.Forsyth if(stop != 0)
332*74a4d8c2SCharles.Forsyth outs(mpegconf.zrport+ZRREG1, 0x1000);
333*74a4d8c2SCharles.Forsyth microdelay(15);
334*74a4d8c2SCharles.Forsyth outs(mpegconf.zrport+ZRREG1, 0x8000);
335*74a4d8c2SCharles.Forsyth freebufs();
336*74a4d8c2SCharles.Forsyth dopen = 0;
337*74a4d8c2SCharles.Forsyth }
338*74a4d8c2SCharles.Forsyth }
339*74a4d8c2SCharles.Forsyth
340*74a4d8c2SCharles.Forsyth static long
mpegread(Chan * c,void * a,long n,ulong off)341*74a4d8c2SCharles.Forsyth mpegread(Chan *c, void *a, long n, ulong off)
342*74a4d8c2SCharles.Forsyth {
343*74a4d8c2SCharles.Forsyth switch(c->qid.path & ~CHDIR){
344*74a4d8c2SCharles.Forsyth default:
345*74a4d8c2SCharles.Forsyth error(Eperm);
346*74a4d8c2SCharles.Forsyth case Qdir:
347*74a4d8c2SCharles.Forsyth return devdirread(c, a, n, mpegtab, nelem(mpegtab), devgen);
348*74a4d8c2SCharles.Forsyth case Qctl:
349*74a4d8c2SCharles.Forsyth return readstr(off, a, n, properties);
350*74a4d8c2SCharles.Forsyth }
351*74a4d8c2SCharles.Forsyth return 0;
352*74a4d8c2SCharles.Forsyth }
353*74a4d8c2SCharles.Forsyth
354*74a4d8c2SCharles.Forsyth #define SCALE(a, b) ((((a)<<10)/(b))-1024)
355*74a4d8c2SCharles.Forsyth enum
356*74a4d8c2SCharles.Forsyth {
357*74a4d8c2SCharles.Forsyth CWINVF = 0x3ff,
358*74a4d8c2SCharles.Forsyth CWINHF = 0x1da,
359*74a4d8c2SCharles.Forsyth };
360*74a4d8c2SCharles.Forsyth
361*74a4d8c2SCharles.Forsyth static void
setwindow(int nf,char ** field)362*74a4d8c2SCharles.Forsyth setwindow(int nf, char **field)
363*74a4d8c2SCharles.Forsyth {
364*74a4d8c2SCharles.Forsyth int minx, miny, maxx, maxy, width, height;
365*74a4d8c2SCharles.Forsyth
366*74a4d8c2SCharles.Forsyth if(field == 0) {
367*74a4d8c2SCharles.Forsyth minx = 0;
368*74a4d8c2SCharles.Forsyth miny = 0;
369*74a4d8c2SCharles.Forsyth maxx = 0;
370*74a4d8c2SCharles.Forsyth maxy = 0;
371*74a4d8c2SCharles.Forsyth }
372*74a4d8c2SCharles.Forsyth else {
373*74a4d8c2SCharles.Forsyth if(nf != 5)
374*74a4d8c2SCharles.Forsyth error(Ebadarg);
375*74a4d8c2SCharles.Forsyth
376*74a4d8c2SCharles.Forsyth minx = strtoul(field[1], 0, 0);
377*74a4d8c2SCharles.Forsyth miny = strtoul(field[2], 0, 0);
378*74a4d8c2SCharles.Forsyth maxx = strtoul(field[3], 0, 0) + 8;
379*74a4d8c2SCharles.Forsyth maxy = strtoul(field[4], 0, 0);
380*74a4d8c2SCharles.Forsyth }
381*74a4d8c2SCharles.Forsyth
382*74a4d8c2SCharles.Forsyth triwr(OVLWINHSTRT, minx);
383*74a4d8c2SCharles.Forsyth triwr(OVLWINVSTRT, miny);
384*74a4d8c2SCharles.Forsyth triwr(OVLWINHEND, maxx+12);
385*74a4d8c2SCharles.Forsyth triwr(OVLWINVEND, maxy);
386*74a4d8c2SCharles.Forsyth
387*74a4d8c2SCharles.Forsyth width = maxx - minx;
388*74a4d8c2SCharles.Forsyth height = maxy - miny;
389*74a4d8c2SCharles.Forsyth if(width >= SIFwidth) {
390*74a4d8c2SCharles.Forsyth triwr(HZOOMF, SCALE(width, SIFwidth));
391*74a4d8c2SCharles.Forsyth triwr(CAPWINHMF, CWINHF);
392*74a4d8c2SCharles.Forsyth }
393*74a4d8c2SCharles.Forsyth else {
394*74a4d8c2SCharles.Forsyth triwr(HZOOMF, SCALE(SIFwidth, SIFwidth));
395*74a4d8c2SCharles.Forsyth triwr(CAPWINHMF, width*CWINHF/SIFwidth);
396*74a4d8c2SCharles.Forsyth }
397*74a4d8c2SCharles.Forsyth if(height >= SIFheight) {
398*74a4d8c2SCharles.Forsyth triwr(VZOOMF, SCALE(height, SIFheight));
399*74a4d8c2SCharles.Forsyth triwr(CAPWINVMF, CWINVF);
400*74a4d8c2SCharles.Forsyth }
401*74a4d8c2SCharles.Forsyth else {
402*74a4d8c2SCharles.Forsyth triwr(VZOOMF, SCALE(SIFheight, SIFheight));
403*74a4d8c2SCharles.Forsyth triwr(CAPWINVMF, height*CWINVF/SIFheight);
404*74a4d8c2SCharles.Forsyth }
405*74a4d8c2SCharles.Forsyth }
406*74a4d8c2SCharles.Forsyth
407*74a4d8c2SCharles.Forsyth static int
mpegflow(void *)408*74a4d8c2SCharles.Forsyth mpegflow(void*)
409*74a4d8c2SCharles.Forsyth {
410*74a4d8c2SCharles.Forsyth return bqueue.qlen < HIWAT || stop;
411*74a4d8c2SCharles.Forsyth }
412*74a4d8c2SCharles.Forsyth
413*74a4d8c2SCharles.Forsyth static int
mkbuf(char * d,int n)414*74a4d8c2SCharles.Forsyth mkbuf(char *d, int n)
415*74a4d8c2SCharles.Forsyth {
416*74a4d8c2SCharles.Forsyth Buf *b;
417*74a4d8c2SCharles.Forsyth
418*74a4d8c2SCharles.Forsyth b = malloc(sizeof(Buf)+n);
419*74a4d8c2SCharles.Forsyth if(b == 0)
420*74a4d8c2SCharles.Forsyth return 0;
421*74a4d8c2SCharles.Forsyth
422*74a4d8c2SCharles.Forsyth memmove(b->data, d, n);
423*74a4d8c2SCharles.Forsyth b->ptr = b->data;
424*74a4d8c2SCharles.Forsyth b->nchar = n;
425*74a4d8c2SCharles.Forsyth b->link = 0;
426*74a4d8c2SCharles.Forsyth
427*74a4d8c2SCharles.Forsyth ilock(&bqueue);
428*74a4d8c2SCharles.Forsyth bqueue.qlen += n;
429*74a4d8c2SCharles.Forsyth if(bqueue.head)
430*74a4d8c2SCharles.Forsyth bqueue.tail->link = b;
431*74a4d8c2SCharles.Forsyth else
432*74a4d8c2SCharles.Forsyth bqueue.head = b;
433*74a4d8c2SCharles.Forsyth bqueue.tail = b;
434*74a4d8c2SCharles.Forsyth iunlock(&bqueue);
435*74a4d8c2SCharles.Forsyth
436*74a4d8c2SCharles.Forsyth return 1;
437*74a4d8c2SCharles.Forsyth }
438*74a4d8c2SCharles.Forsyth
439*74a4d8c2SCharles.Forsyth static void
freebufs(void)440*74a4d8c2SCharles.Forsyth freebufs(void)
441*74a4d8c2SCharles.Forsyth {
442*74a4d8c2SCharles.Forsyth Buf *next;
443*74a4d8c2SCharles.Forsyth
444*74a4d8c2SCharles.Forsyth ilock(&bqueue);
445*74a4d8c2SCharles.Forsyth bqueue.qlen = 0;
446*74a4d8c2SCharles.Forsyth while(bqueue.head) {
447*74a4d8c2SCharles.Forsyth next = bqueue.head->link;
448*74a4d8c2SCharles.Forsyth free(bqueue.head);
449*74a4d8c2SCharles.Forsyth bqueue.head = next;
450*74a4d8c2SCharles.Forsyth }
451*74a4d8c2SCharles.Forsyth iunlock(&bqueue);
452*74a4d8c2SCharles.Forsyth }
453*74a4d8c2SCharles.Forsyth
454*74a4d8c2SCharles.Forsyth typedef struct Audio Audio;
455*74a4d8c2SCharles.Forsyth struct Audio {
456*74a4d8c2SCharles.Forsyth int rate;
457*74a4d8c2SCharles.Forsyth int cd;
458*74a4d8c2SCharles.Forsyth int br;
459*74a4d8c2SCharles.Forsyth };
460*74a4d8c2SCharles.Forsyth
461*74a4d8c2SCharles.Forsyth static Audio AudioclkI[] =
462*74a4d8c2SCharles.Forsyth {
463*74a4d8c2SCharles.Forsyth 64000, 0x000000bb, 0x00071797,
464*74a4d8c2SCharles.Forsyth 96000, 0x0000007d, 0x00071c71,
465*74a4d8c2SCharles.Forsyth 128000, 0x0000005d, 0x00070de1,
466*74a4d8c2SCharles.Forsyth 160000, 0x0000004b, 0x00071c71,
467*74a4d8c2SCharles.Forsyth 192000, 0x0000003e, 0x00070de1,
468*74a4d8c2SCharles.Forsyth 224000, 0x00000035, 0x00070906,
469*74a4d8c2SCharles.Forsyth 256000, 0x0000002e, 0x0006fa76,
470*74a4d8c2SCharles.Forsyth 288000, 0x00000029, 0x0006ff51,
471*74a4d8c2SCharles.Forsyth 320000, 0x00000025, 0x0007042b,
472*74a4d8c2SCharles.Forsyth 352000, 0x00000022, 0x00071797,
473*74a4d8c2SCharles.Forsyth 384000, 0x0000001f, 0x00070de1,
474*74a4d8c2SCharles.Forsyth 416000, 0x0000001c, 0x0006e70b,
475*74a4d8c2SCharles.Forsyth 448000, 0x0000001a, 0x0006e70b,
476*74a4d8c2SCharles.Forsyth };
477*74a4d8c2SCharles.Forsyth
478*74a4d8c2SCharles.Forsyth static Audio AudioclkII[] =
479*74a4d8c2SCharles.Forsyth {
480*74a4d8c2SCharles.Forsyth 48000, 0x000000fa, 0x00071c71,
481*74a4d8c2SCharles.Forsyth 56000, 0x000000d6, 0x00071a04,
482*74a4d8c2SCharles.Forsyth 64000, 0x000000bb, 0x00071797,
483*74a4d8c2SCharles.Forsyth 80000, 0x00000096, 0x00071c71,
484*74a4d8c2SCharles.Forsyth 96000, 0x0000007d, 0x00071c71,
485*74a4d8c2SCharles.Forsyth 112000, 0x0000006b, 0x00071a04,
486*74a4d8c2SCharles.Forsyth 128000, 0x0000005d, 0x00070de1,
487*74a4d8c2SCharles.Forsyth 160000, 0x0000004b, 0x00071c71,
488*74a4d8c2SCharles.Forsyth 192000, 0x0000003e, 0x00070de1,
489*74a4d8c2SCharles.Forsyth 224000, 0x00000035, 0x00070906,
490*74a4d8c2SCharles.Forsyth 256000, 0x0000002e, 0x0006fa76,
491*74a4d8c2SCharles.Forsyth 320000, 0x00000025, 0x0007042b,
492*74a4d8c2SCharles.Forsyth 384000, 0x0000001f, 0x00070de1,
493*74a4d8c2SCharles.Forsyth };
494*74a4d8c2SCharles.Forsyth
495*74a4d8c2SCharles.Forsyth static long
mpegwrite(Chan * c,char * a,long n,vlong)496*74a4d8c2SCharles.Forsyth mpegwrite(Chan *c, char *a, long n, vlong)
497*74a4d8c2SCharles.Forsyth {
498*74a4d8c2SCharles.Forsyth Audio *t;
499*74a4d8c2SCharles.Forsyth int i, nf, l, x;
500*74a4d8c2SCharles.Forsyth char buf[128], *field[10];
501*74a4d8c2SCharles.Forsyth
502*74a4d8c2SCharles.Forsyth switch(c->qid.path & ~CHDIR) {
503*74a4d8c2SCharles.Forsyth case Qctl:
504*74a4d8c2SCharles.Forsyth if(n > sizeof(buf)-1)
505*74a4d8c2SCharles.Forsyth n = sizeof(buf)-1;
506*74a4d8c2SCharles.Forsyth memmove(buf, a, n);
507*74a4d8c2SCharles.Forsyth buf[n] = '\0';
508*74a4d8c2SCharles.Forsyth
509*74a4d8c2SCharles.Forsyth nf = getfields(buf, field, nelem(field), 1, " \t\n");
510*74a4d8c2SCharles.Forsyth if(nf < 1)
511*74a4d8c2SCharles.Forsyth error(Ebadarg);
512*74a4d8c2SCharles.Forsyth
513*74a4d8c2SCharles.Forsyth if(strcmp(field[0], "stop") == 0) {
514*74a4d8c2SCharles.Forsyth if(started == 0)
515*74a4d8c2SCharles.Forsyth error("not started");
516*74a4d8c2SCharles.Forsyth if(pause) {
517*74a4d8c2SCharles.Forsyth pause = 0;
518*74a4d8c2SCharles.Forsyth outs(mpegconf.zrport+ZRREG1, 0x9000);
519*74a4d8c2SCharles.Forsyth }
520*74a4d8c2SCharles.Forsyth stop = 1;
521*74a4d8c2SCharles.Forsyth outs(mpegconf.zrport+ZRREG1, 0x1000);
522*74a4d8c2SCharles.Forsyth microdelay(15);
523*74a4d8c2SCharles.Forsyth outs(mpegconf.zrport+ZRREG1, 0x8000);
524*74a4d8c2SCharles.Forsyth wakeup(&bqueue.flow);
525*74a4d8c2SCharles.Forsyth return n;
526*74a4d8c2SCharles.Forsyth }
527*74a4d8c2SCharles.Forsyth if(strcmp(field[0], "pause") == 0) {
528*74a4d8c2SCharles.Forsyth if(started == 0)
529*74a4d8c2SCharles.Forsyth error("not started");
530*74a4d8c2SCharles.Forsyth if(pause == 0) {
531*74a4d8c2SCharles.Forsyth pause = 1;
532*74a4d8c2SCharles.Forsyth outs(mpegconf.zrport+ZRREG1, 0x1000);
533*74a4d8c2SCharles.Forsyth }
534*74a4d8c2SCharles.Forsyth else {
535*74a4d8c2SCharles.Forsyth pause = 0;
536*74a4d8c2SCharles.Forsyth outs(mpegconf.zrport+ZRREG1, 0x9000);
537*74a4d8c2SCharles.Forsyth }
538*74a4d8c2SCharles.Forsyth return n;
539*74a4d8c2SCharles.Forsyth }
540*74a4d8c2SCharles.Forsyth if(strcmp(field[0], "window") == 0) {
541*74a4d8c2SCharles.Forsyth setwindow(nf, field);
542*74a4d8c2SCharles.Forsyth return n;
543*74a4d8c2SCharles.Forsyth }
544*74a4d8c2SCharles.Forsyth if(strcmp(field[0], "audio") == 0) {
545*74a4d8c2SCharles.Forsyth if(nf < 3)
546*74a4d8c2SCharles.Forsyth error(Ebadarg);
547*74a4d8c2SCharles.Forsyth t = 0;
548*74a4d8c2SCharles.Forsyth if(strcmp(field[1], "musicam,I") == 0)
549*74a4d8c2SCharles.Forsyth t = AudioclkI;
550*74a4d8c2SCharles.Forsyth else
551*74a4d8c2SCharles.Forsyth if(strcmp(field[1], "musicam,II") == 0)
552*74a4d8c2SCharles.Forsyth t = AudioclkII;
553*74a4d8c2SCharles.Forsyth else
554*74a4d8c2SCharles.Forsyth error(Eaudio);
555*74a4d8c2SCharles.Forsyth x = strtoul(field[2], 0, 0);
556*74a4d8c2SCharles.Forsyth for(i = 0; t[i].rate != 0; i++) {
557*74a4d8c2SCharles.Forsyth if(t[i].rate == x) {
558*74a4d8c2SCharles.Forsyth sp2cd = t[i].cd;
559*74a4d8c2SCharles.Forsyth sp2br = t[i].br;
560*74a4d8c2SCharles.Forsyth return n;
561*74a4d8c2SCharles.Forsyth }
562*74a4d8c2SCharles.Forsyth }
563*74a4d8c2SCharles.Forsyth error(Earate);
564*74a4d8c2SCharles.Forsyth }
565*74a4d8c2SCharles.Forsyth if(strcmp(field[0], "video") == 0) {
566*74a4d8c2SCharles.Forsyth if(nf != 3)
567*74a4d8c2SCharles.Forsyth error(Ebadarg);
568*74a4d8c2SCharles.Forsyth if(strcmp(field[1], "iso11172") != 0)
569*74a4d8c2SCharles.Forsyth error(Evmode);
570*74a4d8c2SCharles.Forsyth if(strcmp(field[2], "mpeg1,sif") != 0)
571*74a4d8c2SCharles.Forsyth error(Evmode);
572*74a4d8c2SCharles.Forsyth return n;
573*74a4d8c2SCharles.Forsyth }
574*74a4d8c2SCharles.Forsyth if(strcmp(field[0], "init") == 0) {
575*74a4d8c2SCharles.Forsyth inittrident();
576*74a4d8c2SCharles.Forsyth for(i = 0; i < 3; i++)
577*74a4d8c2SCharles.Forsyth if(initzoran() != -1)
578*74a4d8c2SCharles.Forsyth break;
579*74a4d8c2SCharles.Forsyth initcrystal();
580*74a4d8c2SCharles.Forsyth started = 0;
581*74a4d8c2SCharles.Forsyth stop = 0;
582*74a4d8c2SCharles.Forsyth pause = 0;
583*74a4d8c2SCharles.Forsyth return n;
584*74a4d8c2SCharles.Forsyth }
585*74a4d8c2SCharles.Forsyth error(Ebadarg);
586*74a4d8c2SCharles.Forsyth case Qdata:
587*74a4d8c2SCharles.Forsyth if(n & 1)
588*74a4d8c2SCharles.Forsyth error("odd write");
589*74a4d8c2SCharles.Forsyth
590*74a4d8c2SCharles.Forsyth while(!mpegflow(0))
591*74a4d8c2SCharles.Forsyth sleep(&bqueue.flow, mpegflow, 0);
592*74a4d8c2SCharles.Forsyth
593*74a4d8c2SCharles.Forsyth if(stop)
594*74a4d8c2SCharles.Forsyth error("stopped");
595*74a4d8c2SCharles.Forsyth
596*74a4d8c2SCharles.Forsyth x = n;
597*74a4d8c2SCharles.Forsyth while(x) {
598*74a4d8c2SCharles.Forsyth l = x;
599*74a4d8c2SCharles.Forsyth if(l > DMABLK)
600*74a4d8c2SCharles.Forsyth l = DMABLK;
601*74a4d8c2SCharles.Forsyth if(mkbuf(a, l) == 0)
602*74a4d8c2SCharles.Forsyth error(Enomem);
603*74a4d8c2SCharles.Forsyth x -= l;
604*74a4d8c2SCharles.Forsyth a += l;
605*74a4d8c2SCharles.Forsyth }
606*74a4d8c2SCharles.Forsyth if(started || bqueue.qlen < (HIWAT*3)/4)
607*74a4d8c2SCharles.Forsyth break;
608*74a4d8c2SCharles.Forsyth
609*74a4d8c2SCharles.Forsyth zrdma(bqueue.head);
610*74a4d8c2SCharles.Forsyth outs(mpegconf.zrport+ZRREG1, 0x0000);
611*74a4d8c2SCharles.Forsyth outs(mpegconf.zrport+ZRREG1, 0x0000);
612*74a4d8c2SCharles.Forsyth started = 1;
613*74a4d8c2SCharles.Forsyth break;
614*74a4d8c2SCharles.Forsyth default:
615*74a4d8c2SCharles.Forsyth error(Ebadusefd);
616*74a4d8c2SCharles.Forsyth }
617*74a4d8c2SCharles.Forsyth return n;
618*74a4d8c2SCharles.Forsyth }
619*74a4d8c2SCharles.Forsyth
620*74a4d8c2SCharles.Forsyth Dev mpegdevtab = {
621*74a4d8c2SCharles.Forsyth 'E',
622*74a4d8c2SCharles.Forsyth "mpeg",
623*74a4d8c2SCharles.Forsyth
624*74a4d8c2SCharles.Forsyth mpegreset,
625*74a4d8c2SCharles.Forsyth mpeginit,
626*74a4d8c2SCharles.Forsyth mpegattach,
627*74a4d8c2SCharles.Forsyth devdetach,
628*74a4d8c2SCharles.Forsyth devclone,
629*74a4d8c2SCharles.Forsyth mpegwalk,
630*74a4d8c2SCharles.Forsyth mpegstat,
631*74a4d8c2SCharles.Forsyth mpegopen,
632*74a4d8c2SCharles.Forsyth devcreate,
633*74a4d8c2SCharles.Forsyth mpegclose,
634*74a4d8c2SCharles.Forsyth mpegread,
635*74a4d8c2SCharles.Forsyth devbread,
636*74a4d8c2SCharles.Forsyth mpegwrite,
637*74a4d8c2SCharles.Forsyth devbwrite,
638*74a4d8c2SCharles.Forsyth devremove,
639*74a4d8c2SCharles.Forsyth devwstat,
640*74a4d8c2SCharles.Forsyth };
641*74a4d8c2SCharles.Forsyth
642*74a4d8c2SCharles.Forsyth static void
initctl(void)643*74a4d8c2SCharles.Forsyth initctl(void)
644*74a4d8c2SCharles.Forsyth {
645*74a4d8c2SCharles.Forsyth int boardid;
646*74a4d8c2SCharles.Forsyth static int done;
647*74a4d8c2SCharles.Forsyth
648*74a4d8c2SCharles.Forsyth if(done)
649*74a4d8c2SCharles.Forsyth return;
650*74a4d8c2SCharles.Forsyth
651*74a4d8c2SCharles.Forsyth boardid = ins(mpegconf.zrport+ZRIDREG);
652*74a4d8c2SCharles.Forsyth if(boardid == 0xE3E3) { /* REV c/d */
653*74a4d8c2SCharles.Forsyth STDBY = 0x0000;
654*74a4d8c2SCharles.Forsyth VIDSEL = 0x2020;
655*74a4d8c2SCharles.Forsyth VSNIRQn = 0x1010;
656*74a4d8c2SCharles.Forsyth INTENAn = 0x0808;
657*74a4d8c2SCharles.Forsyth DSPBOOT = 0x0404;
658*74a4d8c2SCharles.Forsyth DSPRST = 0x0202;
659*74a4d8c2SCharles.Forsyth MPGRST = 0x0101;
660*74a4d8c2SCharles.Forsyth }
661*74a4d8c2SCharles.Forsyth else { /* REV b */
662*74a4d8c2SCharles.Forsyth STDBY = 0x0404;
663*74a4d8c2SCharles.Forsyth VIDSEL = 0x1010;
664*74a4d8c2SCharles.Forsyth VSNIRQn = 0x8080;
665*74a4d8c2SCharles.Forsyth INTENAn = 0x4040;
666*74a4d8c2SCharles.Forsyth DSPBOOT = 0x0202;
667*74a4d8c2SCharles.Forsyth DSPRST = 0x0101;
668*74a4d8c2SCharles.Forsyth MPGRST = 0x2020;
669*74a4d8c2SCharles.Forsyth }
670*74a4d8c2SCharles.Forsyth done = 1;
671*74a4d8c2SCharles.Forsyth
672*74a4d8c2SCharles.Forsyth }
673*74a4d8c2SCharles.Forsyth
674*74a4d8c2SCharles.Forsyth /*
675*74a4d8c2SCharles.Forsyth * nbl (reg 0x1[ab]) was 0x0022, nblf (reg 1[cd]) was 0x0006
676*74a4d8c2SCharles.Forsyth */
677*74a4d8c2SCharles.Forsyth static uchar
678*74a4d8c2SCharles.Forsyth zrparam[] =
679*74a4d8c2SCharles.Forsyth {
680*74a4d8c2SCharles.Forsyth /* 00 */ 0xEF, 0x01, 0x01, 0x01, 0x80, 0x0E, 0x31, 0x00,
681*74a4d8c2SCharles.Forsyth /* 08 */ 0x01, 0x60, 0x00, 0x00, 0x03, 0x5A, 0x00, 0x7A,
682*74a4d8c2SCharles.Forsyth /* 10 */ 0x00, 0x10, 0x00, 0x08, 0x00, 0xF0, 0x00, 0x00,
683*74a4d8c2SCharles.Forsyth /* 18 */ 0x02, 0x0D, 0x00, 0x1e, 0x00, 0x0a, 0x00, 0x02,
684*74a4d8c2SCharles.Forsyth /* 20 */ 0x40, 0x06, 0x80, 0x00, 0x80, 0x00, 0x05, 0x9B,
685*74a4d8c2SCharles.Forsyth /* 28 */ 0x07, 0x16, 0xFD, 0x25, 0xFE, 0xA0, 0x00, 0x00,
686*74a4d8c2SCharles.Forsyth /* 30 */ 0x00, 0x07, 0x0d, 0xe1, 0x00, 0x00, 0x00, 0x3E,
687*74a4d8c2SCharles.Forsyth /* 38 */ 0x00, 0x00, 0x09, 0x51, 0x00, 0x00, 0xCD, 0xFE,
688*74a4d8c2SCharles.Forsyth /* 40 */ 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
689*74a4d8c2SCharles.Forsyth /* 48 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
690*74a4d8c2SCharles.Forsyth /* 50 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
691*74a4d8c2SCharles.Forsyth /* 58 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
692*74a4d8c2SCharles.Forsyth /* 60 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
693*74a4d8c2SCharles.Forsyth /* 68 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
694*74a4d8c2SCharles.Forsyth /* 70 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
695*74a4d8c2SCharles.Forsyth /* 78 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
696*74a4d8c2SCharles.Forsyth };
697*74a4d8c2SCharles.Forsyth
698*74a4d8c2SCharles.Forsyth static int
initzoran(void)699*74a4d8c2SCharles.Forsyth initzoran(void)
700*74a4d8c2SCharles.Forsyth {
701*74a4d8c2SCharles.Forsyth int i, nbytes, zrs;
702*74a4d8c2SCharles.Forsyth
703*74a4d8c2SCharles.Forsyth initctl();
704*74a4d8c2SCharles.Forsyth freebufs();
705*74a4d8c2SCharles.Forsyth
706*74a4d8c2SCharles.Forsyth machsr = DSPRST|VSNIRQn;
707*74a4d8c2SCharles.Forsyth outs(mpegconf.zrport+ZRMACH210, machsr);
708*74a4d8c2SCharles.Forsyth microdelay(4000);
709*74a4d8c2SCharles.Forsyth
710*74a4d8c2SCharles.Forsyth machsr |= STDBY;
711*74a4d8c2SCharles.Forsyth outs(mpegconf.zrport+ZRMACH210, machsr);
712*74a4d8c2SCharles.Forsyth microdelay(4000);
713*74a4d8c2SCharles.Forsyth
714*74a4d8c2SCharles.Forsyth machsr |= MPGRST;
715*74a4d8c2SCharles.Forsyth outs(mpegconf.zrport+ZRMACH210, machsr);
716*74a4d8c2SCharles.Forsyth microdelay(4000);
717*74a4d8c2SCharles.Forsyth machsr &= ~MPGRST;
718*74a4d8c2SCharles.Forsyth outs(mpegconf.zrport+ZRMACH210, machsr);
719*74a4d8c2SCharles.Forsyth microdelay(4000);
720*74a4d8c2SCharles.Forsyth machsr |= MPGRST;
721*74a4d8c2SCharles.Forsyth outs(mpegconf.zrport+ZRMACH210, machsr);
722*74a4d8c2SCharles.Forsyth microdelay(4000);
723*74a4d8c2SCharles.Forsyth
724*74a4d8c2SCharles.Forsyth if(zrwaitrdy(2000, "load IDP"))
725*74a4d8c2SCharles.Forsyth return -1;
726*74a4d8c2SCharles.Forsyth
727*74a4d8c2SCharles.Forsyth for(i = 0; i < IDPCOUNT; i++)
728*74a4d8c2SCharles.Forsyth outb(mpegconf.zrport+ZRREG2, zrmpeg1[i]);
729*74a4d8c2SCharles.Forsyth
730*74a4d8c2SCharles.Forsyth if(((zrs = zrstatus()) & 3) != 3) {
731*74a4d8c2SCharles.Forsyth /* print("devmpeg: error loading IDP sr=%2.2ux\n", zrs); */
732*74a4d8c2SCharles.Forsyth USED(zrs);
733*74a4d8c2SCharles.Forsyth return -1;
734*74a4d8c2SCharles.Forsyth }
735*74a4d8c2SCharles.Forsyth
736*74a4d8c2SCharles.Forsyth if(zrwaitrdy(2000, "load PMDP"))
737*74a4d8c2SCharles.Forsyth return -1;
738*74a4d8c2SCharles.Forsyth
739*74a4d8c2SCharles.Forsyth for(i = 0; i < PMDPCOUNT; i++)
740*74a4d8c2SCharles.Forsyth outb(mpegconf.zrport+ZRREG3, zrmpeg2[i]);
741*74a4d8c2SCharles.Forsyth
742*74a4d8c2SCharles.Forsyth if(((zrs = zrstatus()) & 3) != 3) {
743*74a4d8c2SCharles.Forsyth /* print("devmpeg: error loading PMDP sr=%2.2ux\n", zrs); */
744*74a4d8c2SCharles.Forsyth USED(zrs);
745*74a4d8c2SCharles.Forsyth return -1;
746*74a4d8c2SCharles.Forsyth }
747*74a4d8c2SCharles.Forsyth
748*74a4d8c2SCharles.Forsyth zrparam[0x36] = sp2cd>>8;
749*74a4d8c2SCharles.Forsyth zrparam[0x37] = sp2cd>>0;
750*74a4d8c2SCharles.Forsyth zrparam[0x31] = sp2br>>16;
751*74a4d8c2SCharles.Forsyth zrparam[0x32] = sp2br>>8;
752*74a4d8c2SCharles.Forsyth zrparam[0x33] = sp2br>>0;
753*74a4d8c2SCharles.Forsyth
754*74a4d8c2SCharles.Forsyth nbytes = 16;
755*74a4d8c2SCharles.Forsyth for(i = 0; i < 128; i++) {
756*74a4d8c2SCharles.Forsyth if(nbytes >= 16) {
757*74a4d8c2SCharles.Forsyth if(zrwaitrdy(2000, "load parameters"))
758*74a4d8c2SCharles.Forsyth return -1;
759*74a4d8c2SCharles.Forsyth nbytes = 0;
760*74a4d8c2SCharles.Forsyth }
761*74a4d8c2SCharles.Forsyth outb(mpegconf.zrport+ZRREG0, zrparam[i]);
762*74a4d8c2SCharles.Forsyth nbytes++;
763*74a4d8c2SCharles.Forsyth }
764*74a4d8c2SCharles.Forsyth
765*74a4d8c2SCharles.Forsyth if(zrwaitrdy(2000, "load SVMDP"))
766*74a4d8c2SCharles.Forsyth return -1;
767*74a4d8c2SCharles.Forsyth
768*74a4d8c2SCharles.Forsyth for(i = 0; i < SVMDPCOUNT; i++)
769*74a4d8c2SCharles.Forsyth outb(mpegconf.zrport+ZRREG3, zrmpeg3s[i]);
770*74a4d8c2SCharles.Forsyth
771*74a4d8c2SCharles.Forsyth if(((zrs = zrstatus()) & 3) != 3) {
772*74a4d8c2SCharles.Forsyth /* print("devmpeg: error loading SVMDP sr=%2.2ux\n", zrs); */
773*74a4d8c2SCharles.Forsyth USED(zrs);
774*74a4d8c2SCharles.Forsyth return -1;
775*74a4d8c2SCharles.Forsyth }
776*74a4d8c2SCharles.Forsyth return 0;
777*74a4d8c2SCharles.Forsyth }
778*74a4d8c2SCharles.Forsyth
779*74a4d8c2SCharles.Forsyth static struct
780*74a4d8c2SCharles.Forsyth {
781*74a4d8c2SCharles.Forsyth short reg;
782*74a4d8c2SCharles.Forsyth ushort val;
783*74a4d8c2SCharles.Forsyth } trireg[] =
784*74a4d8c2SCharles.Forsyth {
785*74a4d8c2SCharles.Forsyth 0x20, 0x0400,
786*74a4d8c2SCharles.Forsyth 0x21, 0x00e9,
787*74a4d8c2SCharles.Forsyth 0x22, 0x0000,
788*74a4d8c2SCharles.Forsyth 0x23, 0x07ee,
789*74a4d8c2SCharles.Forsyth 0x24, 0x0005,
790*74a4d8c2SCharles.Forsyth 0x25, 0xff00,
791*74a4d8c2SCharles.Forsyth 0x26, 0x0000,
792*74a4d8c2SCharles.Forsyth 0x27, 0x7fff,
793*74a4d8c2SCharles.Forsyth 0x28, 0x0004,
794*74a4d8c2SCharles.Forsyth 0x29, 0x88a0,
795*74a4d8c2SCharles.Forsyth 0x2a, 0x0011,
796*74a4d8c2SCharles.Forsyth 0x2b, 0x8540,
797*74a4d8c2SCharles.Forsyth 0x2c, 0x00c4,
798*74a4d8c2SCharles.Forsyth 0x2d, 0x00ac,
799*74a4d8c2SCharles.Forsyth 0x2e, 0x020f,
800*74a4d8c2SCharles.Forsyth 0x2f, 0x019d,
801*74a4d8c2SCharles.Forsyth 0x30, 0x00bd,
802*74a4d8c2SCharles.Forsyth 0x31, 0x00ff,
803*74a4d8c2SCharles.Forsyth 0x32, 0x0000,
804*74a4d8c2SCharles.Forsyth 0x33, 0x0000,
805*74a4d8c2SCharles.Forsyth 0x34, 0x03ff,
806*74a4d8c2SCharles.Forsyth 0x35, 0x0000,
807*74a4d8c2SCharles.Forsyth 0x36, 0x0000,
808*74a4d8c2SCharles.Forsyth 0x37, 0x03ff,
809*74a4d8c2SCharles.Forsyth 0x38, 0x0000,
810*74a4d8c2SCharles.Forsyth 0x39, 0x0000,
811*74a4d8c2SCharles.Forsyth 0x3a, 0x03ff,
812*74a4d8c2SCharles.Forsyth 0x3b, 0x01da,
813*74a4d8c2SCharles.Forsyth 0x3c, 0xe8ce,
814*74a4d8c2SCharles.Forsyth 0x3d, 0x2ac0,
815*74a4d8c2SCharles.Forsyth 0x3e, 0x891f,
816*74a4d8c2SCharles.Forsyth 0x3f, 0x3e25,
817*74a4d8c2SCharles.Forsyth 0x40, 0x03ff,
818*74a4d8c2SCharles.Forsyth 0x41, 0x01ff,
819*74a4d8c2SCharles.Forsyth 0x42, 0x001f,
820*74a4d8c2SCharles.Forsyth 0x43, 0x01ff,
821*74a4d8c2SCharles.Forsyth 0x44, 0x003b,
822*74a4d8c2SCharles.Forsyth 0x45, 0x0186,
823*74a4d8c2SCharles.Forsyth 0x46, 0x1d06,
824*74a4d8c2SCharles.Forsyth 0x47, 0x1a4f,
825*74a4d8c2SCharles.Forsyth 0x48, 0x020d,
826*74a4d8c2SCharles.Forsyth 0x49, 0x01ad,
827*74a4d8c2SCharles.Forsyth 0x4a, 0x001b,
828*74a4d8c2SCharles.Forsyth 0x4b, 0x01fd,
829*74a4d8c2SCharles.Forsyth 0x4c, 0x003a,
830*74a4d8c2SCharles.Forsyth 0x4d, 0x034b,
831*74a4d8c2SCharles.Forsyth 0x4e, 0x2006,
832*74a4d8c2SCharles.Forsyth 0x4f, 0x0083,
833*74a4d8c2SCharles.Forsyth 0x50, 0xef08,
834*74a4d8c2SCharles.Forsyth 0x51, 0xef3a,
835*74a4d8c2SCharles.Forsyth 0x52, 0xefff,
836*74a4d8c2SCharles.Forsyth 0x53, 0xef08,
837*74a4d8c2SCharles.Forsyth 0x54, 0xef08,
838*74a4d8c2SCharles.Forsyth 0x55, 0xef15,
839*74a4d8c2SCharles.Forsyth 0x56, 0xefc0,
840*74a4d8c2SCharles.Forsyth 0x57, 0xef08,
841*74a4d8c2SCharles.Forsyth 0x58, 0xefef,
842*74a4d8c2SCharles.Forsyth 0x59, 0xefef,
843*74a4d8c2SCharles.Forsyth 0x5a, 0xefef,
844*74a4d8c2SCharles.Forsyth 0x5b, 0xefef,
845*74a4d8c2SCharles.Forsyth 0x5c, 0xefef,
846*74a4d8c2SCharles.Forsyth 0x5d, 0xefef,
847*74a4d8c2SCharles.Forsyth 0x5e, 0xefef,
848*74a4d8c2SCharles.Forsyth 0x5f, 0xefef,
849*74a4d8c2SCharles.Forsyth 0x60, 0x0000,
850*74a4d8c2SCharles.Forsyth 0x61, 0x0004,
851*74a4d8c2SCharles.Forsyth 0x62, 0x0020,
852*74a4d8c2SCharles.Forsyth 0x63, 0x8080,
853*74a4d8c2SCharles.Forsyth 0x64, 0x0300,
854*74a4d8c2SCharles.Forsyth -1
855*74a4d8c2SCharles.Forsyth };
856*74a4d8c2SCharles.Forsyth
857*74a4d8c2SCharles.Forsyth static void
clrI2C(uchar b)858*74a4d8c2SCharles.Forsyth clrI2C(uchar b)
859*74a4d8c2SCharles.Forsyth {
860*74a4d8c2SCharles.Forsyth uchar t;
861*74a4d8c2SCharles.Forsyth
862*74a4d8c2SCharles.Forsyth outb(mpegconf.trport+TRIINDEX, I2CR);
863*74a4d8c2SCharles.Forsyth t = inb(mpegconf.trport+TRIHI);
864*74a4d8c2SCharles.Forsyth t &= ~b;
865*74a4d8c2SCharles.Forsyth outb(mpegconf.trport+TRIHI, t);
866*74a4d8c2SCharles.Forsyth }
867*74a4d8c2SCharles.Forsyth
868*74a4d8c2SCharles.Forsyth static void
setI2C(uchar b)869*74a4d8c2SCharles.Forsyth setI2C(uchar b)
870*74a4d8c2SCharles.Forsyth {
871*74a4d8c2SCharles.Forsyth uchar t;
872*74a4d8c2SCharles.Forsyth
873*74a4d8c2SCharles.Forsyth outb(mpegconf.trport+TRIINDEX, I2CR);
874*74a4d8c2SCharles.Forsyth t = inb(mpegconf.trport+TRIHI);
875*74a4d8c2SCharles.Forsyth t |= b;
876*74a4d8c2SCharles.Forsyth outb(mpegconf.trport+TRIHI, t);
877*74a4d8c2SCharles.Forsyth }
878*74a4d8c2SCharles.Forsyth
879*74a4d8c2SCharles.Forsyth static void
startI2C(void)880*74a4d8c2SCharles.Forsyth startI2C(void)
881*74a4d8c2SCharles.Forsyth {
882*74a4d8c2SCharles.Forsyth setI2C(SDA);
883*74a4d8c2SCharles.Forsyth setI2C(SCL);
884*74a4d8c2SCharles.Forsyth microdelay(I2DLY);
885*74a4d8c2SCharles.Forsyth clrI2C(SDA);
886*74a4d8c2SCharles.Forsyth microdelay(I2DLY);
887*74a4d8c2SCharles.Forsyth clrI2C(SCL);
888*74a4d8c2SCharles.Forsyth microdelay(I2DLY);
889*74a4d8c2SCharles.Forsyth }
890*74a4d8c2SCharles.Forsyth
891*74a4d8c2SCharles.Forsyth static void
endI2C(void)892*74a4d8c2SCharles.Forsyth endI2C(void)
893*74a4d8c2SCharles.Forsyth {
894*74a4d8c2SCharles.Forsyth clrI2C(SDA);
895*74a4d8c2SCharles.Forsyth clrI2C(SCL);
896*74a4d8c2SCharles.Forsyth microdelay(I2DLY);
897*74a4d8c2SCharles.Forsyth setI2C(SCL);
898*74a4d8c2SCharles.Forsyth microdelay(I2DLY);
899*74a4d8c2SCharles.Forsyth setI2C(SDA);
900*74a4d8c2SCharles.Forsyth microdelay(I2DLY);
901*74a4d8c2SCharles.Forsyth }
902*74a4d8c2SCharles.Forsyth
903*74a4d8c2SCharles.Forsyth static void
wrI2Cbit(uchar b)904*74a4d8c2SCharles.Forsyth wrI2Cbit(uchar b)
905*74a4d8c2SCharles.Forsyth {
906*74a4d8c2SCharles.Forsyth clrI2C(SDA);
907*74a4d8c2SCharles.Forsyth clrI2C(SCL);
908*74a4d8c2SCharles.Forsyth microdelay(I2DLY);
909*74a4d8c2SCharles.Forsyth if(b & 1) {
910*74a4d8c2SCharles.Forsyth setI2C(SDA);
911*74a4d8c2SCharles.Forsyth microdelay(I2DLY);
912*74a4d8c2SCharles.Forsyth setI2C(SCL);
913*74a4d8c2SCharles.Forsyth microdelay(I2DLY);
914*74a4d8c2SCharles.Forsyth clrI2C(SCL);
915*74a4d8c2SCharles.Forsyth microdelay(I2DLY);
916*74a4d8c2SCharles.Forsyth clrI2C(SDA);
917*74a4d8c2SCharles.Forsyth microdelay(I2DLY);
918*74a4d8c2SCharles.Forsyth }
919*74a4d8c2SCharles.Forsyth else {
920*74a4d8c2SCharles.Forsyth setI2C(SCL);
921*74a4d8c2SCharles.Forsyth microdelay(I2DLY);
922*74a4d8c2SCharles.Forsyth clrI2C(SCL);
923*74a4d8c2SCharles.Forsyth microdelay(I2DLY);
924*74a4d8c2SCharles.Forsyth }
925*74a4d8c2SCharles.Forsyth }
926*74a4d8c2SCharles.Forsyth
927*74a4d8c2SCharles.Forsyth static void
wrI2CB(unsigned char data)928*74a4d8c2SCharles.Forsyth wrI2CB(unsigned char data)
929*74a4d8c2SCharles.Forsyth {
930*74a4d8c2SCharles.Forsyth int i;
931*74a4d8c2SCharles.Forsyth
932*74a4d8c2SCharles.Forsyth for(i = 0; i < 8; i++)
933*74a4d8c2SCharles.Forsyth wrI2Cbit(data >>(7-i));
934*74a4d8c2SCharles.Forsyth }
935*74a4d8c2SCharles.Forsyth
936*74a4d8c2SCharles.Forsyth static int
rdI2CBit(void)937*74a4d8c2SCharles.Forsyth rdI2CBit(void)
938*74a4d8c2SCharles.Forsyth {
939*74a4d8c2SCharles.Forsyth int bit = 1;
940*74a4d8c2SCharles.Forsyth
941*74a4d8c2SCharles.Forsyth setI2C(SDA);
942*74a4d8c2SCharles.Forsyth clrI2C(SCL);
943*74a4d8c2SCharles.Forsyth setI2C(SCL);
944*74a4d8c2SCharles.Forsyth outb(mpegconf.trport+TRIINDEX, I2CR);
945*74a4d8c2SCharles.Forsyth if(inb(mpegconf.trport+TRIHI) & SDA)
946*74a4d8c2SCharles.Forsyth bit = 0;
947*74a4d8c2SCharles.Forsyth clrI2C(SDA);
948*74a4d8c2SCharles.Forsyth clrI2C(SCL);
949*74a4d8c2SCharles.Forsyth
950*74a4d8c2SCharles.Forsyth return bit;
951*74a4d8c2SCharles.Forsyth }
952*74a4d8c2SCharles.Forsyth
953*74a4d8c2SCharles.Forsyth static int
wrI2CD(uchar data)954*74a4d8c2SCharles.Forsyth wrI2CD(uchar data)
955*74a4d8c2SCharles.Forsyth {
956*74a4d8c2SCharles.Forsyth int r;
957*74a4d8c2SCharles.Forsyth ulong s;
958*74a4d8c2SCharles.Forsyth
959*74a4d8c2SCharles.Forsyth s = splhi();
960*74a4d8c2SCharles.Forsyth wrI2CB(data);
961*74a4d8c2SCharles.Forsyth r = rdI2CBit();
962*74a4d8c2SCharles.Forsyth splx(s);
963*74a4d8c2SCharles.Forsyth return r;
964*74a4d8c2SCharles.Forsyth }
965*74a4d8c2SCharles.Forsyth
966*74a4d8c2SCharles.Forsyth static uchar
967*74a4d8c2SCharles.Forsyth setupSAA7110[] =
968*74a4d8c2SCharles.Forsyth {
969*74a4d8c2SCharles.Forsyth /* Digital */
970*74a4d8c2SCharles.Forsyth 0x4c, 0x3c, 0x0d, 0xef, 0xbd, 0xf0, 0x40, 0x03,
971*74a4d8c2SCharles.Forsyth 0xf8, 0xf8, 0x90, 0x90, 0x00, 0x02, 0x10, 0x77,
972*74a4d8c2SCharles.Forsyth 0x00, 0x2c, 0x40, 0x40, 0x3b, 0x10, 0xfc, 0xd2,
973*74a4d8c2SCharles.Forsyth 0xf0, 0x80,
974*74a4d8c2SCharles.Forsyth
975*74a4d8c2SCharles.Forsyth /* Analog */
976*74a4d8c2SCharles.Forsyth 0xd9, 0x16, 0x40, 0x40, 0x80, 0x40, 0x80, 0x4f,
977*74a4d8c2SCharles.Forsyth 0xfe, 0x01, 0xcf, 0x0f, 0x03, 0x01, 0x81, 0x0a,
978*74a4d8c2SCharles.Forsyth 0x40, 0x35, 0x02, 0x8c, 0x03
979*74a4d8c2SCharles.Forsyth };
980*74a4d8c2SCharles.Forsyth
981*74a4d8c2SCharles.Forsyth static void
addrI2CB(int addr,int val)982*74a4d8c2SCharles.Forsyth addrI2CB(int addr, int val)
983*74a4d8c2SCharles.Forsyth {
984*74a4d8c2SCharles.Forsyth ulong s;
985*74a4d8c2SCharles.Forsyth
986*74a4d8c2SCharles.Forsyth s = splhi();
987*74a4d8c2SCharles.Forsyth startI2C();
988*74a4d8c2SCharles.Forsyth wrI2CD(SAA7110|WRITE_C);
989*74a4d8c2SCharles.Forsyth wrI2CD(addr);
990*74a4d8c2SCharles.Forsyth wrI2CD(val);
991*74a4d8c2SCharles.Forsyth endI2C();
992*74a4d8c2SCharles.Forsyth splx(s);
993*74a4d8c2SCharles.Forsyth }
994*74a4d8c2SCharles.Forsyth
995*74a4d8c2SCharles.Forsyth static void
inittrident(void)996*74a4d8c2SCharles.Forsyth inittrident(void)
997*74a4d8c2SCharles.Forsyth {
998*74a4d8c2SCharles.Forsyth int i;
999*74a4d8c2SCharles.Forsyth
1000*74a4d8c2SCharles.Forsyth for(i = 0; trireg[i].reg != -1; i++)
1001*74a4d8c2SCharles.Forsyth triwr(trireg[i].reg, trireg[i].val);
1002*74a4d8c2SCharles.Forsyth
1003*74a4d8c2SCharles.Forsyth for(i = 0; i < 47; i++)
1004*74a4d8c2SCharles.Forsyth addrI2CB(i, setupSAA7110[i]);
1005*74a4d8c2SCharles.Forsyth }
1006*74a4d8c2SCharles.Forsyth
1007*74a4d8c2SCharles.Forsyth static void
initcrystal(void)1008*74a4d8c2SCharles.Forsyth initcrystal(void)
1009*74a4d8c2SCharles.Forsyth {
1010*74a4d8c2SCharles.Forsyth int i;
1011*74a4d8c2SCharles.Forsyth static int done;
1012*74a4d8c2SCharles.Forsyth
1013*74a4d8c2SCharles.Forsyth if(done)
1014*74a4d8c2SCharles.Forsyth return;
1015*74a4d8c2SCharles.Forsyth
1016*74a4d8c2SCharles.Forsyth done = 1;
1017*74a4d8c2SCharles.Forsyth
1018*74a4d8c2SCharles.Forsyth initctl();
1019*74a4d8c2SCharles.Forsyth
1020*74a4d8c2SCharles.Forsyth /* Reboot the Musicam decoder */
1021*74a4d8c2SCharles.Forsyth clrI2C(SCL);
1022*74a4d8c2SCharles.Forsyth clrI2C(SDA);
1023*74a4d8c2SCharles.Forsyth machsr |= DSPRST;
1024*74a4d8c2SCharles.Forsyth outs(mpegconf.zrport+ZRMACH210, machsr);
1025*74a4d8c2SCharles.Forsyth machsr |= DSPBOOT;
1026*74a4d8c2SCharles.Forsyth outs(mpegconf.zrport+ZRMACH210, machsr);
1027*74a4d8c2SCharles.Forsyth machsr &= ~DSPRST;
1028*74a4d8c2SCharles.Forsyth outs(mpegconf.zrport+ZRMACH210, machsr);
1029*74a4d8c2SCharles.Forsyth machsr |= DSPRST;
1030*74a4d8c2SCharles.Forsyth outs(mpegconf.zrport+ZRMACH210, machsr);
1031*74a4d8c2SCharles.Forsyth machsr &= ~DSPBOOT;
1032*74a4d8c2SCharles.Forsyth outs(mpegconf.zrport+ZRMACH210, machsr);
1033*74a4d8c2SCharles.Forsyth
1034*74a4d8c2SCharles.Forsyth startI2C();
1035*74a4d8c2SCharles.Forsyth wrI2CD(0);
1036*74a4d8c2SCharles.Forsyth for(i = 0; i < sizeof(crystal); i++ )
1037*74a4d8c2SCharles.Forsyth wrI2CD(crystal[i]);
1038*74a4d8c2SCharles.Forsyth endI2C();
1039*74a4d8c2SCharles.Forsyth }
1040*74a4d8c2SCharles.Forsyth
1041*74a4d8c2SCharles.Forsyth static void
mpegintr(Ureg *,void *)1042*74a4d8c2SCharles.Forsyth mpegintr(Ureg*, void*)
1043*74a4d8c2SCharles.Forsyth {
1044*74a4d8c2SCharles.Forsyth Buf *b;
1045*74a4d8c2SCharles.Forsyth
1046*74a4d8c2SCharles.Forsyth b = bqueue.head;
1047*74a4d8c2SCharles.Forsyth if(b == 0 || dmadone(mpegconf.dma) == 0)
1048*74a4d8c2SCharles.Forsyth return;
1049*74a4d8c2SCharles.Forsyth
1050*74a4d8c2SCharles.Forsyth dmaend(mpegconf.dma);
1051*74a4d8c2SCharles.Forsyth if(b->nchar == 0) {
1052*74a4d8c2SCharles.Forsyth bqueue.head = b->link;
1053*74a4d8c2SCharles.Forsyth free(b);
1054*74a4d8c2SCharles.Forsyth
1055*74a4d8c2SCharles.Forsyth b = bqueue.head;
1056*74a4d8c2SCharles.Forsyth if(b == 0) {
1057*74a4d8c2SCharles.Forsyth started = 0;
1058*74a4d8c2SCharles.Forsyth return;
1059*74a4d8c2SCharles.Forsyth }
1060*74a4d8c2SCharles.Forsyth }
1061*74a4d8c2SCharles.Forsyth zrdma(b);
1062*74a4d8c2SCharles.Forsyth wakeup(&bqueue.flow);
1063*74a4d8c2SCharles.Forsyth }
1064