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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [uclinux/] [uClinux-2.0.x/] [drivers/] [net/] [soundmodem/] [sm_sbc.c] - Blame information for rev 199

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

Line No. Rev Author Line
1 199 simons
/*****************************************************************************/
2
 
3
/*
4
 *      sm_sbc.c  -- soundcard radio modem driver soundblaster hardware driver
5
 *
6
 *      Copyright (C) 1996  Thomas Sailer (sailer@ife.ee.ethz.ch)
7
 *
8
 *      This program is free software; you can redistribute it and/or modify
9
 *      it under the terms of the GNU General Public License as published by
10
 *      the Free Software Foundation; either version 2 of the License, or
11
 *      (at your option) any later version.
12
 *
13
 *      This program is distributed in the hope that it will be useful,
14
 *      but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 *      GNU General Public License for more details.
17
 *
18
 *      You should have received a copy of the GNU General Public License
19
 *      along with this program; if not, write to the Free Software
20
 *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21
 *
22
 *  Please note that the GPL allows you to use the driver, NOT the radio.
23
 *  In order to use the radio, you need a license from the communications
24
 *  authority of your country.
25
 *
26
 */
27
 
28
#include <linux/ptrace.h>
29
#include <linux/sched.h>
30
#include <linux/interrupt.h>
31
#include <asm/io.h>
32
#include <asm/dma.h>
33
#include <linux/ioport.h>
34
#include <linux/soundmodem.h>
35
#include <linux/delay.h>
36
#include "sm.h"
37
#include "smdma.h"
38
 
39
/* --------------------------------------------------------------------- */
40
 
41
/*
42
 * currently this module is supposed to support both module styles, i.e.
43
 * the old one present up to about 2.1.9, and the new one functioning
44
 * starting with 2.1.21. The reason is I have a kit allowing to compile
45
 * this module also under 2.0.x which was requested by several people.
46
 * This will go in 2.2
47
 */
48
#include <linux/version.h>
49
 
50
#if LINUX_VERSION_CODE >= 0x20100
51
#include <asm/uaccess.h>
52
#else
53
#include <asm/segment.h>
54
#include <linux/mm.h>
55
 
56
#undef put_user
57
#undef get_user
58
 
59
#define put_user(x,ptr) ({ __put_user((unsigned long)(x),(ptr),sizeof(*(ptr))); 0; })
60
#define get_user(x,ptr) ({ x = ((__typeof__(*(ptr)))__get_user((ptr),sizeof(*(ptr)))); 0; })
61
 
62
extern inline int copy_from_user(void *to, const void *from, unsigned long n)
63
{
64
        int i = verify_area(VERIFY_READ, from, n);
65
        if (i)
66
                return i;
67
        memcpy_fromfs(to, from, n);
68
        return 0;
69
}
70
 
71
extern inline int copy_to_user(void *to, const void *from, unsigned long n)
72
{
73
        int i = verify_area(VERIFY_WRITE, to, n);
74
        if (i)
75
                return i;
76
        memcpy_tofs(to, from, n);
77
        return 0;
78
}
79
#endif
80
 
81
/* --------------------------------------------------------------------- */
82
 
83
struct sc_state_sbc {
84
        unsigned char revhi, revlo;
85
        unsigned char fmt[2];
86
        unsigned int sr[2];
87
};
88
 
89
#define SCSTATE ((struct sc_state_sbc *)(&sm->hw))
90
 
91
/* --------------------------------------------------------------------- */
92
/*
93
 * the sbc converter's registers
94
 */
95
#define DSP_RESET(iobase)        (iobase+0x6)
96
#define DSP_READ_DATA(iobase)    (iobase+0xa)
97
#define DSP_WRITE_DATA(iobase)   (iobase+0xc)
98
#define DSP_WRITE_STATUS(iobase) (iobase+0xc)
99
#define DSP_DATA_AVAIL(iobase)   (iobase+0xe)
100
#define DSP_MIXER_ADDR(iobase)   (iobase+0x4)
101
#define DSP_MIXER_DATA(iobase)   (iobase+0x5)
102
#define DSP_INTACK_16BIT(iobase) (iobase+0xf)
103
#define SBC_EXTENT               16
104
 
105
/* --------------------------------------------------------------------- */
106
/*
107
 * SBC commands
108
 */
109
#define SBC_OUTPUT             0x14
110
#define SBC_INPUT              0x24
111
#define SBC_BLOCKSIZE          0x48
112
#define SBC_HI_OUTPUT          0x91 
113
#define SBC_HI_INPUT           0x99 
114
#define SBC_LO_OUTPUT_AUTOINIT 0x1c
115
#define SBC_LO_INPUT_AUTOINIT  0x2c
116
#define SBC_HI_OUTPUT_AUTOINIT 0x90 
117
#define SBC_HI_INPUT_AUTOINIT  0x98
118
#define SBC_IMMED_INT          0xf2
119
#define SBC_GET_REVISION       0xe1
120
#define ESS_GET_REVISION       0xe7
121
#define SBC_SPEAKER_ON         0xd1
122
#define SBC_SPEAKER_OFF        0xd3
123
#define SBC_DMA_ON             0xd0
124
#define SBC_DMA_OFF            0xd4
125
#define SBC_SAMPLE_RATE        0x40
126
#define SBC_SAMPLE_RATE_OUT    0x41
127
#define SBC_SAMPLE_RATE_IN     0x42
128
#define SBC_MONO_8BIT          0xa0
129
#define SBC_MONO_16BIT         0xa4
130
#define SBC_STEREO_8BIT        0xa8
131
#define SBC_STEREO_16BIT       0xac
132
 
