Commit 89728e0e authored by Andrew Morton's avatar Andrew Morton Committed by Greg Kroah-Hartman

[PATCH] ppc32: Update PowerMac dmasound driver

From: Benjamin Herrenschmidt <benh@kernel.crashing.org>

This patch was missing from my big merge.  It updates the PowerMac
"dmasound" driver.  Adds input support for some recent machines using the
tas3004 coded/mixer chip.  Code mostly written by Renzo Davoli.

This driver isn't (unfortunately) fully obsoleted by the Alsa one.  There
are lots of reports of the Alsa one not working properly on various
PowerMac machines, and some people are unhappy with Alsa in general, enough
to have ported the messy PowerMac dmasound to 2.6 :)
parent 29052d81
......@@ -273,4 +273,11 @@ static inline void wait_ms(unsigned int ms)
schedule_timeout(1 + ms * HZ / 1000);
}
#define SW_INPUT_VOLUME_SCALE 4
#define SW_INPUT_VOLUME_DEFAULT (128 / SW_INPUT_VOLUME_SCALE)
extern int expand_bal; /* Balance factor for expanding (not volume!) */
extern int expand_read_bal; /* Balance factor for reading */
extern uint software_input_volume; /* software implemented recording volume! */
#endif /* _dmasound_h_ */
......@@ -52,6 +52,10 @@
* - Support for snapper & better tumbler integration by Toby Sargeant
* - Headphone detect for scremer by Julien Blache
* - More tumbler fixed by Andreas Schwab
* 11/29/2003 [0.8.1] - Renzo Davoli (King Enzo)
* - Support for Snapper line in
* - snapper input resampling (for rates < 44100)
* - software line gain control
*/
/* GENERAL FIXME/TODO: check that the assumptions about what is written to
......@@ -76,6 +80,7 @@
#include <linux/spinlock.h>
#include <linux/kmod.h>
#include <linux/interrupt.h>
#include <linux/input.h>
#include <asm/semaphore.h>
#ifdef CONFIG_ADB_CUDA
#include <linux/cuda.h>
......@@ -119,7 +124,6 @@ static volatile u32 *i2s;
static volatile struct dbdma_regs *awacs_txdma, *awacs_rxdma;
static int awacs_rate_index;
static int awacs_subframe;
static int awacs_spkr_vol;
static struct device_node* awacs_node;
static struct device_node* i2s_node;
......@@ -264,6 +268,7 @@ struct pmu_sleep_notifier awacs_sleep_notifier = {
/* for (soft) sample rate translations */
int expand_bal; /* Balance factor for expanding (not volume!) */
int expand_read_bal; /* Balance factor for expanding reads (not volume!) */
/*** Low level stuff *********************************************************/
......@@ -285,8 +290,6 @@ static irqreturn_t pmac_awacs_intr(int irq, void *devid, struct pt_regs *regs);
static void awacs_write(int val);
static int awacs_get_volume(int reg, int lshift);
static int awacs_volume_setter(int volume, int n, int mute, int lshift);
static void awacs_mksound(unsigned int hz, unsigned int ticks);
static void awacs_nosound(unsigned long xx);
/*** Mid level stuff **********************************************************/
......@@ -299,6 +302,7 @@ static void PMacAbortRead(void);
extern TRANS transAwacsNormal ;
extern TRANS transAwacsExpand ;
extern TRANS transAwacsNormalRead ;
extern TRANS transAwacsExpandRead ;
extern int daca_init(void);
extern void daca_cleanup(void);
......@@ -545,11 +549,15 @@ tas_mixer_ioctl(u_int cmd, u_long arg)
rc = IOCTL_OUT(arg, 0);
break;
case SOUND_MIXER_READ_RECMASK:
data = 0;
// XXX FIXME: find a way to check what is really available */
data = SOUND_MASK_LINE | SOUND_MASK_MIC;
rc = IOCTL_OUT(arg, data);
break;
case SOUND_MIXER_READ_RECSRC:
data = 0;
if (awacs_reg[0] & MASK_MUX_AUDIN)
data |= SOUND_MASK_LINE;
if (awacs_reg[0] & MASK_MUX_MIC)
data |= SOUND_MASK_MIC;
rc = IOCTL_OUT(arg, data);
break;
case SOUND_MIXER_WRITE_RECSRC:
......@@ -799,11 +807,13 @@ static void PMacInit(void)
set_frame_rate(dmasound.soft.speed, catchRadius) ;
tolerance = (catchRadius * dmasound.hard.speed) / 100;
if (dmasound.soft.speed >= dmasound.hard.speed - tolerance)
if (dmasound.soft.speed >= dmasound.hard.speed - tolerance) {
dmasound.trans_write = &transAwacsNormal;
else
dmasound.trans_read = &transAwacsNormalRead;
} else {
dmasound.trans_write = &transAwacsExpand;
dmasound.trans_read = &transAwacsNormalRead;
dmasound.trans_read = &transAwacsExpandRead;
}
if (awacs) {
if (hw_can_byteswap && (dmasound.hard.format == AFMT_S16_LE))
......@@ -813,6 +823,7 @@ static void PMacInit(void)
}
expand_bal = -dmasound.soft.speed;
expand_read_bal = -dmasound.soft.speed;
}
static int PMacSetFormat(int format)
......@@ -1280,15 +1291,14 @@ static void awacs_nosound(unsigned long xx)
spin_unlock_irqrestore(&dmasound.lock, flags);
}
static struct timer_list beep_timer = TIMER_INITIALIZER(awacs_nosound, 0, 0);
#if 0 /* would need to go through the input layer in 2.6, later.. --hch */
/* we generate the beep with a single dbdma command that loops a buffer
forever - without generating interrupts.
So, to stop it you have to stop dma output as per awacs_nosound.
*/
static void awacs_mksound(unsigned int hz, unsigned int ticks)
/*
* We generate the beep with a single dbdma command that loops a buffer
* forever - without generating interrupts.
*
* So, to stop it you have to stop dma output as per awacs_nosound.
*/
static int awacs_beep_event(struct input_dev *dev, unsigned int type,
unsigned int code, int hz)
{
unsigned long flags;
int beep_speed = 0;
......@@ -1300,8 +1310,21 @@ static void awacs_mksound(unsigned int hz, unsigned int ticks)
static int beep_nsamples_cache;
static int beep_volume_cache;
if (type != EV_SND)
return -1;
switch (code) {
case SND_BELL:
if (hz)
hz = 1000;
break;
case SND_TONE:
break;
default:
return -1;
}
if (beep_buf == NULL)
return;
return -1;
/* quick-hack fix for DACA, Burgundy & Tumbler */
......@@ -1313,26 +1336,17 @@ static void awacs_mksound(unsigned int hz, unsigned int ticks)
beep_speed = i;
srate = awacs_freqs[beep_speed];
}
if (hz <= srate / BEEP_BUFLEN || hz > srate / 2) {
#if 1
/* this is a hack for broken X server code */
hz = 750;
ticks = 12;
#else
/* cancel beep currently playing */
awacs_nosound(0);
return;
#endif
return 0;
}
spin_lock_irqsave(&dmasound.lock, flags);
del_timer(&beep_timer);
if (ticks) {
beep_timer.expires = jiffies + ticks;
add_timer(&beep_timer);
}
if (beep_playing || write_sq.active || beep_buf == NULL) {
spin_unlock_irqrestore(&dmasound.lock, flags);
return; /* too hard, sorry :-( */
return -1; /* too hard, sorry :-( */
}
beep_playing = 1;
st_le16(&beep_dbdma_cmd->command, OUTPUT_MORE + BR_ALWAYS);
......@@ -1375,8 +1389,9 @@ static void awacs_mksound(unsigned int hz, unsigned int ticks)
out_le32(&awacs_txdma->control, RUN | (RUN << 16));
}
spin_unlock_irqrestore(&dmasound.lock, flags);
return 0;
}
#endif
/* used in init and for wake-up */
......@@ -1764,7 +1779,6 @@ awacs_enable_amp(int spkr_vol)
#ifdef CONFIG_ADB_CUDA
struct adb_request req;
awacs_spkr_vol = spkr_vol;
if (sys_ctrler != SYS_CTRLER_CUDA)
return;
......@@ -2797,6 +2811,17 @@ __init setup_beep(void)
return 0 ;
}
static struct input_dev awacs_beep_dev = {
.evbit = { BIT(EV_SND) },
.sndbit = { BIT(SND_BELL) | BIT(SND_TONE) },
.event = awacs_beep_event,
.name = "dmasound beeper",
.phys = "macio/input0", /* what the heck is this?? */
.id = {
.bustype = BUS_HOST,
},
};
int __init dmasound_awacs_init(void)
{
struct device_node *io = NULL, *info = NULL;
......@@ -3086,13 +3111,9 @@ printk("dmasound_pmac: Awacs/Screamer Codec Mfct: %d Rev %d\n", mfg, rev);
/* shut out chips that do output only.
* may need to extend this to machines which have no inputs - even tho'
* they use screamer - IIRC one of the powerbooks is like this.
*
* FIXME: Actually, some TUMBLER and SNAPPER do have inputs...
*/
if (awacs_revision != AWACS_TUMBLER &&
awacs_revision != AWACS_SNAPPER &&
awacs_revision != AWACS_DACA) {
if (awacs_revision != AWACS_DACA) {
dmasound.mach.capabilities = DSP_CAP_DUPLEX ;
dmasound.mach.record = PMacRecord ;
}
......@@ -3122,11 +3143,19 @@ printk("dmasound_pmac: Awacs/Screamer Codec Mfct: %d Rev %d\n", mfg, rev);
break ;
}
/*
* XXX: we should handle errors here, but that would mean
* rewriting the whole init code. later..
*/
input_register_device(&awacs_beep_dev);
return dmasound_init();
}
static void __exit dmasound_awacs_cleanup(void)
{
input_unregister_device(&awacs_beep_dev);
switch (awacs_revision) {
case AWACS_TUMBLER:
case AWACS_SNAPPER:
......@@ -3138,6 +3167,7 @@ static void __exit dmasound_awacs_cleanup(void)
break;
}
dmasound_deinit();
}
MODULE_DESCRIPTION("PowerMac built-in audio driver.");
......
......@@ -218,6 +218,10 @@ static int state_unit = -1;
static int irq_installed;
#endif /* MODULE */
/* software implemented recording volume! */
uint software_input_volume = SW_INPUT_VOLUME_SCALE * SW_INPUT_VOLUME_DEFAULT;
EXPORT_SYMBOL(software_input_volume);
/* control over who can modify resources shared between play/record */
static mode_t shared_resource_owner;
static int shared_resources_initialised;
......@@ -238,6 +242,7 @@ static inline int sound_set_format(int format)
return dmasound.mach.setFormat(format);
}
static int sound_set_speed(int speed)
{
if (speed < 0)
......@@ -1264,15 +1269,13 @@ static int sq_ioctl(struct inode *inode, struct file *file, u_int cmd,
result = IOCTL_OUT(arg, format);
if (result < 0)
return result;
if (format != data)
if (format != data && data != AFMT_QUERY)
return -EINVAL;
return 0;
} else
return -EINVAL ;
break ;
case SNDCTL_DSP_SUBDIVIDE:
return -EINVAL ;
break;
case SNDCTL_DSP_SETFRAGMENT:
/* we can do this independently for the two queues - with the
proviso that for fds opened O_RDWR we cannot separate the
......
......@@ -5,11 +5,7 @@
* Tobias Sargeant <tobias.sargeant@bigpond.com>
* Based upon tas3001c.c by Christopher C. Chimelis <chris@debian.org>:
*
* TODO:
* -----
* * Enable control over input line 2 (is this connected?)
* * Implement sleep support (at least mute everything and
* * set gains to minimum during sleep)
* Input support by Renzo Davoli <renzo@cs.unibo.it>
*
*/
......@@ -293,7 +289,8 @@ tas3004_write_register( struct tas3004_data_t *self,
{
if (reg_num==TAS3004_REG_MCR ||
reg_num==TAS3004_REG_BASS ||
reg_num==TAS3004_REG_TREBLE) {
reg_num==TAS3004_REG_TREBLE ||
reg_num==TAS3004_REG_ANALOG_CTRL) {
return tas_write_byte_register(&self->super,
(uint)reg_num,
*data,
......@@ -313,7 +310,8 @@ tas3004_sync_register( struct tas3004_data_t *self,
{
if (reg_num==TAS3004_REG_MCR ||
reg_num==TAS3004_REG_BASS ||
reg_num==TAS3004_REG_TREBLE) {
reg_num==TAS3004_REG_TREBLE ||
reg_num==TAS3004_REG_ANALOG_CTRL) {
return tas_sync_byte_register(&self->super,
(uint)reg_num,
register_width(reg_num));
......@@ -354,7 +352,9 @@ tas3004_supported_mixers(struct tas3004_data_t *self)
SOUND_MASK_ALTPCM |
SOUND_MASK_IMIX |
SOUND_MASK_TREBLE |
SOUND_MASK_BASS;
SOUND_MASK_BASS |
SOUND_MASK_MIC |
SOUND_MASK_LINE;
}
static int
......@@ -447,6 +447,28 @@ tas3004_set_mixer_level(struct tas3004_data_t *self, int mixer, uint level)
shadow[TAS3004_REG_BASS][0]=temp&0xff;
rc = tas3004_sync_register(self,TAS3004_REG_BASS);
break;
case SOUND_MIXER_MIC:
if ((level&0xff)>0) {
software_input_volume = SW_INPUT_VOLUME_SCALE * (level&0xff);
if (self->super.mixer[mixer] == 0) {
self->super.mixer[SOUND_MIXER_LINE] = 0;
shadow[TAS3004_REG_ANALOG_CTRL][0]=0xc2;
rc = tas3004_sync_register(self,TAS3004_REG_ANALOG_CTRL);
} else rc=0;
} else {
self->super.mixer[SOUND_MIXER_LINE] = SW_INPUT_VOLUME_DEFAULT;
software_input_volume = SW_INPUT_VOLUME_SCALE *
(self->super.mixer[SOUND_MIXER_LINE]&0xff);
shadow[TAS3004_REG_ANALOG_CTRL][0]=0x00;
rc = tas3004_sync_register(self,TAS3004_REG_ANALOG_CTRL);
}
break;
case SOUND_MIXER_LINE:
if (self->super.mixer[SOUND_MIXER_MIC] == 0) {
software_input_volume = SW_INPUT_VOLUME_SCALE * (level&0xff);
rc=0;
}
break;
default:
rc = -1;
break;
......@@ -496,6 +518,7 @@ tas3004_leave_sleep(struct tas3004_data_t *self)
(void)tas3004_sync_register(self,TAS3004_REG_RIGHT_MIXER);
(void)tas3004_sync_register(self,TAS3004_REG_TREBLE);
(void)tas3004_sync_register(self,TAS3004_REG_BASS);
(void)tas3004_sync_register(self,TAS3004_REG_ANALOG_CTRL);
return 0;
}
......@@ -1050,6 +1073,8 @@ tas3004_init_mixer(struct tas3004_data_t *self)
tas3004_set_mixer_level(self, SOUND_MIXER_BASS, BASS_DEFAULT);
tas3004_set_mixer_level(self, SOUND_MIXER_TREBLE, TREBLE_DEFAULT);
tas3004_set_mixer_level(self, SOUND_MIXER_LINE,SW_INPUT_VOLUME_DEFAULT);
return 0;
}
......@@ -1064,6 +1089,8 @@ tas3004_uninit_mixer(struct tas3004_data_t *self)
tas3004_set_mixer_level(self, SOUND_MIXER_BASS, 0);
tas3004_set_mixer_level(self, SOUND_MIXER_TREBLE, 0);
tas3004_set_mixer_level(self, SOUND_MIXER_LINE, 0);
return 0;
}
......
......@@ -195,6 +195,9 @@ tas_init(int driver_id, const char *driver_name)
printk(KERN_INFO "tas driver [%s])\n", driver_name);
#ifndef CONFIG_I2C_KEYWEST
request_module("i2c-keywest");
#endif
tas_node = find_devices("deq");
if (tas_node == NULL)
return -ENODEV;
......
......@@ -87,7 +87,7 @@ struct tas_gain_t
unsigned int *mixer;
};
typedef char tas_shadow_t[16];
typedef char tas_shadow_t[0x45];
struct tas_data_t
{
......
......@@ -8,6 +8,9 @@
*
* 08/02/2001 Iain Sandoe
* split from dmasound_awacs.c
* 11/29/2003 Renzo Davoli (King Enzo)
* - input resampling (for soft rate < hard rate)
* - software line in gain control
*/
#include <linux/soundcard.h>
......@@ -58,7 +61,6 @@ static ssize_t pmac_ct_u16_read(const u_char *userPtr, size_t userCount,
/*** Translations ************************************************************/
extern int expand_bal; /* Balance factor for expanding (not volume!) */
static int expand_data; /* Data for expanding */
static ssize_t pmac_ct_law(const u_char *userPtr, size_t userCount,
......@@ -461,11 +463,13 @@ static ssize_t pmac_ct_s8_read(const u_char *userPtr, size_t userCount,
u_char data;
val = *p++;
val = (val * software_input_volume) >> 7;
data = val >> 8;
if (put_user(data, (u_char *)userPtr++))
return -EFAULT;
if (stereo) {
val = *p;
val = (val * software_input_volume) >> 7;
data = val >> 8;
if (put_user(data, (u_char *)userPtr++))
return -EFAULT;
......@@ -494,11 +498,13 @@ static ssize_t pmac_ct_u8_read(const u_char *userPtr, size_t userCount,
u_char data;
val = *p++;
val = (val * software_input_volume) >> 7;
data = (val >> 8) ^ 0x80;
if (put_user(data, (u_char *)userPtr++))
return -EFAULT;
if (stereo) {
val = *p;
val = (val * software_input_volume) >> 7;
data = (val >> 8) ^ 0x80;
if (put_user(data, (u_char *)userPtr++))
return -EFAULT;
......@@ -517,24 +523,27 @@ static ssize_t pmac_ct_s16_read(const u_char *userPtr, size_t userCount,
ssize_t count, used;
int stereo = dmasound.soft.stereo;
short *fp = (short *) &frame[*frameUsed];
short *up = (short *) userPtr;
frameLeft >>= 2;
userCount >>= (stereo? 2: 1);
used = count = min_t(unsigned long, userCount, frameLeft);
if (!stereo) {
short *up = (short *) userPtr;
while (count > 0) {
short data;
while (count > 0) {
short data;
data = *fp++;
data = (data * software_input_volume) >> 7;
if (put_user(data, up++))
return -EFAULT;
if (stereo) {
data = *fp;
data = (data * software_input_volume) >> 7;
if (put_user(data, up++))
return -EFAULT;
fp+=2;
count--;
}
} else {
if (copy_to_user((u_char *)userPtr, fp, count * 4))
return -EFAULT;
}
fp++;
count--;
}
*frameUsed += used * 4;
return stereo? used * 4: used * 2;
}
......@@ -556,11 +565,13 @@ static ssize_t pmac_ct_u16_read(const u_char *userPtr, size_t userCount,
int data;
data = *fp++;
data = (data * software_input_volume) >> 7;
data ^= mask;
if (put_user(data, up++))
return -EFAULT;
if (stereo) {
data = *fp;
data = (data * software_input_volume) >> 7;
data ^= mask;
if (put_user(data, up++))
return -EFAULT;
......@@ -572,6 +583,204 @@ static ssize_t pmac_ct_u16_read(const u_char *userPtr, size_t userCount,
return stereo? used * 4: used * 2;
}
/* data in routines (reducing speed)... */
static ssize_t pmac_ctx_s8_read(const u_char *userPtr, size_t userCount,
u_char frame[], ssize_t *frameUsed,
ssize_t frameLeft)
{
short *p = (short *) &frame[*frameUsed];
int bal = expand_read_bal;
int vall,valr, stereo = dmasound.soft.stereo;
int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
int utotal, ftotal;
frameLeft >>= 2;
if (stereo)
userCount >>= 1;
ftotal = frameLeft;
utotal = userCount;
while (frameLeft) {
u_char data;
if (bal<0 && userCount == 0)
break;
vall = *p++;
vall = (vall * software_input_volume) >> 7;
if (stereo) {
valr = *p;
valr = (valr * software_input_volume) >> 7;
}
p++;
if (bal < 0) {
data = vall >> 8;
if (put_user(data, (u_char *)userPtr++))
return -EFAULT;
if (stereo) {
data = valr >> 8;
if (put_user(data, (u_char *)userPtr++))
return -EFAULT;
}
userCount--;
bal += hSpeed;
}
frameLeft--;
bal -= sSpeed;
}
expand_read_bal=bal;
*frameUsed += (ftotal - frameLeft) * 4;
utotal -= userCount;
return stereo? utotal * 2: utotal;
}
static ssize_t pmac_ctx_u8_read(const u_char *userPtr, size_t userCount,
u_char frame[], ssize_t *frameUsed,
ssize_t frameLeft)
{
short *p = (short *) &frame[*frameUsed];
int bal = expand_read_bal;
int vall,valr, stereo = dmasound.soft.stereo;
int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
int utotal, ftotal;
frameLeft >>= 2;
if (stereo)
userCount >>= 1;
ftotal = frameLeft;
utotal = userCount;
while (frameLeft) {
u_char data;
if (bal<0 && userCount == 0)
break;
vall = *p++;
vall = (vall * software_input_volume) >> 7;
if (stereo) {
valr = *p;
valr = (valr * software_input_volume) >> 7;
}
p++;
if (bal < 0) {
data = (vall >> 8) ^ 0x80;
if (put_user(data, (u_char *)userPtr++))
return -EFAULT;
if (stereo) {
data = (valr >> 8) ^ 0x80;
if (put_user(data, (u_char *)userPtr++))
return -EFAULT;
}
userCount--;
bal += hSpeed;
}
frameLeft--;
bal -= sSpeed;
}
expand_read_bal=bal;
*frameUsed += (ftotal - frameLeft) * 4;
utotal -= userCount;
return stereo? utotal * 2: utotal;
}
static ssize_t pmac_ctx_s16_read(const u_char *userPtr, size_t userCount,
u_char frame[], ssize_t *frameUsed,
ssize_t frameLeft)
{
int bal = expand_read_bal;
short *fp = (short *) &frame[*frameUsed];
short *up = (short *) userPtr;
int stereo = dmasound.soft.stereo;
int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
int utotal, ftotal;
frameLeft >>= 2;
userCount >>= (stereo? 2: 1);
ftotal = frameLeft;
utotal = userCount;
while (frameLeft) {
int datal,datar;
if (bal<0 && userCount == 0)
break;
datal = *fp++;
datal = (datal * software_input_volume) >> 7;
if (stereo) {
datar = *fp;
datar = (datar * software_input_volume) >> 7;
}
fp++;
if (bal < 0) {
if (put_user(datal, up++))
return -EFAULT;
if (stereo) {
if (put_user(datar, up++))
return -EFAULT;
}
userCount--;
bal += hSpeed;
}
frameLeft--;
bal -= sSpeed;
}
expand_read_bal=bal;
*frameUsed += (ftotal - frameLeft) * 4;
utotal -= userCount;
return stereo? utotal * 4: utotal * 2;
}
static ssize_t pmac_ctx_u16_read(const u_char *userPtr, size_t userCount,
u_char frame[], ssize_t *frameUsed,
ssize_t frameLeft)
{
int bal = expand_read_bal;
int mask = (dmasound.soft.format == AFMT_U16_LE? 0x0080: 0x8000);
short *fp = (short *) &frame[*frameUsed];
short *up = (short *) userPtr;
int stereo = dmasound.soft.stereo;
int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
int utotal, ftotal;
frameLeft >>= 2;
userCount >>= (stereo? 2: 1);
ftotal = frameLeft;
utotal = userCount;
while (frameLeft) {
int datal,datar;
if (bal<0 && userCount == 0)
break;
datal = *fp++;
datal = (datal * software_input_volume) >> 7;
datal ^= mask;
if (stereo) {
datar = *fp;
datar = (datar * software_input_volume) >> 7;
datar ^= mask;
}
fp++;
if (bal < 0) {
if (put_user(datal, up++))
return -EFAULT;
if (stereo) {
if (put_user(datar, up++))
return -EFAULT;
}
userCount--;
bal += hSpeed;
}
frameLeft--;
bal -= sSpeed;
}
expand_read_bal=bal;
*frameUsed += (ftotal - frameLeft) * 4;
utotal -= userCount;
return stereo? utotal * 4: utotal * 2;
}
TRANS transAwacsNormal = {
.ct_ulaw= pmac_ct_law,
.ct_alaw= pmac_ct_law,
......@@ -603,6 +812,15 @@ TRANS transAwacsNormalRead = {
.ct_u16le= pmac_ct_u16_read,
};
TRANS transAwacsExpandRead = {
.ct_s8= pmac_ctx_s8_read,
.ct_u8= pmac_ctx_u8_read,
.ct_s16be= pmac_ctx_s16_read,
.ct_u16be= pmac_ctx_u16_read,
.ct_s16le= pmac_ctx_s16_read,
.ct_u16le= pmac_ctx_u16_read,
};
/* translation tables */
/* 16 bit mu-law */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment