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