133
#define SBC4_OUT8_AI           0xc6
134
#define SBC4_IN8_AI            0xce
135
#define SBC4_MODE_UNS_MONO     0x00
136
#define SBC4_MODE_SIGN_MONO    0x10
137
 
138
#define SBC4_OUT16_AI          0xb6
139
#define SBC4_IN16_AI           0xbe
140
 
141
/* --------------------------------------------------------------------- */
142
 
143
static int inline reset_dsp(struct device *dev)
144
{
145
        int i;
146
 
147
        outb(1, DSP_RESET(dev->base_addr));
148
        udelay(300);
149
        outb(0, DSP_RESET(dev->base_addr));
150
        for (i = 0; i < 0xffff; i++)
151
                if (inb(DSP_DATA_AVAIL(dev->base_addr)) & 0x80)
152
                        if (inb(DSP_READ_DATA(dev->base_addr)) == 0xaa)
153
                                return 1;
154
        return 0;
155
}
156
 
157
/* --------------------------------------------------------------------- */
158
 
159
static void inline write_dsp(struct device *dev, unsigned char data)
160
{
161
        int i;
162
 
163
        for (i = 0; i < 0xffff; i++)
164
                if (!(inb(DSP_WRITE_STATUS(dev->base_addr)) & 0x80)) {
165
                        outb(data, DSP_WRITE_DATA(dev->base_addr));
166
                        return;
167
                }
168
}
169
 
170
/* --------------------------------------------------------------------- */
171
 
172
static int inline read_dsp(struct device *dev, unsigned char *data)
173
{
174
        int i;
175
 
176
        if (!data)
177
                return 0;
178
        for (i = 0; i < 0xffff; i++)
179
                if (inb(DSP_DATA_AVAIL(dev->base_addr)) & 0x80) {
180
                        *data = inb(DSP_READ_DATA(dev->base_addr));
181
                        return 1;
182
                }
183
        return 0;
184
}
185
 
186
/* --------------------------------------------------------------------- */
187
 
188
static int config_resources(struct device *dev, struct sm_state *sm, int fdx)
189
{
190
        unsigned char irqreg = 0, dmareg = 0, realirq, realdma;
191
        unsigned long flags;
192
 
193
        switch (dev->irq) {
194
        case 2:
195
        case 9:
196
                irqreg |= 0x01;
197
                break;
198
 
199
        case 5:
200
                irqreg |= 0x02;
201
                break;
202
 
203
        case 7:
204
                irqreg |= 0x04;
205
                break;
206
 
207
        case 10:
208
                irqreg |= 0x08;
209
                break;
210
 
211
        default:
212
                return -ENODEV;
213
        }
214
 
215
        switch (dev->dma) {
216
        case 0:
217
                dmareg |= 0x01;
218
                break;
219
 
220
        case 1:
221
                dmareg |= 0x02;
222
                break;
223
 
224
        case 3:
225
                dmareg |= 0x08;
226
                break;
227
 
228
        default:
229
                return -ENODEV;
230
        }
231
 
232
        if (fdx) {
233
                switch (sm->hdrv.ptt_out.dma2) {
234
                case 5:
235
                        dmareg |= 0x20;
236
                        break;
237
 
238
                case 6:
239
                        dmareg |= 0x40;
240
                        break;
241
 
242
                case 7:
243
                        dmareg |= 0x80;
244
                        break;
245
 
246
                default:
247
                        return -ENODEV;
248
                }
249
        }
250
        save_flags(flags);
251
        cli();
252
        outb(0x80, DSP_MIXER_ADDR(dev->base_addr));
253
        outb(irqreg, DSP_MIXER_DATA(dev->base_addr));
254
        realirq = inb(DSP_MIXER_DATA(dev->base_addr));
255
        outb(0x81, DSP_MIXER_ADDR(dev->base_addr));
256
        outb(dmareg, DSP_MIXER_DATA(dev->base_addr));
257
        realdma = inb(DSP_MIXER_DATA(dev->base_addr));
258
        restore_flags(flags);
259
        if ((~realirq) & irqreg || (~realdma) & dmareg) {
260
                printk(KERN_ERR "%s: sbc resource registers cannot be set; PnP device "
261
                       "and IRQ/DMA specified wrongly?\n", sm_drvname);
262
                return -EINVAL;
263
        }
264
        return 0;
265
}
266
 
267
/* --------------------------------------------------------------------- */
268
 
269
static void inline sbc_int_ack_8bit(struct device *dev)
270
{
271
        inb(DSP_DATA_AVAIL(dev->base_addr));
272
}
273
 
274
/* --------------------------------------------------------------------- */
275
 
276
static void inline sbc_int_ack_16bit(struct device *dev)
277
{
278
        inb(DSP_INTACK_16BIT(dev->base_addr));
279
}
280
 
