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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [cdrom/] [isp16.c] - Blame information for rev 1774

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/* -- ISP16 cdrom detection and configuration
2
 *
3
 *    Copyright (c) 1995,1996 Eric van der Maarel <H.T.M.v.d.Maarel@marin.nl>
4
 *
5
 *    Version 0.6
6
 *
7
 *    History:
8
 *    0.5 First release.
9
 *        Was included in the sjcd and optcd cdrom drivers.
10
 *    0.6 First "stand-alone" version.
11
 *        Removed sound configuration.
12
 *        Added "module" support.
13
 *
14
 *      9 November 1999 -- Make kernel-parameter implementation work with 2.3.x
15
 *                         Removed init_module & cleanup_module in favor of
16
 *                         module_init & module_exit.
17
 *                         Torben Mathiasen <tmm@image.dk>
18
 *
19
 *    Detect cdrom interface on ISP16 sound card.
20
 *    Configure cdrom interface.
21
 *
22
 *    Algorithm for the card with OPTi 82C928 taken
23
 *    from the CDSETUP.SYS driver for MSDOS,
24
 *    by OPTi Computers, version 2.03.
25
 *    Algorithm for the card with OPTi 82C929 as communicated
26
 *    to me by Vadim Model and Leo Spiekman.
27
 *
28
 *    This program is free software; you can redistribute it and/or modify
29
 *    it under the terms of the GNU General Public License as published by
30
 *    the Free Software Foundation; either version 2 of the License, or
31
 *    (at your option) any later version.
32
 *
33
 *    This program is distributed in the hope that it will be useful,
34
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
35
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
36
 *    GNU General Public License for more details.
37
 *
38
 *    You should have received a copy of the GNU General Public License
39
 *    along with this program; if not, write to the Free Software
40
 *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
41
 *
42
 */
43
 
44
#define ISP16_VERSION_MAJOR 0
45
#define ISP16_VERSION_MINOR 6
46
 
47
#include <linux/module.h>
48
 
49
#include <linux/fs.h>
50
#include <linux/kernel.h>
51
#include <linux/string.h>
52
#include <linux/ioport.h>
53
#include <linux/init.h>
54
#include <asm/io.h>
55
#include "isp16.h"
56
 
57
static short isp16_detect(void);
58
static short isp16_c928__detect(void);
59
static short isp16_c929__detect(void);
60
static short isp16_cdi_config(int base, u_char drive_type, int irq,
61
                              int dma);
62
static short isp16_type;        /* dependent on type of interface card */
63
static u_char isp16_ctrl;
64
static u_short isp16_enable_port;
65
 
66
static int isp16_cdrom_base = ISP16_CDROM_IO_BASE;
67
static int isp16_cdrom_irq = ISP16_CDROM_IRQ;
68
static int isp16_cdrom_dma = ISP16_CDROM_DMA;
69
static char *isp16_cdrom_type = ISP16_CDROM_TYPE;
70
 
71
MODULE_PARM(isp16_cdrom_base, "i");
72
MODULE_PARM(isp16_cdrom_irq, "i");
73
MODULE_PARM(isp16_cdrom_dma, "i");
74
MODULE_PARM(isp16_cdrom_type, "s");
75
 
76
#ifdef MODULE
77
void isp16_exit(void);
78
#endif
79
 
80
#define ISP16_IN(p) (outb(isp16_ctrl,ISP16_CTRL_PORT), inb(p))
81
#define ISP16_OUT(p,b) (outb(isp16_ctrl,ISP16_CTRL_PORT), outb(b,p))
82
 
83
#ifndef MODULE
84
 
85
static int
86
__init isp16_setup(char *str)
87
{
88
        int ints[4];
89
 
90
        (void) get_options(str, ARRAY_SIZE(ints), ints);
91
        if (ints[0] > 0)
92
                isp16_cdrom_base = ints[1];
93
        if (ints[0] > 1)
94
                isp16_cdrom_irq = ints[2];
95
        if (ints[0] > 2)
96
                isp16_cdrom_dma = ints[3];
97
        if (str)
98
                isp16_cdrom_type = str;
99
 
100
        return 1;
101
}
102
 
103
__setup("isp16=", isp16_setup);
104
 
105
#endif                          /* MODULE */
106
 
107
/*
108
 *  ISP16 initialisation.
109
 *
110
 */
