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