OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [pcmcia/] [au1000_generic.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
2
 *
3
 * Alchemy Semi Au1000 pcmcia driver
4
 *
5
 * Copyright 2001-2003 MontaVista Software Inc.
6
 * Author: MontaVista Software, Inc.
7
 *              ppopov@mvista.com or source@mvista.com
8
 *
9
 * ########################################################################
10
 *
11
 *  This program is free software; you can distribute it and/or modify it
12
 *  under the terms of the GNU General Public License (Version 2) as
13
 *  published by the Free Software Foundation.
14
 *
15
 *  This program is distributed in the hope it will be useful, but WITHOUT
16
 *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17
 *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
18
 *  for more details.
19
 *
20
 *  You should have received a copy of the GNU General Public License along
21
 *  with this program; if not, write to the Free Software Foundation, Inc.,
22
 *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
23
 *
24
 * ########################################################################
25
 *
26
 *
27
 */
28
#include <linux/module.h>
29
#include <linux/init.h>
30
#include <linux/config.h>
31
#include <linux/delay.h>
32
#include <linux/ioport.h>
33
#include <linux/kernel.h>
34
#include <linux/tqueue.h>
35
#include <linux/timer.h>
36
#include <linux/mm.h>
37
#include <linux/proc_fs.h>
38
#include <linux/version.h>
39
#include <linux/types.h>
40
#include <linux/vmalloc.h>
41
 
42
#include <pcmcia/version.h>
43
#include <pcmcia/cs_types.h>
44
#include <pcmcia/cs.h>
45
#include <pcmcia/ss.h>
46
#include <pcmcia/bulkmem.h>
47
#include <pcmcia/cistpl.h>
48
#include <pcmcia/bus_ops.h>
49
#include "cs_internal.h"
50
 
51
#include <asm/io.h>
52
#include <asm/irq.h>
53
#include <asm/system.h>
54
 
55
#include <asm/au1000.h>
56
#include <asm/au1000_pcmcia.h>
57
 
58
#ifdef PCMCIA_DEBUG
59
static int pc_debug;
60
#endif
61
 
62
MODULE_LICENSE("GPL");
63
MODULE_AUTHOR("Pete Popov, MontaVista Software <ppopov@mvista.com>");
64
MODULE_DESCRIPTION("Linux PCMCIA Card Services: Au1x00 Socket Controller");
65
 
66
#define MAP_SIZE 0x1000000
67
 
68
/* This structure maintains housekeeping state for each socket, such
69
 * as the last known values of the card detect pins, or the Card Services
70
 * callback value associated with the socket:
71
 */
72
static struct au1000_pcmcia_socket *pcmcia_socket;
73
static int socket_count;
74
 
75
 
76
/* Returned by the low-level PCMCIA interface: */
77
static struct pcmcia_low_level *pcmcia_low_level;
78
 
79
/* Event poll timer structure */
80
static struct timer_list poll_timer;
81
 
82
 
83
/* Prototypes for routines which are used internally: */
84
 
85
static int  au1000_pcmcia_driver_init(void);
86
static void au1000_pcmcia_driver_shutdown(void);
87
static void au1000_pcmcia_task_handler(void *data);
88
static void au1000_pcmcia_poll_event(unsigned long data);
89
static void au1000_pcmcia_interrupt(int irq, void *dev, struct pt_regs *regs);
90
static struct tq_struct au1000_pcmcia_task;
91
 
92
#ifdef CONFIG_PROC_FS
93
static int au1000_pcmcia_proc_status(char *buf, char **start,
94
                off_t pos, int count, int *eof, void *data);
95
#endif
96
 
97
 
98
/* Prototypes for operations which are exported to the
99
 * new-and-impr^H^H^H^H^H^H^H^H^H^H in-kernel PCMCIA core:
100
 */
101
 
102
static int au1000_pcmcia_init(u32 sock);
103
static int au1000_pcmcia_suspend(u32 sock);
104
static int au1000_pcmcia_register_callback(u32 sock,
105
                void (*handler)(void *, u32), void *info);
106
static int au1000_pcmcia_inquire_socket(u32 sock, socket_cap_t *cap);
107
static int au1000_pcmcia_get_status(u32 sock, u_int *value);
108
static int au1000_pcmcia_get_socket(u32 sock, socket_state_t *state);
109
static int au1000_pcmcia_set_socket(u32 sock, socket_state_t *state);
110
static int au1000_pcmcia_get_io_map(u32 sock, struct pccard_io_map *io);
111
static int au1000_pcmcia_set_io_map(u32 sock, struct pccard_io_map *io);
112
static int au1000_pcmcia_get_mem_map(u32 sock, struct pccard_mem_map *mem);
113
static int au1000_pcmcia_set_mem_map(u32 sock, struct pccard_mem_map *mem);
114
#ifdef CONFIG_PROC_FS
115
static void au1000_pcmcia_proc_setup(u32 sock, struct proc_dir_entry *base);
116
#endif
117
 
118
static struct pccard_operations au1000_pcmcia_operations = {
119
        au1000_pcmcia_init,
120
        au1000_pcmcia_suspend,
121
        au1000_pcmcia_register_callback,
122
        au1000_pcmcia_inquire_socket,
123
        au1000_pcmcia_get_status,
124
        au1000_pcmcia_get_socket,
125
        au1000_pcmcia_set_socket,
126
        au1000_pcmcia_get_io_map,
127
        au1000_pcmcia_set_io_map,
128
        au1000_pcmcia_get_mem_map,
129
        au1000_pcmcia_set_mem_map,
130
#ifdef CONFIG_PROC_FS
131
        au1000_pcmcia_proc_setup
132
#endif
133
};
134
 
135
static spinlock_t pcmcia_lock = SPIN_LOCK_UNLOCKED;
136
 
137
extern const unsigned long mips_io_port_base;
138
 
139
static int __init au1000_pcmcia_driver_init(void)
140
{
141
        servinfo_t info;
142
        struct pcmcia_init pcmcia_init;
143
        struct pcmcia_state state;
144
        unsigned int i;
145
 
146
        printk("\nAu1x00 PCMCIA (CS release %s)\n", CS_RELEASE);
147
 
148
#ifndef CONFIG_64BIT_PHYS_ADDR
149
        printk(KERN_ERR "Au1x00 PCMCIA 36 bit IO support not enabled\n");
150
        return -1;
151
#endif
152
 
153
        CardServices(GetCardServicesInfo, &info);
154
 
155
        if(info.Revision!=CS_RELEASE_CODE){
156
                printk(KERN_ERR "Card Services release codes do not match\n");
157
                return -1;
158
        }
159
 
160
#if defined(CONFIG_MIPS_PB1000) || defined(CONFIG_MIPS_PB1100) || defined(CONFIG_MIPS_PB1500)
161
        pcmcia_low_level=&pb1x00_pcmcia_ops;
162
#elif defined(CONFIG_MIPS_DB1000) || defined(CONFIG_MIPS_DB1100) || defined(CONFIG_MIPS_DB1500)
163
        pcmcia_low_level=&db1x00_pcmcia_ops;
164
#elif defined(CONFIG_MIPS_XXS1500)
165
        pcmcia_low_level=&xxs1500_pcmcia_ops;
166
#else
167
#error Unsupported AU1000 board.
168
#endif
169
 
170
        pcmcia_init.handler=au1000_pcmcia_interrupt;
171
        if((socket_count=pcmcia_low_level->init(&pcmcia_init))<0) {
172
                printk(KERN_ERR "Unable to initialize PCMCIA service.\n");
173
                return -EIO;
174
        }
175
 
176
        /* NOTE: the chip select must already be setup */
177
 
178
        pcmcia_socket =
179
                kmalloc(sizeof(struct au1000_pcmcia_socket) * socket_count,
180
                                GFP_KERNEL);
181
        if (!pcmcia_socket) {
182
                printk(KERN_ERR "Card Services can't get memory \n");
183
                return -1;
184
        }
185
        memset(pcmcia_socket, 0,
186
                        sizeof(struct au1000_pcmcia_socket) * socket_count);
187
 
188
        /*
189
         * Assuming max of 2 sockets, which the Au1000 supports.
190
         * WARNING: the Pb1000 has two sockets, and both work, but you
191
         * can't use them both at the same time due to glue logic conflicts.
192
         */
193
        for(i=0; i < socket_count; i++) {
194
 
195
                if(pcmcia_low_level->socket_state(i, &state)<0){
196
                        printk(KERN_ERR "Unable to get PCMCIA status\n");
197
                        return -EIO;
198
                }
199
                pcmcia_socket[i].k_state=state;
200
                pcmcia_socket[i].cs_state.csc_mask=SS_DETECT;
201
 
202
                /*
203
                 * PCMCIA drivers use the inb/outb macros to access the
204
                 * IO registers. Since mips_io_port_base is added to the
205
                 * access address, we need to subtract it here.
206
                 */
207
                if (i == 0) {
208
                        pcmcia_socket[i].virt_io =
209
                                (u32)ioremap((ioaddr_t)AU1X_SOCK0_IO, 0x1000) -
210
                                mips_io_port_base;
211
                        pcmcia_socket[i].phys_attr =
212
                                (ioaddr_t)AU1X_SOCK0_PHYS_ATTR;
213
                        pcmcia_socket[i].phys_mem =
214
                                (ioaddr_t)AU1X_SOCK0_PHYS_MEM;
215
                }
216
#ifndef CONFIG_MIPS_XXS1500
217
                else  {
218
                        pcmcia_socket[i].virt_io =
219
                                (u32)ioremap((ioaddr_t)AU1X_SOCK1_IO, 0x1000) -
220
                                mips_io_port_base;
221
                        pcmcia_socket[i].phys_attr =
222
                                (ioaddr_t)AU1X_SOCK1_PHYS_ATTR;
223
                        pcmcia_socket[i].phys_mem =
224
                                (ioaddr_t)AU1X_SOCK1_PHYS_MEM;
225
                }
226
#endif
227
        }
228
 
229
        /* Only advertise as many sockets as we can detect: */
230
        if(register_ss_entry(socket_count, &au1000_pcmcia_operations)<0){
231
                printk(KERN_ERR "Unable to register socket service routine\n");
232
                return -ENXIO;
233
        }
234
 
235
        /* Start the event poll timer.
236
         * It will reschedule by itself afterwards.
237
         */
238
        au1000_pcmcia_poll_event(0);
239
 
240
        DEBUG(1, "au1000: initialization complete\n");
241
        return 0;
242
 
243
}  /* au1000_pcmcia_driver_init() */
244
 
245
module_init(au1000_pcmcia_driver_init);
246
 
247
static void __exit au1000_pcmcia_driver_shutdown(void)
248
{
249
        int i;
250
 
251
        del_timer_sync(&poll_timer);
252
        unregister_ss_entry(&au1000_pcmcia_operations);
253
        pcmcia_low_level->shutdown();
254
        flush_scheduled_tasks();
255
        for(i=0; i < socket_count; i++) {
256
                if (pcmcia_socket[i].virt_io)
257
                        iounmap((void *)pcmcia_socket[i].virt_io +
258
                                        mips_io_port_base);
259
        }
260
        DEBUG(1, "au1000: shutdown complete\n");
261
}
262
 
263
module_exit(au1000_pcmcia_driver_shutdown);
264
 
265
static int au1000_pcmcia_init(unsigned int sock) { return 0; }
266
 
267
static int au1000_pcmcia_suspend(unsigned int sock)
268
{
269
        return 0;
270
}
271
 
272
 
273
static inline unsigned
274
au1000_pcmcia_events(struct pcmcia_state *state,
275
                struct pcmcia_state *prev_state,
276
                unsigned int mask, unsigned int flags)
277
{
278
        unsigned int events=0;
279
 
280
        if(state->detect!=prev_state->detect){
281
                DEBUG(2, "%s(): card detect value %u\n",
282
                                __FUNCTION__, state->detect);
283
                events |= mask&SS_DETECT;
284
        }
285
 
286
 
287
        if(state->ready!=prev_state->ready){
288
                DEBUG(2, "%s(): card ready value %u\n",
289
                                __FUNCTION__, state->ready);
290
                events |= mask&((flags&SS_IOCARD)?0:SS_READY);
291
        }
292
 
293
        *prev_state=*state;
294
        return events;
295
 
296
}  /* au1000_pcmcia_events() */
297
 
298
 
299
/*
300
 * Au1000_pcmcia_task_handler()
301
 * Processes socket events.
302
 */
303
static void au1000_pcmcia_task_handler(void *data)
304
{
305
        struct pcmcia_state state;
306
        int i, events, irq_status;
307
 
308
        for(i=0; i<socket_count; i++)  {
309
                if((irq_status = pcmcia_low_level->socket_state(i, &state))<0)
310
                        printk(KERN_ERR "low-level PCMCIA error\n");
311
 
312
                events = au1000_pcmcia_events(&state,
313
                                &pcmcia_socket[i].k_state,
314
                                pcmcia_socket[i].cs_state.csc_mask,
315
                                pcmcia_socket[i].cs_state.flags);
316
                if(pcmcia_socket[i].handler!=NULL) {
317
                        pcmcia_socket[i].handler(pcmcia_socket[i].handler_info,
318
                                        events);
319
                }
320
        }
321
 
322
}  /* au1000_pcmcia_task_handler() */
323
 
324
static struct tq_struct au1000_pcmcia_task = {
325
        routine: au1000_pcmcia_task_handler
326
};
327
 
328
 
329
static void au1000_pcmcia_poll_event(unsigned long dummy)
330
{
331
        poll_timer.function = au1000_pcmcia_poll_event;
332
        poll_timer.expires = jiffies + AU1000_PCMCIA_POLL_PERIOD;
333
        add_timer(&poll_timer);
334
        schedule_task(&au1000_pcmcia_task);
335
}
336
 
337
 
338
/*
339
 * au1000_pcmcia_interrupt()
340
 * The actual interrupt work is performed by au1000_pcmcia_task(),
341
 * because the Card Services event handling code performs scheduling
342
 * operations which cannot be executed from within an interrupt context.
343
 */
344
static void
345
au1000_pcmcia_interrupt(int irq, void *dev, struct pt_regs *regs)
346
{
347
        schedule_task(&au1000_pcmcia_task);
348
}
349
 
350
 
351
static int
352
au1000_pcmcia_register_callback(unsigned int sock,
353
                void (*handler)(void *, unsigned int), void *info)
354
{
355
        if(handler==NULL){
356
                pcmcia_socket[sock].handler=NULL;
357
                MOD_DEC_USE_COUNT;
358
        } else {
359
                MOD_INC_USE_COUNT;
360
                pcmcia_socket[sock].handler=handler;
361
                pcmcia_socket[sock].handler_info=info;
362
        }
363
        return 0;
364
}
365
 
366
 
367
/* au1000_pcmcia_inquire_socket()
368
 *
369
 * From the sa1100 socket driver :
370
 *
371
 * Implements the inquire_socket() operation for the in-kernel PCMCIA
372
 * service (formerly SS_InquireSocket in Card Services).  We set
373
 * SS_CAP_STATIC_MAP, which disables the memory resource database check.
374
 * (Mapped memory is set up within the socket driver itself.)
375
 *
376
 * In conjunction with the STATIC_MAP capability is a new field,
377
 * `io_offset', recommended by David Hinds. Rather than go through
378
 * the SetIOMap interface (which is not quite suited for communicating
379
 * window locations up from the socket driver), we just pass up
380
 * an offset which is applied to client-requested base I/O addresses
381
 * in alloc_io_space().
382
 *
383
 * Returns: 0 on success, -1 if no pin has been configured for `sock'
384
 */
385
static int au1000_pcmcia_inquire_socket(unsigned int sock, socket_cap_t *cap)
386
{
387
        struct pcmcia_irq_info irq_info;
388
 
389
        if(sock > socket_count){
390
                printk(KERN_ERR "au1000: socket %u not configured\n", sock);
391
                return -1;
392
        }
393
 
394
        /* from the sa1100_generic driver: */
395
 
396
        /* SS_CAP_PAGE_REGS: used by setup_cis_mem() in cistpl.c to set the
397
        *   force_low argument to validate_mem() in rsrc_mgr.c -- since in
398
        *   general, the mapped * addresses of the PCMCIA memory regions
399
        *   will not be within 0xffff, setting force_low would be
400
        *   undesirable.
401
        *
402
        * SS_CAP_STATIC_MAP: don't bother with the (user-configured) memory
403
        *   resource database; we instead pass up physical address ranges
404
        *   and allow other parts of Card Services to deal with remapping.
405
        *
406
        * SS_CAP_PCCARD: we can deal with 16-bit PCMCIA & CF cards, but
407
        *   not 32-bit CardBus devices.
408
        */
409
        cap->features=(SS_CAP_PAGE_REGS  | SS_CAP_STATIC_MAP | SS_CAP_PCCARD);
410
 
411
        irq_info.sock=sock;
412
        irq_info.irq=-1;
413
 
414
        if(pcmcia_low_level->get_irq_info(&irq_info)<0){
415
                printk(KERN_ERR "Error obtaining IRQ info socket %u\n", sock);
416
                return -1;
417
        }
418
 
419
        cap->irq_mask=0;
420
        cap->map_size=MAP_SIZE;
421
        cap->pci_irq=irq_info.irq;
422
        cap->io_offset=pcmcia_socket[sock].virt_io;
423
 
424
        return 0;
425
 
426
}  /* au1000_pcmcia_inquire_socket() */
427
 
428
 
429
static int
430
au1000_pcmcia_get_status(unsigned int sock, unsigned int *status)
431
{
432
        struct pcmcia_state state;
433
 
434
 
435
        if((pcmcia_low_level->socket_state(sock, &state))<0){
436
                printk(KERN_ERR "Unable to get PCMCIA status from kernel.\n");
437
                return -1;
438
        }
439
 
440
        pcmcia_socket[sock].k_state = state;
441
 
442
        *status = state.detect?SS_DETECT:0;
443
 
444
        *status |= state.ready?SS_READY:0;
445
 
446
        *status |= pcmcia_socket[sock].cs_state.Vcc?SS_POWERON:0;
447
 
448
        if(pcmcia_socket[sock].cs_state.flags&SS_IOCARD)
449
                *status |= state.bvd1?SS_STSCHG:0;
450
        else {
451
                if(state.bvd1==0)
452
                        *status |= SS_BATDEAD;
453
                else if(state.bvd2 == 0)
454
                        *status |= SS_BATWARN;
455
        }
456
 
457
        *status|=state.vs_3v?SS_3VCARD:0;
458
 
459
        *status|=state.vs_Xv?SS_XVCARD:0;
460
 
461
        DEBUG(2, "\tstatus: %s%s%s%s%s%s%s%s\n",
462
        (*status&SS_DETECT)?"DETECT ":"",
463
        (*status&SS_READY)?"READY ":"",
464
        (*status&SS_BATDEAD)?"BATDEAD ":"",
465
        (*status&SS_BATWARN)?"BATWARN ":"",
466
        (*status&SS_POWERON)?"POWERON ":"",
467
        (*status&SS_STSCHG)?"STSCHG ":"",
468
        (*status&SS_3VCARD)?"3VCARD ":"",
469
        (*status&SS_XVCARD)?"XVCARD ":"");
470
 
471
        return 0;
472
 
473
}  /* au1000_pcmcia_get_status() */
474
 
475
 
476
static int
477
au1000_pcmcia_get_socket(unsigned int sock, socket_state_t *state)
478
{
479
        *state = pcmcia_socket[sock].cs_state;
480
        return 0;
481
}
482
 
483
 
484
static int
485
au1000_pcmcia_set_socket(unsigned int sock, socket_state_t *state)
486
{
487
        struct pcmcia_configure configure;
488
 
489
        DEBUG(2, "\tmask:  %s%s%s%s%s%s\n\tflags: %s%s%s%s%s%s\n"
490
        "\tVcc %d  Vpp %d  irq %d\n",
491
        (state->csc_mask==0)?"<NONE>":"",
492
        (state->csc_mask&SS_DETECT)?"DETECT ":"",
493
        (state->csc_mask&SS_READY)?"READY ":"",
494
        (state->csc_mask&SS_BATDEAD)?"BATDEAD ":"",
495
        (state->csc_mask&SS_BATWARN)?"BATWARN ":"",
496
        (state->csc_mask&SS_STSCHG)?"STSCHG ":"",
497
        (state->flags==0)?"<NONE>":"",
498
        (state->flags&SS_PWR_AUTO)?"PWR_AUTO ":"",
499
        (state->flags&SS_IOCARD)?"IOCARD ":"",
500
        (state->flags&SS_RESET)?"RESET ":"",
501
        (state->flags&SS_SPKR_ENA)?"SPKR_ENA ":"",
502
        (state->flags&SS_OUTPUT_ENA)?"OUTPUT_ENA ":"",
503
        state->Vcc, state->Vpp, state->io_irq);
504
 
505
        configure.sock=sock;
506
        configure.vcc=state->Vcc;
507
        configure.vpp=state->Vpp;
508
        configure.output=(state->flags&SS_OUTPUT_ENA)?1:0;
509
        configure.speaker=(state->flags&SS_SPKR_ENA)?1:0;
510
        configure.reset=(state->flags&SS_RESET)?1:0;
511
 
512
        if(pcmcia_low_level->configure_socket(&configure)<0){
513
                printk(KERN_ERR "Unable to configure socket %u\n", sock);
514
                return -1;
515
        }
516
 
517
        pcmcia_socket[sock].cs_state = *state;
518
        return 0;
519
 
520
}  /* au1000_pcmcia_set_socket() */
521
 
522
 
523
static int
524
au1000_pcmcia_get_io_map(unsigned int sock, struct pccard_io_map *map)
525
{
526
        DEBUG(1, "au1000_pcmcia_get_io_map: sock %d\n", sock);
527
        if(map->map>=MAX_IO_WIN){
528
                printk(KERN_ERR "%s(): map (%d) out of range\n",
529
                                __FUNCTION__, map->map);
530
                return -1;
531
        }
532
        *map=pcmcia_socket[sock].io_map[map->map];
533
        return 0;
534
}
535
 
536
 
537
int
538
au1000_pcmcia_set_io_map(unsigned int sock, struct pccard_io_map *map)
539
{
540
        unsigned int speed;
541
        unsigned long start;
542
 
543
        if(map->map>=MAX_IO_WIN){
544
                printk(KERN_ERR "%s(): map (%d) out of range\n",
545
                                __FUNCTION__, map->map);
546
                return -1;
547
        }
548
 
549
        if(map->flags&MAP_ACTIVE){
550
                speed=(map->speed>0)?map->speed:AU1000_PCMCIA_IO_SPEED;
551
                pcmcia_socket[sock].speed_io=speed;
552
        }
553
 
554
        start=map->start;
555
 
556
        if(map->stop==1) {
557
                map->stop=PAGE_SIZE-1;
558
        }
559
 
560
        map->start=pcmcia_socket[sock].virt_io;
561
        map->stop=map->start+(map->stop-start);
562
        pcmcia_socket[sock].io_map[map->map]=*map;
563
        DEBUG(3, "set_io_map %d start %x stop %x\n",
564
                        map->map, map->start, map->stop);
565
        return 0;
566
 
567
}  /* au1000_pcmcia_set_io_map() */
568
 
569
 
570
static int
571
au1000_pcmcia_get_mem_map(unsigned int sock, struct pccard_mem_map *map)
572
{
573
 
574
        if(map->map>=MAX_WIN) {
575
                printk(KERN_ERR "%s(): map (%d) out of range\n",
576
                                __FUNCTION__, map->map);
577
                return -1;
578
        }
579
        *map=pcmcia_socket[sock].mem_map[map->map];
580
        return 0;
581
}
582
 
583
 
584
static int
585
au1000_pcmcia_set_mem_map(unsigned int sock, struct pccard_mem_map *map)
586
{
587
        unsigned int speed;
588
        unsigned long start;
589
        u_long flags;
590
 
591
        if(map->map>=MAX_WIN){
592
                printk(KERN_ERR "%s(): map (%d) out of range\n",
593
                                __FUNCTION__, map->map);
594
                return -1;
595
        }
596
 
597
        if(map->flags&MAP_ACTIVE){
598
                speed=(map->speed>0)?map->speed:AU1000_PCMCIA_MEM_SPEED;
599
 
600
                /* TBD */
601
                if(map->flags&MAP_ATTRIB){
602
                        pcmcia_socket[sock].speed_attr=speed;
603
                }
604
                else {
605
                        pcmcia_socket[sock].speed_mem=speed;
606
                }
607
        }
608
 
609
        spin_lock_irqsave(&pcmcia_lock, flags);
610
        start=map->sys_start;
611
 
612
        if(map->sys_stop==0)
613
                map->sys_stop=MAP_SIZE-1;
614
 
615
        if (map->flags & MAP_ATTRIB) {
616
                map->sys_start = pcmcia_socket[sock].phys_attr +
617
                        map->card_start;
618
        }
619
        else {
620
                map->sys_start = pcmcia_socket[sock].phys_mem +
621
                        map->card_start;
622
        }
623
 
624
        map->sys_stop=map->sys_start+(map->sys_stop-start);
625
        pcmcia_socket[sock].mem_map[map->map]=*map;
626
        spin_unlock_irqrestore(&pcmcia_lock, flags);
627
        DEBUG(3, "set_mem_map %d start %x stop %x card_start %x\n",
628
                        map->map, map->sys_start, map->sys_stop,
629
                        map->card_start);
630
        return 0;
631
 
632
}  /* au1000_pcmcia_set_mem_map() */
633
 
634
 
635
#if defined(CONFIG_PROC_FS)
636
 
637
static void
638
au1000_pcmcia_proc_setup(unsigned int sock, struct proc_dir_entry *base)
639
{
640
        struct proc_dir_entry *entry;
641
 
642
        if((entry=create_proc_entry("status", 0, base))==NULL){
643
                printk(KERN_ERR "Unable to install \"status\" procfs entry\n");
644
                return;
645
        }
646
 
647
        entry->read_proc=au1000_pcmcia_proc_status;
648
        entry->data=(void *)sock;
649
}
650
 
651
 
652
/* au1000_pcmcia_proc_status()
653
 * Implements the /proc/bus/pccard/??/status file.
654
 *
655
 * Returns: the number of characters added to the buffer
656
 */
657
static int
658
au1000_pcmcia_proc_status(char *buf, char **start, off_t pos,
659
                int count, int *eof, void *data)
660
{
661
        char *p=buf;
662
        unsigned int sock=(unsigned int)data;
663
 
664
        p+=sprintf(p, "k_flags  : %s%s%s%s%s%s%s\n",
665
             pcmcia_socket[sock].k_state.detect?"detect ":"",
666
             pcmcia_socket[sock].k_state.ready?"ready ":"",
667
             pcmcia_socket[sock].k_state.bvd1?"bvd1 ":"",
668
             pcmcia_socket[sock].k_state.bvd2?"bvd2 ":"",
669
             pcmcia_socket[sock].k_state.wrprot?"wrprot ":"",
670
             pcmcia_socket[sock].k_state.vs_3v?"vs_3v ":"",
671
             pcmcia_socket[sock].k_state.vs_Xv?"vs_Xv ":"");
672
 
673
        p+=sprintf(p, "status   : %s%s%s%s%s%s%s%s%s\n",
674
             pcmcia_socket[sock].k_state.detect?"SS_DETECT ":"",
675
             pcmcia_socket[sock].k_state.ready?"SS_READY ":"",
676
             pcmcia_socket[sock].cs_state.Vcc?"SS_POWERON ":"",
677
             pcmcia_socket[sock].cs_state.flags&SS_IOCARD?\
678
             "SS_IOCARD ":"",
679
             (pcmcia_socket[sock].cs_state.flags&SS_IOCARD &&
680
              pcmcia_socket[sock].k_state.bvd1)?"SS_STSCHG ":"",
681
             ((pcmcia_socket[sock].cs_state.flags&SS_IOCARD)==0 &&
682
              (pcmcia_socket[sock].k_state.bvd1==0))?"SS_BATDEAD ":"",
683
             ((pcmcia_socket[sock].cs_state.flags&SS_IOCARD)==0 &&
684
              (pcmcia_socket[sock].k_state.bvd2==0))?"SS_BATWARN ":"",
685
             pcmcia_socket[sock].k_state.vs_3v?"SS_3VCARD ":"",
686
             pcmcia_socket[sock].k_state.vs_Xv?"SS_XVCARD ":"");
687
 
688
        p+=sprintf(p, "mask     : %s%s%s%s%s\n",
689
             pcmcia_socket[sock].cs_state.csc_mask&SS_DETECT?\
690
             "SS_DETECT ":"",
691
             pcmcia_socket[sock].cs_state.csc_mask&SS_READY?\
692
             "SS_READY ":"",
693
             pcmcia_socket[sock].cs_state.csc_mask&SS_BATDEAD?\
694
             "SS_BATDEAD ":"",
695
             pcmcia_socket[sock].cs_state.csc_mask&SS_BATWARN?\
696
             "SS_BATWARN ":"",
697
             pcmcia_socket[sock].cs_state.csc_mask&SS_STSCHG?\
698
             "SS_STSCHG ":"");
699
 
700
        p+=sprintf(p, "cs_flags : %s%s%s%s%s\n",
701
             pcmcia_socket[sock].cs_state.flags&SS_PWR_AUTO?\
702
             "SS_PWR_AUTO ":"",
703
             pcmcia_socket[sock].cs_state.flags&SS_IOCARD?\
704
             "SS_IOCARD ":"",
705
             pcmcia_socket[sock].cs_state.flags&SS_RESET?\
706
             "SS_RESET ":"",
707
             pcmcia_socket[sock].cs_state.flags&SS_SPKR_ENA?\
708
             "SS_SPKR_ENA ":"",
709
             pcmcia_socket[sock].cs_state.flags&SS_OUTPUT_ENA?\
710
             "SS_OUTPUT_ENA ":"");
711
 
712
        p+=sprintf(p, "Vcc      : %d\n", pcmcia_socket[sock].cs_state.Vcc);
713
        p+=sprintf(p, "Vpp      : %d\n", pcmcia_socket[sock].cs_state.Vpp);
714
        p+=sprintf(p, "irq      : %d\n", pcmcia_socket[sock].cs_state.io_irq);
715
        p+=sprintf(p, "I/O      : %u\n", pcmcia_socket[sock].speed_io);
716
        p+=sprintf(p, "attribute: %u\n", pcmcia_socket[sock].speed_attr);
717
        p+=sprintf(p, "common   : %u\n", pcmcia_socket[sock].speed_mem);
718
        return p-buf;
719
}
720
 
721
 
722
#endif  /* defined(CONFIG_PROC_FS) */

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.