281
/* --------------------------------------------------------------------- */
282
 
283
static void setup_dma_dsp(struct device *dev, struct sm_state *sm, int send)
284
{
285
        unsigned long flags;
286
        static const unsigned char sbcmode[2][2] = {
287
                { SBC_LO_INPUT_AUTOINIT, SBC_LO_OUTPUT_AUTOINIT },
288
                { SBC_HI_INPUT_AUTOINIT, SBC_HI_OUTPUT_AUTOINIT }
289
        };
290
        static const unsigned char sbc4mode[2] = { SBC4_IN8_AI, SBC4_OUT8_AI };
291
        static const unsigned char sbcskr[2] = { SBC_SPEAKER_OFF, SBC_SPEAKER_ON };
292
        unsigned int nsamps;
293
 
294
        send = !!send;
295
        if (!reset_dsp(dev)) {
296
                printk(KERN_ERR "%s: sbc: cannot reset sb dsp\n", sm_drvname);
297
                return;
298
        }
299
        save_flags(flags);
300
        cli();
301
        sbc_int_ack_8bit(dev);
302
        write_dsp(dev, SBC_SAMPLE_RATE); /* set sampling rate */
303
        write_dsp(dev, SCSTATE->fmt[send]);
304
        write_dsp(dev, sbcskr[send]);
305
        nsamps = dma_setup(sm, send, dev->dma) - 1;
306
        sbc_int_ack_8bit(dev);
307
        if (SCSTATE->revhi >= 4) {
308
                write_dsp(dev, sbc4mode[send]);
309
                write_dsp(dev, SBC4_MODE_UNS_MONO);
310
                write_dsp(dev, nsamps & 0xff);
311
                write_dsp(dev, nsamps >> 8);
312
        } else {
313
                write_dsp(dev, SBC_BLOCKSIZE);
314
                write_dsp(dev, nsamps & 0xff);
315
                write_dsp(dev, nsamps >> 8);
316
                write_dsp(dev, sbcmode[SCSTATE->fmt[send] >= 180][send]);
317
                /* hispeed mode if sample rate > 13kHz */
318
        }
319
        restore_flags(flags);
320
}
321
 
322
/* --------------------------------------------------------------------- */
323
 
324
static void sbc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
325
{
326
        struct device *dev = (struct device *)dev_id;
327
        struct sm_state *sm = (struct sm_state *)dev->priv;
328
        unsigned int curfrag;
329
 
330
        if (!dev || !sm || sm->hdrv.magic != HDLCDRV_MAGIC)
331
                return;
332
        cli();
333
        sbc_int_ack_8bit(dev);
334
        disable_dma(dev->dma);
335
        clear_dma_ff(dev->dma);
336
        dma_ptr(sm, sm->dma.ptt_cnt > 0, dev->dma, &curfrag);
337
        enable_dma(dev->dma);
338
        sm_int_freq(sm);
339
        sti();
340
        if (sm->dma.ptt_cnt <= 0) {
341
                dma_receive(sm, curfrag);
342
                hdlcdrv_arbitrate(dev, &sm->hdrv);
343
                if (hdlcdrv_ptt(&sm->hdrv)) {
344
                        /* starting to transmit */
345
                        disable_dma(dev->dma);
346
                        hdlcdrv_transmitter(dev, &sm->hdrv); /* prefill HDLC buffer */
347
                        dma_start_transmit(sm);
348
                        setup_dma_dsp(dev, sm, 1);
349
                        dma_transmit(sm);
350
                }
351
        } else if (dma_end_transmit(sm, curfrag)) {
352
                /* stopping transmission */
353
                disable_dma(dev->dma);
354
                sti();
355
                dma_init_receive(sm);
356
                setup_dma_dsp(dev, sm, 0);
357
        } else
358
                dma_transmit(sm);
359
        sm_output_status(sm);
360
        hdlcdrv_transmitter(dev, &sm->hdrv);
361
        hdlcdrv_receiver(dev, &sm->hdrv);
362
 
363
}
364
 
365
/* --------------------------------------------------------------------- */
366
 
