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