File: /usr/src/linux/drivers/sbus/audio/amd7930.c

1     /* $Id: amd7930.c,v 1.27 2001/05/21 01:25:22 davem 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     	enable_irq(info->irq);
1623     	amd7930_enable_ints(info);
1624     
1625     	/* Initalize the local copy of the MAP registers. */
1626     	memset(&info->map, 0, sizeof(info->map));
1627     	info->map.mmr1 = AM_MAP_MMR1_GX | AM_MAP_MMR1_GER |
1628     			 AM_MAP_MMR1_GR | AM_MAP_MMR1_STG;
1629             /* Start out with speaker, microphone */
1630             info->map.mmr2 |= (AM_MAP_MMR2_LS | AM_MAP_MMR2_AINB);
1631     
1632     	/* Set the default audio parameters. */
1633     	info->rgain = 128;
1634     	info->pgain = 200;
1635     	info->mgain = 0;
1636     	info->format_type = AUDIO_ENCODING_ULAW;
1637     	info->Bb.input_format = AUDIO_ENCODING_ULAW;
1638     	info->Bb.output_format = AUDIO_ENCODING_ULAW;
1639     	info->Bc.input_format = AUDIO_ENCODING_ULAW;
1640     	info->Bc.output_format = AUDIO_ENCODING_ULAW;
1641     	amd7930_update_map(drv);
1642     
1643     	/* Register the amd7930 with the midlevel audio driver. */
1644     	err = register_sparcaudio_driver(drv, 1);
1645     	if (err < 0) {
1646     		printk(KERN_ERR "amd7930: unable to register\n");
1647     		disable_irq(info->irq);
1648     		free_irq(info->irq, drv);
1649     		sbus_iounmap(info->regs, info->regs_size);
1650     		kfree(drv->private);
1651     		return -EIO;
1652     	}
1653     
1654     	/* Announce the hardware to the user. */
1655     	printk(KERN_INFO "amd7930 at %lx irq %d\n",
1656     	       info->regs, info->irq);
1657     
1658     	/* Success! */
1659     	return 0;
1660     }
1661     
1662     /* Detach from an amd7930 chip given the device structure. */
1663     static void __exit amd7930_detach(struct sparcaudio_driver *drv)
1664     {
1665     	struct amd7930_info *info = (struct amd7930_info *)drv->private;
1666     
1667     	unregister_sparcaudio_driver(drv, 1);
1668     	amd7930_idle(info);
1669     	disable_irq(info->irq);
1670     	free_irq(info->irq, drv);
1671     	sbus_iounmap(info->regs, info->regs_size);
1672     	kfree(drv->private);
1673     }
1674     
1675     /* Probe for the amd7930 chip and then attach the driver. */
1676     static int __init amd7930_init(void)
1677     {
1678     	struct sbus_bus *sbus;
1679     	struct sbus_dev *sdev;
1680     	int node;
1681     
1682     	/* Try to find the sun4c "audio" node first. */
1683     	node = prom_getchild(prom_root_node);
1684     	node = prom_searchsiblings(node, "audio");
1685     	if (node && amd7930_attach(&drivers[0], node, NULL, NULL) == 0)
1686     		num_drivers = 1;
1687     	else
1688     		num_drivers = 0;
1689     
1690     	/* Probe each SBUS for amd7930 chips. */
1691     	for_all_sbusdev(sdev, sbus) {
1692     		if (!strcmp(sdev->prom_name, "audio")) {
1693     			/* Don't go over the max number of drivers. */
1694     			if (num_drivers >= MAX_DRIVERS)
1695     				continue;
1696     
1697     			if (amd7930_attach(&drivers[num_drivers],
1698     					   sdev->prom_node, sdev->bus, sdev) == 0)
1699     				num_drivers++;
1700     		}
1701     	}
1702     
1703     	/* Only return success if we found some amd7930 chips. */
1704     	return (num_drivers > 0) ? 0 : -EIO;
1705     }
1706     
1707     static void __exit amd7930_exit(void)
1708     {
1709     	register int i;
1710     
1711     	for (i = 0; i < num_drivers; i++) {
1712     		amd7930_detach(&drivers[i]);
1713     		num_drivers--;
1714     	}
1715     }
1716     
1717     module_init(amd7930_init);
1718     module_exit(amd7930_exit);
1719     
1720     /*************************************************************/
1721     /*                 Audio format conversion                   */
1722     /*************************************************************/
1723     
1724     /* Translation tables */
1725     
1726     static unsigned char ulaw[] = {
1727         3,   7,  11,  15,  19,  23,  27,  31, 
1728        35,  39,  43,  47,  51,  55,  59,  63, 
1729        66,  68,  70,  72,  74,  76,  78,  80, 
1730        82,  84,  86,  88,  90,  92,  94,  96, 
1731        98,  99, 100, 101, 102, 103, 104, 105, 
1732       106, 107, 108, 109, 110, 111, 112, 113, 
1733       113, 114, 114, 115, 115, 116, 116, 117, 
1734       117, 118, 118, 119, 119, 120, 120, 121, 
1735       121, 121, 122, 122, 122, 122, 123, 123, 
1736       123, 123, 124, 124, 124, 124, 125, 125, 
1737       125, 125, 125, 125, 126, 126, 126, 126, 
1738       126, 126, 126, 126, 127, 127, 127, 127, 
1739       127, 127, 127, 127, 127, 127, 127, 127, 
1740       128, 128, 128, 128, 128, 128, 128, 128, 
1741       128, 128, 128, 128, 128, 128, 128, 128, 
1742       128, 128, 128, 128, 128, 128, 128, 128, 
1743       253, 249, 245, 241, 237, 233, 229, 225, 
1744       221, 217, 213, 209, 205, 201, 197, 193, 
1745       190, 188, 186, 184, 182, 180, 178, 176, 
1746       174, 172, 170, 168, 166, 164, 162, 160, 
1747       158, 157, 156, 155, 154, 153, 152, 151, 
1748       150, 149, 148, 147, 146, 145, 144, 143, 
1749       143, 142, 142, 141, 141, 140, 140, 139, 
1750       139, 138, 138, 137, 137, 136, 136, 135, 
1751       135, 135, 134, 134, 134, 134, 133, 133, 
1752       133, 133, 132, 132, 132, 132, 131, 131, 
1753       131, 131, 131, 131, 130, 130, 130, 130, 
1754       130, 130, 130, 130, 129, 129, 129, 129, 
1755       129, 129, 129, 129, 129, 129, 129, 129, 
1756       128, 128, 128, 128, 128, 128, 128, 128, 
1757       128, 128, 128, 128, 128, 128, 128, 128, 
1758       128, 128, 128, 128, 128, 128, 128, 128
1759     };
1760     
1761     static __u8 mulaw2bilinear(__u8 data)
1762     {
1763     	return ulaw[data];
1764     }
1765     
1766     static unsigned char linear[] = {
1767          0,    0,    0,    0,    0,    0,    0,    1,
1768          0,    0,    0,    2,    0,    0,    0,    3,
1769          0,    0,    0,    4,    0,    0,    0,    5,
1770          0,    0,    0,    6,    0,    0,    0,    7,
1771          0,    0,    0,    8,    0,    0,    0,    9,
1772          0,    0,    0,   10,    0,    0,    0,   11,
1773          0,    0,    0,   12,    0,    0,    0,   13,
1774          0,    0,    0,   14,    0,    0,    0,   15,
1775          0,    0,   16,    0,   17,    0,   18,    0,
1776         19,    0,   20,    0,   21,    0,   22,    0,
1777         23,    0,   24,    0,   25,    0,   26,    0,
1778         27,    0,   28,    0,   29,    0,   30,    0,
1779         31,    0,   32,   33,   34,   35,   36,   37,
1780         38,   39,   40,   41,   42,   43,   44,   45,
1781         46,   48,   50,   52,   54,   56,   58,   60,
1782         62,   65,   69,   73,   77,   83,   91,  103,
1783        255,  231,  219,  211,  205,  201,  197,  193,
1784        190,  188,  186,  184,  182,  180,  178,  176,
1785        174,  173,  172,  171,  170,  169,  168,  167,
1786        166,  165,  164,  163,  162,  161,  160,    0,
1787        159,    0,  158,    0,  157,    0,  156,    0,
1788        155,    0,  154,    0,  153,    0,  152,    0,
1789        151,    0,  150,    0,  149,    0,  148,    0,
1790        147,    0,  146,    0,  145,    0,  144,    0,
1791          0,  143,    0,    0,    0,  142,    0,    0,
1792          0,  141,    0,    0,    0,  140,    0,    0,
1793          0,  139,    0,    0,    0,  138,    0,    0,
1794          0,  137,    0,    0,    0,  136,    0,    0,
1795          0,  135,    0,    0,    0,  134,    0,    0,
1796          0,  133,    0,    0,    0,  132,    0,    0,
1797          0,  131,    0,    0,    0,  130,    0,    0,
1798          0,  129,    0,    0,    0,  128,    0,    0
1799     };
1800     
1801     static __u8 bilinear2mulaw(__u8 data)
1802     {
1803     	return linear[data];
1804     }
1805     
1806     static int exp_lut[256] = {
1807     	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,
1808     	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,
1809     	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,
1810     	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,
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     	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,
1814     	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
1815     };
1816     
1817     #define BIAS 0x84
1818     #define CLIP 32635
1819     
1820     #define SWAP_ENDIAN(x) ((x >> 8) | ((x & 0xff) << 8))
1821     
1822     static __u8  linear2mulaw(__u16 data)
1823     {
1824     	static int sign, exponent, mantissa;
1825     
1826     	/* not really sure, if swapping is ok - comment next line to disable it */
1827     	data = SWAP_ENDIAN(data);
1828     	
1829     	sign = (data >> 8) & 0x80;
1830     	if (sign != 0) data = -data;
1831     
1832     	if (data > CLIP) data = CLIP;
1833     	data += BIAS;
1834     	exponent = exp_lut[(data >> 7) & 0xFF];
1835     	mantissa = (data >> (exponent + 3)) & 0x0F;
1836     
1837     	return (~(sign | (exponent << 4) | mantissa));
1838     }
1839     
1840     static __u16 mulaw2linear(__u8 data)
1841     {
1842     	/* this conversion is not working */
1843     	return data;
1844     }
1845     
1846     #if 0
1847     #define INOUT(x,y) (((x) << 16) | (y))
1848     static int convert_audio(int in_format, int out_format, __u8* buffer, int count)
1849     {
1850     	static int i,sign,exponent;
1851     	static __u16 data;
1852     
1853     	if (in_format == out_format) return count;
1854     
1855     	switch(INOUT(in_format, out_format)) {
1856     	case INOUT(AUDIO_ENCODING_ULAW, AUDIO_ENCODING_LINEAR8):
1857     		for (i = 0;i < count; i++) {
1858     			buffer[i] = ulaw[buffer[i]];
1859     		};
1860     		break;
1861     	case INOUT(AUDIO_ENCODING_ULAW, AUDIO_ENCODING_LINEAR):
1862     		break;
1863     	case INOUT(AUDIO_ENCODING_LINEAR, AUDIO_ENCODING_ULAW):
1864     		/* buffer is two-byte => convert to first */
1865     		for (i = 0; i < count/2; i++) {
1866     			data = ((__u16*)buffer)[i];
1867     			sign = (data >> 8) & 0x80;
1868     			if (data > CLIP) data = CLIP;
1869     			data += BIAS;
1870     			exponent = exp_lut[(data >> 7) & 0xFF];
1871     			buffer[i] = ~(sign | (exponent << 4) | 
1872     						  ((data >> (exponent + 3)) & 0x0F));
1873     		};
1874     		break;
1875     	case INOUT(AUDIO_ENCODING_LINEAR8, AUDIO_ENCODING_ULAW):
1876     		for (i = 0; i < count; i++) {
1877     			buffer[i] = linear[buffer[i]];
1878     		};
1879     		break;
1880     	default:
1881     		return 0;
1882     	};
1883     
1884     	return count;
1885     }
1886     #undef INOUT
1887     #endif
1888     
1889     #undef BIAS
1890     #undef CLIP
1891     #undef SWAP_ENDIAN
1892