367
static int sbc_open(struct device *dev, struct sm_state *sm)
368
{
369
        int err;
370
        unsigned int dmasz, u;
371
 
372
        if (sizeof(sm->m) < sizeof(struct sc_state_sbc)) {
373
                printk(KERN_ERR "sm sbc: sbc state too big: %d > %d\n",
374
                       sizeof(struct sc_state_sbc), sizeof(sm->m));
375
                return -ENODEV;
376
        }
377
        if (!dev || !sm)
378
                return -ENXIO;
379
        if (dev->base_addr <= 0 || dev->base_addr > 0x1000-SBC_EXTENT ||
380
            dev->irq < 2 || dev->irq > 15 || dev->dma > 3)
381
                return -ENXIO;
382
        if (check_region(dev->base_addr, SBC_EXTENT))
383
                return -EACCES;
384
        /*
385
         * check if a card is available
386
         */
387
        if (!reset_dsp(dev)) {
388
                printk(KERN_ERR "%s: sbc: no card at io address 0x%lx\n",
389
                       sm_drvname, dev->base_addr);
390
                return -ENODEV;
391
        }
392
        write_dsp(dev, SBC_GET_REVISION);
393
        if (!read_dsp(dev, &SCSTATE->revhi) ||
394
            !read_dsp(dev, &SCSTATE->revlo))
395
                return -ENODEV;
396
        printk(KERN_INFO "%s: SoundBlaster DSP revision %d.%d\n", sm_drvname,
397
               SCSTATE->revhi, SCSTATE->revlo);
398
        if (SCSTATE->revhi < 2) {
399
                printk(KERN_ERR "%s: your card is an antiquity, at least DSP "
400
                       "rev 2.00 required\n", sm_drvname);
401
                return -ENODEV;
402
        }
403
        if (SCSTATE->revhi < 3 &&
404
            (SCSTATE->fmt[0] >= 180 || SCSTATE->fmt[1] >= 180)) {
405
                printk(KERN_ERR "%s: sbc io 0x%lx: DSP rev %d.%02d too "
406
                       "old, at least 3.00 required\n", sm_drvname,
407
                       dev->base_addr, SCSTATE->revhi, SCSTATE->revlo);
408
                return -ENODEV;
409
        }
410
        if (SCSTATE->revhi >= 4 &&
411
            (err = config_resources(dev, sm, 0))) {
412
                printk(KERN_ERR "%s: invalid IRQ and/or DMA specified\n", sm_drvname);
413
                return err;
414
        }
415
        /*
416
         * initialize some variables
417
         */
418
        dma_init_receive(sm);
419
        dmasz = (NUM_FRAGMENTS + 1) * sm->dma.ifragsz;
420
        u = NUM_FRAGMENTS * sm->dma.ofragsz;
421
        if (u > dmasz)
422
                dmasz = u;
423
        if (!(sm->dma.ibuf = sm->dma.obuf = kmalloc(dmasz, GFP_KERNEL | GFP_DMA)))
424
                return -ENOMEM;
425
        dma_init_transmit(sm);
426
        dma_init_receive(sm);
427
 
428
        memset(&sm->m, 0, sizeof(sm->m));
429
        memset(&sm->d, 0, sizeof(sm->d));
430
        if (sm->mode_tx->init)
431
                sm->mode_tx->init(sm);
432
        if (sm->mode_rx->init)
433
                sm->mode_rx->init(sm);
434
 
435
        if (request_dma(dev->dma, sm->hwdrv->hw_name)) {
436
                kfree_s(sm->dma.obuf, dmasz);
437
                return -EBUSY;
438
        }
439
        if (request_irq(dev->irq, sbc_interrupt, SA_INTERRUPT,
440
                        sm->hwdrv->hw_name, dev)) {
441
                free_dma(dev->dma);
442
                kfree_s(sm->dma.obuf, dmasz);
443
                return -EBUSY;
444
        }
445
        request_region(dev->base_addr, SBC_EXTENT, sm->hwdrv->hw_name);
446
        setup_dma_dsp(dev, sm, 0);
447
        return 0;
448
}
449
 
450
/* --------------------------------------------------------------------- */
451
 
452
static int sbc_close(struct device *dev, struct sm_state *sm)
453
{
454
        if (!dev || !sm)
455
                return -EINVAL;
456
        /*
457
         * disable interrupts
458
         */
459
        disable_dma(dev->dma);
460
        reset_dsp(dev);
461
        free_irq(dev->irq, dev);
462
        free_dma(dev->dma);
463
        release_region(dev->base_addr, SBC_EXTENT);
464
        kfree(sm->dma.obuf);
465
        return 0;
466
}
467
 
468
/* --------------------------------------------------------------------- */
469
 
470
static int sbc_sethw(struct device *dev, struct sm_state *sm, char *mode)
471
{
472
        char *cp = strchr(mode, '.');
473
        const struct modem_tx_info **mtp = sm_modem_tx_table;
474
        const struct modem_rx_info **mrp;
475
 
476
        if (!strcmp(mode, "off")) {
477
                sm->mode_tx = NULL;
478
                sm->mode_rx = NULL;
479
                return 0;
480
        }
481
        if (cp)
482
                *cp++ = '\0';
483
        else
484
                cp = mode;
485
        for (; *mtp; mtp++) {
486
                if ((*mtp)->loc_storage > sizeof(sm->m)) {
487
                        printk(KERN_ERR "%s: insufficient storage for modulator %s (%d)\n",
488
                               sm_drvname, (*mtp)->name, (*mtp)->loc_storage);
489
                        continue;
490
                }
491
                if (!(*mtp)->name || strcmp((*mtp)->name, mode))
492
                        continue;
493
                if ((*mtp)->srate < 5000 || (*mtp)->srate > 44100)
494
                        continue;
495
                if (!(*mtp)->modulator_u8)
496
                        continue;
497
                for (mrp = sm_modem_rx_table; *mrp; mrp++) {
498
                        if ((*mrp)->loc_storage > sizeof(sm->d)) {
499
                                printk(KERN_ERR "%s: insufficient storage for demodulator %s (%d)\n",
500
                                       sm_drvname, (*mrp)->name, (*mrp)->loc_storage);
501
                                continue;
502
                        }
503
                        if (!(*mrp)->demodulator_u8)
504
                                continue;
505
                        if ((*mrp)->name && !strcmp((*mrp)->name, cp) &&
506
                            (*mrp)->srate >= 5000 && (*mrp)->srate <= 44100) {
507
                                sm->mode_tx = *mtp;
508
                                sm->mode_rx = *mrp;
509
                                SCSTATE->fmt[0] = 256-((1000000L+sm->mode_rx->srate/2)/
510
                                                         sm->mode_rx->srate);
511
                                SCSTATE->fmt[1] = 256-((1000000L+sm->mode_tx->srate/2)/
512
                                                         sm->mode_tx->srate);
513
                                sm->dma.ifragsz = (sm->mode_rx->srate + 50)/100;
514
                                sm->dma.ofragsz = (sm->mode_tx->srate + 50)/100;
515
                                if (sm->dma.ifragsz < sm->mode_rx->overlap)
516
                                        sm->dma.ifragsz = sm->mode_rx->overlap;
517
                                sm->dma.i16bit = sm->dma.o16bit = 0;
518
                                return 0;
519
                        }
520
                }
521
        }
522
        return -EINVAL;
523
}
524
 