111
int __init isp16_init(void)
112
{
113
        u_char expected_drive;
114
 
115
        printk(KERN_INFO
116
               "ISP16: configuration cdrom interface, version %d.%d.\n",
117
               ISP16_VERSION_MAJOR, ISP16_VERSION_MINOR);
118
 
119
        if (!strcmp(isp16_cdrom_type, "noisp16")) {
120
                printk("ISP16: no cdrom interface configured.\n");
121
                return (0);
122
        }
123
 
124
        if (check_region(ISP16_IO_BASE, ISP16_IO_SIZE)) {
125
                printk("ISP16: i/o ports already in use.\n");
126
                return (-EIO);
127
        }
128
 
129
        if ((isp16_type = isp16_detect()) < 0) {
130
                printk("ISP16: no cdrom interface found.\n");
131
                return (-EIO);
132
        }
133
 
134
        printk(KERN_INFO
135
               "ISP16: cdrom interface (with OPTi 82C92%d chip) detected.\n",
136
               (isp16_type == 2) ? 9 : 8);
137
 
138
        if (!strcmp(isp16_cdrom_type, "Sanyo"))
139
                expected_drive =
140
                    (isp16_type ? ISP16_SANYO1 : ISP16_SANYO0);
141
        else if (!strcmp(isp16_cdrom_type, "Sony"))
142
                expected_drive = ISP16_SONY;
143
        else if (!strcmp(isp16_cdrom_type, "Panasonic"))
144
                expected_drive =
145
                    (isp16_type ? ISP16_PANASONIC1 : ISP16_PANASONIC0);
146
        else if (!strcmp(isp16_cdrom_type, "Mitsumi"))
147
                expected_drive = ISP16_MITSUMI;
148
        else {
149
                printk("ISP16: %s not supported by cdrom interface.\n",
150
                       isp16_cdrom_type);
151
                return (-EIO);
152
        }
153
 
154
        if (isp16_cdi_config(isp16_cdrom_base, expected_drive,
155
                             isp16_cdrom_irq, isp16_cdrom_dma) < 0) {
156
                printk
157
                    ("ISP16: cdrom interface has not been properly configured.\n");
158
                return (-EIO);
159
        }
160
        printk(KERN_INFO
161
               "ISP16: cdrom interface set up with io base 0x%03X, irq %d, dma %d,"
162
               " type %s.\n", isp16_cdrom_base, isp16_cdrom_irq,
163
               isp16_cdrom_dma, isp16_cdrom_type);
164
        return (0);
165
}
166
 
167
static short __init isp16_detect(void)
168
{
169
 
170
        if (isp16_c929__detect() >= 0)
171
                return (2);
172
        else
173
                return (isp16_c928__detect());
174
}
175
 
176
static short __init isp16_c928__detect(void)
177
{
178
        u_char ctrl;
179
        u_char enable_cdrom;
180
        u_char io;
181
        short i = -1;
182
 
183
        isp16_ctrl = ISP16_C928__CTRL;
184
        isp16_enable_port = ISP16_C928__ENABLE_PORT;
185
 
186
        /* read' and write' are a special read and write, respectively */
187
 
188
        /* read' ISP16_CTRL_PORT, clear last two bits and write' back the result */
189
        ctrl = ISP16_IN(ISP16_CTRL_PORT) & 0xFC;
190
        ISP16_OUT(ISP16_CTRL_PORT, ctrl);
191
 
192
        /* read' 3,4 and 5-bit from the cdrom enable port */
193
        enable_cdrom = ISP16_IN(ISP16_C928__ENABLE_PORT) & 0x38;
194
 
195
        if (!(enable_cdrom & 0x20)) {   /* 5-bit not set */
196
                /* read' last 2 bits of ISP16_IO_SET_PORT */
197
                io = ISP16_IN(ISP16_IO_SET_PORT) & 0x03;
198
                if (((io & 0x01) << 1) == (io & 0x02)) {        /* bits are the same */
199
                        if (io == 0) {   /* ...the same and 0 */
200
                                i = 0;
201
                                enable_cdrom |= 0x20;
202
                        } else {        /* ...the same and 1 *//* my card, first time 'round */
203
                                i = 1;
204
                                enable_cdrom |= 0x28;
205
                        }
206
                        ISP16_OUT(ISP16_C928__ENABLE_PORT, enable_cdrom);
207
                } else {        /* bits are not the same */
208
                        ISP16_OUT(ISP16_CTRL_PORT, ctrl);
209
                        return (i);     /* -> not detected: possibly incorrect conclusion */
210
                }
211
        } else if (enable_cdrom == 0x20)
212
                i = 0;
213
        else if (enable_cdrom == 0x28)  /* my card, already initialised */
214
                i = 1;
215
 
216
        ISP16_OUT(ISP16_CTRL_PORT, ctrl);
217
 
218
        return (i);
219
}
220
 
221
static short __init isp16_c929__detect(void)
222
{
223
        u_char ctrl;
224
        u_char tmp;
225
 
226
        isp16_ctrl = ISP16_C929__CTRL;
227
        isp16_enable_port = ISP16_C929__ENABLE_PORT;
228
 
229
        /* read' and write' are a special read and write, respectively */
230
 
231
        /* read' ISP16_CTRL_PORT and save */
232
        ctrl = ISP16_IN(ISP16_CTRL_PORT);
233
 
234
        /* write' zero to the ctrl port and get response */
235
        ISP16_OUT(ISP16_CTRL_PORT, 0);
236
        tmp = ISP16_IN(ISP16_CTRL_PORT);
237
 
238
        if (tmp != 2)           /* isp16 with 82C929 not detected */
239
                return (-1);
240
 
241
        /* restore ctrl port value */
242
        ISP16_OUT(ISP16_CTRL_PORT, ctrl);
243
 
244
        return (2);
245
}
246
 
