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