525
/* --------------------------------------------------------------------- */
526
 
527
static int sbc_ioctl(struct device *dev, struct sm_state *sm, struct ifreq *ifr,
528
                     struct hdlcdrv_ioctl *hi, int cmd)
529
{
530
        struct sm_ioctl bi;
531
        unsigned long flags;
532
        int i;
533
 
534
        if (cmd != SIOCDEVPRIVATE)
535
                return -ENOIOCTLCMD;
536
 
537
        if (hi->cmd == HDLCDRVCTL_MODEMPARMASK)
538
                return HDLCDRV_PARMASK_IOBASE | HDLCDRV_PARMASK_IRQ |
539
                        HDLCDRV_PARMASK_DMA | HDLCDRV_PARMASK_SERIOBASE |
540
                        HDLCDRV_PARMASK_PARIOBASE | HDLCDRV_PARMASK_MIDIIOBASE;
541
 
542
        if (copy_from_user(&bi, ifr->ifr_data, sizeof(bi)))
543
                return -EFAULT;
544
 
545
        switch (bi.cmd) {
546
        default:
547
                return -ENOIOCTLCMD;
548
 
549
        case SMCTL_GETMIXER:
550
                i = 0;
551
                bi.data.mix.sample_rate = sm->mode_rx->srate;
552
                bi.data.mix.bit_rate = sm->hdrv.par.bitrate;
553
                bi.data.mix.mixer_type = SM_MIXER_INVALID;
554
                switch (SCSTATE->revhi) {
555
                case 2:
556
                        bi.data.mix.mixer_type = SM_MIXER_CT1335;
557
                        break;
558
                case 3:
559
                        bi.data.mix.mixer_type = SM_MIXER_CT1345;
560
                        break;
561
                case 4:
562
                        bi.data.mix.mixer_type = SM_MIXER_CT1745;
563
                        break;
564
                }
565
                if (bi.data.mix.mixer_type != SM_MIXER_INVALID &&
566
                    bi.data.mix.reg < 0x80) {
567
                        save_flags(flags);
568
                        cli();
569
                        outb(bi.data.mix.reg, DSP_MIXER_ADDR(dev->base_addr));
570
                        bi.data.mix.data = inb(DSP_MIXER_DATA(dev->base_addr));
571
                        restore_flags(flags);
572
                        i = 1;
573
                }
574
                if (copy_to_user(ifr->ifr_data, &bi, sizeof(bi)))
575
                        return -EFAULT;
576
                return i;
577
 
578
        case SMCTL_SETMIXER:
579
                if (!suser())
580
                        return -EACCES;
581
                switch (SCSTATE->revhi) {
582
                case 2:
583
                        if (bi.data.mix.mixer_type != SM_MIXER_CT1335)
584
                                return -EINVAL;
585
                        break;
586
                case 3:
587
                        if (bi.data.mix.mixer_type != SM_MIXER_CT1345)
588
                                return -EINVAL;
589
                        break;
590
                case 4:
591
                        if (bi.data.mix.mixer_type != SM_MIXER_CT1745)
592
                                return -EINVAL;
593
                        break;
594
                default:
595
                        return -ENODEV;
596
                }
597
                if (bi.data.mix.reg >= 0x80)
598
                        return -EACCES;
599
                save_flags(flags);
600
                cli();
601
                outb(bi.data.mix.reg, DSP_MIXER_ADDR(dev->base_addr));
602
                outb(bi.data.mix.data, DSP_MIXER_DATA(dev->base_addr));
603
                restore_flags(flags);
604
                return 0;
605
 
606
        }
607
        if (copy_to_user(ifr->ifr_data, &bi, sizeof(bi)))
608
                return -EFAULT;
609
        return 0;
610
 
611
}
612
 
613
/* --------------------------------------------------------------------- */
614
 
615
const struct hardware_info sm_hw_sbc = {
616
        "sbc", sizeof(struct sc_state_sbc),
617
        sbc_open, sbc_close, sbc_ioctl, sbc_sethw
618
};
619
 
620
/* --------------------------------------------------------------------- */
621
 
