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