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