247
static short __init
248
isp16_cdi_config(int base, u_char drive_type, int irq, int dma)
249
{
250
        u_char base_code;
251
        u_char irq_code;
252
        u_char dma_code;
253
        u_char i;
254
 
255
        if ((drive_type == ISP16_MITSUMI) && (dma != 0))
256
                printk("ISP16: Mitsumi cdrom drive has no dma support.\n");
257
 
258
        switch (base) {
259
        case 0x340:
260
                base_code = ISP16_BASE_340;
261
                break;
262
        case 0x330:
263
                base_code = ISP16_BASE_330;
264
                break;
265
        case 0x360:
266
                base_code = ISP16_BASE_360;
267
                break;
268
        case 0x320:
269
                base_code = ISP16_BASE_320;
270
                break;
271
        default:
272
                printk
273
                    ("ISP16: base address 0x%03X not supported by cdrom interface.\n",
274
                     base);
275
                return (-1);
276
        }
277
        switch (irq) {
278
        case 0:
279
                irq_code = ISP16_IRQ_X;
280
                break;          /* disable irq */
281
        case 5:
282
                irq_code = ISP16_IRQ_5;
283
                printk("ISP16: irq 5 shouldn't be used by cdrom interface,"
284
                       " due to possible conflicts with the sound card.\n");
285
                break;
286
        case 7:
287
                irq_code = ISP16_IRQ_7;
288
                printk("ISP16: irq 7 shouldn't be used by cdrom interface,"
289
                       " due to possible conflicts with the sound card.\n");
290
                break;
291
        case 3:
292
                irq_code = ISP16_IRQ_3;
293
                break;
294
        case 9:
295
                irq_code = ISP16_IRQ_9;
296
                break;
297
        case 10:
298
                irq_code = ISP16_IRQ_10;
299
                break;
300
        case 11:
301
                irq_code = ISP16_IRQ_11;
302
                break;
303
        default:
304
                printk("ISP16: irq %d not supported by cdrom interface.\n",
305
                       irq);
306
                return (-1);
307
        }
308
        switch (dma) {
309
        case 0:
310
                dma_code = ISP16_DMA_X;
311
                break;          /* disable dma */
312
        case 1:
313
                printk("ISP16: dma 1 cannot be used by cdrom interface,"
314
                       " due to conflict with the sound card.\n");
315
                return (-1);
316
                break;
317
        case 3:
318
                dma_code = ISP16_DMA_3;
319
                break;
320
        case 5:
321
                dma_code = ISP16_DMA_5;
322
                break;
323
        case 6:
324
                dma_code = ISP16_DMA_6;
325
                break;
326
        case 7:
327
                dma_code = ISP16_DMA_7;
328
                break;
329
        default:
330
                printk("ISP16: dma %d not supported by cdrom interface.\n",
331
                       dma);
332
                return (-1);
333
        }
334
 
335
        if (drive_type != ISP16_SONY && drive_type != ISP16_PANASONIC0 &&
336
            drive_type != ISP16_PANASONIC1 && drive_type != ISP16_SANYO0 &&
337
            drive_type != ISP16_SANYO1 && drive_type != ISP16_MITSUMI &&
338
            drive_type != ISP16_DRIVE_X) {
339
                printk
340
                    ("ISP16: drive type (code 0x%02X) not supported by cdrom"
341
                     " interface.\n", drive_type);
342
                return (-1);
343
        }
344
 
345
        /* set type of interface */
346
        i = ISP16_IN(ISP16_DRIVE_SET_PORT) & ISP16_DRIVE_SET_MASK;      /* clear some bits */
347
        ISP16_OUT(ISP16_DRIVE_SET_PORT, i | drive_type);
348
 
349
        /* enable cdrom on interface with 82C929 chip */
350
        if (isp16_type > 1)
351
                ISP16_OUT(isp16_enable_port, ISP16_ENABLE_CDROM);
352
 
353
        /* set base address, irq and dma */
354
        i = ISP16_IN(ISP16_IO_SET_PORT) & ISP16_IO_SET_MASK;    /* keep some bits */
355
        ISP16_OUT(ISP16_IO_SET_PORT, i | base_code | irq_code | dma_code);
356
 
357
        return (0);
358
}
359
 
360
void __exit isp16_exit(void)
361
{
362
        release_region(ISP16_IO_BASE, ISP16_IO_SIZE);
363
        printk(KERN_INFO "ISP16: module released.\n");
364
}
365
 
366
#ifdef MODULE
367
module_init(isp16_init);
368
#endif
369
module_exit(isp16_exit);
370
 
371
EXPORT_NO_SYMBOLS;
372
MODULE_LICENSE("GPL");

powered by: WebSVN 2.1.0

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