import of ftp.dlink.com/GPL/DSMG-600_reB/ppclinux.tar.gz
[linux-2.4.21-pre4.git] / drivers / sbus / audio / amd7930.c
1 /* $Id: amd7930.c,v 1.1.1.1 2005/04/11 02:50:34 jack Exp $
2  * drivers/sbus/audio/amd7930.c
3  *
4  * Copyright (C) 1996,1997 Thomas K. Dyas (tdyas@eden.rutgers.edu)
5  *
6  * This is the lowlevel driver for the AMD7930 audio chip found on all
7  * sun4c machines and some sun4m machines.
8  *
9  * The amd7930 is actually an ISDN chip which has a very simple
10  * integrated audio encoder/decoder. When Sun decided on what chip to
11  * use for audio, they had the brilliant idea of using the amd7930 and
12  * only connecting the audio encoder/decoder pins.
13  *
14  * Thanks to the AMD engineer who was able to get us the AMD79C30
15  * databook which has all the programming information and gain tables.
16  *
17  * Advanced Micro Devices' Am79C30A is an ISDN/audio chip used in the
18  * SparcStation 1+.  The chip provides microphone and speaker interfaces
19  * which provide mono-channel audio at 8K samples per second via either
20  * 8-bit A-law or 8-bit mu-law encoding.  Also, the chip features an
21  * ISDN BRI Line Interface Unit (LIU), I.430 S/T physical interface,
22  * which performs basic D channel LAPD processing and provides raw
23  * B channel data.  The digital audio channel, the two ISDN B channels,
24  * and two 64 Kbps channels to the microprocessor are all interconnected
25  * via a multiplexer.
26  *
27  * This driver interfaces to the Linux HiSax ISDN driver, which performs
28  * all high-level Q.921 and Q.931 ISDN functions.  The file is not
29  * itself a hardware driver; rather it uses functions exported by
30  * the AMD7930 driver in the sparcaudio subsystem (drivers/sbus/audio),
31  * allowing the chip to be simultaneously used for both audio and ISDN data.
32  * The hardware driver does _no_ buffering, but provides several callbacks
33  * which are called during interrupt service and should therefore run quickly.
34  *
35  * D channel transmission is performed by passing the hardware driver the
36  * address and size of an skb's data area, then waiting for a callback
37  * to signal successful transmission of the packet.  A task is then
38  * queued to notify the HiSax driver that another packet may be transmitted.
39  *
40  * D channel reception is quite simple, mainly because of:
41  *   1) the slow speed of the D channel - 16 kbps, and
42  *   2) the presence of an 8- or 32-byte (depending on chip version) FIFO
43  *      to buffer the D channel data on the chip
44  * Worst case scenario of back-to-back packets with the 8 byte buffer
45  * at 16 kbps yields an service time of 4 ms - long enough to preclude
46  * the need for fancy buffering.  We queue a background task that copies
47  * data out of the receive buffer into an skb, and the hardware driver
48  * simply does nothing until we're done with the receive buffer and
49  * reset it for a new packet.
50  *
51  * B channel processing is more complex, because of:
52  *   1) the faster speed - 64 kbps,
53  *   2) the lack of any on-chip buffering (it interrupts for every byte), and
54  *   3) the lack of any chip support for HDLC encapsulation
55  *
56  * The HiSax driver can put each B channel into one of three modes -
57  * L1_MODE_NULL (channel disabled), L1_MODE_TRANS (transparent data relay),
58  * and L1_MODE_HDLC (HDLC encapsulation by low-level driver).
59  * L1_MODE_HDLC is the most common, used for almost all "pure" digital
60  * data sessions.  L1_MODE_TRANS is used for ISDN audio.
61  *
62  * HDLC B channel transmission is performed via a large buffer into
63  * which the skb is copied while performing HDLC bit-stuffing.  A CRC
64  * is computed and attached to the end of the buffer, which is then
65  * passed to the low-level routines for raw transmission.  Once
66  * transmission is complete, the hardware driver is set to enter HDLC
67  * idle by successive transmission of mark (all 1) bytes, waiting for
68  * the ISDN driver to prepare another packet for transmission and
69  * deliver it.
70  *
71  * HDLC B channel reception is performed via an X-byte ring buffer
72  * divided into N sections of X/N bytes each.  Defaults: X=256 bytes, N=4.
73  * As the hardware driver notifies us that each section is full, we
74  * hand it the next section and schedule a background task to peruse
75  * the received section, bit-by-bit, with an HDLC decoder.  As
76  * packets are detected, they are copied into a large buffer while
77  * decoding HDLC bit-stuffing.  The ending CRC is verified, and if
78  * it is correct, we alloc a new skb of the correct length (which we
79  * now know), copy the packet into it, and hand it to the upper layers.
80  * Optimization: for large packets, we hand the buffer (which also
81  * happens to be an skb) directly to the upper layer after an skb_trim,
82  * and alloc a new large buffer for future packets, thus avoiding a copy.
83  * Then we return to HDLC processing; state is saved between calls.
84  */
85
86 #include <linux/module.h>
87 #include <linux/kernel.h>
88 #include <linux/sched.h>
89 #include <linux/errno.h>
90 #include <linux/interrupt.h>
91 #include <linux/slab.h>
92 #include <linux/init.h>
93 #include <linux/version.h>
94 #include <linux/soundcard.h>
95 #include <asm/openprom.h>
96 #include <asm/oplib.h>
97 #include <asm/system.h>
98 #include <asm/irq.h>
99 #include <asm/io.h>
100 #include <asm/sbus.h>
101
102 #include <asm/audioio.h>
103 #include "amd7930.h"
104
105 static __u8  bilinear2mulaw(__u8 data);
106 static __u8  mulaw2bilinear(__u8 data);
107 static __u8  linear2mulaw(__u16 data);
108 static __u16 mulaw2linear(__u8 data);
109
110 #if defined (AMD79C30_ISDN)
111 #include "../../isdn/hisax/hisax.h"
112 #include "../../isdn/hisax/isdnl1.h"
113 #include "../../isdn/hisax/foreign.h"
114 #endif
115
116 #define MAX_DRIVERS 1
117
118 static struct sparcaudio_driver drivers[MAX_DRIVERS];
119 static int num_drivers;
120
121 /* Each amd7930 chip has two bi-directional B channels and a D
122  * channel available to the uproc.  This structure handles all
123  * the buffering needed to transmit and receive via a single channel.
124  */
125
126 #define CHANNEL_AVAILABLE       0x00
127 #define CHANNEL_INUSE_AUDIO_IN  0x01
128 #define CHANNEL_INUSE_AUDIO_OUT 0x02
129 #define CHANNEL_INUSE_ISDN_B1   0x04
130 #define CHANNEL_INUSE_ISDN_B2   0x08
131 #define CHANNEL_INUSE           0xff
132
133 struct amd7930_channel {
134         /* Channel status */
135         u8 channel_status;
136
137         /* Current buffer that the driver is playing on channel */
138         volatile __u8 * output_ptr;
139         volatile u32 output_count;
140         u8 xmit_idle_char;
141
142         /* Callback routine (and argument) when output is done on */
143         void (*output_callback)(void *, unsigned char);
144         void * output_callback_arg;
145
146         /* Current buffer that the driver is recording on channel */
147         volatile __u8 * input_ptr;
148         volatile u32 input_count;
149         volatile u32 input_limit;
150
151         /* Callback routine (and argument) when input is done on */
152         void (*input_callback)(void *, unsigned char, unsigned long);
153         void * input_callback_arg;
154
155         int input_format;
156         int output_format;
157 };
158
159 /* Private information we store for each amd7930 chip. */
160 struct amd7930_info {
161         struct amd7930_channel D;
162         struct amd7930_channel Bb;
163         struct amd7930_channel Bc;
164
165         /* Pointers to which B channels are being used for what
166          * These three fields (Baudio, Bisdn[0], and Bisdn[1]) will either
167          * be NULL or point to one of the Bb/Bc structures above.
168          */
169         struct amd7930_channel *Baudio;
170         struct amd7930_channel *Bisdn[2];
171
172         /* Device registers information. */
173         unsigned long regs;
174         unsigned long regs_size;
175         struct amd7930_map map;
176
177         /* Volume information. */
178         int pgain, rgain, mgain;
179
180         /* Device interrupt information. */
181         int irq;
182         volatile int ints_on;
183
184         /* Format type */
185         int format_type;
186
187         /* Someone to signal when the ISDN LIU state changes */
188         int liu_state;
189         void (*liu_callback)(void *);
190         void *liu_callback_arg;
191 };
192
193 /* Output a 16-bit quantity in the order that the amd7930 expects. */
194 static __inline__ void amd7930_out16(unsigned long regs, u16 val)
195 {
196         sbus_writeb(val & 0xff, regs + DR);
197         sbus_writeb(val >> 8, regs + DR);
198 }
199
200 /* gx, gr & stg gains.  this table must contain 256 elements with
201  * the 0th being "infinity" (the magic value 9008).  The remaining
202  * elements match sun's gain curve (but with higher resolution):
203  * -18 to 0dB in .16dB steps then 0 to 12dB in .08dB steps.
204  */
205 static __const__ __u16 gx_coeff[256] = {
206         0x9008, 0x8b7c, 0x8b51, 0x8b45, 0x8b42, 0x8b3b, 0x8b36, 0x8b33,
207         0x8b32, 0x8b2a, 0x8b2b, 0x8b2c, 0x8b25, 0x8b23, 0x8b22, 0x8b22,
208         0x9122, 0x8b1a, 0x8aa3, 0x8aa3, 0x8b1c, 0x8aa6, 0x912d, 0x912b,
209         0x8aab, 0x8b12, 0x8aaa, 0x8ab2, 0x9132, 0x8ab4, 0x913c, 0x8abb,
210         0x9142, 0x9144, 0x9151, 0x8ad5, 0x8aeb, 0x8a79, 0x8a5a, 0x8a4a,
211         0x8b03, 0x91c2, 0x91bb, 0x8a3f, 0x8a33, 0x91b2, 0x9212, 0x9213,
212         0x8a2c, 0x921d, 0x8a23, 0x921a, 0x9222, 0x9223, 0x922d, 0x9231,
213         0x9234, 0x9242, 0x925b, 0x92dd, 0x92c1, 0x92b3, 0x92ab, 0x92a4,
214         0x92a2, 0x932b, 0x9341, 0x93d3, 0x93b2, 0x93a2, 0x943c, 0x94b2,
215         0x953a, 0x9653, 0x9782, 0x9e21, 0x9d23, 0x9cd2, 0x9c23, 0x9baa,
216         0x9bde, 0x9b33, 0x9b22, 0x9b1d, 0x9ab2, 0xa142, 0xa1e5, 0x9a3b,
217         0xa213, 0xa1a2, 0xa231, 0xa2eb, 0xa313, 0xa334, 0xa421, 0xa54b,
218         0xada4, 0xac23, 0xab3b, 0xaaab, 0xaa5c, 0xb1a3, 0xb2ca, 0xb3bd,
219         0xbe24, 0xbb2b, 0xba33, 0xc32b, 0xcb5a, 0xd2a2, 0xe31d, 0x0808,
220         0x72ba, 0x62c2, 0x5c32, 0x52db, 0x513e, 0x4cce, 0x43b2, 0x4243,
221         0x41b4, 0x3b12, 0x3bc3, 0x3df2, 0x34bd, 0x3334, 0x32c2, 0x3224,
222         0x31aa, 0x2a7b, 0x2aaa, 0x2b23, 0x2bba, 0x2c42, 0x2e23, 0x25bb,
223         0x242b, 0x240f, 0x231a, 0x22bb, 0x2241, 0x2223, 0x221f, 0x1a33,
224         0x1a4a, 0x1acd, 0x2132, 0x1b1b, 0x1b2c, 0x1b62, 0x1c12, 0x1c32,
225         0x1d1b, 0x1e71, 0x16b1, 0x1522, 0x1434, 0x1412, 0x1352, 0x1323,
226         0x1315, 0x12bc, 0x127a, 0x1235, 0x1226, 0x11a2, 0x1216, 0x0a2a,
227         0x11bc, 0x11d1, 0x1163, 0x0ac2, 0x0ab2, 0x0aab, 0x0b1b, 0x0b23,
228         0x0b33, 0x0c0f, 0x0bb3, 0x0c1b, 0x0c3e, 0x0cb1, 0x0d4c, 0x0ec1,
229         0x079a, 0x0614, 0x0521, 0x047c, 0x0422, 0x03b1, 0x03e3, 0x0333,
230         0x0322, 0x031c, 0x02aa, 0x02ba, 0x02f2, 0x0242, 0x0232, 0x0227,
231         0x0222, 0x021b, 0x01ad, 0x0212, 0x01b2, 0x01bb, 0x01cb, 0x01f6,
232         0x0152, 0x013a, 0x0133, 0x0131, 0x012c, 0x0123, 0x0122, 0x00a2,
233         0x011b, 0x011e, 0x0114, 0x00b1, 0x00aa, 0x00b3, 0x00bd, 0x00ba,
234         0x00c5, 0x00d3, 0x00f3, 0x0062, 0x0051, 0x0042, 0x003b, 0x0033,
235         0x0032, 0x002a, 0x002c, 0x0025, 0x0023, 0x0022, 0x001a, 0x0021,
236         0x001b, 0x001b, 0x001d, 0x0015, 0x0013, 0x0013, 0x0012, 0x0012,
237         0x000a, 0x000a, 0x0011, 0x0011, 0x000b, 0x000b, 0x000c, 0x000e,
238 };
239
240 static __const__ __u16 ger_coeff[] = {
241         0x431f, /* 5. dB */
242         0x331f, /* 5.5 dB */
243         0x40dd, /* 6. dB */
244         0x11dd, /* 6.5 dB */
245         0x440f, /* 7. dB */
246         0x411f, /* 7.5 dB */
247         0x311f, /* 8. dB */
248         0x5520, /* 8.5 dB */
249         0x10dd, /* 9. dB */
250         0x4211, /* 9.5 dB */
251         0x410f, /* 10. dB */
252         0x111f, /* 10.5 dB */
253         0x600b, /* 11. dB */
254         0x00dd, /* 11.5 dB */
255         0x4210, /* 12. dB */
256         0x110f, /* 13. dB */
257         0x7200, /* 14. dB */
258         0x2110, /* 15. dB */
259         0x2200, /* 15.9 dB */
260         0x000b, /* 16.9 dB */
261         0x000f  /* 18. dB */
262 };
263 #define NR_GER_COEFFS (sizeof(ger_coeff) / sizeof(ger_coeff[0]))
264
265 /* Enable amd7930 interrupts atomically. */
266 static void amd7930_enable_ints(struct amd7930_info *info)
267 {
268         unsigned long flags;
269
270         save_and_cli(flags);
271         if (!info->ints_on) {
272                 sbus_writeb(AMR_INIT, info->regs + CR);
273                 sbus_writeb(AM_INIT_ACTIVE, info->regs + DR);
274                 info->ints_on = 1;
275         }
276         restore_flags(flags);
277 }
278
279 /* Disable amd7930 interrupts atomically. */
280 static __inline__ void amd7930_disable_ints(struct amd7930_info *info)
281 {
282         unsigned long flags;
283
284         save_and_cli(flags);
285         if (info->ints_on) {
286                 sbus_writeb(AMR_INIT, info->regs + CR);
287                 sbus_writeb(AM_INIT_ACTIVE | AM_INIT_DISABLE_INTS,
288                             info->regs + DR);
289                 info->ints_on = 0;
290         }
291         restore_flags(flags);
292
293 }  
294
295 /* Idle amd7930 (no interrupts, no audio, no data) */
296 static __inline__ void amd7930_idle(struct amd7930_info *info)
297 {
298         unsigned long flags;
299
300         save_and_cli(flags);
301         if (info->ints_on) {
302                 sbus_writeb(AMR_INIT, info->regs + CR);
303                 sbus_writeb(0, info->regs + DR);
304                 info->ints_on = 0;
305         }
306         restore_flags(flags);
307 }  
308
309 /* Commit the local copy of the MAP registers to the amd7930. */
310 static void amd7930_write_map(struct sparcaudio_driver *drv)
311 {
312         struct amd7930_info *info = (struct amd7930_info *) drv->private;
313         unsigned long        regs = info->regs;
314         struct amd7930_map  *map  = &info->map;
315         unsigned long flags;
316
317         save_and_cli(flags);
318
319         sbus_writeb(AMR_MAP_GX, regs + CR);
320         amd7930_out16(regs, map->gx);
321
322         sbus_writeb(AMR_MAP_GR, regs + CR);
323         amd7930_out16(regs, map->gr);
324
325         sbus_writeb(AMR_MAP_STGR, regs + CR);
326         amd7930_out16(regs, map->stgr);
327
328         sbus_writeb(AMR_MAP_GER, regs + CR);
329         amd7930_out16(regs, map->ger);
330
331         sbus_writeb(AMR_MAP_MMR1, regs + CR);
332         sbus_writeb(map->mmr1, regs + DR);
333
334         sbus_writeb(AMR_MAP_MMR2, regs + CR);
335         sbus_writeb(map->mmr2, regs + DR);
336
337         restore_flags(flags);
338 }
339
340 /* Update the MAP registers with new settings. */
341 static void amd7930_update_map(struct sparcaudio_driver *drv)
342 {
343         struct amd7930_info *info = (struct amd7930_info *) drv->private;
344         struct amd7930_map  *map  = &info->map;
345         int level;
346
347         map->gx = gx_coeff[info->rgain];
348         map->stgr = gx_coeff[info->mgain];
349
350         level = (info->pgain * (256 + NR_GER_COEFFS)) >> 8;
351         if (level >= 256) {
352                 map->ger = ger_coeff[level - 256];
353                 map->gr = gx_coeff[255];
354         } else {
355                 map->ger = ger_coeff[0];
356                 map->gr = gx_coeff[level];
357         }
358
359         amd7930_write_map(drv);
360 }
361
362 /* Bit of a hack here - if the HISAX ISDN driver has got INTSTAT debugging
363  * turned on, we send debugging characters to the ISDN driver:
364  *
365  *   i# - Interrupt received - number from 0 to 7 is low three bits of IR
366  *   >  - Loaded a single char into the Dchan xmit FIFO
367  *   +  - Finished loading an xmit packet into the Dchan xmit FIFO
368  *   <  - Read a single char from the Dchan recv FIFO
369  *   !  - Finished reading a packet from the Dchan recv FIFO
370  *
371  * This code needs to be removed if anything other than HISAX uses the ISDN
372  * driver, since D.output_callback_arg is assumed to be a certain struct ptr
373  */
374
375 #ifdef L2FRAME_DEBUG
376
377 inline void debug_info(struct amd7930_info *info, char c)
378 {
379         struct IsdnCardState *cs;
380
381         if (!info || !info->D.output_callback_arg)
382                 return;
383
384         cs = (struct IsdnCardState *) info->D.output_callback_arg;
385
386         if (!cs || !cs->status_write)
387                 return;
388
389         if (cs->debug & L1_DEB_INTSTAT) {
390                 *(cs->status_write++) = c;
391                 if (cs->status_write > cs->status_end)
392                         cs->status_write = cs->status_buf;
393         }
394 }
395
396 #else
397
398 #define debug_info(info,c)
399
400 #endif
401
402 static void fill_D_xmit_fifo(struct amd7930_info *info)
403 {
404         /* Send next byte(s) of outgoing data. */
405         while (info->D.output_ptr && info->D.output_count > 0 &&
406                (sbus_readb(info->regs + DSR2) & AMR_DSR2_TBE)) {
407                 u8 byte = *(info->D.output_ptr);
408
409                 /* Send the next byte and advance buffer pointer. */
410                 sbus_writeb(byte, info->regs + DCTB);
411                 info->D.output_ptr++;
412                 info->D.output_count--;
413
414                 debug_info(info, '>');
415         }
416 }
417
418 static void transceive_Dchannel(struct amd7930_info *info)
419 {
420         __u8 dummy;
421
422 #define D_XMIT_ERRORS (AMR_DER_COLLISION | AMR_DER_UNRN)
423 #define D_RECV_ERRORS (AMR_DER_RABRT | AMR_DER_RFRAME | AMR_DER_FCS | \
424                         AMR_DER_OVFL | AMR_DER_UNFL | AMR_DER_OVRN)
425
426         /* Transmit if we can */
427         fill_D_xmit_fifo(info);
428
429         /* Done with the xmit buffer? Notify the midlevel driver. */
430         if (info->D.output_ptr != NULL && info->D.output_count == 0) {
431                 info->D.output_ptr = NULL;
432                 info->D.output_count = 0;
433                 debug_info(info, '+');
434                 if (info->D.output_callback)
435                         (*info->D.output_callback)
436                                 (info->D.output_callback_arg,
437                                  sbus_readb(info->regs + DER));
438                                  /* sbus_readb(info->regs + DER) & D_XMIT_ERRORS); */
439         }
440
441         /* Read the next byte(s) of incoming data. */
442
443         while (sbus_readb(info->regs + DSR2) & AMR_DSR2_RBA) {
444                 if (info->D.input_ptr &&
445                     (info->D.input_count < info->D.input_limit)) {
446                         /* Get the next byte and advance buffer pointer. */
447                         *(info->D.input_ptr) = sbus_readb(info->regs + DCRB);
448                         info->D.input_ptr++;
449                         info->D.input_count++;
450                 } else {
451                         /* Overflow - should be detected by chip via RBLR
452                          * so we'll just consume data until we see LBRP
453                          */
454                         dummy = sbus_readb(info->regs + DCRB);
455                 }
456
457                 debug_info(info, '<');
458
459                 if (sbus_readb(info->regs + DSR2) & AMR_DSR2_LBRP) {
460                         __u8 der;
461
462                         /* End of recv packet? Notify the midlevel driver. */
463                         debug_info(info, '!');
464                         info->D.input_ptr = NULL;
465                         der = sbus_readb(info->regs + DER) & D_RECV_ERRORS;
466
467                         /* Read receive byte count - advances FIFOs */
468                         sbus_writeb(AMR_DLC_DRCR, info->regs + CR);
469                         dummy = sbus_readb(info->regs + DR);
470                         dummy = sbus_readb(info->regs + DR);
471
472                         if (info->D.input_callback)
473                                 (*info->D.input_callback)
474                                         (info->D.input_callback_arg, der,
475                                          info->D.input_count);
476                 }
477
478         }
479 }
480
481 long amd7930_xmit_idles = 0;
482
483 static void transceive_Bchannel(struct amd7930_channel *channel,
484                                 unsigned long reg)
485 {
486         /* Send the next byte of outgoing data. */
487         if (channel->output_ptr && channel->output_count > 0) {
488                 u8 byte;
489
490                 /* Send the next byte and advance buffer pointer. */
491                 switch(channel->output_format) {
492                 case AUDIO_ENCODING_ULAW:
493                 case AUDIO_ENCODING_ALAW:
494                         byte = *(channel->output_ptr);
495                         sbus_writeb(byte, reg);
496                         break;
497                 case AUDIO_ENCODING_LINEAR8:
498                         byte = bilinear2mulaw(*(channel->output_ptr));
499                         sbus_writeb(byte, reg);
500                         break;
501                 case AUDIO_ENCODING_LINEAR:
502                         if (channel->output_count >= 2) {
503                                 u16 val = channel->output_ptr[0] << 8;
504
505                                 val |= channel->output_ptr[1];
506                                 byte = linear2mulaw(val);
507                                 sbus_writeb(byte, reg);
508                                 channel->output_ptr++;
509                                 channel->output_count--;
510                         };
511                 };
512                 channel->output_ptr++;
513                 channel->output_count--;
514
515
516                 /* Done with the buffer? Notify the midlevel driver. */
517                 if (channel->output_count == 0) {
518                         channel->output_ptr = NULL;
519                         channel->output_count = 0;
520                         if (channel->output_callback)
521                                 (*channel->output_callback)
522                                         (channel->output_callback_arg,1);
523                 }
524         } else {
525                 sbus_writeb(channel->xmit_idle_char, reg);
526                 amd7930_xmit_idles++;
527         }
528
529         /* Read the next byte of incoming data. */
530         if (channel->input_ptr && channel->input_count > 0) {
531                 /* Get the next byte and advance buffer pointer. */
532                 switch(channel->input_format) {
533                 case AUDIO_ENCODING_ULAW:
534                 case AUDIO_ENCODING_ALAW:
535                         *(channel->input_ptr) = sbus_readb(reg);
536                         break;
537                 case AUDIO_ENCODING_LINEAR8:
538                         *(channel->input_ptr) = mulaw2bilinear(sbus_readb(reg));
539                         break;
540                 case AUDIO_ENCODING_LINEAR:
541                         if (channel->input_count >= 2) {
542                                 u16 val = mulaw2linear(sbus_readb(reg));
543                                 channel->input_ptr[0] = val >> 8;
544                                 channel->input_ptr[1] = val & 0xff;
545                                 channel->input_ptr++;
546                                 channel->input_count--;
547                         } else {
548                                 *(channel->input_ptr) = 0;
549                         }
550                 };
551                 channel->input_ptr++;
552                 channel->input_count--;
553
554                 /* Done with the buffer? Notify the midlevel driver. */
555                 if (channel->input_count == 0) {
556                         channel->input_ptr = NULL;
557                         channel->input_count = 0;
558                         if (channel->input_callback)
559                                 (*channel->input_callback)
560                                         (channel->input_callback_arg, 1, 0);
561                 }
562         }
563 }
564
565 /* Interrupt handler (The chip takes only one byte per interrupt. Grrr!) */
566 static void amd7930_interrupt(int irq, void *dev_id, struct pt_regs *intr_regs)
567 {
568         struct sparcaudio_driver *drv = (struct sparcaudio_driver *) dev_id;
569         struct amd7930_info *info = (struct amd7930_info *) drv->private;
570         unsigned long regs = info->regs;
571         __u8 ir;
572
573         /* Clear the interrupt. */
574         ir = sbus_readb(regs + IR);
575
576         if (ir & AMR_IR_BBUF) {
577                 if (info->Bb.channel_status == CHANNEL_INUSE)
578                         transceive_Bchannel(&info->Bb, info->regs + BBTB);
579                 if (info->Bc.channel_status == CHANNEL_INUSE)
580                         transceive_Bchannel(&info->Bc, info->regs + BCTB);
581         }
582
583         if (ir & (AMR_IR_DRTHRSH | AMR_IR_DTTHRSH | AMR_IR_DSRI)) {
584                 debug_info(info, 'i');
585                 debug_info(info, '0' + (ir&7));
586                 transceive_Dchannel(info);
587         }
588
589         if (ir & AMR_IR_LSRI) {
590                 __u8 lsr;
591
592                 sbus_writeb(AMR_LIU_LSR, regs + CR);
593                 lsr = sbus_readb(regs + DR);
594
595                 info->liu_state = (lsr & 0x7) + 2;
596
597                 if (info->liu_callback)
598                         (*info->liu_callback)(info->liu_callback_arg);
599         }
600 }
601
602 static int amd7930_open(struct inode * inode, struct file * file,
603                         struct sparcaudio_driver *drv)
604 {
605         struct amd7930_info *info = (struct amd7930_info *) drv->private;
606
607         switch(MINOR(inode->i_rdev) & 0xf) {
608         case SPARCAUDIO_AUDIO_MINOR:
609                 info->format_type = AUDIO_ENCODING_ULAW;
610                 break;
611         case SPARCAUDIO_DSP_MINOR:
612                 info->format_type = AUDIO_ENCODING_LINEAR8;
613                 break;
614         case SPARCAUDIO_DSP16_MINOR:
615                 info->format_type = AUDIO_ENCODING_LINEAR;
616                 break;
617         };
618
619         MOD_INC_USE_COUNT;
620         return 0;
621 }
622
623 static void amd7930_release(struct inode * inode, struct file * file,
624                             struct sparcaudio_driver *drv)
625 {
626         /* amd7930_disable_ints(drv->private); */
627         MOD_DEC_USE_COUNT;
628 }
629
630 static void request_Baudio(struct amd7930_info *info)
631 {
632         if (info->Bb.channel_status == CHANNEL_AVAILABLE) {
633                 info->Bb.channel_status = CHANNEL_INUSE;
634                 info->Baudio = &info->Bb;
635
636                 /* Multiplexor map - audio (Ba) to Bb */
637                 sbus_writeb(AMR_MUX_MCR1, info->regs + CR);
638                 sbus_writeb(AM_MUX_CHANNEL_Ba | (AM_MUX_CHANNEL_Bb << 4),
639                             info->regs + DR);
640
641                 /* Enable B channel interrupts */
642                 sbus_writeb(AMR_MUX_MCR4, info->regs + CR);
643                 sbus_writeb(AM_MUX_MCR4_ENABLE_INTS, info->regs + DR);
644         } else if (info->Bc.channel_status == CHANNEL_AVAILABLE) {
645                 info->Bc.channel_status = CHANNEL_INUSE;
646                 info->Baudio = &info->Bc;
647
648                 /* Multiplexor map - audio (Ba) to Bc */
649                 sbus_writeb(AMR_MUX_MCR1, info->regs + CR);
650                 sbus_writeb(AM_MUX_CHANNEL_Ba | (AM_MUX_CHANNEL_Bc << 4),
651                             info->regs + DR);
652
653                 /* Enable B channel interrupts */
654                 sbus_writeb(AMR_MUX_MCR4, info->regs + CR);
655                 sbus_writeb(AM_MUX_MCR4_ENABLE_INTS, info->regs + DR);
656         }
657 }
658
659 static void release_Baudio(struct amd7930_info *info)
660 {
661         if (info->Baudio) {
662                 info->Baudio->channel_status = CHANNEL_AVAILABLE;
663                 sbus_writeb(AMR_MUX_MCR1, info->regs + CR);
664                 sbus_writeb(0, info->regs + DR);
665                 info->Baudio = NULL;
666
667                 if (info->Bb.channel_status == CHANNEL_AVAILABLE &&
668                     info->Bc.channel_status == CHANNEL_AVAILABLE) {
669                         /* Disable B channel interrupts */
670                         sbus_writeb(AMR_MUX_MCR4, info->regs + CR);
671                         sbus_writeb(0, info->regs + DR);
672                 }
673         }
674 }
675
676 static void amd7930_start_output(struct sparcaudio_driver *drv,
677                                  __u8 * buffer, unsigned long count)
678 {
679         struct amd7930_info *info = (struct amd7930_info *) drv->private;
680
681         if (! info->Baudio)
682                 request_Baudio(info);
683
684         if (info->Baudio) {
685                 info->Baudio->output_ptr = buffer;
686                 info->Baudio->output_count = count;
687                 info->Baudio->output_format = info->format_type;
688                 info->Baudio->output_callback = (void *) &sparcaudio_output_done;
689                 info->Baudio->output_callback_arg = (void *) drv;
690                 info->Baudio->xmit_idle_char = 0;
691         }
692 }
693
694 static void amd7930_stop_output(struct sparcaudio_driver *drv)
695 {
696         struct amd7930_info *info = (struct amd7930_info *) drv->private;
697
698         if (info->Baudio) {
699                 info->Baudio->output_ptr = NULL;
700                 info->Baudio->output_count = 0;
701                 if (! info->Baudio->input_ptr)
702                         release_Baudio(info);
703         }
704 }
705
706 static void amd7930_start_input(struct sparcaudio_driver *drv,
707                                 __u8 * buffer, unsigned long count)
708 {
709         struct amd7930_info *info = (struct amd7930_info *) drv->private;
710
711         if (! info->Baudio)
712                 request_Baudio(info);
713
714         if (info->Baudio) {
715                 info->Baudio->input_ptr = buffer;
716                 info->Baudio->input_count = count;
717                 info->Baudio->input_format = info->format_type;
718                 info->Baudio->input_callback = (void *) &sparcaudio_input_done;
719                 info->Baudio->input_callback_arg = (void *) drv;
720         }
721 }
722
723 static void amd7930_stop_input(struct sparcaudio_driver *drv)
724 {
725         struct amd7930_info *info = (struct amd7930_info *) drv->private;
726
727         if (info->Baudio) {
728                 info->Baudio->input_ptr = NULL;
729                 info->Baudio->input_count = 0;
730                 if (! info->Baudio->output_ptr)
731                         release_Baudio(info);
732         }
733
734 }
735
736 static void amd7930_sunaudio_getdev(struct sparcaudio_driver *drv,
737                                  audio_device_t * audinfo)
738 {
739         strncpy(audinfo->name, "SUNW,am79c30", sizeof(audinfo->name) - 1);
740         strncpy(audinfo->version, "a", sizeof(audinfo->version) - 1);
741         strncpy(audinfo->config, "onboard1", sizeof(audinfo->config) - 1);
742 }
743
744 static int amd7930_sunaudio_getdev_sunos(struct sparcaudio_driver *drv)
745 {
746         return AUDIO_DEV_AMD;
747 }
748
749 static int amd7930_get_formats(struct sparcaudio_driver *drv)
750 {
751       return (AFMT_MU_LAW | AFMT_A_LAW | AFMT_U8 | AFMT_S16_BE);
752 }
753
754 static int amd7930_get_output_ports(struct sparcaudio_driver *drv)
755 {
756       return (AUDIO_SPEAKER | AUDIO_HEADPHONE);
757 }
758
759 static int amd7930_get_input_ports(struct sparcaudio_driver *drv)
760 {
761       return (AUDIO_MICROPHONE);
762 }
763
764 static int amd7930_set_output_volume(struct sparcaudio_driver *drv, int vol)
765 {
766         struct amd7930_info *info = (struct amd7930_info *) drv->private;
767
768         info->pgain = vol;
769         amd7930_update_map(drv);
770         return 0;
771 }
772
773 static int amd7930_get_output_volume(struct sparcaudio_driver *drv)
774 {
775         struct amd7930_info *info = (struct amd7930_info *) drv->private;
776
777         return info->pgain;
778 }
779
780 static int amd7930_set_input_volume(struct sparcaudio_driver *drv, int vol)
781 {
782         struct amd7930_info *info = (struct amd7930_info *) drv->private;
783
784         info->rgain = vol;
785         amd7930_update_map(drv);
786         return 0;
787 }
788
789 static int amd7930_get_input_volume(struct sparcaudio_driver *drv)
790 {
791         struct amd7930_info *info = (struct amd7930_info *) drv->private;
792
793         return info->rgain;
794 }
795
796 static int amd7930_set_monitor_volume(struct sparcaudio_driver *drv, int vol)
797 {
798         struct amd7930_info *info = (struct amd7930_info *) drv->private;
799
800         info->mgain = vol;
801         amd7930_update_map(drv);
802         return 0;
803 }
804
805 static int amd7930_get_monitor_volume(struct sparcaudio_driver *drv)
806 {
807       struct amd7930_info *info = (struct amd7930_info *) drv->private;
808
809       return info->mgain;
810 }
811
812 /* Cheats. The amd has the minimum capabilities we support */
813 static int amd7930_get_output_balance(struct sparcaudio_driver *drv)
814 {
815         return AUDIO_MID_BALANCE;
816 }
817
818 static int amd7930_get_input_balance(struct sparcaudio_driver *drv)
819 {
820         return AUDIO_MID_BALANCE;
821 }
822
823 static int amd7930_get_output_channels(struct sparcaudio_driver *drv)
824 {
825         return AUDIO_MIN_PLAY_CHANNELS;
826 }
827
828 static int amd7930_set_output_channels(struct sparcaudio_driver *drv, 
829                                        int value)
830 {
831   return (value == AUDIO_MIN_PLAY_CHANNELS) ? 0 : -EINVAL;
832 }
833
834 static int amd7930_get_input_channels(struct sparcaudio_driver *drv)
835 {
836         return AUDIO_MIN_REC_CHANNELS;
837 }
838
839 static int 
840 amd7930_set_input_channels(struct sparcaudio_driver *drv, int value)
841 {
842         return (value == AUDIO_MIN_REC_CHANNELS) ? 0 : -EINVAL;
843 }
844
845 static int amd7930_get_output_precision(struct sparcaudio_driver *drv)
846 {
847         return AUDIO_MIN_PLAY_PRECISION;
848 }
849
850 static int 
851 amd7930_set_output_precision(struct sparcaudio_driver *drv, int value)
852 {
853         return (value == AUDIO_MIN_PLAY_PRECISION) ? 0 : -EINVAL;
854 }
855
856 static int amd7930_get_input_precision(struct sparcaudio_driver *drv)
857 {
858         return AUDIO_MIN_REC_PRECISION;
859 }
860
861 static int 
862 amd7930_set_input_precision(struct sparcaudio_driver *drv, int value)
863 {
864         return (value == AUDIO_MIN_REC_PRECISION) ? 0 : -EINVAL;
865 }
866
867 static int amd7930_get_output_port(struct sparcaudio_driver *drv)
868 {
869         struct amd7930_info *info = (struct amd7930_info *) drv->private;
870
871         if (info->map.mmr2 & AM_MAP_MMR2_LS)
872                 return AUDIO_SPEAKER; 
873
874         return AUDIO_HEADPHONE;
875 }
876
877 static int amd7930_set_output_port(struct sparcaudio_driver *drv, int value)
878 {
879         struct amd7930_info *info = (struct amd7930_info *) drv->private;
880
881         switch (value) {
882         case AUDIO_HEADPHONE:
883                 info->map.mmr2 &= ~AM_MAP_MMR2_LS;
884                 break;
885         case AUDIO_SPEAKER:
886                 info->map.mmr2 |= AM_MAP_MMR2_LS;
887                 break;
888         default:
889                 return -EINVAL;
890         };
891
892         amd7930_update_map(drv);
893         return 0;
894 }
895
896 /* Only a microphone here, so no troubles */
897 static int amd7930_get_input_port(struct sparcaudio_driver *drv)
898 {
899         return AUDIO_MICROPHONE;
900 }
901
902 static int amd7930_get_encoding(struct sparcaudio_driver *drv)
903 {
904         struct amd7930_info *info = (struct amd7930_info *) drv->private;
905
906         if ((info->map.mmr1 & AM_MAP_MMR1_ALAW) && 
907             (info->format_type == AUDIO_ENCODING_ALAW))
908                 return AUDIO_ENCODING_ALAW;
909
910         return info->format_type;
911 }
912
913 static int 
914 amd7930_set_encoding(struct sparcaudio_driver *drv, int value)
915 {
916         struct amd7930_info *info = (struct amd7930_info *) drv->private;
917
918         switch (value) {
919         case AUDIO_ENCODING_ALAW:
920                 info->map.mmr1 |= AM_MAP_MMR1_ALAW;
921                 break;
922         case AUDIO_ENCODING_LINEAR8:
923         case AUDIO_ENCODING_LINEAR:
924         case AUDIO_ENCODING_ULAW:
925                 info->map.mmr1 &= ~AM_MAP_MMR1_ALAW;
926                 break;
927         default:
928                 return -EINVAL;
929         };
930
931         info->format_type = value;
932
933         amd7930_update_map(drv);
934         return 0;
935 }
936
937 /* This is what you get. Take it or leave it */
938 static int amd7930_get_output_rate(struct sparcaudio_driver *drv)
939 {
940         return AMD7930_RATE;
941 }
942
943 static int 
944 amd7930_set_output_rate(struct sparcaudio_driver *drv, int value)
945 {
946         return (value == AMD7930_RATE) ? 0 : -EINVAL;
947 }
948
949 static int amd7930_get_input_rate(struct sparcaudio_driver *drv)
950 {
951         return AMD7930_RATE;
952 }
953
954 static int
955 amd7930_set_input_rate(struct sparcaudio_driver *drv, int value)
956 {
957         return (value == AMD7930_RATE) ? 0 : -EINVAL;
958 }
959
960 static int amd7930_get_output_muted(struct sparcaudio_driver *drv)
961 {
962       return 0;
963 }
964
965 static void amd7930_loopback(struct sparcaudio_driver *drv, unsigned int value)
966 {
967         struct amd7930_info *info = (struct amd7930_info *) drv->private;
968
969         if (value)
970                 info->map.mmr1 |= AM_MAP_MMR1_LOOPBACK;
971         else
972                 info->map.mmr1 &= ~AM_MAP_MMR1_LOOPBACK;
973         amd7930_update_map(drv);
974 }
975
976 static int amd7930_ioctl(struct inode * inode, struct file * file,
977                          unsigned int cmd, unsigned long arg, 
978                          struct sparcaudio_driver *drv)
979 {
980         int retval = 0;
981   
982         switch (cmd) {
983         case AUDIO_DIAG_LOOPBACK:
984                 amd7930_loopback(drv, (unsigned int)arg);
985                 break;
986         default:
987                 retval = -EINVAL;
988         };
989
990         return retval;
991 }
992
993
994 /*
995  *       ISDN operations
996  *
997  * Many of these routines take an "int dev" argument, which is simply
998  * an index into the drivers[] array.  Currently, we only support a
999  * single AMD 7930 chip, so the value should always be 0.  B channel
1000  * operations require an "int chan", which should be 0 for channel B1
1001  * and 1 for channel B2
1002  *
1003  * int amd7930_get_irqnum(int dev)
1004  *
1005  *   returns the interrupt number being used by the chip.  ISDN4linux
1006  *   uses this number to watch the interrupt during initialization and
1007  *   make sure something is happening.
1008  *
1009  * int amd7930_get_liu_state(int dev)
1010  *
1011  *   returns the current state of the ISDN Line Interface Unit (LIU)
1012  *   as a number between 2 (state F2) and 7 (state F7).  0 may also be
1013  *   returned if the chip doesn't exist or the LIU hasn't been
1014  *   activated.  The meanings of the states are defined in I.430, ISDN
1015  *   BRI Physical Layer Interface.  The most important two states are
1016  *   F3 (shutdown) and F7 (syncronized).
1017  *
1018  * void amd7930_liu_init(int dev, void (*callback)(), void *callback_arg)
1019  *
1020  *   initializes the LIU and optionally registers a callback to be
1021  *   signaled upon a change of LIU state.  The callback will be called
1022  *   with a single opaque callback_arg Once the callback has been
1023  *   triggered, amd7930_get_liu_state can be used to determine the LIU
1024  *   current state.
1025  *
1026  * void amd7930_liu_activate(int dev, int priority)
1027  *
1028  *   requests LIU activation at a given D-channel priority.
1029  *   Successful activatation is achieved upon entering state F7, which
1030  *   will trigger any callback previously registered with
1031  *   amd7930_liu_init.
1032  *
1033  * void amd7930_liu_deactivate(int dev)
1034  *
1035  *   deactivates LIU.  Outstanding D and B channel transactions are
1036  *   terminated rudely and without callback notification.  LIU change
1037  *   of state callback will be triggered, however.
1038  *
1039  * void amd7930_dxmit(int dev, __u8 *buffer, unsigned int count,
1040  *               void (*callback)(void *, int), void *callback_arg)
1041  *
1042  *   transmits a packet - specified with buffer, count - over the D-channel
1043  *   interface.  Buffer should begin with the LAPD address field and
1044  *   end with the information field.  FCS and flag sequences should not
1045  *   be included, nor is bit-stuffing required - all these functions are
1046  *   performed by the chip.  The callback function will be called
1047  *   DURING THE TOP HALF OF AN INTERRUPT HANDLER and will be passed
1048  *   both the arbitrary callback_arg and an integer error indication:
1049  *
1050  *       0 - successful transmission; ready for next packet
1051  *   non-0 - error value from chip's DER (D-Channel Error Register):
1052  *       4 - collision detect
1053  *     128 - underrun; irq routine didn't service chip fast enough
1054  *
1055  *   The callback routine should defer any time-consuming operations
1056  *   to a bottom-half handler; however, amd7930_dxmit may be called
1057  *   from within the callback to request back-to-back transmission of
1058  *   a second packet (without repeating the priority/collision mechanism)
1059  *
1060  *   A comment about the "collision detect" error, which is signalled
1061  *   whenever the echoed D-channel data didn't match the transmitted
1062  *   data.  This is part of ISDN's normal multi-drop T-interface
1063  *   operation, indicating that another device has attempted simultaneous
1064  *   transmission, but can also result from line noise.  An immediate
1065  *   requeue via amd7930_dxmit is suggested, but repeated collision
1066  *   errors may indicate a more serious problem.
1067  *
1068  * void amd7930_drecv(int dev, __u8 *buffer, unsigned int size,
1069  *               void (*callback)(void *, int, unsigned int),
1070  *               void *callback_arg)
1071  *
1072  *   register a buffer - buffer, size - into which a D-channel packet
1073  *   can be received.  The callback function will be called DURING
1074  *   THE TOP HALF OF AN INTERRUPT HANDLER and will be passed an
1075  *   arbitrary callback_arg, an integer error indication and the length
1076  *   of the received packet, which will start with the address field,
1077  *   end with the information field, and not contain flag or FCS
1078  *   bytes.  Bit-stuffing will already have been corrected for.
1079  *   Possible values of second callback argument "error":
1080  *
1081  *       0 - successful reception
1082  *   non-0 - error value from chip's DER (D-Channel Error Register):
1083  *       1 - received packet abort
1084  *       2 - framing error; non-integer number of bytes received
1085  *       8 - FCS error; CRC sequence indicated corrupted data
1086  *      16 - overflow error; packet exceeded size of buffer
1087  *      32 - underflow error; packet smaller than required five bytes
1088  *      64 - overrun error; irq routine didn't service chip fast enough
1089  *
1090  * int amd7930_bopen(int dev, int chan, u_char xmit_idle_char)
1091  *
1092  *   This function should be called before any other operations on a B
1093  *   channel.  In addition to arranging for interrupt handling and
1094  *   channel multiplexing, it sets the xmit_idle_char which is
1095  *   transmitted on the interface when no data buffer is available.
1096  *   Suggested values are: 0 for ISDN audio; FF for HDLC mark idle; 7E
1097  *   for HDLC flag idle.  Returns 0 on a successful open; -1 on error,
1098  *   which is quite possible if audio and the other ISDN channel are
1099  *   already in use, since the Am7930 can only send two of the three
1100  *   channels to the processor
1101  *
1102  * void amd7930_bclose(int dev, int chan)
1103  *
1104  *   Shuts down a B channel when no longer in use.
1105  *
1106  * void amd7930_bxmit(int dev, int chan, __u8 *buffer, unsigned int count,
1107  *               void (*callback)(void *), void *callback_arg)
1108  *
1109  *   transmits a raw data block - specified with buffer, count - over
1110  *   the B channel interface specified by dev/chan.  The callback
1111  *   function will be called DURING THE TOP HALF OF AN INTERRUPT
1112  *   HANDLER and will be passed the arbitrary callback_arg
1113  *
1114  *   The callback routine should defer any time-consuming operations
1115  *   to a bottom-half handler; however, amd7930_bxmit may be called
1116  *   from within the callback to request back-to-back transmission of
1117  *   another data block
1118  *
1119  * void amd7930_brecv(int dev, int chan, __u8 *buffer, unsigned int size,
1120  *               void (*callback)(void *), void *callback_arg)
1121  *
1122  *   receive a raw data block - specified with buffer, size - over the
1123  *   B channel interface specified by dev/chan.  The callback function
1124  *   will be called DURING THE TOP HALF OF AN INTERRUPT HANDLER and
1125  *   will be passed the arbitrary callback_arg
1126  *
1127  *   The callback routine should defer any time-consuming operations
1128  *   to a bottom-half handler; however, amd7930_brecv may be called
1129  *   from within the callback to register another buffer and ensure
1130  *   continuous B channel reception without loss of data
1131  *
1132  */
1133
1134 #if defined (AMD79C30_ISDN)
1135 static int amd7930_get_irqnum(int dev)
1136 {
1137         struct amd7930_info *info;
1138
1139         if (dev > num_drivers)
1140                 return(0);
1141
1142         info = (struct amd7930_info *) drivers[dev].private;
1143
1144         return info->irq;
1145 }
1146
1147 static int amd7930_get_liu_state(int dev)
1148 {
1149         struct amd7930_info *info;
1150
1151         if (dev > num_drivers)
1152                 return(0);
1153
1154         info = (struct amd7930_info *) drivers[dev].private;
1155
1156         return info->liu_state;
1157 }
1158
1159 static void amd7930_liu_init(int dev, void (*callback)(), void *callback_arg)
1160 {
1161         struct amd7930_info *info;
1162         unsigned long flags;
1163
1164         if (dev > num_drivers)
1165                 return;
1166
1167         info = (struct amd7930_info *) drivers[dev].private;
1168
1169         save_and_cli(flags);
1170
1171         /* Set callback for LIU state change */
1172         info->liu_callback = callback;
1173         info->liu_callback_arg = callback_arg;
1174
1175         /* De-activate the ISDN Line Interface Unit (LIU) */
1176         sbus_writeb(AMR_LIU_LMR1, info->regs + CR);
1177         sbus_writeb(0, info->regs + DR);
1178
1179         /* Request interrupt when LIU changes state from/to F3/F7/F8 */
1180         sbus_writeb(AMR_LIU_LMR2, info->regs + CR);
1181         sbus_writeb(AM_LIU_LMR2_EN_F3_INT |
1182                     AM_LIU_LMR2_EN_F7_INT |
1183                     AM_LIU_LMR2_EN_F8_INT,
1184                     info->regs + DR);
1185
1186         /* amd7930_enable_ints(info); */
1187
1188         /* Activate the ISDN Line Interface Unit (LIU) */
1189         sbus_writeb(AMR_LIU_LMR1, info->regs + CR);
1190         sbus_writeb(AM_LIU_LMR1_LIU_ENABL, info->regs + DR);
1191
1192         restore_flags(flags);
1193 }
1194
1195 static void amd7930_liu_activate(int dev, int priority)
1196 {
1197         struct amd7930_info *info;
1198         unsigned long flags;
1199
1200         if (dev > num_drivers)
1201                 return;
1202
1203         info = (struct amd7930_info *) drivers[dev].private;
1204
1205         save_and_cli(flags);
1206
1207         /* Set D-channel access priority
1208          *
1209          * I.430 defines a priority mechanism based on counting 1s
1210          * in the echo channel before transmitting
1211          *
1212          * Priority 0 is eight 1s; priority 1 is ten 1s; etc
1213          */
1214         sbus_writeb(AMR_LIU_LPR, info->regs + CR);
1215         sbus_writeb(priority & 0x0f, info->regs + DR);
1216
1217         /* request LIU activation */
1218         sbus_writeb(AMR_LIU_LMR1, info->regs + CR);
1219         sbus_writeb(AM_LIU_LMR1_LIU_ENABL | AM_LIU_LMR1_REQ_ACTIV,
1220                     info->regs + DR);
1221
1222         restore_flags(flags);
1223 }
1224
1225 static void amd7930_liu_deactivate(int dev)
1226 {
1227         struct amd7930_info *info;
1228         unsigned long flags;
1229
1230         if (dev > num_drivers)
1231                 return;
1232
1233         info = (struct amd7930_info *) drivers[dev].private;
1234
1235         save_and_cli(flags);
1236
1237         /* deactivate LIU */
1238         sbus_writeb(AMR_LIU_LMR1, info->regs + CR);
1239         sbus_writeb(0, info->regs + DR);
1240
1241         restore_flags(flags);
1242 }
1243
1244 static void amd7930_dxmit(int dev, __u8 *buffer, unsigned int count,
1245                           void (*callback)(void *, int), void *callback_arg)
1246 {
1247         struct amd7930_info *info;
1248         unsigned long flags;
1249         __u8 dmr1;
1250
1251         if (dev > num_drivers)
1252                 return;
1253
1254         info = (struct amd7930_info *) drivers[dev].private;
1255
1256         save_and_cli(flags);
1257
1258         if (info->D.output_ptr) {
1259                 restore_flags(flags);
1260                 printk("amd7930_dxmit: transmitter in use\n");
1261                 return;
1262         }
1263
1264         info->D.output_ptr = buffer;
1265         info->D.output_count = count;
1266         info->D.output_callback = callback;
1267         info->D.output_callback_arg = callback_arg;
1268
1269         /* Enable D-channel Transmit Threshold interrupt; disable addressing */
1270         sbus_writeb(AMR_DLC_DMR1, info->regs + CR);
1271         dmr1 = sbus_readb(info->regs + DR);
1272         dmr1 |= AMR_DLC_DMR1_DTTHRSH_INT;
1273         dmr1 &= ~AMR_DLC_DMR1_EN_ADDRS;
1274         sbus_writeb(dmr1, info->regs + DR);
1275
1276         /* Begin xmit by setting D-channel Transmit Byte Count Reg (DTCR) */
1277         sbus_writeb(AMR_DLC_DTCR, info->regs + CR);
1278         sbus_writeb(count & 0xff, info->regs + DR);
1279         sbus_writeb((count >> 8) & 0xff, info->regs + DR);
1280
1281         /* Prime xmit FIFO */
1282         /* fill_D_xmit_fifo(info); */
1283         transceive_Dchannel(info);
1284
1285         restore_flags(flags);
1286 }
1287
1288 static void amd7930_drecv(int dev, __u8 *buffer, unsigned int size,
1289                           void (*callback)(void *, int, unsigned int),
1290                           void *callback_arg)
1291 {
1292         struct amd7930_info *info;
1293         unsigned long flags;
1294         __u8 dmr1;
1295
1296         if (dev > num_drivers)
1297                 return;
1298
1299         info = (struct amd7930_info *) drivers[dev].private;
1300
1301         save_and_cli(flags);
1302
1303         if (info->D.input_ptr) {
1304                 restore_flags(flags);
1305                 printk("amd7930_drecv: receiver already has buffer!\n");
1306                 return;
1307         }
1308
1309         info->D.input_ptr = buffer;
1310         info->D.input_count = 0;
1311         info->D.input_limit = size;
1312         info->D.input_callback = callback;
1313         info->D.input_callback_arg = callback_arg;
1314
1315         /* Enable D-channel Receive Threshold interrupt;
1316          * Enable D-channel End of Receive Packet interrupt;
1317          * Disable address recognition
1318          */
1319         sbus_writeb(AMR_DLC_DMR1, info->regs + CR);
1320         dmr1 = sbus_readb(info->regs + DR);
1321         dmr1 |= AMR_DLC_DMR1_DRTHRSH_INT | AMR_DLC_DMR1_EORP_INT;
1322         dmr1 &= ~AMR_DLC_DMR1_EN_ADDRS;
1323         sbus_writeb(dmr1, info->regs + DR);
1324
1325         /* Set D-channel Receive Byte Count Limit Register */
1326         sbus_writeb(AMR_DLC_DRCR, info->regs + CR);
1327         sbus_writeb(size & 0xff, info->regs + DR);
1328         sbus_writeb((size >> 8) & 0xff, info->regs + DR);
1329
1330         restore_flags(flags);
1331 }
1332
1333 static int amd7930_bopen(int dev, unsigned int chan, 
1334                          int mode, u_char xmit_idle_char)
1335 {
1336         struct amd7930_info *info;
1337         unsigned long flags;
1338         u8 tmp;
1339
1340         if (dev > num_drivers || chan<0 || chan>1)
1341                 return -1;
1342
1343         if (mode == L1_MODE_HDLC)
1344                 return -1;
1345  
1346         info = (struct amd7930_info *) drivers[dev].private;
1347
1348         save_and_cli(flags);
1349
1350         if (info->Bb.channel_status == CHANNEL_AVAILABLE) {
1351                 info->Bb.channel_status = CHANNEL_INUSE;
1352                 info->Bb.xmit_idle_char = xmit_idle_char;
1353                 info->Bisdn[chan] = &info->Bb;
1354
1355                 /* Multiplexor map - isdn (B1/2) to Bb */
1356                 sbus_writeb(AMR_MUX_MCR2 + chan, info->regs + CR);
1357                 sbus_writeb((AM_MUX_CHANNEL_B1 + chan) |
1358                             (AM_MUX_CHANNEL_Bb << 4),
1359                             info->regs + DR);
1360         } else if (info->Bc.channel_status == CHANNEL_AVAILABLE) {
1361                 info->Bc.channel_status = CHANNEL_INUSE;
1362                 info->Bc.xmit_idle_char = xmit_idle_char;
1363                 info->Bisdn[chan] = &info->Bc;
1364
1365                 /* Multiplexor map - isdn (B1/2) to Bc */
1366                 sbus_writeb(AMR_MUX_MCR2 + chan, info->regs + CR);
1367                 sbus_writeb((AM_MUX_CHANNEL_B1 + chan) |
1368                             (AM_MUX_CHANNEL_Bc << 4),
1369                             info->regs + DR);
1370         } else {
1371                 restore_flags(flags);
1372                 return (-1);
1373         }
1374
1375         /* Enable B channel transmit */
1376         sbus_writeb(AMR_LIU_LMR1, info->regs + CR);
1377         tmp = sbus_readb(info->regs + DR);
1378         tmp |= AM_LIU_LMR1_B1_ENABL + chan;
1379         sbus_writeb(tmp, info->regs + DR);
1380
1381         /* Enable B channel interrupts */
1382         sbus_writeb(AMR_MUX_MCR4, info->regs + CR);
1383         sbus_writeb(AM_MUX_MCR4_ENABLE_INTS |
1384                     AM_MUX_MCR4_REVERSE_Bb |
1385                     AM_MUX_MCR4_REVERSE_Bc,
1386                     info->regs + DR);
1387
1388         restore_flags(flags);
1389         return 0;
1390 }
1391
1392 static void amd7930_bclose(int dev, unsigned int chan)
1393 {
1394         struct amd7930_info *info;
1395         unsigned long flags;
1396
1397         if (dev > num_drivers || chan<0 || chan>1)
1398                 return;
1399
1400         info = (struct amd7930_info *) drivers[dev].private;
1401
1402         save_and_cli(flags);
1403
1404         if (info->Bisdn[chan]) {
1405                 u8 tmp;
1406
1407                 info->Bisdn[chan]->channel_status = CHANNEL_AVAILABLE;
1408
1409                 sbus_writeb(AMR_MUX_MCR2 + chan, info->regs + CR);
1410                 sbus_writeb(0, info->regs + DR);
1411
1412                 info->Bisdn[chan] = NULL;
1413
1414                 /* Disable B channel transmit */
1415                 sbus_writeb(AMR_LIU_LMR1, info->regs + CR);
1416                 tmp = sbus_readb(info->regs + DR);
1417                 tmp &= ~(AM_LIU_LMR1_B1_ENABL + chan);
1418                 sbus_writeb(tmp, info->regs + DR);
1419
1420                 if (info->Bb.channel_status == CHANNEL_AVAILABLE &&
1421                     info->Bc.channel_status == CHANNEL_AVAILABLE) {
1422                         /* Disable B channel interrupts */
1423                         sbus_writeb(AMR_MUX_MCR4, info->regs + CR);
1424                         sbus_writeb(0, info->regs + DR);
1425                 }
1426         }
1427
1428         restore_flags(flags);
1429 }
1430
1431 static void amd7930_bxmit(int dev, unsigned int chan,
1432                           __u8 * buffer, unsigned long count,
1433                           void (*callback)(void *, int), void *callback_arg)
1434 {
1435         struct amd7930_info *info;
1436         struct amd7930_channel *Bchan;
1437         unsigned long flags;
1438
1439         if (dev > num_drivers)
1440                 return;
1441
1442         info = (struct amd7930_info *) drivers[dev].private;
1443         Bchan = info->Bisdn[chan];
1444
1445         if (Bchan) {
1446                 save_and_cli(flags);
1447
1448                 Bchan->output_ptr = buffer;
1449                 Bchan->output_count = count;
1450                 Bchan->output_format = AUDIO_ENCODING_ULAW;
1451                 Bchan->output_callback = (void *) callback;
1452                 Bchan->output_callback_arg = callback_arg;
1453
1454                 restore_flags(flags);
1455         }
1456 }
1457
1458 static void amd7930_brecv(int dev, unsigned int chan, 
1459                           __u8 * buffer, unsigned long size,
1460                           void (*callback)(void *, int, unsigned int),
1461                           void *callback_arg)
1462 {
1463         struct amd7930_info *info;
1464         struct amd7930_channel *Bchan;
1465         unsigned long flags;
1466
1467         if (dev > num_drivers)
1468                 return;
1469
1470         info = (struct amd7930_info *) drivers[dev].private;
1471         Bchan = info->Bisdn[chan];
1472
1473         if (Bchan) {
1474                 save_and_cli(flags);
1475
1476                 Bchan->input_ptr = buffer;
1477                 Bchan->input_count = size;
1478                 Bchan->input_format = AUDIO_ENCODING_ULAW;
1479                 Bchan->input_callback = (void *) callback;
1480                 Bchan->input_callback_arg = callback_arg;
1481
1482                 restore_flags(flags);
1483         }
1484 }
1485
1486 struct foreign_interface amd7930_foreign_interface = {
1487         amd7930_get_irqnum,
1488         amd7930_get_liu_state,
1489         amd7930_liu_init,
1490         amd7930_liu_activate,
1491         amd7930_liu_deactivate,
1492         amd7930_dxmit,
1493         amd7930_drecv,
1494         amd7930_bopen,
1495         amd7930_bclose,
1496         amd7930_bxmit,
1497         amd7930_brecv
1498 };
1499 EXPORT_SYMBOL(amd7930_foreign_interface);
1500 #endif
1501
1502
1503 /*
1504  *      Device detection and initialization.
1505  */
1506
1507 static struct sparcaudio_operations amd7930_ops = {
1508         amd7930_open,
1509         amd7930_release,
1510         amd7930_ioctl,
1511         amd7930_start_output,
1512         amd7930_stop_output,
1513         amd7930_start_input,
1514         amd7930_stop_input,
1515         amd7930_sunaudio_getdev,
1516         amd7930_set_output_volume,
1517         amd7930_get_output_volume,
1518         amd7930_set_input_volume,
1519         amd7930_get_input_volume,
1520         amd7930_set_monitor_volume,
1521         amd7930_get_monitor_volume,
1522         NULL,                   /* amd7930_set_output_balance */
1523         amd7930_get_output_balance,
1524         NULL,                   /* amd7930_set_input_balance */
1525         amd7930_get_input_balance,
1526         amd7930_set_output_channels,
1527         amd7930_get_output_channels,
1528         amd7930_set_input_channels,
1529         amd7930_get_input_channels,
1530         amd7930_set_output_precision,
1531         amd7930_get_output_precision,
1532         amd7930_set_input_precision,
1533         amd7930_get_input_precision,
1534         amd7930_set_output_port,
1535         amd7930_get_output_port,
1536         NULL,                   /* amd7930_set_input_port */
1537         amd7930_get_input_port,
1538         amd7930_set_encoding,
1539         amd7930_get_encoding,
1540         amd7930_set_encoding,
1541         amd7930_get_encoding,
1542         amd7930_set_output_rate,
1543         amd7930_get_output_rate,
1544         amd7930_set_input_rate,
1545         amd7930_get_input_rate,
1546         amd7930_sunaudio_getdev_sunos,
1547         amd7930_get_output_ports,
1548         amd7930_get_input_ports,
1549         NULL,                    /* amd7930_set_output_muted */
1550         amd7930_get_output_muted,
1551         NULL,                   /* amd7930_set_output_pause */
1552         NULL,                   /* amd7930_get_output_pause */
1553         NULL,                   /* amd7930_set_input_pause */
1554         NULL,                   /* amd7930_get_input_pause */
1555         NULL,                   /* amd7930_set_output_samples */
1556         NULL,                   /* amd7930_get_output_samples */
1557         NULL,                   /* amd7930_set_input_samples */
1558         NULL,                   /* amd7930_get_input_samples */
1559         NULL,                   /* amd7930_set_output_error */
1560         NULL,                   /* amd7930_get_output_error */
1561         NULL,                   /* amd7930_set_input_error */
1562         NULL,                   /* amd7930_get_input_error */
1563         amd7930_get_formats,
1564 };
1565
1566 /* Attach to an amd7930 chip given its PROM node. */
1567 static int amd7930_attach(struct sparcaudio_driver *drv, int node,
1568                           struct sbus_bus *sbus, struct sbus_dev *sdev)
1569 {
1570         struct linux_prom_registers regs;
1571         struct linux_prom_irqs irq;
1572         struct resource res, *resp;
1573         struct amd7930_info *info;
1574         int err;
1575
1576         /* Allocate our private information structure. */
1577         drv->private = kmalloc(sizeof(struct amd7930_info), GFP_KERNEL);
1578         if (drv->private == NULL)
1579                 return -ENOMEM;
1580
1581         /* Point at the information structure and initialize it. */
1582         drv->ops = &amd7930_ops;
1583         info = (struct amd7930_info *)drv->private;
1584         memset(info, 0, sizeof(*info));
1585         info->ints_on = 1; /* force disable below */
1586
1587         drv->dev = sdev;
1588
1589         /* Map the registers into memory. */
1590         prom_getproperty(node, "reg", (char *)&regs, sizeof(regs));
1591         if (sbus && sdev) {
1592                 resp = &sdev->resource[0];
1593         } else {
1594                 resp = &res;
1595                 res.start = regs.phys_addr;
1596                 res.end = res.start + regs.reg_size - 1;
1597                 res.flags = IORESOURCE_IO | (regs.which_io & 0xff);
1598         }
1599         info->regs_size = regs.reg_size;
1600         info->regs = sbus_ioremap(resp, 0, regs.reg_size, "amd7930");
1601         if (!info->regs) {
1602                 printk(KERN_ERR "amd7930: could not remap registers\n");
1603                 kfree(drv->private);
1604                 return -EIO;
1605         }
1606
1607         /* Put amd7930 in idle mode (interrupts disabled) */
1608         amd7930_idle(info);
1609
1610         /* Enable extended FIFO operation on D-channel */
1611         sbus_writeb(AMR_DLC_EFCR, info->regs + CR);
1612         sbus_writeb(AMR_DLC_EFCR_EXTEND_FIFO, info->regs + DR);
1613         sbus_writeb(AMR_DLC_DMR4, info->regs + CR);
1614         sbus_writeb(/* AMR_DLC_DMR4_RCV_30 | */ AMR_DLC_DMR4_XMT_14,
1615                     info->regs + DR);
1616
1617         /* Attach the interrupt handler to the audio interrupt. */
1618         prom_getproperty(node, "intr", (char *)&irq, sizeof(irq));
1619         info->irq = irq.pri;
1620         request_irq(info->irq, amd7930_interrupt,
1621                     SA_INTERRUPT, "amd7930", drv);
1622         amd7930_enable_ints(info);
1623
1624         /* Initalize the local copy of the MAP registers. */
1625         memset(&info->map, 0, sizeof(info->map));
1626         info->map.mmr1 = AM_MAP_MMR1_GX | AM_MAP_MMR1_GER |
1627                          AM_MAP_MMR1_GR | AM_MAP_MMR1_STG;
1628         /* Start out with speaker, microphone */
1629         info->map.mmr2 |= (AM_MAP_MMR2_LS | AM_MAP_MMR2_AINB);
1630
1631         /* Set the default audio parameters. */
1632         info->rgain = 128;
1633         info->pgain = 200;
1634         info->mgain = 0;
1635         info->format_type = AUDIO_ENCODING_ULAW;
1636         info->Bb.input_format = AUDIO_ENCODING_ULAW;
1637         info->Bb.output_format = AUDIO_ENCODING_ULAW;
1638         info->Bc.input_format = AUDIO_ENCODING_ULAW;
1639         info->Bc.output_format = AUDIO_ENCODING_ULAW;
1640         amd7930_update_map(drv);
1641
1642         /* Register the amd7930 with the midlevel audio driver. */
1643         err = register_sparcaudio_driver(drv, 1);
1644         if (err < 0) {
1645                 printk(KERN_ERR "amd7930: unable to register\n");
1646                 free_irq(info->irq, drv);
1647                 sbus_iounmap(info->regs, info->regs_size);
1648                 kfree(drv->private);
1649                 return -EIO;
1650         }
1651
1652         /* Announce the hardware to the user. */
1653         printk(KERN_INFO "amd7930 at %lx irq %d\n",
1654                info->regs, info->irq);
1655
1656         /* Success! */
1657         return 0;
1658 }
1659
1660 /* Detach from an amd7930 chip given the device structure. */
1661 static void __exit amd7930_detach(struct sparcaudio_driver *drv)
1662 {
1663         struct amd7930_info *info = (struct amd7930_info *)drv->private;
1664
1665         unregister_sparcaudio_driver(drv, 1);
1666         amd7930_idle(info);
1667         free_irq(info->irq, drv);
1668         sbus_iounmap(info->regs, info->regs_size);
1669         kfree(drv->private);
1670 }
1671
1672 /* Probe for the amd7930 chip and then attach the driver. */
1673 static int __init amd7930_init(void)
1674 {
1675         struct sbus_bus *sbus;
1676         struct sbus_dev *sdev;
1677         int node;
1678
1679         /* Try to find the sun4c "audio" node first. */
1680         node = prom_getchild(prom_root_node);
1681         node = prom_searchsiblings(node, "audio");
1682         if (node && amd7930_attach(&drivers[0], node, NULL, NULL) == 0)
1683                 num_drivers = 1;
1684         else
1685                 num_drivers = 0;
1686
1687         /* Probe each SBUS for amd7930 chips. */
1688         for_all_sbusdev(sdev, sbus) {
1689                 if (!strcmp(sdev->prom_name, "audio")) {
1690                         /* Don't go over the max number of drivers. */
1691                         if (num_drivers >= MAX_DRIVERS)
1692                                 continue;
1693
1694                         if (amd7930_attach(&drivers[num_drivers],
1695                                            sdev->prom_node, sdev->bus, sdev) == 0)
1696                                 num_drivers++;
1697                 }
1698         }
1699
1700         /* Only return success if we found some amd7930 chips. */
1701         return (num_drivers > 0) ? 0 : -EIO;
1702 }
1703
1704 static void __exit amd7930_exit(void)
1705 {
1706         register int i;
1707
1708         for (i = 0; i < num_drivers; i++) {
1709                 amd7930_detach(&drivers[i]);
1710                 num_drivers--;
1711         }
1712 }
1713
1714 module_init(amd7930_init);
1715 module_exit(amd7930_exit);
1716 MODULE_LICENSE("GPL");
1717
1718 /*************************************************************/
1719 /*                 Audio format conversion                   */
1720 /*************************************************************/
1721
1722 /* Translation tables */
1723
1724 static unsigned char ulaw[] = {
1725     3,   7,  11,  15,  19,  23,  27,  31, 
1726    35,  39,  43,  47,  51,  55,  59,  63, 
1727    66,  68,  70,  72,  74,  76,  78,  80, 
1728    82,  84,  86,  88,  90,  92,  94,  96, 
1729    98,  99, 100, 101, 102, 103, 104, 105, 
1730   106, 107, 108, 109, 110, 111, 112, 113, 
1731   113, 114, 114, 115, 115, 116, 116, 117, 
1732   117, 118, 118, 119, 119, 120, 120, 121, 
1733   121, 121, 122, 122, 122, 122, 123, 123, 
1734   123, 123, 124, 124, 124, 124, 125, 125, 
1735   125, 125, 125, 125, 126, 126, 126, 126, 
1736   126, 126, 126, 126, 127, 127, 127, 127, 
1737   127, 127, 127, 127, 127, 127, 127, 127, 
1738   128, 128, 128, 128, 128, 128, 128, 128, 
1739   128, 128, 128, 128, 128, 128, 128, 128, 
1740   128, 128, 128, 128, 128, 128, 128, 128, 
1741   253, 249, 245, 241, 237, 233, 229, 225, 
1742   221, 217, 213, 209, 205, 201, 197, 193, 
1743   190, 188, 186, 184, 182, 180, 178, 176, 
1744   174, 172, 170, 168, 166, 164, 162, 160, 
1745   158, 157, 156, 155, 154, 153, 152, 151, 
1746   150, 149, 148, 147, 146, 145, 144, 143, 
1747   143, 142, 142, 141, 141, 140, 140, 139, 
1748   139, 138, 138, 137, 137, 136, 136, 135, 
1749   135, 135, 134, 134, 134, 134, 133, 133, 
1750   133, 133, 132, 132, 132, 132, 131, 131, 
1751   131, 131, 131, 131, 130, 130, 130, 130, 
1752   130, 130, 130, 130, 129, 129, 129, 129, 
1753   129, 129, 129, 129, 129, 129, 129, 129, 
1754   128, 128, 128, 128, 128, 128, 128, 128, 
1755   128, 128, 128, 128, 128, 128, 128, 128, 
1756   128, 128, 128, 128, 128, 128, 128, 128
1757 };
1758
1759 static __u8 mulaw2bilinear(__u8 data)
1760 {
1761         return ulaw[data];
1762 }
1763
1764 static unsigned char linear[] = {
1765      0,    0,    0,    0,    0,    0,    0,    1,
1766      0,    0,    0,    2,    0,    0,    0,    3,
1767      0,    0,    0,    4,    0,    0,    0,    5,
1768      0,    0,    0,    6,    0,    0,    0,    7,
1769      0,    0,    0,    8,    0,    0,    0,    9,
1770      0,    0,    0,   10,    0,    0,    0,   11,
1771      0,    0,    0,   12,    0,    0,    0,   13,
1772      0,    0,    0,   14,    0,    0,    0,   15,
1773      0,    0,   16,    0,   17,    0,   18,    0,
1774     19,    0,   20,    0,   21,    0,   22,    0,
1775     23,    0,   24,    0,   25,    0,   26,    0,
1776     27,    0,   28,    0,   29,    0,   30,    0,
1777     31,    0,   32,   33,   34,   35,   36,   37,
1778     38,   39,   40,   41,   42,   43,   44,   45,
1779     46,   48,   50,   52,   54,   56,   58,   60,
1780     62,   65,   69,   73,   77,   83,   91,  103,
1781    255,  231,  219,  211,  205,  201,  197,  193,
1782    190,  188,  186,  184,  182,  180,  178,  176,
1783    174,  173,  172,  171,  170,  169,  168,  167,
1784    166,  165,  164,  163,  162,  161,  160,    0,
1785    159,    0,  158,    0,  157,    0,  156,    0,
1786    155,    0,  154,    0,  153,    0,  152,    0,
1787    151,    0,  150,    0,  149,    0,  148,    0,
1788    147,    0,  146,    0,  145,    0,  144,    0,
1789      0,  143,    0,    0,    0,  142,    0,    0,
1790      0,  141,    0,    0,    0,  140,    0,    0,
1791      0,  139,    0,    0,    0,  138,    0,    0,
1792      0,  137,    0,    0,    0,  136,    0,    0,
1793      0,  135,    0,    0,    0,  134,    0,    0,
1794      0,  133,    0,    0,    0,  132,    0,    0,
1795      0,  131,    0,    0,    0,  130,    0,    0,
1796      0,  129,    0,    0,    0,  128,    0,    0
1797 };
1798
1799 static __u8 bilinear2mulaw(__u8 data)
1800 {
1801         return linear[data];
1802 }
1803
1804 static int exp_lut[256] = {
1805         0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
1806         5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
1807         6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
1808         6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
1809         7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1810         7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1811         7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1812         7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7
1813 };
1814
1815 #define BIAS 0x84
1816 #define CLIP 32635
1817
1818 #define SWAP_ENDIAN(x) ((x >> 8) | ((x & 0xff) << 8))
1819
1820 static __u8  linear2mulaw(__u16 data)
1821 {
1822         static int sign, exponent, mantissa;
1823
1824         /* not really sure, if swapping is ok - comment next line to disable it */
1825         data = SWAP_ENDIAN(data);
1826         
1827         sign = (data >> 8) & 0x80;
1828         if (sign != 0) data = -data;
1829
1830         if (data > CLIP) data = CLIP;
1831         data += BIAS;
1832         exponent = exp_lut[(data >> 7) & 0xFF];
1833         mantissa = (data >> (exponent + 3)) & 0x0F;
1834
1835         return (~(sign | (exponent << 4) | mantissa));
1836 }
1837
1838 static __u16 mulaw2linear(__u8 data)
1839 {
1840         /* this conversion is not working */
1841         return data;
1842 }
1843
1844 #if 0
1845 #define INOUT(x,y) (((x) << 16) | (y))
1846 static int convert_audio(int in_format, int out_format, __u8* buffer, int count)
1847 {
1848         static int i,sign,exponent;
1849         static __u16 data;
1850
1851         if (in_format == out_format) return count;
1852
1853         switch(INOUT(in_format, out_format)) {
1854         case INOUT(AUDIO_ENCODING_ULAW, AUDIO_ENCODING_LINEAR8):
1855                 for (i = 0;i < count; i++) {
1856                         buffer[i] = ulaw[buffer[i]];
1857                 };
1858                 break;
1859         case INOUT(AUDIO_ENCODING_ULAW, AUDIO_ENCODING_LINEAR):
1860                 break;
1861         case INOUT(AUDIO_ENCODING_LINEAR, AUDIO_ENCODING_ULAW):
1862                 /* buffer is two-byte => convert to first */
1863                 for (i = 0; i < count/2; i++) {
1864                         data = ((__u16*)buffer)[i];
1865                         sign = (data >> 8) & 0x80;
1866                         if (data > CLIP) data = CLIP;
1867                         data += BIAS;
1868                         exponent = exp_lut[(data >> 7) & 0xFF];
1869                         buffer[i] = ~(sign | (exponent << 4) | 
1870                                                   ((data >> (exponent + 3)) & 0x0F));
1871                 };
1872                 break;
1873         case INOUT(AUDIO_ENCODING_LINEAR8, AUDIO_ENCODING_ULAW):
1874                 for (i = 0; i < count; i++) {
1875                         buffer[i] = linear[buffer[i]];
1876                 };
1877                 break;
1878         default:
1879                 return 0;
1880         };
1881
1882         return count;
1883 }
1884 #undef INOUT
1885 #endif
1886
1887 #undef BIAS
1888 #undef CLIP
1889 #undef SWAP_ENDIAN