622
static void setup_dma_fdx_dsp(struct device *dev, struct sm_state *sm)
623
{
624
        unsigned long flags;
625
        unsigned int isamps, osamps;
626
 
627
        if (!reset_dsp(dev)) {
628
                printk(KERN_ERR "%s: sbc: cannot reset sb dsp\n", sm_drvname);
629
                return;
630
        }
631
        save_flags(flags);
632
        cli();
633
        sbc_int_ack_8bit(dev);
634
        sbc_int_ack_16bit(dev);
635
        /* should eventually change to set rates individually by SBC_SAMPLE_RATE_{IN/OUT} */
636
        write_dsp(dev, SBC_SAMPLE_RATE_IN);
637
        write_dsp(dev, SCSTATE->sr[0] >> 8);
638
        write_dsp(dev, SCSTATE->sr[0] & 0xff);
639
        write_dsp(dev, SBC_SAMPLE_RATE_OUT);
640
        write_dsp(dev, SCSTATE->sr[1] >> 8);
641
        write_dsp(dev, SCSTATE->sr[1] & 0xff);
642
        write_dsp(dev, SBC_SPEAKER_ON);
643
        if (sm->dma.o16bit) {
644
                /*
645
                 * DMA channel 1 (8bit) does input (capture),
646
                 * DMA channel 2 (16bit) does output (playback)
647
                 */
648
                isamps = dma_setup(sm, 0, dev->dma) - 1;
649
                osamps = dma_setup(sm, 1, sm->hdrv.ptt_out.dma2) - 1;
650
                sbc_int_ack_8bit(dev);
651
                sbc_int_ack_16bit(dev);
652
                write_dsp(dev, SBC4_IN8_AI);
653
                write_dsp(dev, SBC4_MODE_UNS_MONO);
654
                write_dsp(dev, isamps & 0xff);
655
                write_dsp(dev, isamps >> 8);
656
                write_dsp(dev, SBC4_OUT16_AI);
657
                write_dsp(dev, SBC4_MODE_SIGN_MONO);
658
                write_dsp(dev, osamps & 0xff);
659
                write_dsp(dev, osamps >> 8);
660
        } else {
661
                /*
662
                 * DMA channel 1 (8bit) does output (playback),
663
                 * DMA channel 2 (16bit) does input (capture)
664
                 */
665
                isamps = dma_setup(sm, 0, sm->hdrv.ptt_out.dma2) - 1;
666
                osamps = dma_setup(sm, 1, dev->dma) - 1;
667
                sbc_int_ack_8bit(dev);
668
                sbc_int_ack_16bit(dev);
669
                write_dsp(dev, SBC4_OUT8_AI);
670
                write_dsp(dev, SBC4_MODE_UNS_MONO);
671
                write_dsp(dev, osamps & 0xff);
672
                write_dsp(dev, osamps >> 8);
673
                write_dsp(dev, SBC4_IN16_AI);
674
                write_dsp(dev, SBC4_MODE_SIGN_MONO);
675
                write_dsp(dev, isamps & 0xff);
676
                write_dsp(dev, isamps >> 8);
677
        }
678
        dma_init_receive(sm);
679
        dma_init_transmit(sm);
680
        restore_flags(flags);
681
}
682
 
683
/* --------------------------------------------------------------------- */
684
 
685
static void sbcfdx_interrupt(int irq, void *dev_id, struct pt_regs *regs)
686
{
687
        struct device *dev = (struct device *)dev_id;
688
        struct sm_state *sm = (struct sm_state *)dev->priv;
689
        unsigned char intsrc, pbint = 0, captint = 0;
690
        unsigned int ocfrag, icfrag;
691
        unsigned long flags;
692
 
693
        if (!dev || !sm || sm->hdrv.magic != HDLCDRV_MAGIC)
694
                return;
695
        save_flags(flags);
696
        cli();
697
        outb(0x82, DSP_MIXER_ADDR(dev->base_addr));
698
        intsrc = inb(DSP_MIXER_DATA(dev->base_addr));
699
        if (intsrc & 0x01) {
700
                sbc_int_ack_8bit(dev);
701
                if (sm->dma.o16bit) {
702
                        captint = 1;
703
                        disable_dma(dev->dma);
704
                        clear_dma_ff(dev->dma);
705
                        dma_ptr(sm, 0, dev->dma, &icfrag);
706
                        enable_dma(dev->dma);
707
                } else {
708
                        pbint = 1;
709
                        disable_dma(dev->dma);
710
                        clear_dma_ff(dev->dma);
711
                        dma_ptr(sm, 1, dev->dma, &ocfrag);
712
                        enable_dma(dev->dma);
713
                }
714
        }
715
        if (intsrc & 0x02) {
716
                sbc_int_ack_16bit(dev);
717
                if (sm->dma.o16bit) {
718
                        pbint = 1;
719
                        disable_dma(sm->hdrv.ptt_out.dma2);
720
                        clear_dma_ff(sm->hdrv.ptt_out.dma2);
721
                        dma_ptr(sm, 1, sm->hdrv.ptt_out.dma2, &ocfrag);
722
                        enable_dma(sm->hdrv.ptt_out.dma2);
723
                } else {
724
                        captint = 1;
725
                        disable_dma(sm->hdrv.ptt_out.dma2);
726
                        clear_dma_ff(sm->hdrv.ptt_out.dma2);
727
                        dma_ptr(sm, 0, sm->hdrv.ptt_out.dma2, &icfrag);
728
                        enable_dma(sm->hdrv.ptt_out.dma2);
729
                }
730
        }
731
        restore_flags(flags);
732
        sm_int_freq(sm);
733
        sti();
734
        if (pbint) {
735
                if (dma_end_transmit(sm, ocfrag))
736
                        dma_clear_transmit(sm);
737
                dma_transmit(sm);
738
        }
739
        if (captint) {
740
                dma_receive(sm, icfrag);
741
                hdlcdrv_arbitrate(dev, &sm->hdrv);
742
        }
743
        sm_output_status(sm);
744
        hdlcdrv_transmitter(dev, &sm->hdrv);
745
        hdlcdrv_receiver(dev, &sm->hdrv);
746
}
747
 
