Annotation of margi2/margi.c, revision 1.17
1.1 cvs 1: /*
2: margi.c
3:
4: Copyright (C) Marcus Metzler for convergence integrated media.
5:
6: This program is free software; you can redistribute it and/or modify
7: it under the terms of the GNU General Public License as published by
8: the Free Software Foundation; either version 2 of the License, or
9: (at your option) any later version.
10:
11: This program is distributed in the hope that it will be useful,
12: but WITHOUT ANY WARRANTY; without even the implied warranty of
13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14: GNU General Public License for more details.
15:
16: You should have received a copy of the GNU General Public License
17: along with this program; if not, write to the Free Software
18: Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19: */
20:
21: #include "margi.h"
22:
23: #include <pcmcia/version.h>
24: #include <pcmcia/cs_types.h>
25: #include <pcmcia/cs.h>
26: #include <pcmcia/cistpl.h>
27: #include <pcmcia/cisreg.h>
28: #include <pcmcia/bus_ops.h>
29: #include <pcmcia/ds.h>
30:
31:
32:
33: #include "l64014.h"
34: #include "l64021.h"
35: #include "i2c.h"
36: #include "decoder.h"
37: #include "dram.h"
38: #include "video.h"
39: #include "cvdv.h"
40:
1.13 mocm 41:
42: static char *version = "margi_cs.c 0.5 11/1/2000 (Marcus Metzler)";
43:
1.1 cvs 44: //#define USE_BH 1
45: #ifdef USE_BH
46: #define MARGI_BH 31
47: // shouldn't be a number, but then MARGI_BH must be entered into interrupt.h
48: #endif
49:
50: MODULE_AUTHOR(AUTHOR);
51: MODULE_DESCRIPTION(MEDDEVNAME " Driver V." DVERSION);
52:
53: #define MAX_DEV 4
54: #define DEVICE_NR(minor) ((minor)>>4)
55:
56: /*====================================================================*/
57:
58: /* Parameters that can be set with 'insmod' */
59:
60: /* Release IO ports after configuration? */
61: static int free_ports = 0;
62:
63: /* The old way: bit map of interrupts to choose from */
64: /* This means pick from 15, 14, 12, 11, 10, 9, 7, 5, 4, and 3 */
65: static u_int irq_mask = 0xdeb8;
66: /* Newer, simpler way of listing specific interrupts */
67: static int irq_list[4] = { -1 };
68:
69: MODULE_PARM(free_ports, "i");
70: MODULE_PARM(irq_mask, "i");
71: MODULE_PARM(irq_list, "1-4i");
72:
73: extern unsigned int major_device_number;
74: extern struct file_operations cvdv_fileops;
75:
76: typedef struct margi_info_t {
77: dev_link_t link;
78: dev_node_t node;
79: struct cvdv_cards card;
80: int stop;
81: } margi_info_t;
82:
83:
84:
85: /*
86: The event() function is this driver's Card Services event handler.
87: It will be called by Card Services when an appropriate card status
88: event is received. The config() and release() entry points are
89: used to configure or release a socket, in response to card
90: insertion and ejection events. They are invoked from the margi
91: event handler.
92: */
93:
94: static void margi_config(dev_link_t * link);
95: static void margi_release(u_long arg);
96: static int margi_event(event_t event, int priority,
97: event_callback_args_t * args);
98: /*
99: The attach() and detach() entry points are used to create and destroy
100: "instances" of the driver, where each instance represents everything
101: needed to manage one actual PCMCIA card.
102: */
103:
104: static dev_link_t *margi_attach(void);
105: static void margi_detach(dev_link_t *);
106: static u_char read_lsi_status(struct cvdv_cards *card);
107:
108: /*
109: You'll also need to prototype all the functions that will actually
110: be used to talk to your device. See 'memory_cs' for a good example
111: of a fully self-sufficient driver; the other drivers rely more or
112: less on other parts of the kernel.
113: */
114:
115: /*
116: The dev_info variable is the "key" that is used to match up this
117: device driver with appropriate cards, through the card configuration
118: database.
119: */
120:
121: static dev_link_t *dev_table[MAX_DEV] = { NULL, /* ... */ };
122:
123: static dev_info_t dev_info = "margi_cs";
124:
125: /*
126: A linked list of "instances" of the margi device. Each actual
127: PCMCIA card corresponds to one device instance, and is described
128: by one dev_link_t structure (defined in ds.h).
129:
130: You may not want to use a linked list for this -- for example, the
131: memory card driver uses an array of dev_link_t pointers, where minor
132: device numbers are used to derive the corresponding array index.
133: */
134:
135: static dev_link_t *dev_list = NULL;
136:
137: /*
138: A dev_link_t structure has fields for most things that are needed
139: to keep track of a socket, but there will usually be some device
140: specific information that also needs to be kept track of. The
141: 'priv' pointer in a dev_link_t structure can be used to point to
142: a device-specific private data structure, like this.
143:
144: To simplify the data structure handling, we actually include the
145: dev_link_t structure in the device's private data structure.
146:
147: A driver needs to provide a dev_node_t structure for each device
148: on a card. In some cases, there is only one device per card (for
149: example, ethernet cards, modems). In other cases, there may be
150: many actual or logical devices (SCSI adapters, memory cards with
151: multiple partitions). The dev_node_t structures need to be kept
152: in a linked list starting at the 'dev' field of a dev_link_t
153: structure. We allocate them in the card's private data structure,
154: because they generally shouldn't be allocated dynamically.
155:
156: In this case, we also provide a flag to indicate if a device is
157: "stopped" due to a power management event, or card ejection. The
158: device IO routines can use a flag like this to throttle IO to a
159: card that is not ready to accept it.
160:
161: The bus_operations pointer is used on platforms for which we need
162: to use special socket-specific versions of normal IO primitives
163: (inb, outb, readb, writeb, etc) for card IO.
164: */
165:
166: void DACSetFrequency(struct cvdv_cards *card, int khz, int multiple) {
1.11 mocm 167: uint8_t b = read_indexed_register(card, IIO_OSC_AUD);
1.1 cvs 168:
169: b &= 0xf8;
170:
171: switch (khz){
1.2 rjkm 172: case 32:
173: b |= 0x04;
174: break;
1.1 cvs 175: case 48:
176: b |= 0x00;
177: break;
178: case 44:
179: b |= 0x01;
180: break;
181: case 96:
182: b |= 0x02;
183: break;
184: default:
185: b |= 0x00;
186: break;
187: }
188: write_indexed_register(card, IIO_OSC_AUD, b);
189:
190: }
191:
1.17 ! mocm 192: int MargiFreeBuffers(struct cvdv_cards *card)
1.1 cvs 193: {
1.13 mocm 194: MDEBUG(1, ": -- MargiFreeBuffers\n");
1.1 cvs 195:
1.17 ! mocm 196: ring_destroy(&(card->rbufB));
! 197: card->use_ringB = 0;
! 198: ring_destroy(&(card->rbufA));
! 199: card->use_ringA = 0;
1.15 mocm 200:
1.1 cvs 201: return 0;
202: }
203:
204:
1.15 mocm 205: int MargiSetBuffers(struct cvdv_cards *card, uint32_t size, int isB)
1.1 cvs 206: {
1.15 mocm 207: int err = 0;
1.1 cvs 208:
1.15 mocm 209: MDEBUG(0, ": -- MargiSetBuffers(%d) %d\n",
210: size, isB);
211:
212: if (isB){
213: err = ring_init(&(card->rbufB),size);
214: if (!err) card->use_ringB = 1;
215: } else {
216: err = ring_init(&(card->rbufA),size);
217: if (!err) card->use_ringA = 1;
218: }
219:
1.17 ! mocm 220: MDEBUG(0,"set buffers: %d use_ringA: %d use_ringB: %d\n",err,
1.15 mocm 221: card->use_ringA,card->use_ringB);
222: return err;
1.13 mocm 223: }
1.1 cvs 224:
225:
226: int MargiFlush (struct cvdv_cards *card)
227: {
228: int co = 0;
229: int i;
1.13 mocm 230: for (i=0;i<100;i++){
231: MargiPushA(card, 32, FlushPacket);
232: MargiPushB(card, 32, FlushPacket);
233: }
234: while ( (ring_write_rest(&(card->rbufA))|| ring_write_rest(&(card->rbufB))) && co<100)
235: co++;
1.1 cvs 236: VideoSetBackground(card, 1, 0, 0, 0); // black
237:
1.13 mocm 238: if (card->use_ringA) ring_flush(&(card->rbufA));
239: if (card->use_ringB) ring_flush(&(card->rbufB));
1.1 cvs 240: card->DMAABusy = 0;
1.13 mocm 241: card->DMABBusy = 0;
1.1 cvs 242:
243:
244: DecoderStopChannel(card);
245: DecoderStreamReset(card);
246: DecoderSetupReset(card);
247: card->channelrun = 0;
248:
1.13 mocm 249: MDEBUG(1, ": Margi Flush \n");
1.1 cvs 250: return 0;
251: }
252:
253:
1.13 mocm 254: int MargiPushA(struct cvdv_cards *card, int count, const char *data)
1.1 cvs 255: {
1.11 mocm 256: int fill;
257:
1.13 mocm 258: fill = ring_read_rest(&(card->rbufA));
1.11 mocm 259:
1.13 mocm 260: if (!card->use_ringA)
1.1 cvs 261: return 0;
1.15 mocm 262: if ((count>fill || fill > 3*card->rbufA.size/4)
263: && !card->channelrun){
1.1 cvs 264: DecoderStartChannel(card);
1.11 mocm 265: card->DMAABusy = 1;
1.1 cvs 266: }
267:
1.13 mocm 268: count = ring_write(&(card->rbufA),data,count);
1.15 mocm 269:
1.13 mocm 270: return count;
271: }
272:
273: int MargiPushB(struct cvdv_cards *card, int count, const char *data)
274: {
275: int fill;
276:
277: fill = ring_read_rest(&(card->rbufB));
278:
279: if (!card->use_ringB)
280: return 0;
1.15 mocm 281: if ((count>fill || fill > 3*card->rbufB.size/4)
282: && !card->channelrun){
1.13 mocm 283: DecoderStartChannel(card);
284: card->DMABBusy = 1;
285: }
286:
287: count = ring_write(&(card->rbufB),data,count);
1.15 mocm 288:
1.1 cvs 289: return count;
290: }
291:
292: int DecoderStartChannel(struct cvdv_cards *card)
293: {
294: DecoderMaskByte(card, 0x007, 0xC3, 0xC3); // channel start
1.11 mocm 295:
1.1 cvs 296: #ifdef BYPASS
297: DecoderMaskByte(card,0x005,0x0F,0x08);
298: #else
299: DecoderMaskByte(card,0x005,0x0F,0x01);
300: #endif
301: card->channelrun = 1;
302: return 0;
303: }
304:
305: int DecoderStopChannel(struct cvdv_cards *card)
306: {
307: DecoderMaskByte(card, 0x007, 0xC3, 0xC2); // channel reset
308: DecoderSetByte(card, 0x005, 0x04); // channel pause
309: card->channelrun = 0;
310: return 0;
311: }
312:
1.11 mocm 313: uint32_t DecoderGetAudioBufferSpace(struct cvdv_cards *card)
1.1 cvs 314: {
315:
1.11 mocm 316: uint32_t MaxSize, Size;
1.1 cvs 317:
318: MaxSize = card->AudioESSize;
319: Size = DecoderGetAudioESLevel(card);
320:
321: if (Size>MaxSize)
322: return 0;
323: return (MaxSize - Size);
324:
325: }
326:
1.11 mocm 327: uint32_t DecoderGetVideoBufferSpace(struct cvdv_cards *card)
1.1 cvs 328: {
329:
1.11 mocm 330: uint32_t MaxSize, Size;
1.1 cvs 331:
332: MaxSize = card->VideoESSize;
333: Size = DecoderGetVideoESLevel(card);
334:
335: if (Size>MaxSize)
336: return 0;
337: return (MaxSize - Size);
338:
339: }
340:
1.11 mocm 341: uint32_t DecoderGetBufferSpace(struct cvdv_cards *card)
1.1 cvs 342: {
1.11 mocm 343: uint32_t audio,video;
1.1 cvs 344:
345: audio = DecoderGetAudioBufferSpace(card);
346: video = DecoderGetVideoBufferSpace(card);
347:
1.10 mocm 348: if (audio > 2048) audio -= 2048;
1.11 mocm 349: if (video > 2048) video -= 2048;
1.1 cvs 350:
351: if (audio < video) return audio;
352: return video;
353: }
354:
1.13 mocm 355:
1.7 mocm 356:
1.1 cvs 357: static int ringDMA (struct cvdv_cards *card){
358:
1.11 mocm 359: uint32_t size = 0;
1.1 cvs 360: u_char stat;
361: dev_link_t *link = &(((margi_info_t *) card->margi)->link);
1.15 mocm 362: uint32_t acount=0;
363: uint32_t vcount=0;
1.11 mocm 364: uint8_t data;
1.15 mocm 365: ringbuffy *buffy;
366: int stype;
367: wait_queue_head_t *wq;
1.1 cvs 368: stat = read_lsi_status(card);
1.10 mocm 369:
1.15 mocm 370:
371: stype = card->setup.streamtype;
372:
1.1 cvs 373: if (stat & LSI_ARQ) {
374: stat = read_lsi_status(card);
375: }
376:
377: if (stat & LSI_READY){
378: data = read_indexed_register(card, IIO_LSI_CONTROL);
379: data |= RR;
380: write_indexed_register(card, IIO_LSI_CONTROL, data);
381: return 0;
382: }
383:
384: if ((stat & LSI_ARQ) == 0) {
1.15 mocm 385: switch(stype){
386: case stream_PES:
387: case stream_ES:
388: data = read_indexed_register(card, IIO_LSI_CONTROL);
389: data &= ~DSVC;
390: write_indexed_register(card, IIO_LSI_CONTROL, data);
391: buffy = &card->rbufB;
392: wq = &(card->wqB);
393: acount = ring_read_rest(buffy);
394: size = DecoderGetAudioBufferSpace(card);
395: if (size > 2048) size -= 2048;
396: break;
397: default:
398: buffy = &card->rbufA;
399: wq = &(card->wqA);
400: acount = ring_read_rest(buffy);
401: size = DecoderGetBufferSpace(card);
402: break;
403: }
404: if (acount > size) acount = size & 0xfffffffc;
405: if (acount>=2048) acount &=0xfffff800;
406: acount &=0xfffffffc;
1.5 mocm 407:
1.15 mocm 408: if (acount > size) acount = size & 0xfffffffc;
409: if (acount) {
410: ring_read_direct(buffy,
411: link->io.BasePort1+DIO_LSI_STATUS,
412: acount);
413: } else {
414: wake_up_interruptible(wq);
415: acount = 0;
416: }
417: } else {
418: acount = 0;
419: }
1.11 mocm 420:
1.15 mocm 421: if ((stat & LSI_VRQ) == 0 &&
422: (stype == stream_PES || stype == stream_ES)) {
423: data = read_indexed_register(card, IIO_LSI_CONTROL);
424: data |= DSVC;
425: write_indexed_register(card, IIO_LSI_CONTROL, data);
426: buffy = &card->rbufA;
427: wq = &(card->wqA);
428: vcount = ring_read_rest(buffy);
429:
430: size = DecoderGetVideoBufferSpace(card);
431: if (size > 2048) size -= 2048;
432: if (vcount > size) vcount = size & 0xfffffffc;
433: if (vcount>=2048) vcount &=0xfffff800;
434: vcount &=0xfffffffc;
435:
436: if (vcount > size) vcount = size & 0xfffffffc;
437: if (vcount) {
438: ring_read_direct(buffy,
1.1 cvs 439: link->io.BasePort1+DIO_LSI_STATUS,
1.15 mocm 440: vcount);
441: } else {
442: wake_up_interruptible(wq);
443: vcount = 0;
444: }
1.1 cvs 445: } else {
1.15 mocm 446: vcount = 0;
1.1 cvs 447: }
448:
1.15 mocm 449: return vcount+acount;
1.1 cvs 450: }
451:
452:
453: u_char read_indexed_register(struct cvdv_cards * card, int addr)
454: {
455: dev_link_t *link = &(((margi_info_t *) card->margi)->link);
1.10 mocm 456: u_char data;
457: #ifdef NOINT
458: spin_lock(&card->timelock);
459: #endif
1.1 cvs 460: outb(addr, link->io.BasePort1 + DIO_CONTROL_INDEX);
1.10 mocm 461: data = (inb(link->io.BasePort1 + DIO_CONTROL_DATA));
462: #ifdef NOINT
463: spin_unlock(&card->timelock);
464: #endif
465: return data;
1.1 cvs 466: }
467:
468:
469: void write_indexed_register(struct cvdv_cards *card, int addr, u_char data)
470: {
471: dev_link_t *link = &(((margi_info_t *) card->margi)->link);
1.10 mocm 472: #ifdef NOINT
473: spin_lock(&card->timelock);
474: #endif
1.1 cvs 475: outb(addr, link->io.BasePort1 + DIO_CONTROL_INDEX);
476: outb(data, link->io.BasePort1 + DIO_CONTROL_DATA);
1.10 mocm 477:
478: #ifdef NOINT
479: spin_unlock(&card->timelock);
480: #endif
1.1 cvs 481: }
482:
483: void WriteByte(struct cvdv_cards *card, int addr, u_char data)
484: {
485: dev_link_t *link = &(((margi_info_t *) card->margi)->link);
486:
1.10 mocm 487: #ifdef NOINT
488: spin_lock(&card->timelock);
489: #endif
1.1 cvs 490: outb((u_char) (addr & 255),
491: link->io.BasePort1 + DIO_LSI_INDEX_LOW);
492: outb(((addr & 256) ? 1 : 0),
493: link->io.BasePort1 + DIO_LSI_INDEX_HIGH);
494: outb(data, link->io.BasePort1 + DIO_LSI_DATA);
1.10 mocm 495: #ifdef NOINT
496: spin_unlock(&card->timelock);
497: #endif
1.1 cvs 498: }
499:
500: u_char ReadByte(struct cvdv_cards *card, int addr)
501: {
502: dev_link_t *link = &(((margi_info_t *) card->margi)->link);
1.10 mocm 503: u_char data;
1.1 cvs 504:
1.10 mocm 505: #ifdef NOINT
506: spin_lock(&card->timelock);
507: #endif
1.1 cvs 508: outb((u_char) (addr & 255),
509: link->io.BasePort1 + DIO_LSI_INDEX_LOW);
510: outb(((addr & 256) ? 1 : 0),
511: link->io.BasePort1 + DIO_LSI_INDEX_HIGH);
1.10 mocm 512: data = inb(link->io.BasePort1 + DIO_LSI_DATA);
513: #ifdef NOINT
514: spin_unlock(&card->timelock);
515: #endif
516: return data;
1.1 cvs 517: }
518:
519: void MaskByte(struct cvdv_cards *card, int addr, u_char mask, u_char bits)
520: {
521: WriteByte(card, addr, (ReadByte(card, addr) & ~(mask)) | (bits));
522: }
523:
524:
525:
1.14 mocm 526: #define MAXWRITE CHANNELBUFFERSIZE/2
1.15 mocm 527: #define MAX_COUNT 400
1.1 cvs 528:
529: #ifdef USE_BH
530: struct cvdv_cards *bh_card;
531:
532: static void do_margi_bh(void)
533: {
534: struct cvdv_cards *card = bh_card;
535: #else
536:
537: static void do_margi(struct cvdv_cards *card)
538: {
539:
540: #endif
1.15 mocm 541: int countA;
1.1 cvs 542: int try;
1.13 mocm 543: int stype = card->setup.streamtype;
1.1 cvs 544:
545: countA = 0;
546:
547: card->currentType = 0;
548: for ( try = 0; try < MAX_COUNT ;try++)
549: if (countA < MAXWRITE){
550: int count = 0;
1.13 mocm 551: switch (stype){
552: case stream_PES:
553: case stream_ES:
554: count = ringDMA(card);
555: countA += count;
556: if (!count)
557: try=MAX_COUNT;
558: break;
559: case stream_PS:
560: case stream_DVD:
561: count = ringDMA(card);
562: countA += count;
563: if (!count)
564: try=MAX_COUNT;
565: break;
566: }
1.1 cvs 567: } else break;
568:
569: }
570:
1.7 mocm 571:
572:
573:
574: void L64014Intr_function(struct cvdv_cards *card)
1.1 cvs 575: {
1.11 mocm 576: uint8_t control,mask,stat;
1.1 cvs 577: int try;
578:
1.13 mocm 579:
1.1 cvs 580: control= read_indexed_register(card, IIO_IRQ_CONTROL);
581: if (control & IRQ_EN){
582: mask = 0;
583: if ( control & DEC_EN ) mask |= DEC_INT;
584: if ( control & VSYNC_EN ) mask |= VSYNC_INT;
585: stat = read_indexed_register(card, IIO_IRQ_STATUS);
586: try = 0;
587: while ( (try++ < 100) && (stat & mask) ){
1.11 mocm 588:
589: if (stat & VSYNC_INT) {
590:
1.1 cvs 591: write_indexed_register(card,IIO_IRQ_CONTROL,
592: control & (~VSYNC_EN));
593: write_indexed_register(card,IIO_IRQ_CONTROL,
594: control);
1.10 mocm 595:
596:
1.13 mocm 597: if (card->DMAABusy || card->DMABBusy){
1.1 cvs 598:
599: #ifdef USE_BH
600: bh_card = card;
601: mark_bh(MARGI_BH);
602: #else
603: do_margi(card);
604: #endif
1.13 mocm 605: if(card->use_ringA || card->use_ringB){
1.11 mocm 606: L64021Intr(card);
607: }
1.15 mocm 608: }
1.11 mocm 609: }
610:
611: if (stat & DEC_INT) {
612: write_indexed_register(card,IIO_IRQ_CONTROL,
613: control & (~DEC_EN));
614: write_indexed_register(card,IIO_IRQ_CONTROL,
615: control);
616:
1.13 mocm 617: if(card->use_ringA || card->use_ringB){
1.11 mocm 618: L64021Intr(card);
619: }
1.1 cvs 620: }
621:
622: stat = read_indexed_register(card, IIO_IRQ_STATUS);
623: }
624: }
625:
1.7 mocm 626: }
627:
628:
629: #ifdef NOINT
630: void Timerfunction(unsigned long data)
631: {
632: struct cvdv_cards *card = (struct cvdv_cards *) data;
633:
634: L64014Intr_function(card);
635:
636: card->timer.function = Timerfunction;
637: card->timer.data=(unsigned long) card;
1.15 mocm 638: card->timer.expires=jiffies+10;
1.13 mocm 639: if ( card->open)
1.10 mocm 640: add_timer(&card->timer);
1.7 mocm 641:
642: }
643: #endif
644:
645:
646: void L64014Intr(int irq, void *dev_id, struct pt_regs *regs)
647: {
648: margi_info_t *margi = dev_id;
649: struct cvdv_cards *card = &(margi->card);
650: u_char dio_index, lsi_index_low, lsi_index_high;
651:
1.10 mocm 652: #ifdef NOINT
653: spin_lock(&card->timelock);
654: #endif
1.7 mocm 655: //save registers
656: dio_index = inb(margi->link.io.BasePort1 + DIO_CONTROL_INDEX);
657: lsi_index_low = inb(margi->link.io.BasePort1 + DIO_LSI_INDEX_LOW);
1.10 mocm 658: lsi_index_high = inb(margi->link.io.BasePort1 + DIO_LSI_INDEX_HIGH);
1.7 mocm 659:
660:
661: L64014Intr_function(card);
662:
1.1 cvs 663: //load registers
664: outb(dio_index, margi->link.io.BasePort1 + DIO_CONTROL_INDEX);
665: outb(lsi_index_low, margi->link.io.BasePort1 + DIO_LSI_INDEX_LOW);
666: outb(lsi_index_high,margi->link.io.BasePort1 + DIO_LSI_INDEX_HIGH);
1.10 mocm 667: #ifdef NOINT
668: spin_unlock(&card->timelock);
669: #endif
1.1 cvs 670: }
671:
672: int L64014RemoveIntr(struct cvdv_cards *card)
673: {
1.13 mocm 674: MDEBUG(1, ": -- L64014RemoveIntr\n");
1.1 cvs 675: // Disable the IRQ's
676: write_indexed_register(card, IIO_IRQ_CONTROL, 0x00);
677: if (!card->IntInstalled)
678: return 1;
679: L64021RemoveIntr(card);
680: return 0;
681: }
682:
683: void l64020Reset(struct cvdv_cards *card){
1.11 mocm 684: uint8_t data;
1.1 cvs 685:
686:
687: data = read_indexed_register(card, IIO_LSI_CONTROL);
688: data &= ~(RR | DR);
689: write_indexed_register(card, IIO_LSI_CONTROL, data);
690: mdelay(100);
691: data = read_indexed_register(card, IIO_LSI_CONTROL);
692: data |= DR;
693: write_indexed_register(card, IIO_LSI_CONTROL, data);
694:
695: data = read_indexed_register(card,IIO_GPIO_PINS);
696: data &= ~0x01;
697: write_indexed_register(card,IIO_GPIO_PINS,data);
698: data |= 0x01;
699: write_indexed_register(card,IIO_GPIO_PINS,data);
700:
701: //write_indexed_register(card, IIO_LSI_CONTROL, DR);
1.15 mocm 702:
703: data = read_indexed_register(card, IIO_LSI_CONTROL);
704: data &= ~DSVC;
705: write_indexed_register(card, IIO_LSI_CONTROL, data);
706:
1.1 cvs 707: }
708:
1.7 mocm 709: void ZV_init(struct cvdv_cards *card)
710: {
1.11 mocm 711: uint32_t delay, activel;
712: uint8_t reg;
1.7 mocm 713: delay = 235;
714: activel = delay + 1448;
715:
716: // init delay and active lines
717: write_indexed_register(card, IIO_VIDEO_HOR_DELAY,
1.11 mocm 718: (uint8_t)(delay & 0x00FF));
1.7 mocm 719: write_indexed_register(card, IIO_VIDEO_HOR_ACTIVE,
1.11 mocm 720: (uint8_t)(activel & 0x00FF));
721: reg = ((uint8_t)((activel >> 4) & 0x0070))|((uint8_t)((delay >> 8) & 0x0007));
1.7 mocm 722: write_indexed_register(card, IIO_VIDEO_HOR_HIGH, reg);
723:
724: //init video
725: reg = read_indexed_register(card, IIO_VIDEO_CONTROL0);
726: reg |= (ZVCLK13 | ZV16BIT | ZVCLKINV);
727: write_indexed_register(card, IIO_VIDEO_CONTROL0, reg);
728: reg = read_indexed_register(card, IIO_VIDEO_CONTROL1);
729: reg |= (ZV_OVERRIDE | ZV_ENABLE);
730: write_indexed_register(card, IIO_VIDEO_CONTROL1, reg);
731: }
732:
1.1 cvs 733: int L64014Init(struct cvdv_cards *card)
734: {
1.11 mocm 735: uint16_t testram[16];
1.1 cvs 736: int i, err;
737:
1.13 mocm 738: MDEBUG(1, ": -- L64014Init\n");
1.1 cvs 739: card->videomode = VIDEO_MODE;
740:
741: /* Reset 64020 */
742: write_indexed_register(card, IIO_GPIO_CONTROL, 0x01);
743: l64020Reset(card);
744: /* init GPIO */
745: write_indexed_register(card, IIO_GPIO_CONTROL, 0x01);
746: write_indexed_register(card, IIO_GPIO_PINS, 0xff);
747:
748: /* Set to PAL */
749: write_indexed_register(card, IIO_VIDEO_CONTROL0, 0);
750: write_indexed_register(card, IIO_VIDEO_CONTROL1, VMS_PAL);
751:
752: /* Set Audio freq */
753: write_indexed_register(card, IIO_OSC_AUD, 0x12);
754:
755: write_indexed_register(card, CSS_COMMAND, 0x01);
756:
757:
1.13 mocm 758: MDEBUG(0, "CSID: %02x\n", I2CRead(card, 0, 0x3d));
1.1 cvs 759: card->i2c_addr = I2CRead(card, 0, 0x0f);
1.13 mocm 760: MDEBUG(0, "I2CADDR: %02x\n", card->i2c_addr);
1.1 cvs 761:
762: I2CWrite(card, card->i2c_addr, CS_CONTROL0, 0x4a);
763: I2CWrite(card, card->i2c_addr, CS_CONTROL1, 0x04);
764: I2CWrite(card, card->i2c_addr, CS_SC_AMP, 0x15);
765: I2CWrite(card, card->i2c_addr, CS_SC_SYNTH0, 0x96);
766: I2CWrite(card, card->i2c_addr, CS_SC_SYNTH1, 0x15);
767: I2CWrite(card, card->i2c_addr, CS_SC_SYNTH2, 0x13);
768: I2CWrite(card, card->i2c_addr, CS_SC_SYNTH3, 0x54);
769:
770: I2CWrite(card, card->i2c_addr, CS_DAC, 0x87);
771: I2CWrite(card, card->i2c_addr, CS_BKG_COL, 0x03);
772:
1.13 mocm 773: MDEBUG(0,"Decoder Status: %d\n", read_lsi_status(card));
774: MDEBUG(0,"lsi stat %d\n", DecoderReadByte(card, 0x005));
1.1 cvs 775:
1.7 mocm 776: #ifdef USE_ZV
777: ZV_init(card);
778: #endif
1.1 cvs 779: L64021Init(card);
780:
781: // Find out how much DRAM we have
1.5 mocm 782: card->DRAMSize = 0x00100000; // maximum size
1.1 cvs 783: do {
1.13 mocm 784: MDEBUG(0,
1.1 cvs 785: ": Probing DRAM Size: 0x%08X (%d kByte) ... ",
786: card->DRAMSize, card->DRAMSize / 512);
787: for (i = 0; i < 8; i++)
788: testram[i] = rnd(0x100) | (rnd(0x100) << 8);
789: if (DRAMWriteWord(card, 0, 4, &testram[0], 0))
1.13 mocm 790: MDEBUG(0, ": DRAM Write error.\n");
1.1 cvs 791: if (DRAMWriteWord
792: (card, card->DRAMSize - 4, 4, &testram[4],
1.13 mocm 793: 0)) MDEBUG(0,
1.1 cvs 794: ": DRAM Write error.\n");
795: if (DRAMReadWord(card, 0, 4, &testram[8], 0))
1.13 mocm 796: MDEBUG(0, ": DRAM Read error.\n");
1.1 cvs 797: if (DRAMReadWord
798: (card, card->DRAMSize - 4, 4, &testram[12],
1.13 mocm 799: 0)) MDEBUG(0, ": DRAM Read error.\n");
1.1 cvs 800: err = 0;
801: for (i = 0; (!err) && (i < 8); i++)
802: if (testram[i] != testram[i + 8])
803: err = i + 1;
1.13 mocm 804: if (err) {
805: MDEBUG(0," failed\n");
806: } else {
807: MDEBUG(0," ok\n");
808: }
1.1 cvs 809: if (err)
1.13 mocm 810: MDEBUG(2,": DRAM compare error at cell %d: 0x%04X %04X %04X %04X->0x%04X %04X %04X %04X / 0x%04X %04X %04X %04X->0x%04X %04X %04X %04X\n",
1.1 cvs 811: err, testram[0], testram[1], testram[2],
812: testram[3], testram[8], testram[9],
813: testram[10], testram[11], testram[4],
814: testram[5], testram[6], testram[7],
815: testram[12], testram[13], testram[14],
816: testram[15]);
817: if (err)
818: card->DRAMSize >>= 1;
819: } while (err && (card->DRAMSize >= 0x00100000));
820: printk(KERN_INFO LOGNAME ": DRAM Size: 0x%08X (%d kByte)\n",
821: card->DRAMSize, card->DRAMSize / 512);
822: if (card->DRAMSize < 0x00100000) { // minimum size
823: printk(KERN_INFO LOGNAME
824: ": DRAM ERROR: Not enough memory on card!\n");
825: return 1;
826: }
827: return 0;
828: }
829:
830:
831: void CardDeInit(struct cvdv_cards *card)
832: {
833: CloseCard(card);
834: MargiFlush(card);
1.17 ! mocm 835: MargiFreeBuffers(card);
1.7 mocm 836:
1.1 cvs 837: L64014RemoveIntr(card);
1.4 rjkm 838: card_init(card, 0);
1.1 cvs 839: }
840:
841:
842: static u_char read_lsi_status(struct cvdv_cards *card)
843: {
844: margi_info_t *margi = (margi_info_t *) card->margi;
845: return (inb(margi->link.io.BasePort1 + DIO_LSI_STATUS) & 15);
846:
847: }
848:
849: /*====================================================================*/
850:
851: static void cs_error(client_handle_t handle, int func, int ret)
852: {
853: error_info_t err = { func, ret };
854: CardServices(ReportError, handle, &err);
855: }
856:
857: /*======================================================================
858:
859: margi_attach() creates an "instance" of the driver, allocating
860: local data structures for one device. The device is registered
861: with Card Services.
862:
863: The dev_link structure is initialized, but we don't actually
864: configure the card at this point -- we wait until we receive a
865: card insertion event.
866:
867: ======================================================================*/
868:
869: static dev_link_t *margi_attach(void)
870: {
871: margi_info_t *local;
872: dev_link_t *link;
873: client_reg_t client_reg;
874: int ret, i;
875:
1.13 mocm 876: MDEBUG(0, "margi_attach()\n");
1.1 cvs 877:
878: for (i = 0; i < MAX_DEV; i++)
879: if (dev_table[i] == NULL)
880: break;
881: if (i == MAX_DEV) {
882: printk(KERN_NOTICE "margi_cs: no devices available\n");
883: return NULL;
884: }
885:
886: /* Allocate space for private device-specific data */
887: local = kmalloc(sizeof(margi_info_t), GFP_KERNEL);
888: if (!local)
889: return NULL;
890: memset(local, 0, sizeof(margi_info_t));
891: link = &local->link;
892: link->priv = local;
893: local->card.margi = (void *) local;
894: dev_table[i] = link;
895:
896: /* Initialize the dev_link_t structure */
897: link->release.function = &margi_release;
898: link->release.data = (u_long) link;
899:
900: /* Interrupt setup */
901: link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
902: link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_LEVEL_ID;
903: if (irq_list[0] == -1)
904: link->irq.IRQInfo2 = irq_mask;
905: else
906: for (i = 0; i < 4; i++)
907: link->irq.IRQInfo2 |= 1 << irq_list[i];
908: link->irq.Handler = NULL;
909:
910: /*
911: General socket configuration defaults can go here. In this
912: client, we assume very little, and rely on the CIS for almost
913: everything. In most clients, many details (i.e., number, sizes,
914: and attributes of IO windows) are fixed by the nature of the
915: device, and can be hard-wired here.
916: */
917: link->conf.Attributes = 0;
918: link->conf.Vcc = 50;
1.7 mocm 919:
920: #ifndef USE_ZV
1.1 cvs 921: link->conf.IntType = INT_MEMORY_AND_IO;
1.7 mocm 922: #else
923: link->conf.IntType = INT_ZOOMED_VIDEO;
924: #endif
1.1 cvs 925:
926: /* Register with Card Services */
927: link->next = dev_list;
928: dev_list = link;
929: client_reg.dev_info = &dev_info;
930: client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
931: client_reg.EventMask =
932: CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
933: CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
934: CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
935: client_reg.event_handler = &margi_event;
936: client_reg.Version = 0x0210;
937: client_reg.event_callback_args.client_data = link;
938: ret = CardServices(RegisterClient, &link->handle, &client_reg);
939: if (ret != CS_SUCCESS) {
940: cs_error(link->handle, RegisterClient, ret);
941: margi_detach(link);
942: return NULL;
943: }
944:
945: return link;
946: } /* margi_attach */
947:
948: /*======================================================================
949:
950: This deletes a driver "instance". The device is de-registered
951: with Card Services. If it has been released, all local data
952: structures are freed. Otherwise, the structures will be freed
953: when the device is released.
954:
955: ======================================================================*/
956:
957: static void margi_detach(dev_link_t * link)
958: {
959: dev_link_t **linkp;
960:
961: int nd;
962:
1.13 mocm 963: MDEBUG(0, "margi_detach(0x%p)\n", link);
1.1 cvs 964:
965: for (nd = 0; nd < MAX_DEV; nd++)
966: if (dev_table[nd] == link)
967: break;
968: if (nd == MAX_DEV)
969: return;
970:
971: /* Locate device structure */
972: for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
973: if (*linkp == link)
974: break;
975: if (*linkp == NULL)
976: return;
977:
978: /*
979: If the device is currently configured and active, we won't
980: actually delete it yet. Instead, it is marked so that when
981: the release() function is called, that will trigger a proper
982: detach().
983: */
984: if (link->state & DEV_CONFIG) {
1.13 mocm 985: MDEBUG(2, "margi_cs: detach postponed, '%s' "
1.1 cvs 986: "still locked\n", link->dev->dev_name);
987: link->state |= DEV_STALE_LINK;
988: return;
989: }
990:
991: /* Break the link with Card Services */
992: if (link->handle)
993: CardServices(DeregisterClient, link->handle);
994:
995: /* Unlink device structure, and free it */
996: *linkp = link->next;
997: /* This points to the parent struct cvdv_cards struct */
998: dev_table[nd] = NULL;
999:
1000: kfree(link->priv);
1001:
1002: } /* margi_detach */
1003:
1004: /*======================================================================
1005:
1006: margi_config() is scheduled to run after a CARD_INSERTION event
1007: is received, to configure the PCMCIA socket, and to make the
1008: device available to the system.
1009:
1010: ======================================================================*/
1011:
1012: #define CS_CHECK(fn, args...) \
1013: while ((last_ret=CardServices(last_fn=(fn),args))!=0) goto cs_failed
1014:
1015: #define CFG_CHECK(fn, args...) \
1016: if (CardServices(fn, args) != 0) goto next_entry
1017:
1018: static void margi_config(dev_link_t * link)
1019: {
1020: client_handle_t handle = link->handle;
1021: margi_info_t *dev = link->priv;
1022: struct cvdv_cards *card = &(dev->card);
1023: tuple_t tuple;
1024: cisparse_t parse;
1025: int last_fn, last_ret, i;
1026: u_char buf[64];
1027: config_info_t conf;
1028: win_req_t req;
1029: memreq_t map;
1030: int minor = 0;
1031:
1.13 mocm 1032: MDEBUG(0, "margi_config(0x%p)\n", link);
1.1 cvs 1033:
1034: /*
1035: This reads the card's CONFIG tuple to find its configuration
1036: registers.
1037: */
1038: tuple.DesiredTuple = CISTPL_CONFIG;
1039: tuple.Attributes = 0;
1040: tuple.TupleData = buf;
1041: tuple.TupleDataMax = sizeof(buf);
1042: tuple.TupleOffset = 0;
1043: CS_CHECK(GetFirstTuple, handle, &tuple);
1044: CS_CHECK(GetTupleData, handle, &tuple);
1045: CS_CHECK(ParseTuple, handle, &tuple, &parse);
1046: link->conf.ConfigBase = parse.config.base;
1047: link->conf.Present = parse.config.rmask[0];
1048:
1049: /* Configure card */
1050: link->state |= DEV_CONFIG;
1051:
1052: /* Look up the current Vcc */
1053: CS_CHECK(GetConfigurationInfo, handle, &conf);
1054: link->conf.Vcc = conf.Vcc;
1055:
1056: /*
1057: In this loop, we scan the CIS for configuration table entries,
1058: each of which describes a valid card configuration, including
1059: voltage, IO window, memory window, and interrupt settings.
1060:
1061: We make no assumptions about the card to be configured: we use
1062: just the information available in the CIS. In an ideal world,
1063: this would work for any PCMCIA card, but it requires a complete
1064: and accurate CIS. In practice, a driver usually "knows" most of
1065: these things without consulting the CIS, and most client drivers
1066: will only use the CIS to fill in implementation-defined details.
1067: */
1068: tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
1069: CS_CHECK(GetFirstTuple, handle, &tuple);
1070: while (1) {
1071: cistpl_cftable_entry_t dflt = { 0 };
1072: cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
1073: CFG_CHECK(GetTupleData, handle, &tuple);
1074: CFG_CHECK(ParseTuple, handle, &tuple, &parse);
1075:
1076: if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
1077: dflt = *cfg;
1078: if (cfg->index == 0)
1079: goto next_entry;
1080: link->conf.ConfigIndex = cfg->index;
1081:
1082: /* Does this card need audio output? */
1083: if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
1084: link->conf.Attributes |= CONF_ENABLE_SPKR;
1085: link->conf.Status = CCSR_AUDIO_ENA;
1086: }
1087:
1088: /* Use power settings for Vcc and Vpp if present */
1089: /* Note that the CIS values need to be rescaled */
1090: if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) {
1091: if (conf.Vcc !=
1092: cfg->vcc.param[CISTPL_POWER_VNOM] /
1093: 10000) goto next_entry;
1094: } else if (dflt.vcc.present & (1 << CISTPL_POWER_VNOM)) {
1095: if (conf.Vcc !=
1096: dflt.vcc.param[CISTPL_POWER_VNOM] /
1097: 10000) goto next_entry;
1098: }
1099:
1100: if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM))
1101: link->conf.Vpp1 = link->conf.Vpp2 =
1102: cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000;
1103: else if (dflt.vpp1.present & (1 << CISTPL_POWER_VNOM))
1104: link->conf.Vpp1 = link->conf.Vpp2 =
1105: dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000;
1106:
1107: /*
1108: Allocate an interrupt line. Note that this does not assign a
1109: handler to the interrupt, unless the 'Handler' member of the
1110: irq structure is initialized.
1111: */
1.7 mocm 1112: #ifndef NOINT
1.1 cvs 1113: link->irq.Attributes =
1114: IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
1115: link->irq.Handler = &L64014Intr;
1116: link->irq.Instance = link;
1.7 mocm 1117: link->conf.Attributes |= CONF_ENABLE_IRQ;
1.1 cvs 1118: #ifdef USE_BH
1119: init_bh(MARGI_BH, do_margi_bh);
1120: #endif
1121: if (link->conf.Attributes & CONF_ENABLE_IRQ)
1122: CS_CHECK(RequestIRQ, link->handle, &link->irq);
1.7 mocm 1123: #endif
1.1 cvs 1124:
1125: /* IO window settings */
1126: link->io.NumPorts1 = link->io.NumPorts2 = 0;
1127: if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
1128: cistpl_io_t *io =
1129: (cfg->io.nwin) ? &cfg->io : &dflt.io;
1130: link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
1131: if (!(io->flags & CISTPL_IO_8BIT))
1132: link->io.Attributes1 =
1133: IO_DATA_PATH_WIDTH_16;
1134: if (!(io->flags & CISTPL_IO_16BIT))
1135: link->io.Attributes1 =
1136: IO_DATA_PATH_WIDTH_8;
1137: link->io.IOAddrLines =
1138: io->flags & CISTPL_IO_LINES_MASK;
1139: link->io.BasePort1 = io->win[0].base;
1140: link->io.NumPorts1 = io->win[0].len;
1141: if (io->nwin > 1) {
1142: link->io.Attributes2 =
1143: link->io.Attributes1;
1144: link->io.BasePort2 = io->win[1].base;
1145: link->io.NumPorts2 = io->win[1].len;
1146: }
1147: }
1148:
1149: /* This reserves IO space but doesn't actually enable it */
1150: CFG_CHECK(RequestIO, link->handle, &link->io);
1151:
1152: /*
1153: Now set up a common memory window, if needed. There is room
1154: in the dev_link_t structure for one memory window handle,
1155: but if the base addresses need to be saved, or if multiple
1156: windows are needed, the info should go in the private data
1157: structure for this device.
1158:
1159: Note that the memory window base is a physical address, and
1160: needs to be mapped to virtual space with ioremap() before it
1161: is used.
1162: */
1163: if ((cfg->mem.nwin > 0) || (dflt.mem.nwin > 0)) {
1164: cistpl_mem_t *mem =
1165: (cfg->mem.nwin) ? &cfg->mem : &dflt.mem;
1166: req.Attributes =
1167: WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_CM;
1168: req.Attributes |= WIN_ENABLE;
1169: req.Base = mem->win[0].host_addr;
1170: req.Size = mem->win[0].len;
1171: req.AccessSpeed = 0;
1172: link->win = (window_handle_t) link->handle;
1173: CFG_CHECK(RequestWindow, &link->win, &req);
1174: map.Page = 0;
1175: map.CardOffset = mem->win[0].card_addr;
1176: CFG_CHECK(MapMemPage, link->win, &map);
1177: }
1178: /* If we got this far, we're cool! */
1179: break;
1180:
1181: next_entry:
1182: CS_CHECK(GetNextTuple, handle, &tuple);
1183: }
1184:
1185: /*
1186: This actually configures the PCMCIA socket -- setting up
1187: the I/O windows and the interrupt mapping, and putting the
1188: card and host interface into "Memory and IO" mode.
1189: */
1190: CS_CHECK(RequestConfiguration, link->handle, &link->conf);
1191:
1192: /*
1193: We can release the IO port allocations here, if some other
1194: driver for the card is going to loaded, and will expect the
1195: ports to be available.
1196: */
1197: if (free_ports) {
1198: if (link->io.BasePort1)
1199: release_region(link->io.BasePort1,
1200: link->io.NumPorts1);
1201: if (link->io.BasePort2)
1202: release_region(link->io.BasePort2,
1203: link->io.NumPorts2);
1204: }
1205:
1206: /*
1207: At this point, the dev_node_t structure(s) need to be
1208: initialized and arranged in a linked list at link->dev.
1209: */
1210:
1211: first_card = card;
1212: minor=0;
1213: card->next = NULL;
1214: card_init(card, minor);
1215: if ((i = register_chrdev(CVDV_MAJOR, CVDV_PROCNAME, &cvdv_fileops))
1216: >= 0) {
1217: major_device_number = ((i) ? i : CVDV_MAJOR);
1218: printk(KERN_INFO LOGNAME
1219: ": Char-device with major number %d installed\n",
1220: major_device_number);
1221: } else {
1222: printk(KERN_ERR LOGNAME
1223: ": ERROR: Failed to install Char-device %d, error %d\n",
1224: CVDV_MAJOR, i);
1225: }
1.7 mocm 1226:
1227:
1.1 cvs 1228: sprintf(dev->node.dev_name, "margi");
1229: dev->node.major = major_device_number;
1230: dev->node.minor = minor;
1231: link->dev = &dev->node;
1.7 mocm 1232: #ifdef DVB
1233: dvb_register(card);
1234: #endif
1.1 cvs 1235: /* Finally, report what we've done */
1236: printk(KERN_INFO "%s: index 0x%02x: Vcc %d.%d",
1237: dev->node.dev_name, link->conf.ConfigIndex,
1238: link->conf.Vcc / 10, link->conf.Vcc % 10);
1239: if (link->conf.Vpp1)
1240: printk(", Vpp %d.%d", link->conf.Vpp1 / 10,
1241: link->conf.Vpp1 % 10);
1242: if (link->conf.Attributes & CONF_ENABLE_IRQ)
1243: printk(", irq %d", link->irq.AssignedIRQ);
1244: if (link->io.NumPorts1)
1245: printk(", io 0x%04x-0x%04x", link->io.BasePort1,
1246: link->io.BasePort1 + link->io.NumPorts1 - 1);
1247: if (link->io.NumPorts2)
1248: printk(" & 0x%04x-0x%04x", link->io.BasePort2,
1249: link->io.BasePort2 + link->io.NumPorts2 - 1);
1250: if (link->win)
1251: printk(", mem 0x%06lx-0x%06lx", req.Base,
1252: req.Base + req.Size - 1);
1253: printk("\n");
1254:
1255: link->state &= ~DEV_CONFIG_PENDING;
1256: if (0xdd == read_indexed_register(card, IIO_ID)) {
1257: printk("L64014 Version %d in mode %d detected\n",
1258: (read_indexed_register(card, IIO_MODE) & 248) >> 3,
1259: read_indexed_register(card, IIO_MODE) & 7);
1260: write_indexed_register(card, IIO_GPIO_CONTROL, 0x07);
1261:
1262: L64014Init(card);
1.7 mocm 1263:
1.1 cvs 1264: // default: color bars
1265: VideoSetBackground(card, 1, 0, 0, 0); // black
1266: SetVideoSystem(card);
1267: minorlist[minor] = card; // fast access for the char driver
1268:
1269:
1270: /*enable L64014 IRQ */
1271: write_indexed_register(card, IIO_IRQ_CONTROL,
1272: IRQ_POL | IRQ_EN | VSYNC_EN);
1273: // write_indexed_register(card, IIO_IRQ_CONTROL, 0x24);
1.7 mocm 1274:
1.6 mocm 1275: OSDOpen(card, 50, 50, 150, 150, 2, 1);
1276: OSDTest(card);
1.1 cvs 1277: }
1278: return;
1279:
1280: cs_failed:
1281: cs_error(link->handle, last_fn, last_ret);
1282: margi_release((u_long) link);
1283:
1284: } /* margi_config */
1285:
1286: /*======================================================================
1287:
1288: After a card is removed, margi_release() will unregister the
1289: device, and release the PCMCIA configuration. If the device is
1290: still open, this will be postponed until it is closed.
1291:
1292: ======================================================================*/
1293:
1294: static void margi_release(u_long arg)
1295: {
1296: dev_link_t *link = (dev_link_t *) arg;
1297: margi_info_t *dev = link->priv;
1298: struct cvdv_cards *card = &(dev->card);
1299:
1.13 mocm 1300: MDEBUG(0, "margi_release(0x%p)\n", link);
1.1 cvs 1301: /*
1302: If the device is currently in use, we won't release until it
1303: is actually closed, because until then, we can't be sure that
1304: no one will try to access the device or its data structures.
1305: */
1306: if (link->open) {
1.13 mocm 1307: MDEBUG(1, "margi_cs: release postponed, '%s' still open\n",
1.1 cvs 1308: link->dev->dev_name);
1309: link->state |= DEV_STALE_CONFIG;
1310: return;
1311: }
1312:
1313: /* Unlink the device chain */
1314: link->dev = NULL;
1315:
1316: /*
1317: In a normal driver, additional code may be needed to release
1318: other kernel data structures associated with this device.
1319: */
1320:
1.13 mocm 1321: MDEBUG(1,": Unloading device driver\n");
1.1 cvs 1322: if (major_device_number)
1323: unregister_chrdev(major_device_number, CVDV_PROCNAME);
1324: CardDeInit(card);
1325:
1.7 mocm 1326: #ifndef NOINT
1.1 cvs 1327: #ifdef USE_BH
1328: remove_bh(MARGI_BH);
1329: #endif
1330: mdelay(100);
1.7 mocm 1331: #endif
1332: CloseCard(card);
1333: #ifdef DVB
1334: dvb_unregister(card);
1335: #endif
1.1 cvs 1336: /* Don't bother checking to see if these succeed or not */
1337: if (link->win)
1338: CardServices(ReleaseWindow, link->win);
1339: CardServices(ReleaseConfiguration, link->handle);
1340: if (link->io.NumPorts1)
1341: CardServices(ReleaseIO, link->handle, &link->io);
1.7 mocm 1342: #ifndef NOINT
1.1 cvs 1343: if (link->irq.AssignedIRQ)
1344: CardServices(ReleaseIRQ, link->handle, &link->irq);
1.7 mocm 1345: #endif
1.1 cvs 1346: link->state &= ~DEV_CONFIG;
1347:
1348: if (link->state & DEV_STALE_LINK)
1349: margi_detach(link);
1350:
1351: } /* margi_release */
1352:
1353: /*======================================================================
1354:
1355: The card status event handler. Mostly, this schedules other
1356: stuff to run after an event is received.
1357:
1358: When a CARD_REMOVAL event is received, we immediately set a
1359: private flag to block future accesses to this device. All the
1360: functions that actually access the device should check this flag
1361: to make sure the card is still present.
1362:
1363: ======================================================================*/
1364:
1365: static int margi_event(event_t event, int priority,
1366: event_callback_args_t * args)
1367: {
1368: dev_link_t *link = args->client_data;
1369: margi_info_t *dev = link->priv;
1370:
1.13 mocm 1371: MDEBUG(1, "margi_event(0x%06x)\n", event);
1.1 cvs 1372:
1373: switch (event) {
1374: case CS_EVENT_CARD_REMOVAL:
1375: link->state &= ~DEV_PRESENT;
1376: if (link->state & DEV_CONFIG) {
1377: ((margi_info_t *) link->priv)->stop = 1;
1378: link->release.expires = jiffies + HZ / 20;
1379: add_timer(&link->release);
1380: }
1381: break;
1382: case CS_EVENT_CARD_INSERTION:
1383: link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
1384: dev->card.bus = args->bus;
1385: margi_config(link);
1386: break;
1387: case CS_EVENT_PM_SUSPEND:
1388: link->state |= DEV_SUSPEND;
1389: /* Fall through... */
1390: case CS_EVENT_RESET_PHYSICAL:
1391: /* Mark the device as stopped, to block IO until later */
1392: dev->stop = 1;
1393: if (link->state & DEV_CONFIG)
1394: CardServices(ReleaseConfiguration, link->handle);
1395: break;
1396: case CS_EVENT_PM_RESUME:
1397: link->state &= ~DEV_SUSPEND;
1398: /* Fall through... */
1399: case CS_EVENT_CARD_RESET:
1400: if (link->state & DEV_CONFIG)
1401: CardServices(RequestConfiguration, link->handle,
1402: &link->conf);
1403: dev->stop = 0;
1404: /*
1405: In a normal driver, additional code may go here to restore
1406: the device state and restart IO.
1407: */
1408: break;
1409: }
1410: return 0;
1411: } /* margi_event */
1412:
1413: /*====================================================================*/
1414:
1415: static int __init init_margi_cs(void)
1416: {
1417: servinfo_t serv;
1.13 mocm 1418: MDEBUG(0, "%s\n", version);
1.1 cvs 1419: CardServices(GetCardServicesInfo, &serv);
1420: if (serv.Revision != CS_RELEASE_CODE) {
1421: printk(KERN_NOTICE "margi_cs: Card Services release "
1422: "does not match!\n");
1423: return -1;
1424: }
1425: register_pccard_driver(&dev_info, &margi_attach, &margi_detach);
1426: return 0;
1427: }
1428:
1429: static void __exit exit_margi_cs(void)
1430: {
1.13 mocm 1431: MDEBUG(0, "margi_cs: unloading\n");
1.1 cvs 1432: unregister_pccard_driver(&dev_info);
1433: while (dev_list != NULL) {
1434: if (dev_list->state & DEV_CONFIG)
1435: margi_release((u_long) dev_list);
1436: margi_detach(dev_list);
1437: }
1438: }
1439:
1440: module_init(init_margi_cs);
1441: module_exit(exit_margi_cs);
LinuxTV legacy CVS <linuxtv.org/cvs>