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