748
/* --------------------------------------------------------------------- */
749
 
750
static int sbcfdx_open(struct device *dev, struct sm_state *sm)
751
{
752
        int err;
753
 
754
        if (sizeof(sm->m) < sizeof(struct sc_state_sbc)) {
755
                printk(KERN_ERR "sm sbc: sbc state too big: %d > %d\n",
756
                       sizeof(struct sc_state_sbc), sizeof(sm->m));
757
                return -ENODEV;
758
        }
759
        if (!dev || !sm)
760
                return -ENXIO;
761
        if (dev->base_addr <= 0 || dev->base_addr > 0x1000-SBC_EXTENT ||
762
            dev->irq < 2 || dev->irq > 15 || dev->dma > 3)
763
                return -ENXIO;
764
        if (check_region(dev->base_addr, SBC_EXTENT))
765
                return -EACCES;
766
        /*
767
         * check if a card is available
768
         */
769
        if (!reset_dsp(dev)) {
770
                printk(KERN_ERR "%s: sbc: no card at io address 0x%lx\n",
771
                       sm_drvname, dev->base_addr);
772
                return -ENODEV;
773
        }
774
        write_dsp(dev, SBC_GET_REVISION);
775
        if (!read_dsp(dev, &SCSTATE->revhi) ||
776
            !read_dsp(dev, &SCSTATE->revlo))
777
                return -ENODEV;
778
        printk(KERN_INFO "%s: SoundBlaster DSP revision %d.%d\n", sm_drvname,
779
               SCSTATE->revhi, SCSTATE->revlo);
780
        if (SCSTATE->revhi < 4) {
781
                printk(KERN_ERR "%s: at least DSP rev 4.00 required\n", sm_drvname);
782
                return -ENODEV;
783
        }
784
        if ((err = config_resources(dev, sm, 1))) {
785
                printk(KERN_ERR "%s: invalid IRQ and/or DMA specified\n", sm_drvname);
786
                return err;
787
        }
788
        /*
789
         * initialize some variables
790
         */
791
        if (!(sm->dma.ibuf = kmalloc(sm->dma.ifragsz * (NUM_FRAGMENTS+1), GFP_KERNEL | GFP_DMA)))
792
                return -ENOMEM;
793
        if (!(sm->dma.obuf = kmalloc(sm->dma.ofragsz * NUM_FRAGMENTS, GFP_KERNEL | GFP_DMA))) {
794
                kfree(sm->dma.ibuf);
795
                return -ENOMEM;
796
        }
797
        dma_init_transmit(sm);
798
        dma_init_receive(sm);
799
 
800
        memset(&sm->m, 0, sizeof(sm->m));
801
        memset(&sm->d, 0, sizeof(sm->d));
802
        if (sm->mode_tx->init)
803
                sm->mode_tx->init(sm);
804
        if (sm->mode_rx->init)
805
                sm->mode_rx->init(sm);
806
 
807
        if (request_dma(dev->dma, sm->hwdrv->hw_name)) {
808
                kfree(sm->dma.ibuf);
809
                kfree(sm->dma.obuf);
810
                return -EBUSY;
811
        }
812
        if (request_dma(sm->hdrv.ptt_out.dma2, sm->hwdrv->hw_name)) {
813
                kfree(sm->dma.ibuf);
814
                kfree(sm->dma.obuf);
815
                free_dma(dev->dma);
816
                return -EBUSY;
817
        }
818
        if (request_irq(dev->irq, sbcfdx_interrupt, SA_INTERRUPT,
819
                        sm->hwdrv->hw_name, dev)) {
820
                kfree(sm->dma.ibuf);
821
                kfree(sm->dma.obuf);
822
                free_dma(dev->dma);
823
                free_dma(sm->hdrv.ptt_out.dma2);
824
                return -EBUSY;
825
        }
826
        request_region(dev->base_addr, SBC_EXTENT, sm->hwdrv->hw_name);
827
        setup_dma_fdx_dsp(dev, sm);
828
        return 0;
829
}
830
 
831
/* --------------------------------------------------------------------- */
832
 
