diff options
-rw-r--r-- | arch/ppc/8xx_io/Kconfig | 4 | ||||
-rw-r--r-- | arch/ppc/8xx_io/Makefile | 1 | ||||
-rw-r--r-- | arch/ppc/8xx_io/cs4218.h | 166 | ||||
-rw-r--r-- | arch/ppc/8xx_io/cs4218_tdm.c | 2833 | ||||
-rw-r--r-- | arch/ppc/platforms/rpxclassic.h | 4 | ||||
-rw-r--r-- | arch/ppc/platforms/rpxhiox.h | 41 | ||||
-rw-r--r-- | arch/ppc/platforms/rpxlite.h | 4 | ||||
-rw-r--r-- | arch/ppc/syslib/m8xx_setup.c | 2 |
8 files changed, 1 insertions, 3054 deletions
diff --git a/arch/ppc/8xx_io/Kconfig b/arch/ppc/8xx_io/Kconfig index 57dacf97853..c623e44f01a 100644 --- a/arch/ppc/8xx_io/Kconfig +++ b/arch/ppc/8xx_io/Kconfig @@ -74,10 +74,6 @@ config ENET_BIG_BUFFERS Allocate large buffers for MPC8xx Ethernet. Increases throughput and decreases the likelihood of dropped packets, but costs memory. -config HTDMSOUND - bool "Embedded Planet HIOX Audio" - depends on SOUND=y - # This doesn't really belong here, but it is convenient to ask # 8xx specific questions. comment "Generic MPC8xx Options" diff --git a/arch/ppc/8xx_io/Makefile b/arch/ppc/8xx_io/Makefile index d8760181fe9..1051a06df7e 100644 --- a/arch/ppc/8xx_io/Makefile +++ b/arch/ppc/8xx_io/Makefile @@ -7,4 +7,3 @@ obj-y := commproc.o obj-$(CONFIG_FEC_ENET) += fec.o obj-$(CONFIG_SCC_ENET) += enet.o obj-$(CONFIG_UCODE_PATCH) += micropatch.o -obj-$(CONFIG_HTDMSOUND) += cs4218_tdm.o diff --git a/arch/ppc/8xx_io/cs4218.h b/arch/ppc/8xx_io/cs4218.h deleted file mode 100644 index e5f943045af..00000000000 --- a/arch/ppc/8xx_io/cs4218.h +++ /dev/null @@ -1,166 +0,0 @@ -#ifndef _cs4218_h_ -/* - * Hacked version of linux/drivers/sound/dmasound/dmasound.h - * - * - * Minor numbers for the sound driver. - * - * Unfortunately Creative called the codec chip of SB as a DSP. For this - * reason the /dev/dsp is reserved for digitized audio use. There is a - * device for true DSP processors but it will be called something else. - * In v3.0 it's /dev/sndproc but this could be a temporary solution. - */ -#define _cs4218_h_ - -#include <linux/types.h> - -#define SND_NDEVS 256 /* Number of supported devices */ -#define SND_DEV_CTL 0 /* Control port /dev/mixer */ -#define SND_DEV_SEQ 1 /* Sequencer output /dev/sequencer (FM - synthesizer and MIDI output) */ -#define SND_DEV_MIDIN 2 /* Raw midi access */ -#define SND_DEV_DSP 3 /* Digitized voice /dev/dsp */ -#define SND_DEV_AUDIO 4 /* Sparc compatible /dev/audio */ -#define SND_DEV_DSP16 5 /* Like /dev/dsp but 16 bits/sample */ -#define SND_DEV_STATUS 6 /* /dev/sndstat */ -/* #7 not in use now. Was in 2.4. Free for use after v3.0. */ -#define SND_DEV_SEQ2 8 /* /dev/sequencer, level 2 interface */ -#define SND_DEV_SNDPROC 9 /* /dev/sndproc for programmable devices */ -#define SND_DEV_PSS SND_DEV_SNDPROC - -/* switch on various prinks */ -#define DEBUG_DMASOUND 1 - -#define MAX_AUDIO_DEV 5 -#define MAX_MIXER_DEV 4 -#define MAX_SYNTH_DEV 3 -#define MAX_MIDI_DEV 6 -#define MAX_TIMER_DEV 3 - -#define MAX_CATCH_RADIUS 10 - -#define le2be16(x) (((x)<<8 & 0xff00) | ((x)>>8 & 0x00ff)) -#define le2be16dbl(x) (((x)<<8 & 0xff00ff00) | ((x)>>8 & 0x00ff00ff)) - -#define IOCTL_IN(arg, ret) \ - do { int error = get_user(ret, (int *)(arg)); \ - if (error) return error; \ - } while (0) -#define IOCTL_OUT(arg, ret) ioctl_return((int *)(arg), ret) - -static inline int ioctl_return(int *addr, int value) -{ - return value < 0 ? value : put_user(value, addr); -} - -#define HAS_RECORD - - /* - * Initialization - */ - -/* description of the set-up applies to either hard or soft settings */ - -typedef struct { - int format; /* AFMT_* */ - int stereo; /* 0 = mono, 1 = stereo */ - int size; /* 8/16 bit*/ - int speed; /* speed */ -} SETTINGS; - - /* - * Machine definitions - */ - -typedef struct { - const char *name; - const char *name2; - void (*open)(void); - void (*release)(void); - void *(*dma_alloc)(unsigned int, gfp_t); - void (*dma_free)(void *, unsigned int); - int (*irqinit)(void); -#ifdef MODULE - void (*irqcleanup)(void); -#endif - void (*init)(void); - void (*silence)(void); - int (*setFormat)(int); - int (*setVolume)(int); - int (*setBass)(int); - int (*setTreble)(int); - int (*setGain)(int); - void (*play)(void); - void (*record)(void); /* optional */ - void (*mixer_init)(void); /* optional */ - int (*mixer_ioctl)(u_int, u_long); /* optional */ - int (*write_sq_setup)(void); /* optional */ - int (*read_sq_setup)(void); /* optional */ - int (*sq_open)(mode_t); /* optional */ - int (*state_info)(char *, size_t); /* optional */ - void (*abort_read)(void); /* optional */ - int min_dsp_speed; - int max_dsp_speed; - int version ; - int hardware_afmts ; /* OSS says we only return h'ware info */ - /* when queried via SNDCTL_DSP_GETFMTS */ - int capabilities ; /* low-level reply to SNDCTL_DSP_GETCAPS */ - SETTINGS default_hard ; /* open() or init() should set something valid */ - SETTINGS default_soft ; /* you can make it look like old OSS, if you want to */ -} MACHINE; - - /* - * Low level stuff - */ - -typedef struct { - ssize_t (*ct_ulaw)(const u_char *, size_t, u_char *, ssize_t *, ssize_t); - ssize_t (*ct_alaw)(const u_char *, size_t, u_char *, ssize_t *, ssize_t); - ssize_t (*ct_s8)(const u_char *, size_t, u_char *, ssize_t *, ssize_t); - ssize_t (*ct_u8)(const u_char *, size_t, u_char *, ssize_t *, ssize_t); - ssize_t (*ct_s16be)(const u_char *, size_t, u_char *, ssize_t *, ssize_t); - ssize_t (*ct_u16be)(const u_char *, size_t, u_char *, ssize_t *, ssize_t); - ssize_t (*ct_s16le)(const u_char *, size_t, u_char *, ssize_t *, ssize_t); - ssize_t (*ct_u16le)(const u_char *, size_t, u_char *, ssize_t *, ssize_t); -} TRANS; - - - /* - * Sound queue stuff, the heart of the driver - */ - -struct sound_queue { - /* buffers allocated for this queue */ - int numBufs; /* real limits on what the user can have */ - int bufSize; /* in bytes */ - char **buffers; - - /* current parameters */ - int locked ; /* params cannot be modified when != 0 */ - int user_frags ; /* user requests this many */ - int user_frag_size ; /* of this size */ - int max_count; /* actual # fragments <= numBufs */ - int block_size; /* internal block size in bytes */ - int max_active; /* in-use fragments <= max_count */ - - /* it shouldn't be necessary to declare any of these volatile */ - int front, rear, count; - int rear_size; - /* - * The use of the playing field depends on the hardware - * - * Atari, PMac: The number of frames that are loaded/playing - * - * Amiga: Bit 0 is set: a frame is loaded - * Bit 1 is set: a frame is playing - */ - int active; - wait_queue_head_t action_queue, open_queue, sync_queue; - int open_mode; - int busy, syncing, xruns, died; -}; - -#define SLEEP(queue) interruptible_sleep_on_timeout(&queue, HZ) -#define WAKE_UP(queue) (wake_up_interruptible(&queue)) - -#endif /* _cs4218_h_ */ diff --git a/arch/ppc/8xx_io/cs4218_tdm.c b/arch/ppc/8xx_io/cs4218_tdm.c deleted file mode 100644 index a956f28ab16..00000000000 --- a/arch/ppc/8xx_io/cs4218_tdm.c +++ /dev/null @@ -1,2833 +0,0 @@ - -/* This is a modified version of linux/drivers/sound/dmasound.c to - * support the CS4218 codec on the 8xx TDM port. Thanks to everyone - * that contributed to the dmasound software (which includes me :-). - * - * The CS4218 is configured in Mode 4, sub-mode 0. This provides - * left/right data only on the TDM port, as a 32-bit word, per frame - * pulse. The control of the CS4218 is provided by some other means, - * like the SPI port. - * Dan Malek (dmalek@jlc.net) - */ - -#include <linux/module.h> -#include <linux/sched.h> -#include <linux/timer.h> -#include <linux/major.h> -#include <linux/fcntl.h> -#include <linux/errno.h> -#include <linux/mm.h> -#include <linux/slab.h> -#include <linux/sound.h> -#include <linux/init.h> -#include <linux/delay.h> - -#include <asm/system.h> -#include <asm/irq.h> -#include <asm/pgtable.h> -#include <asm/uaccess.h> -#include <asm/io.h> - -/* Should probably do something different with this path name..... - * Actually, I should just stop using it... - */ -#include "cs4218.h" -#include <linux/soundcard.h> - -#include <asm/mpc8xx.h> -#include <asm/8xx_immap.h> -#include <asm/commproc.h> - -#define DMASND_CS4218 5 - -#define MAX_CATCH_RADIUS 10 -#define MIN_BUFFERS 4 -#define MIN_BUFSIZE 4 -#define MAX_BUFSIZE 128 - -#define HAS_8BIT_TABLES - -static int sq_unit = -1; -static int mixer_unit = -1; -static int state_unit = -1; -static int irq_installed = 0; -static char **sound_buffers = NULL; -static char **sound_read_buffers = NULL; - -static DEFINE_SPINLOCK(cs4218_lock); - -/* Local copies of things we put in the control register. Output - * volume, like most codecs is really attenuation. - */ -static int cs4218_rate_index; - -/* - * Stuff for outputting a beep. The values range from -327 to +327 - * so we can multiply by an amplitude in the range 0..100 to get a - * signed short value to put in the output buffer. - */ -static short beep_wform[256] = { - 0, 40, 79, 117, 153, 187, 218, 245, - 269, 288, 304, 316, 323, 327, 327, 324, - 318, 310, 299, 288, 275, 262, 249, 236, - 224, 213, 204, 196, 190, 186, 183, 182, - 182, 183, 186, 189, 192, 196, 200, 203, - 206, 208, 209, 209, 209, 207, 204, 201, - 197, 193, 188, 183, 179, 174, 170, 166, - 163, 161, 160, 159, 159, 160, 161, 162, - 164, 166, 168, 169, 171, 171, 171, 170, - 169, 167, 163, 159, 155, 150, 144, 139, - 133, 128, 122, 117, 113, 110, 107, 105, - 103, 103, 103, 103, 104, 104, 105, 105, - 105, 103, 101, 97, 92, 86, 78, 68, - 58, 45, 32, 18, 3, -11, -26, -41, - -55, -68, -79, -88, -95, -100, -102, -102, - -99, -93, -85, -75, -62, -48, -33, -16, - 0, 16, 33, 48, 62, 75, 85, 93, - 99, 102, 102, 100, 95, 88, 79, 68, - 55, 41, 26, 11, -3, -18, -32, -45, - -58, -68, -78, -86, -92, -97, -101, -103, - -105, -105, -105, -104, -104, -103, -103, -103, - -103, -105, -107, -110, -113, -117, -122, -128, - -133, -139, -144, -150, -155, -159, -163, -167, - -169, -170, -171, -171, -171, -169, -168, -166, - -164, -162, -161, -160, -159, -159, -160, -161, - -163, -166, -170, -174, -179, -183, -188, -193, - -197, -201, -204, -207, -209, -209, -209, -208, - -206, -203, -200, -196, -192, -189, -186, -183, - -182, -182, -183, -186, -190, -196, -204, -213, - -224, -236, -249, -262, -275, -288, -299, -310, - -318, -324, -327, -327, -323, -316, -304, -288, - -269, -245, -218, -187, -153, -117, -79, -40, -}; - -#define BEEP_SPEED 5 /* 22050 Hz sample rate */ -#define BEEP_BUFLEN 512 -#define BEEP_VOLUME 15 /* 0 - 100 */ - -static int beep_volume = BEEP_VOLUME; -static int beep_playing = 0; -static int beep_state = 0; -static short *beep_buf; -static void (*orig_mksound)(unsigned int, unsigned int); - -/* This is found someplace else......I guess in the keyboard driver - * we don't include. - */ -static void (*kd_mksound)(unsigned int, unsigned int); - -static int catchRadius = 0; -static int numBufs = 4, bufSize = 32; -static int numReadBufs = 4, readbufSize = 32; - - -/* TDM/Serial transmit and receive buffer descriptors. -*/ -static volatile cbd_t *rx_base, *rx_cur, *tx_base, *tx_cur; - -module_param(catchRadius, int, 0); -module_param(numBufs, int, 0); -module_param(bufSize, int, 0); -module_param(numreadBufs, int, 0); -module_param(readbufSize, int, 0); - -#define arraysize(x) (sizeof(x)/sizeof(*(x))) -#define le2be16(x) (((x)<<8 & 0xff00) | ((x)>>8 & 0x00ff)) -#define le2be16dbl(x) (((x)<<8 & 0xff00ff00) | ((x)>>8 & 0x00ff00ff)) - -#define IOCTL_IN(arg, ret) \ - do { int error = get_user(ret, (int *)(arg)); \ - if (error) return error; \ - } while (0) -#define IOCTL_OUT(arg, ret) ioctl_return((int *)(arg), ret) - -/* CS4218 serial port control in mode 4. -*/ -#define CS_INTMASK ((uint)0x40000000) -#define CS_DO1 ((uint)0x20000000) -#define CS_LATTEN ((uint)0x1f000000) -#define CS_RATTEN ((uint)0x00f80000) -#define CS_MUTE ((uint)0x00040000) -#define CS_ISL ((uint)0x00020000) -#define CS_ISR ((uint)0x00010000) -#define CS_LGAIN ((uint)0x0000f000) -#define CS_RGAIN ((uint)0x00000f00) - -#define CS_LATTEN_SET(X) (((X) & 0x1f) << 24) -#define CS_RATTEN_SET(X) (((X) & 0x1f) << 19) -#define CS_LGAIN_SET(X) (((X) & 0x0f) << 12) -#define CS_RGAIN_SET(X) (((X) & 0x0f) << 8) - -#define CS_LATTEN_GET(X) (((X) >> 24) & 0x1f) -#define CS_RATTEN_GET(X) (((X) >> 19) & 0x1f) -#define CS_LGAIN_GET(X) (((X) >> 12) & 0x0f) -#define CS_RGAIN_GET(X) (((X) >> 8) & 0x0f) - -/* The control register is effectively write only. We have to keep a copy - * of what we write. - */ -static uint cs4218_control; - -/* A place to store expanding information. -*/ -static int expand_bal; -static int expand_data; - -/* Since I can't make the microcode patch work for the SPI, I just - * clock the bits using software. - */ -static void sw_spi_init(void); -static void sw_spi_io(u_char *obuf, u_char *ibuf, uint bcnt); -static uint cs4218_ctl_write(uint ctlreg); - -/*** Some low level helpers **************************************************/ - -/* 16 bit mu-law */ - -static short ulaw2dma16[] = { - -32124, -31100, -30076, -29052, -28028, -27004, -25980, -24956, - -23932, -22908, -21884, -20860, -19836, -18812, -17788, -16764, - -15996, -15484, -14972, -14460, -13948, -13436, -12924, -12412, - -11900, -11388, -10876, -10364, -9852, -9340, -8828, -8316, - -7932, -7676, -7420, -7164, -6908, -6652, -6396, -6140, - -5884, -5628, -5372, -5116, -4860, -4604, -4348, -4092, - -3900, -3772, -3644, -3516, -3388, -3260, -3132, -3004, - -2876, -2748, -2620, -2492, -2364, -2236, -2108, -1980, - -1884, -1820, -1756, -1692, -1628, -1564, -1500, -1436, - -1372, -1308, -1244, -1180, -1116, -1052, -988, -924, - -876, -844, -812, -780, -748, -716, -684, -652, - -620, -588, -556, -524, -492, -460, -428, -396, - -372, -356, -340, -324, -308, -292, -276, -260, - -244, -228, -212, -196, -180, -164, -148, -132, - -120, -112, -104, -96, -88, -80, -72, -64, - -56, -48, -40, -32, -24, -16, -8, 0, - 32124, 31100, 30076, 29052, 28028, 27004, 25980, 24956, - 23932, 22908, 21884, 20860, 19836, 18812, 17788, 16764, - 15996, 15484, 14972, 14460, 13948, 13436, 12924, 12412, - 11900, 11388, 10876, 10364, 9852, 9340, 8828, 8316, - 7932, 7676, 7420, 7164, 6908, 6652, 6396, 6140, - 5884, 5628, 5372, 5116, 4860, 4604, 4348, 4092, - 3900, 3772, 3644, 3516, 3388, 3260, 3132, 3004, - 2876, 2748, 2620, 2492, 2364, 2236, 2108, 1980, - 1884, 1820, 1756, 1692, 1628, 1564, 1500, 1436, - 1372, 1308, 1244, 1180, 1116, 1052, 988, 924, - 876, 844, 812, 780, 748, 716, 684, 652, - 620, 588, 556, 524, 492, 460, 428, 396, - 372, 356, 340, 324, 308, 292, 276, 260, - 244, 228, 212, 196, 180, 164, 148, 132, - 120, 112, 104, 96, 88, 80, 72, 64, - 56, 48, 40, 32, 24, 16, 8, 0, -}; - -/* 16 bit A-law */ - -static short alaw2dma16[] = { - -5504, -5248, -6016, -5760, -4480, -4224, -4992, -4736, - -7552, -7296, -8064, -7808, -6528, -6272, -7040, -6784, - -2752, -2624, -3008, -2880, -2240, -2112, -2496, -2368, - -3776, -3648, -4032, -3904, -3264, -3136, -3520, -3392, - -22016, -20992, -24064, -23040, -17920, -16896, -19968, -18944, - -30208, -29184, -32256, -31232, -26112, -25088, -28160, -27136, - -11008, -10496, -12032, -11520, -8960, -8448, -9984, -9472, - -15104, -14592, -16128, -15616, -13056, -12544, -14080, -13568, - -344, -328, -376, -360, -280, -264, -312, -296, - -472, -456, -504, -488, -408, -392, -440, -424, - -88, -72, -120, -104, -24, -8, -56, -40, - -216, -200, -248, -232, -152, -136, -184, -168, - -1376, -1312, -1504, -1440, -1120, -1056, -1248, -1184, - -1888, -1824, -2016, -1952, -1632, -1568, -1760, -1696, - -688, -656, -752, -720, -560, -528, -624, -592, - -944, -912, -1008, -976, -816, -784, -880, -848, - 5504, 5248, 6016, 5760, 4480, 4224, 4992, 4736, - 7552, 7296, 8064, 7808, 6528, 6272, 7040, 6784, - 2752, 2624, 3008, 2880, 2240, 2112, 2496, 2368, - 3776, 3648, 4032, 3904, 3264, 3136, 3520, 3392, - 22016, 20992, 24064, 23040, 17920, 16896, 19968, 18944, - 30208, 29184, 32256, 31232, 26112, 25088, 28160, 27136, - 11008, 10496, 12032, 11520, 8960, 8448, 9984, 9472, - 15104, 14592, 16128, 15616, 13056, 12544, 14080, 13568, - 344, 328, 376, 360, 280, 264, 312, 296, - 472, 456, 504, 488, 408, 392, 440, 424, - 88, 72, 120, 104, 24, 8, 56, 40, - 216, 200, 248, 232, 152, 136, 184, 168, - 1376, 1312, 1504, 1440, 1120, 1056, 1248, 1184, - 1888, 1824, 2016, 1952, 1632, 1568, 1760, 1696, - 688, 656, 752, 720, 560, 528, 624, 592, - 944, 912, 1008, 976, 816, 784, 880, 848, -}; - - -/*** Translations ************************************************************/ - - -static ssize_t cs4218_ct_law(const u_char *userPtr, size_t userCount, - u_char frame[], ssize_t *frameUsed, - ssize_t frameLeft); -static ssize_t cs4218_ct_s8(const u_char *userPtr, size_t userCount, - u_char frame[], ssize_t *frameUsed, - ssize_t frameLeft); -static ssize_t cs4218_ct_u8(const u_char *userPtr, size_t userCount, - u_char frame[], ssize_t *frameUsed, - ssize_t frameLeft); -static ssize_t cs4218_ct_s16(const u_char *userPtr, size_t userCount, - u_char frame[], ssize_t *frameUsed, - ssize_t frameLeft); -static ssize_t cs4218_ct_u16(const u_char *userPtr, size_t userCount, - u_char frame[], ssize_t *frameUsed, - ssize_t frameLeft); -static ssize_t cs4218_ctx_law(const u_char *userPtr, size_t userCount, - u_char frame[], ssize_t *frameUsed, - ssize_t frameLeft); -static ssize_t cs4218_ctx_s8(const u_char *userPtr, size_t userCount, - u_char frame[], ssize_t *frameUsed, - ssize_t frameLeft); -static ssize_t cs4218_ctx_u8(const u_char *userPtr, size_t userCount, - u_char frame[], ssize_t *frameUsed, - ssize_t frameLeft); -static ssize_t cs4218_ctx_s16(const u_char *userPtr, size_t userCount, - u_char frame[], ssize_t *frameUsed, - ssize_t frameLeft); -static ssize_t cs4218_ctx_u16(const u_char *userPtr, size_t userCount, - u_char frame[], ssize_t *frameUsed, - ssize_t frameLeft); -static ssize_t cs4218_ct_s16_read(const u_char *userPtr, size_t userCount, - u_char frame[], ssize_t *frameUsed, - ssize_t frameLeft); -static ssize_t cs4218_ct_u16_read(const u_char *userPtr, size_t userCount, - u_char frame[], ssize_t *frameUsed, - ssize_t frameLeft); - - -/*** Low level stuff *********************************************************/ - -struct cs_sound_settings { - MACHINE mach; /* machine dependent things */ - SETTINGS hard; /* hardware settings */ - SETTINGS soft; /* software settings */ - SETTINGS dsp; /* /dev/dsp default settings */ - TRANS *trans_write; /* supported translations for playback */ - TRANS *trans_read; /* supported translations for record */ - int volume_left; /* volume (range is machine dependent) */ - int volume_right; - int bass; /* tone (range is machine dependent) */ - int treble; - int gain; - int minDev; /* minor device number currently open */ -}; - -static struct cs_sound_settings sound; - -static void *CS_Alloc(unsigned int size, gfp_t flags); -static void CS_Free(void *ptr, unsigned int size); -static int CS_IrqInit(void); -#ifdef MODULE -static void CS_IrqCleanup(void); -#endif /* MODULE */ -static void CS_Silence(void); -static void CS_Init(void); -static void CS_Play(void); -static void CS_Record(void); -static int CS_SetFormat(int format); -static int CS_SetVolume(int volume); -static void cs4218_tdm_tx_intr(void *devid); -static void cs4218_tdm_rx_intr(void *devid); -static void cs4218_intr(void *devid); -static int cs_get_volume(uint reg); -static int cs_volume_setter(int volume, int mute); -static int cs_get_gain(uint reg); -static int cs_set_gain(int gain); -static void cs_mksound(unsigned int hz, unsigned int ticks); -static void cs_nosound(unsigned long xx); - -/*** Mid level stuff *********************************************************/ - - -static void sound_silence(void); -static void sound_init(void); -static int sound_set_format(int format); -static int sound_set_speed(int speed); -static int sound_set_stereo(int stereo); -static int sound_set_volume(int volume); - -static ssize_t sound_copy_translate(const u_char *userPtr, - size_t userCount, - u_char frame[], ssize_t *frameUsed, - ssize_t frameLeft); -static ssize_t sound_copy_translate_read(const u_char *userPtr, - size_t userCount, - u_char frame[], ssize_t *frameUsed, - ssize_t frameLeft); - - -/* - * /dev/mixer abstraction - */ - -struct sound_mixer { - int busy; - int modify_counter; -}; - -static struct sound_mixer mixer; - -static struct sound_queue sq; -static struct sound_queue read_sq; - -#define sq_block_address(i) (sq.buffers[i]) -#define SIGNAL_RECEIVED (signal_pending(current)) -#define NON_BLOCKING(open_mode) (open_mode & O_NONBLOCK) -#define ONE_SECOND HZ /* in jiffies (100ths of a second) */ -#define NO_TIME_LIMIT 0xffffffff - -/* - * /dev/sndstat - */ - -struct sound_state { - int busy; - char buf[512]; - int len, ptr; -}; - -static struct sound_state state; - -/*** Common stuff ********************************************************/ - -static long long sound_lseek(struct file *file, long long offset, int orig); - -/*** Config & Setup **********************************************************/ - -void dmasound_setup(char *str, int *ints); - -/*** Translations ************************************************************/ - - -/* ++TeSche: radically changed for new expanding purposes... - * - * These two routines now deal with copying/expanding/translating the samples - * from user space into our buffer at the right frequency. They take care about - * how much data there's actually to read, how much buffer space there is and - * to convert samples into the right frequency/encoding. They will only work on - * complete samples so it may happen they leave some bytes in the input stream - * if the user didn't write a multiple of the current sample size. They both - * return the number of bytes they've used from both streams so you may detect - * such a situation. Luckily all programs should be able to cope with that. - * - * I think I've optimized anything as far as one can do in plain C, all - * variables should fit in registers and the loops are really short. There's - * one loop for every possible situation. Writing a more generalized and thus - * parameterized loop would only produce slower code. Feel free to optimize - * this in assembler if you like. :) - * - * I think these routines belong here because they're not yet really hardware - * independent, especially the fact that the Falcon can play 16bit samples - * only in stereo is hardcoded in both of them! - * - * ++geert: split in even more functions (one per format) - */ - -static ssize_t cs4218_ct_law(const u_char *userPtr, size_t userCount, - u_char frame[], ssize_t *frameUsed, - ssize_t frameLeft) -{ - short *table = sound.soft.format == AFMT_MU_LAW ? ulaw2dma16: alaw2dma16; - ssize_t count, used; - short *p = (short *) &frame[*frameUsed]; - int val, stereo = sound.soft.stereo; - - frameLeft >>= 2; - if (stereo) - userCount >>= 1; - used = count = min(userCount, frameLeft); - while (count > 0) { - u_char data; - if (get_user(data, userPtr++)) - return -EFAULT; - val = table[data]; - *p++ = val; - if (stereo) { - if (get_user(data, userPtr++)) - return -EFAULT; - val = table[data]; - } - *p++ = val; - count--; - } - *frameUsed += used * 4; - return stereo? used * 2: used; -} - - -static ssize_t cs4218_ct_s8(const u_char *userPtr, size_t userCount, - u_char frame[], ssize_t *frameUsed, - ssize_t frameLeft) -{ - ssize_t count, used; - short *p = (short *) &frame[*frameUsed]; - int val, stereo = sound.soft.stereo; - - frameLeft >>= 2; - if (stereo) - userCount >>= 1; - used = count = min(userCount, frameLeft); - while (count > 0) { - u_char data; - if (get_user(data, userPtr++)) - return -EFAULT; - val = data << 8; - *p++ = val; - if (stereo) { - if (get_user(data, userPtr++)) - return -EFAULT; - val = data << 8; - } - *p++ = val; - count--; - } - *frameUsed += used * 4; - return stereo? used * 2: used; -} - - -static ssize_t cs4218_ct_u8(const u_char *userPtr, size_t userCount, - u_char frame[], ssize_t *frameUsed, - ssize_t frameLeft) -{ - ssize_t count, used; - short *p = (short *) &frame[*frameUsed]; - int val, stereo = sound.soft.stereo; - - frameLeft >>= 2; - if (stereo) - userCount >>= 1; - used = count = min(userCount, frameLeft); - while (count > 0) { - u_char data; - if (get_user(data, userPtr++)) - return -EFAULT; - val = (data ^ 0x80) << 8; - *p++ = val; - if (stereo) { - if (get_user(data, userPtr++)) - return -EFAULT; - val = (data ^ 0x80) << 8; - } - *p++ = val; - count--; - } - *frameUsed += used * 4; - return stereo? used * 2: used; -} - - -/* This is the default format of the codec. Signed, 16-bit stereo - * generated by an application shouldn't have to be copied at all. - * We should just get the phsical address of the buffers and update - * the TDM BDs directly. - */ -static ssize_t cs4218_ct_s16(const u_char *userPtr, size_t userCount, - u_char frame[], ssize_t *frameUsed, - ssize_t frameLeft) -{ - ssize_t count, used; - int stereo = sound.soft.stereo; - short *fp = (short *) &frame[*frameUsed]; - - frameLeft >>= 2; - userCount >>= (stereo? 2: 1); - used = count = min(userCount, frameLeft); - if (!stereo) { - short *up = (short *) userPtr; - while (count > 0) { - short data; - if (get_user(data, up++)) - return -EFAULT; - *fp++ = data; - *fp++ = data; - count--; - } - } else { - if (copy_from_user(fp, userPtr, count * 4)) - return -EFAULT; - } - *frameUsed += used * 4; - return stereo? used * 4: used * 2; -} - -static ssize_t cs4218_ct_u16(const u_char *userPtr, size_t userCount, - u_char frame[], ssize_t *frameUsed, - ssize_t frameLeft) -{ - ssize_t count, used; - int mask = (sound.soft.format == AFMT_U16_LE? 0x0080: 0x8000); - int stereo = sound.soft.stereo; - short *fp = (short *) &frame[*frameUsed]; - short *up = (short *) userPtr; - - frameLeft >>= 2; - userCount >>= (stereo? 2: 1); - used = count = min(userCount, frameLeft); - while (count > 0) { - int data; - if (get_user(data, up++)) - return -EFAULT; - data ^= mask; - *fp++ = data; - if (stereo) { - if (get_user(data, up++)) - return -EFAULT; - data ^= mask; - } - *fp++ = data; - count--; - } - *frameUsed += used * 4; - return stereo? used * 4: used * 2; -} - - -static ssize_t cs4218_ctx_law(const u_char *userPtr, size_t userCount, - u_char frame[], ssize_t *frameUsed, - ssize_t frameLeft) -{ - unsigned short *table = (unsigned short *) - (sound.soft.format == AFMT_MU_LAW ? ulaw2dma16: alaw2dma16); - unsigned int data = expand_data; - unsigned int *p = (unsigned int *) &frame[*frameUsed]; - int bal = expand_bal; - int hSpeed = sound.hard.speed, sSpeed = sound.soft.speed; - int utotal, ftotal; - int stereo = sound.soft.stereo; - - frameLeft >>= 2; - if (stereo) - userCount >>= 1; - ftotal = frameLeft; - utotal = userCount; - while (frameLeft) { - u_char c; - if (bal < 0) { - if (userCount == 0) - break; - if (get_user(c, userPtr++)) - return -EFAULT; - data = table[c]; - if (stereo) { - if (get_user(c, userPtr++)) - return -EFAULT; - data = (data << 16) + table[c]; - } else - data = (data << 16) + data; - userCount--; - bal += hSpeed; - } - *p++ = data; - frameLeft--; - bal -= sSpeed; - } - expand_bal = bal; - expand_data = data; - *frameUsed += (ftotal - frameLeft) * 4; - utotal -= userCount; - return stereo? utotal * 2: utotal; -} - - -static ssize_t cs4218_ctx_s8(const u_char *userPtr, size_t userCount, - u_char frame[], ssize_t *frameUsed, - ssize_t frameLeft) -{ - unsigned int *p = (unsigned int *) &frame[*frameUsed]; - unsigned int data = expand_data; - int bal = expand_bal; - int hSpeed = sound.hard.speed, sSpeed = sound.soft.speed; - int stereo = sound.soft.stereo; - int utotal, ftotal; - - frameLeft >>= 2; - if (stereo) - userCount >>= 1; - ftotal = frameLeft; - utotal = userCount; - while (frameLeft) { - u_char c; - if (bal < 0) { - if (userCount == 0) - break; - if (get_user(c, userPtr++)) - return -EFAULT; - data = c << 8; - if (stereo) { - if (get_user(c, userPtr++)) - return -EFAULT; - data = (data << 16) + (c << 8); - } else - data = (data << 16) + data; - userCount--; - bal += hSpeed; - } - *p++ = data; - frameLeft--; - bal -= sSpeed; - } - expand_bal = bal; - expand_data = data; - *frameUsed += (ftotal - frameLeft) * 4; - utotal -= userCount; - return stereo? utotal * 2: utotal; -} - - -static ssize_t cs4218_ctx_u8(const u_char *userPtr, size_t userCount, - u_char frame[], ssize_t *frameUsed, - ssize_t frameLeft) -{ - unsigned int *p = (unsigned int *) &frame[*frameUsed]; - unsigned int data = expand_data; - int bal = expand_bal; - int hSpeed = sound.hard.speed, sSpeed = sound.soft.speed; - int stereo = sound.soft.stereo; - int utotal, ftotal; - - frameLeft >>= 2; - if (stereo) - userCount >>= 1; - ftotal = frameLeft; - utotal = userCount; - while (frameLeft) { - u_char c; - if (bal < 0) { - if (userCount == 0) - break; - if (get_user(c, userPtr++)) - return -EFAULT; - data = (c ^ 0x80) << 8; - if (stereo) { - if (get_user(c, userPtr++)) - return -EFAULT; - data = (data << 16) + ((c ^ 0x80) << 8); - } else - data = (data << 16) + data; - userCount--; - bal += hSpeed; - } - *p++ = data; - frameLeft--; - bal -= sSpeed; - } - expand_bal = bal; - expand_data = data; - *frameUsed += (ftotal - frameLeft) * 4; - utotal -= userCount; - return stereo? utotal * 2: utotal; -} - - -static ssize_t cs4218_ctx_s16(const u_char *userPtr, size_t userCount, - u_char frame[], ssize_t *frameUsed, - ssize_t frameLeft) -{ - unsigned int *p = (unsigned int *) &frame[*frameUsed]; - unsigned int data = expand_data; - unsigned short *up = (unsigned short *) userPtr; - int bal = expand_bal; - int hSpeed = sound.hard.speed, sSpeed = sound.soft.speed; - int stereo = sound.soft.stereo; - int utotal, ftotal; - - frameLeft >>= 2; - userCount >>= (stereo? 2: 1); - ftotal = frameLeft; - utotal = userCount; - while (frameLeft) { - unsigned short c; - if (bal < 0) { - if (userCount == 0) - break; - if (get_user(data, up++)) - return -EFAULT; - if (stereo) { - if (get_user(c, up++)) - return -EFAULT; - data = (data << 16) + c; - } else - data = (data << 16) + data; - userCount--; - bal += hSpeed; - } - *p++ = data; - frameLeft--; - bal -= sSpeed; - } - expand_bal = bal; - expand_data = data; - *frameUsed += (ftotal - frameLeft) * 4; - utotal -= userCount; - return stereo? utotal * 4: utotal * 2; -} - - -static ssize_t cs4218_ctx_u16(const u_char *userPtr, size_t userCount, - u_char frame[], ssize_t *frameUsed, - ssize_t frameLeft) -{ - int mask = (sound.soft.format == AFMT_U16_LE? 0x0080: 0x8000); - unsigned int *p = (unsigned int *) &frame[*frameUsed]; - unsigned int data = expand_data; - unsigned short *up = (unsigned short *) userPtr; - int bal = expand_bal; - int hSpeed = sound.hard.speed, sSpeed = sound.soft.speed; - int stereo = sound.soft.stereo; - int utotal, ftotal; - - frameLeft >>= 2; - userCount >>= (stereo? 2: 1); - ftotal = frameLeft; - utotal = userCount; - while (frameLeft) { - unsigned short c; - if (bal < 0) { - if (userCount == 0) - break; - if (get_user(data, up++)) - return -EFAULT; - data ^= mask; - if (stereo) { - if (get_user(c, up++)) - return -EFAULT; - data = (data << 16) + (c ^ mask); - } else - data = (data << 16) + data; - userCount--; - bal += hSpeed; - } - *p++ = data; - frameLeft--; - bal -= sSpeed; - } - expand_bal = bal; - expand_data = data; - *frameUsed += (ftotal - frameLeft) * 4; - utotal -= userCount; - return stereo? utotal * 4: utotal * 2; -} - -static ssize_t cs4218_ct_s8_read(const u_char *userPtr, size_t userCount, - u_char frame[], ssize_t *frameUsed, - ssize_t frameLeft) -{ - ssize_t count, used; - short *p = (short *) &frame[*frameUsed]; - int val, stereo = sound.soft.stereo; - - frameLeft >>= 2; - if (stereo) - userCount >>= 1; - used = count = min(userCount, frameLeft); - while (count > 0) { - u_char data; - - val = *p++; - data = val >> 8; - if (put_user(data, (u_char *)userPtr++)) - return -EFAULT; - if (stereo) { - val = *p; - data = val >> 8; - if (put_user(data, (u_char *)userPtr++)) - return -EFAULT; - } - p++; - count--; - } - *frameUsed += used * 4; - return stereo? used * 2: used; -} - - -static ssize_t cs4218_ct_u8_read(const u_char *userPtr, size_t userCount, - u_char frame[], ssize_t *frameUsed, - ssize_t frameLeft) -{ - ssize_t count, used; - short *p = (short *) &frame[*frameUsed]; - int val, stereo = sound.soft.stereo; - - frameLeft >>= 2; - if (stereo) - userCount >>= 1; - used = count = min(userCount, frameLeft); - while (count > 0) { - u_char data; - - val = *p++; - data = (val >> 8) ^ 0x80; - if (put_user(data, (u_char *)userPtr++)) - return -EFAULT; - if (stereo) { - val = *p; - data = (val >> 8) ^ 0x80; - if (put_user(data, (u_char *)userPtr++)) - return -EFAULT; - } - p++; - count--; - } - *frameUsed += used * 4; - return stereo? used * 2: used; -} - - -static ssize_t cs4218_ct_s16_rea |