833
static int sbcfdx_close(struct device *dev, struct sm_state *sm)
834
{
835
        if (!dev || !sm)
836
                return -EINVAL;
837
        /*
838
         * disable interrupts
839
         */
840
        disable_dma(dev->dma);
841
        disable_dma(sm->hdrv.ptt_out.dma2);
842
        reset_dsp(dev);
843
        free_irq(dev->irq, dev);
844
        free_dma(dev->dma);
845
        free_dma(sm->hdrv.ptt_out.dma2);
846
        release_region(dev->base_addr, SBC_EXTENT);
847
        kfree(sm->dma.ibuf);
848
        kfree(sm->dma.obuf);
849
        return 0;
850
}
851
 
852
/* --------------------------------------------------------------------- */
853
 
854
static int sbcfdx_sethw(struct device *dev, struct sm_state *sm, char *mode)
855
{
856
        char *cp = strchr(mode, '.');
857
        const struct modem_tx_info **mtp = sm_modem_tx_table;
858
        const struct modem_rx_info **mrp;
859
 
860
        if (!strcmp(mode, "off")) {
861
                sm->mode_tx = NULL;
862
                sm->mode_rx = NULL;
863
                return 0;
864
        }
865
        if (cp)
866
                *cp++ = '\0';
867
        else
868
                cp = mode;
869
        for (; *mtp; mtp++) {
870
                if ((*mtp)->loc_storage > sizeof(sm->m)) {
871
                        printk(KERN_ERR "%s: insufficient storage for modulator %s (%d)\n",
872
                               sm_drvname, (*mtp)->name, (*mtp)->loc_storage);
873
                        continue;
874
                }
875
                if (!(*mtp)->name || strcmp((*mtp)->name, mode))
876
                        continue;
877
                if ((*mtp)->srate < 5000 || (*mtp)->srate > 44100)
878
                        continue;
879
                for (mrp = sm_modem_rx_table; *mrp; mrp++) {
880
                        if ((*mrp)->loc_storage > sizeof(sm->d)) {
881
                                printk(KERN_ERR "%s: insufficient storage for demodulator %s (%d)\n",
882
                                       sm_drvname, (*mrp)->name, (*mrp)->loc_storage);
883
                                continue;
884
                        }
885
                        if ((*mrp)->name && !strcmp((*mrp)->name, cp) &&
886
                            (*mtp)->srate >= 5000 && (*mtp)->srate <= 44100 &&
887
                            (*mrp)->srate == (*mtp)->srate) {
888
                                sm->mode_tx = *mtp;
889
                                sm->mode_rx = *mrp;
890
                                SCSTATE->sr[0] = sm->mode_rx->srate;
891
                                SCSTATE->sr[1] = sm->mode_tx->srate;
892
                                sm->dma.ifragsz = (sm->mode_rx->srate + 50)/100;
893
                                sm->dma.ofragsz = (sm->mode_tx->srate + 50)/100;
894
                                if (sm->dma.ifragsz < sm->mode_rx->overlap)
895
                                        sm->dma.ifragsz = sm->mode_rx->overlap;
896
                                if (sm->mode_rx->demodulator_s16 && sm->mode_tx->modulator_u8) {
897
                                        sm->dma.i16bit = 1;
898
                                        sm->dma.o16bit = 0;
899
                                        sm->dma.ifragsz <<= 1;
900
                                } else if (sm->mode_rx->demodulator_u8 && sm->mode_tx->modulator_s16) {
901
                                        sm->dma.i16bit = 0;
902
                                        sm->dma.o16bit = 1;
903
                                        sm->dma.ofragsz <<= 1;
904
                                } else {
905
                                        printk(KERN_INFO "%s: mode %s or %s unusable\n", sm_drvname,
906
                                               sm->mode_rx->name, sm->mode_tx->name);
907
                                        sm->mode_tx = NULL;
908
                                        sm->mode_rx = NULL;
909
                                        return -EINVAL;
910
                                }
911
                                return 0;
912
                        }
913
                }
914
        }
915
        return -EINVAL;
916
}
917
 
918
/* --------------------------------------------------------------------- */
919
 
920
static int sbcfdx_ioctl(struct device *dev, struct sm_state *sm, struct ifreq *ifr,
921
                        struct hdlcdrv_ioctl *hi, int cmd)
922
{
923
        if (cmd != SIOCDEVPRIVATE)
924
                return -ENOIOCTLCMD;
925
 
926
        if (hi->cmd == HDLCDRVCTL_MODEMPARMASK)
927
                return HDLCDRV_PARMASK_IOBASE | HDLCDRV_PARMASK_IRQ |
928
                        HDLCDRV_PARMASK_DMA | HDLCDRV_PARMASK_DMA2 | HDLCDRV_PARMASK_SERIOBASE |
929
                        HDLCDRV_PARMASK_PARIOBASE | HDLCDRV_PARMASK_MIDIIOBASE;
930
 
931
        return sbc_ioctl(dev, sm, ifr, hi, cmd);
932
}
933
 
934
/* --------------------------------------------------------------------- */
935
 
936
const struct hardware_info sm_hw_sbcfdx = {
937
        "sbcfdx", sizeof(struct sc_state_sbc),
938
        sbcfdx_open, sbcfdx_close, sbcfdx_ioctl, sbcfdx_sethw
939
};
940
 
941
/* --------------------------------------------------------------------- */

powered by: WebSVN 2.1.0

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