es1370 driver and updated es1371 and framework by Pieter Hijma.

This commit is contained in:
Ben Gras 2007-11-23 11:40:33 +00:00
parent 0d2d8c6db2
commit c67a56708e
19 changed files with 2348 additions and 1316 deletions

View file

@ -1,9 +1,9 @@
***** Minix 3 Audio drivers *****
Directories:
framework/ Generic driver framework
sb16/ SB16 ISA driver
es1370/ ES1370 driver
es1371/ ES1371 driver
@ -18,11 +18,12 @@ Creating special files:
* mknod rec c 13 1
* mknod mixer c 13 2
* chmod 666 audio rec mixer
(for es1371 one can add a special file for the second DAC-channel, major 13, minor 3)
(one can add a special file for the second DAC-channel, major 13, minor 3)
Running the driver:
* service up /usr/sbin/sb16 -dev /dev/audio
* service up /usr/sbin/es1370 -dev /dev/audio
or:
* service up /usr/sbin/es1371 -dev /dev/audio

View file

@ -0,0 +1,39 @@
# Makefile for the ES1371 sounddriver (SB16)
# directories
u = /usr
i = $u/include
s = $i/sys
m = $i/minix
b = $i/ibm
gen_drv_dir = ../../gen_drivers/cyclic_dma
# programs, flags, etc.
CC = exec cc
CFLAGS = -I$i
LDFLAGS = -i
LIBS = -lsys -lsysutil
# build local binary
all: es1370
es1370: es1370.o ak4531.o audio_fw.o pci_helper.o
$(CC) -o $@ $(LDFLAGS) es1370.o ak4531.o audio_fw.o pci_helper.o $(LIBS)
audio_fw.o: ../framework/audio_fw.c ../framework/audio_fw.h
$(CC) -c ../framework/audio_fw.c
install: /usr/sbin/es1370
/usr/sbin/es1370: es1370
install -o root -S 1024k -c $? $@
# clean up local files
clean:
rm -f *.o *.bak core es1370
depend:
/usr/bin/mkdep "$(CC) -E $(CPPFLAGS)" *.c > .depend
# Include generated dependencies.
include .depend

View file

@ -0,0 +1,177 @@
/* best viewed with tabsize 4 */
#include "ak4531.h"
#include "pci_helper.h"
#define MASTER_VOLUME_LCH 0x00
#define MASTER_VOLUME_RCH 0x01
#define FM_VOLUME_LCH 0x04
#define FM_VOLUME_RCH 0x05
#define CD_AUDIO_VOLUME_LCH 0x06
#define CD_AUDIO_VOLUME_RCH 0x07
#define LINE_VOLUME_LCH 0x08
#define LINE_VOLUME_RCH 0x09
#define MIC_VOLUME 0x0e
#define MONO_OUT_VOLUME 0x0f
#define RESET_AND_POWER_DOWN 0x16
#define PD 0x02
#define RST 0x01
#define AD_INPUT_SELECT 0x18
#define MIC_AMP_GAIN 0x19
#define MUTE 0x80
FORWARD _PROTOTYPE( int ak4531_write, (u8_t address, u8_t data) );
FORWARD _PROTOTYPE( int ak4531_finished, (void) );
FORWARD _PROTOTYPE( int set_volume, (struct volume_level *level,
int cmd_left, int cmd_right, int max_level) );
PRIVATE u16_t base_address;
PRIVATE u16_t status_register;
PRIVATE u16_t status_bit;
PRIVATE u16_t poll_address;
u8_t mixer_values[0x20] = {
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, /* 0x00 - 0x07 */
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x08, /* 0x08 - 0x0f */
0x7e, 0x3d, 0x01, 0x01, 0x00, 0x00, 0x03, 0x00, /* 0x10 - 0x17 */
0x00, 0x01 /* 0x18 - 0x19 */
};
#if 0
u8_t mixer_values[0x20] = {
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, /* 0x00 - 0x07 */
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, /* 0x08 - 0x0f */
0x7f, 0x3d, 0x55, 0x26, 0xf7, 0xef, 0x03, 0x00, /* 0x10 - 0x17 */
0x00, 0x01 /* 0x18 - 0x19 */
};
#endif
PRIVATE int ak4531_finished(void) {
int i;
u16_t cstat;
for (i = 0; i < 0x40000; i++) {
cstat = pci_inw(status_register);
if (!(cstat & status_bit)) {
return 1;
}
}
return 0;
}
PRIVATE int ak4531_write (u8_t address, u8_t data) {
u16_t to_be_written;
if (address < MASTER_VOLUME_LCH || address > MIC_AMP_GAIN) return -1;
to_be_written = (u16_t)((address << 8) | data);
if (!ak4531_finished()) return -1;
pci_outw(base_address, to_be_written);
return 0;
}
PUBLIC int ak4531_init(u16_t base, u16_t status_reg, u16_t bit,
u16_t poll) {
int i;
base_address = base;
status_register = status_reg;
status_bit = bit;
poll_address = poll;
for (i=0; i<100; i++) {
pci_inb(poll_address);
}
if(ak4531_write(RESET_AND_POWER_DOWN, PD|RST) < 0) return -1;
for (i=0; i<100; i++) {
pci_inb(poll_address);
}
ak4531_write(AD_INPUT_SELECT, 0x00);
for (i = MASTER_VOLUME_LCH ; i <= MIC_AMP_GAIN; i++) {
if (ak4531_write(i, mixer_values[i]) < 0) return -1;
}
return 0;
}
PUBLIC int ak4531_get_set_volume(struct volume_level *level, int flag) {
int cmd_left, cmd_right, max_level;
max_level = 0x1f;
switch(level->device) {
case Master:
cmd_left = MASTER_VOLUME_LCH;
cmd_right = MASTER_VOLUME_RCH;
break;
case Dac:
return EINVAL;
break;
case Fm:
cmd_left = FM_VOLUME_LCH;
cmd_right = FM_VOLUME_RCH;
break;
case Cd:
cmd_left = CD_AUDIO_VOLUME_LCH;
cmd_right = CD_AUDIO_VOLUME_RCH;
break;
case Line:
cmd_left = LINE_VOLUME_LCH;
cmd_right = LINE_VOLUME_RCH;
break;
case Mic:
cmd_left = cmd_right = MIC_VOLUME;
break;
case Speaker:
cmd_left = cmd_right = MONO_OUT_VOLUME;
max_level = 0x03;
break;
case Treble:
return EINVAL;
break;
case Bass:
return EINVAL;
break;
default:
return EINVAL;
}
if (flag) { /* set volume */
return set_volume(level, cmd_left, cmd_right, max_level);
}
else { /* get volume */
level->left = - ((int) (mixer_values[cmd_left] & ~MUTE)) + 0x1f;
level->right = - ((int) (mixer_values[cmd_right] & ~MUTE)) + 0x1f;
return OK;
}
}
PRIVATE int set_volume(struct volume_level *level, int cmd_left, int cmd_right,
int max_level) {
if(level->right < 0) level->right = 0;
else if(level->right > max_level) level->right = max_level;
if(level->left < 0) level->left = 0;
else if(level->left > max_level) level->left = max_level;
mixer_values[cmd_left] = (-level->left)+0x1f;
ak4531_write(cmd_left, mixer_values[cmd_left]);
mixer_values[cmd_right] = (-level->right)+0x1f;
ak4531_write(cmd_right, mixer_values[cmd_right]);
return OK;
}

View file

@ -0,0 +1,12 @@
#ifndef AK4531_H
#define AK4531_H
/* best viewed with tabsize=4 */
#include "../../drivers.h"
#include <minix/sound.h>
_PROTOTYPE( int ak4531_init, (u16_t base, u16_t status_reg, u16_t bit,
u16_t poll) );
_PROTOTYPE( int ak4531_get_set_volume, (struct volume_level *level, int flag) );
#endif

View file

@ -0,0 +1,653 @@
/* Best viewed with tabsize 4 */
/* Ensoniq ES1370 driver
*
* aka AudioPCI '97
*
* This is the main file of the ES1370 sound driver. There is no main function
* over here, instead the main function is located in the generic dma driver.
* All this driver does is implement the interface audio/audio_fw.h. All
* functions having the prefix 'drv_' are dictated by audio/audio_fw.h. The
* function prototypes you see below define a set of private helper functions.
* Control over the AK4531 codec is delegated ak4531.c.
*
* September 2007 ES1370 driver (Pieter Hijma),
* based on ES1371 driver by Laurens Bronwasser
*/
#include <ibm/pci.h>
#include "../framework/audio_fw.h"
#include "es1370.h"
#include "ak4531.h"
#include "pci_helper.h"
/* reg(n) will be the device specific addresses */
#define reg(n) dev.base + n
/* prototypes of private functions */
FORWARD _PROTOTYPE( int detect_hw, (void) );
FORWARD _PROTOTYPE( int disable_int, (int sub_dev) );
FORWARD _PROTOTYPE( int set_stereo, (u32_t stereo, int sub_dev) );
FORWARD _PROTOTYPE( int set_bits, (u32_t nr_of_bits, int sub_dev) );
FORWARD _PROTOTYPE( int set_sample_rate, (u32_t rate, int sub_dev) );
FORWARD _PROTOTYPE( int set_sign, (u32_t val, int sub_dev) );
FORWARD _PROTOTYPE( int get_max_frag_size,
(u32_t * val, int *len, int sub_dev) );
FORWARD _PROTOTYPE( int set_frag_size, (u32_t fragment_size, int sub_dev) );
FORWARD _PROTOTYPE( int set_int_cnt, (int sub_dev) );
FORWARD _PROTOTYPE( int free_buf, (u32_t *val, int *len, int sub_dev) );
FORWARD _PROTOTYPE( int get_samples_in_buf,
(u32_t *val, int *len, int sub_dev) );
FORWARD _PROTOTYPE( int get_set_volume, (struct volume_level *level, int *len,
int sub_dev, int flag) );
FORWARD _PROTOTYPE( int reset, (int sub_dev) );
DEV_STRUCT dev;
aud_sub_dev_conf_t aud_conf[4];
PUBLIC sub_dev_t sub_dev[4];
PUBLIC special_file_t special_file[4];
PUBLIC drv_t drv;
PUBLIC int drv_init(void) {
drv.DriverName = DRIVER_NAME;
drv.NrOfSubDevices = 4;
drv.NrOfSpecialFiles = 4;
sub_dev[DAC1_CHAN].readable = 0;
sub_dev[DAC1_CHAN].writable = 1;
sub_dev[DAC1_CHAN].DmaSize = 64 * 1024;
sub_dev[DAC1_CHAN].NrOfDmaFragments = 2;
sub_dev[DAC1_CHAN].MinFragmentSize = 1024;
sub_dev[DAC1_CHAN].NrOfExtraBuffers = 4;
sub_dev[ADC1_CHAN].readable = 1;
sub_dev[ADC1_CHAN].writable = 0;
sub_dev[ADC1_CHAN].DmaSize = 64 * 1024;
sub_dev[ADC1_CHAN].NrOfDmaFragments = 2;
sub_dev[ADC1_CHAN].MinFragmentSize = 1024;
sub_dev[ADC1_CHAN].NrOfExtraBuffers = 4;
sub_dev[MIXER].writable = 0;
sub_dev[MIXER].readable = 0;
sub_dev[DAC2_CHAN].readable = 0;
sub_dev[DAC2_CHAN].writable = 1;
sub_dev[DAC2_CHAN].DmaSize = 64 * 1024;
sub_dev[DAC2_CHAN].NrOfDmaFragments = 2;
sub_dev[DAC2_CHAN].MinFragmentSize = 1024;
sub_dev[DAC2_CHAN].NrOfExtraBuffers = 4;
special_file[0].minor_dev_nr = 0;
special_file[0].write_chan = DAC1_CHAN;
special_file[0].read_chan = NO_CHANNEL;
special_file[0].io_ctl = DAC1_CHAN;
special_file[1].minor_dev_nr = 1;
special_file[1].write_chan = NO_CHANNEL;
special_file[1].read_chan = ADC1_CHAN;
special_file[1].io_ctl = ADC1_CHAN;
special_file[2].minor_dev_nr = 2;
special_file[2].write_chan = NO_CHANNEL;
special_file[2].read_chan = NO_CHANNEL;
special_file[2].io_ctl = MIXER;
special_file[3].minor_dev_nr = 3;
special_file[3].write_chan = DAC2_CHAN;
special_file[3].read_chan = NO_CHANNEL;
special_file[3].io_ctl = DAC2_CHAN;
}
PUBLIC int drv_init_hw (void) {
u16_t i, j;
u16_t chip_sel_ctrl_reg;
/* First, detect the hardware */
if (detect_hw() != OK) {
return EIO;
}
/* PCI command register
* enable the SERR# driver, PCI bus mastering and I/O access
*/
pci_attr_w16 (dev.devind, PCI_CR, SERR_EN|PCI_MASTER|IO_ACCESS);
/* turn everything off */
pci_outl(reg(CHIP_SEL_CTRL), 0x0UL);
/* turn off legacy (legacy control is undocumented) */
pci_outl(reg(LEGACY), 0x0UL);
pci_outl(reg(LEGACY+4), 0x0UL);
/* turn off serial interface */
pci_outl(reg(SERIAL_INTERFACE_CTRL), 0x0UL);
/*pci_outl(reg(SERIAL_INTERFACE_CTRL), 0x3UL);*/
/* enable the codec */
chip_sel_ctrl_reg = pci_inw(reg(CHIP_SEL_CTRL));
chip_sel_ctrl_reg |= XCTL0 | CDC_EN;
pci_outw(reg(CHIP_SEL_CTRL), chip_sel_ctrl_reg);
/* initialize the codec */
if (ak4531_init(reg(CODEC_WRITE_ADDRESS),
reg(INTERRUPT_STATUS), CWRIP, reg(0)) < 0) {
return EINVAL;
}
/* clear all the memory */
for (i = 0; i < 0x10; ++i) {
pci_outb(reg(MEM_PAGE), i);
for (j = 0; j < 0x10; j += 4) {
pci_outl (reg(MEMORY) + j, 0x0UL);
}
}
/* initialize variables for each sub_device */
for (i = 0; i < drv.NrOfSubDevices; i++) {
if(i != MIXER) {
aud_conf[i].busy = 0;
aud_conf[i].stereo = DEFAULT_STEREO;
aud_conf[i].sample_rate = DEFAULT_RATE;
aud_conf[i].nr_of_bits = DEFAULT_NR_OF_BITS;
aud_conf[i].sign = DEFAULT_SIGNED;
aud_conf[i].fragment_size =
sub_dev[i].DmaSize / sub_dev[i].NrOfDmaFragments;
}
}
return OK;
}
PRIVATE int detect_hw(void) {
u32_t device;
int devind;
u16_t v_id, d_id;
/* detect_hw tries to find device and get IRQ and base address
with a little (much) help from the PCI library.
This code is quite device independent and you can copy it.
(just make sure to get the bugs out first)*/
pci_init();
/* get first device and then search through the list */
device = pci_first_dev(&devind, &v_id, &d_id);
while( device > 0 ) {
/* if we have a match...break */
if (v_id == VENDOR_ID && d_id == DEVICE_ID) break;
device = pci_next_dev(&devind, &v_id, &d_id);
}
/* did we find anything? */
if (v_id != VENDOR_ID || d_id != DEVICE_ID) {
return EIO;
}
pci_reserve(devind);
dev.name = pci_dev_name(v_id, d_id);
/* get base address of our device, ignore least signif. bit
this last bit thing could be device dependent, i don't know */
dev.base = pci_attr_r32(devind, PCI_BAR) & 0xfffffffe;
/* get IRQ */
dev.irq = pci_attr_r8(devind, PCI_ILR);
dev.revision = pci_attr_r8(devind, PCI_REV);
dev.d_id = d_id;
dev.v_id = v_id;
dev.devind = devind; /* pci device identifier */
return OK;
}
PRIVATE int reset(int chan) {
drv_stop(chan);
sub_dev[chan].OutOfData = 1;
return OK;
}
int drv_reset() {
return OK;
}
int drv_start(int sub_dev, int DmaMode) {
u32_t enable_bit, result = 0;
u32_t debug;
/* Write default values to device in case user failed to configure.
If user did configure properly, everything is written twice.
please raise your hand if you object against to this strategy...*/
result |= set_sample_rate(aud_conf[sub_dev].sample_rate, sub_dev);
result |= set_stereo(aud_conf[sub_dev].stereo, sub_dev);
result |= set_bits(aud_conf[sub_dev].nr_of_bits, sub_dev);
result |= set_sign(aud_conf[sub_dev].sign, sub_dev);
/* set the interrupt count */
result |= set_int_cnt(sub_dev);
if (result) {
return EIO;
}
/* if device currently paused, resume */
drv_resume(sub_dev);
switch(sub_dev) {
case ADC1_CHAN: enable_bit = ADC1_EN;break;
case DAC1_CHAN: enable_bit = DAC1_EN;break;
case DAC2_CHAN: enable_bit = DAC2_EN;break;
default: return EINVAL;
}
/* enable interrupts from 'sub device' */
drv_reenable_int(sub_dev);
/* this means play!!! */
pci_outw(reg(CHIP_SEL_CTRL), pci_inw(reg(CHIP_SEL_CTRL)) | enable_bit);
aud_conf[sub_dev].busy = 1;
return OK;
}
int drv_stop(int sub_dev)
{
u32_t enable_bit;
switch(sub_dev) {
case ADC1_CHAN: enable_bit = ADC1_EN;break;
case DAC1_CHAN: enable_bit = DAC1_EN;break;
case DAC2_CHAN: enable_bit = DAC2_EN;break;
default: return EINVAL;
}
/* stop the specified channel */
pci_outw(reg(CHIP_SEL_CTRL),
pci_inw(reg(CHIP_SEL_CTRL)) & ~enable_bit);
aud_conf[sub_dev].busy = 0;
disable_int(sub_dev);
return OK;
}
/* all IO-ctl's sent to the upper driver are passed to this function */
int drv_io_ctl(int request, void * val, int * len, int sub_dev) {
int status;
switch(request) {
case DSPIORATE:
status = set_sample_rate(*((u32_t *) val), sub_dev); break;
case DSPIOSTEREO:
status = set_stereo(*((u32_t *) val), sub_dev); break;
case DSPIOBITS:
status = set_bits(*((u32_t *) val), sub_dev); break;
case DSPIOSIZE:
status = set_frag_size(*((u32_t *) val), sub_dev); break;
case DSPIOSIGN:
status = set_sign(*((u32_t *) val), sub_dev); break;
case DSPIOMAX:
status = get_max_frag_size(val, len, sub_dev); break;
case DSPIORESET:
status = reset(sub_dev); break;
case DSPIOFREEBUF:
status = free_buf(val, len, sub_dev); break;
case DSPIOSAMPLESINBUF:
status = get_samples_in_buf(val, len, sub_dev); break;
case DSPIOPAUSE:
status = drv_pause(sub_dev); break;
case DSPIORESUME:
status = drv_resume(sub_dev); break;
case MIXIOGETVOLUME:
status = get_set_volume(val, len, sub_dev, 0); break;
case MIXIOSETVOLUME:
status = get_set_volume(val, len, sub_dev, 1); break;
default:
status = EINVAL; break;
}
return OK;
}
int drv_get_irq(char *irq) {
*irq = dev.irq;
return OK;
}
int drv_get_frag_size(u32_t *frag_size, int sub_dev) {
*frag_size = aud_conf[sub_dev].fragment_size;
return OK;
}
int drv_set_dma(u32_t dma, u32_t length, int chan) {
/* dma length in bytes,
max is 64k long words for es1370 = 256k bytes */
u32_t page, frame_count_reg, dma_add_reg;
switch(chan) {
case ADC1_CHAN: page = ADC_MEM_PAGE;
frame_count_reg = ADC_BUFFER_SIZE;
dma_add_reg = ADC_PCI_ADDRESS;
break;
case DAC1_CHAN: page = DAC_MEM_PAGE;
frame_count_reg = DAC1_BUFFER_SIZE;
dma_add_reg = DAC1_PCI_ADDRESS;
break;;
case DAC2_CHAN: page = DAC_MEM_PAGE;
frame_count_reg = DAC2_BUFFER_SIZE;
dma_add_reg = DAC2_PCI_ADDRESS;
break;;
default: return EIO;
}
pci_outb(reg(MEM_PAGE), page);
pci_outl(reg(dma_add_reg), dma);
/* device expects long word count in stead of bytes */
length /= 4;
/* It seems that register _CURRENT_COUNT is overwritten, but this is
* the way to go. The register frame_count_reg is only longword
* addressable.
* It expects length -1
*/
pci_outl(reg(frame_count_reg), (u32_t) (length - 1));
return OK;
}
/* return status of the interrupt summary bit */
int drv_int_sum(void) {
return pci_inl(reg(INTERRUPT_STATUS)) & INTR;
}
int drv_int(int sub_dev) {
u32_t int_status;
u32_t bit;
u32_t debug;
/* return status of interrupt bit of specified channel*/
switch (sub_dev) {
case DAC1_CHAN: bit = DAC1;break;
case DAC2_CHAN: bit = DAC2;break;
case ADC1_CHAN: bit = ADC;break;
}
int_status = pci_inl(reg(INTERRUPT_STATUS)) & bit;
return int_status;
}
int drv_reenable_int(int chan) {
u16_t ser_interface, int_en_bit;
switch(chan) {
case ADC1_CHAN: int_en_bit = R1_INT_EN; break;
case DAC1_CHAN: int_en_bit = P1_INTR_EN; break;
case DAC2_CHAN: int_en_bit = P2_INTR_EN; break;
default: EINVAL;
}
/* clear and reenable an interrupt */
ser_interface = pci_inw(reg(SERIAL_INTERFACE_CTRL));
pci_outw(reg(SERIAL_INTERFACE_CTRL), ser_interface & ~int_en_bit);
pci_outw(reg(SERIAL_INTERFACE_CTRL), ser_interface | int_en_bit);
return OK;
}
int drv_pause(int sub_dev) {
u32_t pause_bit;
disable_int(sub_dev); /* don't send interrupts */
switch(sub_dev) {
case DAC1_CHAN: pause_bit = P1_PAUSE;break;
case DAC2_CHAN: pause_bit = P2_PAUSE;break;
default: return EINVAL;
}
/* pause */
pci_outl(reg(SERIAL_INTERFACE_CTRL),
pci_inl(reg(SERIAL_INTERFACE_CTRL)) | pause_bit);
return OK;
}
int drv_resume(int sub_dev) {
u32_t pause_bit = 0;
drv_reenable_int(sub_dev); /* enable interrupts */
switch(sub_dev) {
case DAC1_CHAN: pause_bit = P1_PAUSE;break;
case DAC2_CHAN: pause_bit = P2_PAUSE;break;
default: return EINVAL;
}
/* clear pause bit */
pci_outl(reg(SERIAL_INTERFACE_CTRL),
pci_inl(reg(SERIAL_INTERFACE_CTRL)) & ~pause_bit);
return OK;
}
PRIVATE int set_bits(u32_t nr_of_bits, int sub_dev) {
/* set format bits for specified channel. */
u16_t size_16_bit, ser_interface;
switch(sub_dev) {
case ADC1_CHAN: size_16_bit = R1_S_EB; break;
case DAC1_CHAN: size_16_bit = P1_S_EB; break;
case DAC2_CHAN: size_16_bit = P2_S_EB; break;
default: return EINVAL;
}
ser_interface = pci_inw(reg(SERIAL_INTERFACE_CTRL));
ser_interface &= ~size_16_bit;
switch(nr_of_bits) {
case 16: ser_interface |= size_16_bit;break;
case 8: break;
default: return EINVAL;
}
pci_outw(reg(SERIAL_INTERFACE_CTRL), ser_interface);
aud_conf[sub_dev].nr_of_bits = nr_of_bits;
return OK;
}
PRIVATE int set_stereo(u32_t stereo, int sub_dev) {
/* set format bits for specified channel. */
u16_t stereo_bit, ser_interface;
switch(sub_dev) {
case ADC1_CHAN: stereo_bit = R1_S_MB; break;
case DAC1_CHAN: stereo_bit = P1_S_MB; break;
case DAC2_CHAN: stereo_bit = P2_S_MB; break;
default: return EINVAL;
}
ser_interface = pci_inw(reg(SERIAL_INTERFACE_CTRL));
ser_interface &= ~stereo_bit;
if (stereo) {
ser_interface |= stereo_bit;
}
pci_outw(reg(SERIAL_INTERFACE_CTRL), ser_interface);
aud_conf[sub_dev].stereo = stereo;
return OK;
}
PRIVATE int set_sign(u32_t val, int sub_dev) {
return OK;
}
PRIVATE int set_frag_size(u32_t fragment_size, int sub_dev_nr) {
if (fragment_size > (sub_dev[sub_dev_nr].DmaSize /
sub_dev[sub_dev_nr].NrOfDmaFragments) ||
fragment_size < sub_dev[sub_dev_nr].MinFragmentSize) {
return EINVAL;
}
aud_conf[sub_dev_nr].fragment_size = fragment_size;
return OK;
}
PRIVATE int set_sample_rate(u32_t rate, int sub_dev) {
/* currently only 44.1kHz */
u32_t controlRegister;
if (rate > MAX_RATE || rate < MIN_RATE) {
return EINVAL;
}
controlRegister = pci_inl(reg(CHIP_SEL_CTRL));
controlRegister |= FREQ_44K100;
pci_outl(reg(CHIP_SEL_CTRL), controlRegister);
aud_conf[sub_dev].sample_rate = rate;
return OK;
}
PRIVATE int set_int_cnt(int chan) {
/* Write interrupt count for specified channel.
After <DspFragmentSize> bytes, an interrupt will be generated */
int sample_count;
u16_t int_cnt_reg;
if (aud_conf[chan].fragment_size >
(sub_dev[chan].DmaSize / sub_dev[chan].NrOfDmaFragments)
|| aud_conf[chan].fragment_size < sub_dev[chan].MinFragmentSize) {
return EINVAL;
}
switch(chan) {
case ADC1_CHAN: int_cnt_reg = ADC_SAMP_CT; break;
case DAC1_CHAN: int_cnt_reg = DAC1_SAMP_CT; break;
case DAC2_CHAN: int_cnt_reg = DAC2_SAMP_CT; break;
default: return EINVAL;
}
sample_count = aud_conf[chan].fragment_size;
/* adjust sample count according to sample format */
if( aud_conf[chan].stereo == TRUE ) sample_count >>= 1;
switch(aud_conf[chan].nr_of_bits) {
case 16: sample_count >>= 1;break;
case 8: break;
default: return EINVAL;
}
/* set the sample count - 1 for the specified channel. */
pci_outw(reg(int_cnt_reg), sample_count - 1);
return OK;
}
PRIVATE int get_max_frag_size(u32_t * val, int * len, int sub_dev_nr) {
*len = sizeof(*val);
*val = (sub_dev[sub_dev_nr].DmaSize /
sub_dev[sub_dev_nr].NrOfDmaFragments);
return OK;
}
PRIVATE int disable_int(int chan) {
u16_t ser_interface, int_en_bit;
switch(chan) {
case ADC1_CHAN: int_en_bit = R1_INT_EN; break;
case DAC1_CHAN: int_en_bit = P1_INTR_EN; break;
case DAC2_CHAN: int_en_bit = P2_INTR_EN; break;
default: EINVAL;
}
/* clear the interrupt */
ser_interface = pci_inw(reg(SERIAL_INTERFACE_CTRL));
pci_outw(reg(SERIAL_INTERFACE_CTRL), ser_interface & ~int_en_bit);
}
PRIVATE int get_samples_in_buf (u32_t *samples_in_buf, int *len, int chan) {
u16_t samp_ct_reg;
u16_t curr_samp_ct_reg;
u16_t samp_ct; /* nr of samples - 1 that will be played back */
u16_t curr_samp_ct; /* counts back from SAMP_CT till 0 */
*len = sizeof(*samples_in_buf);
switch(chan) {
case ADC1_CHAN:
curr_samp_ct_reg = ADC_CURR_SAMP_CT;
samp_ct_reg = ADC_SAMP_CT; break;
case DAC1_CHAN:
curr_samp_ct_reg = DAC1_CURR_SAMP_CT;
samp_ct_reg = DAC1_SAMP_CT; break;
case DAC2_CHAN:
curr_samp_ct_reg = DAC2_CURR_SAMP_CT;
samp_ct_reg = DAC2_SAMP_CT; break;
default: return EINVAL;
}
samp_ct = pci_inw(reg(samp_ct_reg));
curr_samp_ct = pci_inw(reg(curr_samp_ct_reg));
*samples_in_buf = (u32_t) (sub_dev[chan].BufLength * 8192) +
curr_samp_ct;
return OK;
}
/* returns 1 if there are free buffers */
PRIVATE int free_buf (u32_t *val, int *len, int sub_dev_nr) {
*len = sizeof(*val);
if (sub_dev[sub_dev_nr].BufLength ==
sub_dev[sub_dev_nr].NrOfExtraBuffers) {
*val = 0;
}
else {
*val = 1;
}
return OK;
}
PRIVATE int get_set_volume(struct volume_level *level, int *len, int sub_dev,
int flag) {
*len = sizeof(struct volume_level);
if (sub_dev == MIXER) {
return ak4531_get_set_volume(level, flag);
}
else {
return EINVAL;
}
}

View file

@ -0,0 +1,125 @@
#ifndef ES1370_H
#define ES1370_H
/* best viewed with tabsize=4 */
#include <sys/types.h>
#include "../../drivers.h"
#include <sys/ioc_sound.h>
/* set your vendor and device ID's here */
#define VENDOR_ID 0x1274
#define DEVICE_ID 0x5000
#define DRIVER_NAME "ES1370"
/* channels or subdevices */
#define DAC1_CHAN 0
#define ADC1_CHAN 1
#define MIXER 2
#define DAC2_CHAN 3
/* PCI command register defines */
#define SERR_EN 0x0100
#define PCI_MASTER 0x0004
#define IO_ACCESS 0x0001
/* Interrupt/Chip Select Control */
#define CHIP_SEL_CTRL 0x00
#define FREQ_44K100 0x3000 /* 44.1 Khz */
#define CDC_EN 0x0002 /* codec enable */
#define ADC1_EN 0x0010
#define DAC1_EN 0x0040
#define DAC2_EN 0x0020
#define XCTL0 0x0100
#define CCB_INTRM 0x0400
/* Interrupt/Chip Select Status */
#define INTERRUPT_STATUS 0x04
#define ADC 0x0001
#define DAC2 0x0002
#define DAC1 0x0004
#define CSTAT 0x0400 /* == CBUSY || CWRIP */
#define CWRIP 0x0100 /* == CBUSY || CWRIP */
#define INTR 0x80000000
/* AK4531 address */
#define CODEC_WRITE_ADDRESS 0x10
/* Legacy address */
#define LEGACY 0x18
/* Memory related defines */
#define MEM_PAGE 0x0c
#define ADC_MEM_PAGE 0x0d
#define DAC_MEM_PAGE 0x0c /* for DAC1 and DAC2 */
#define MEMORY 0x30
#define ADC_BUFFER_SIZE 0x34
#define DAC1_BUFFER_SIZE 0x34
#define DAC2_BUFFER_SIZE 0X3c
#define ADC_PCI_ADDRESS 0x30
#define DAC1_PCI_ADDRESS 0x30
#define DAC2_PCI_ADDRESS 0x38
/* Serial Interface Control */
#define SERIAL_INTERFACE_CTRL 0x20
#define P1_S_MB 0x0001 /* DAC1 Stereo/Mono bit */
#define P1_S_EB 0x0002 /* DAC1 Sixteen/Eight bit */
#define P2_S_MB 0x0004 /* DAC2 Stereo/Mono bit */
#define P2_S_EB 0x0008 /* DAC2 Sixteen/Eight bit */
#define R1_S_MB 0x0010 /* ADC Stereo/Mono bit */
#define R1_S_EB 0x0020 /* ADC Sixteen/Eight bit */
#define P1_INTR_EN 0x0100
#define P2_INTR_EN 0x0200
#define R1_INT_EN 0x0400
#define P1_PAUSE 0x0800
#define P2_PAUSE 0x1000
#define DAC1_SAMP_CT 0x24
#define DAC1_CURR_SAMP_CT 0x26
#define DAC2_SAMP_CT 0x28
#define DAC2_CURR_SAMP_CT 0x2a
#define ADC_SAMP_CT 0x2c
#define ADC_CURR_SAMP_CT 0x2e
typedef struct {
u32_t stereo;
u16_t sample_rate;
u32_t nr_of_bits;
u32_t sign;
u32_t busy;
u32_t fragment_size;
} aud_sub_dev_conf_t;
/* Some defaults for the aud_sub_dev_conf_t*/
#define DEFAULT_RATE 44100 /* Sample rate */
#define DEFAULT_NR_OF_BITS 16 /* Nr. of bits per sample per chan */
#define DEFAULT_SIGNED 0 /* 0 = unsigned, 1 = signed */
#define DEFAULT_STEREO 1 /* 0 = mono, 1 = stereo */
#define MAX_RATE 44100 /* Max sample speed in KHz */
#define MIN_RATE 4000 /* Min sample speed in KHz */
typedef struct DEVSTRUCT {
char* name;
u16_t v_id; /* vendor id */
u16_t d_id; /* device id */
u32_t devind; /* minix pci device id, for
* pci configuration space */
u32_t base; /* changed to 32 bits */
char irq;
char revision; /* version of the device */
} DEV_STRUCT;
#endif /* ES1370_H */

View file

@ -0,0 +1,65 @@
/* best viewed with tabsize 4 */
#include "../../drivers.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <minix/sysutil.h>
#include <errno.h>
#include "pci_helper.h"
#include "es1370.h"
/*===========================================================================*
* helper functions for I/O *
*===========================================================================*/
PUBLIC unsigned pci_inb(U16_t port) {
u32_t value;
int s;
if ((s=sys_inb(port, &value)) !=OK)
printf("%s: warning, sys_inb failed: %d\n", DRIVER_NAME, s);
return value;
}
PUBLIC unsigned pci_inw(U16_t port) {
u32_t value;
int s;
if ((s=sys_inw(port, &value)) !=OK)
printf("%s: warning, sys_inw failed: %d\n", DRIVER_NAME, s);
return value;
}
PUBLIC unsigned pci_inl(U16_t port) {
U32_t value;
int s;
if ((s=sys_inl(port, &value)) !=OK)
printf("%s: warning, sys_inl failed: %d\n", DRIVER_NAME, s);
return value;
}
PUBLIC void pci_outb(U16_t port, U8_t value) {
int s;
if ((s=sys_outb(port, value)) !=OK)
printf("%s: warning, sys_outb failed: %d\n", DRIVER_NAME, s);
}
PUBLIC void pci_outw(U16_t port, U16_t value) {
int s;
if ((s=sys_outw(port, value)) !=OK)
printf("%s: warning, sys_outw failed: %d\n", DRIVER_NAME, s);
}
PUBLIC void pci_outl(U16_t port, U32_t value) {
int s;
if ((s=sys_outl(port, value)) !=OK)
printf("%s: warning, sys_outl failed: %d\n", DRIVER_NAME, s);
}

View file

@ -0,0 +1,12 @@
#ifndef PCI_HELPER
#define PCI_HELPER
_PROTOTYPE( unsigned pci_inb, (U16_t port) );
_PROTOTYPE( unsigned pci_inw, (U16_t port) );
_PROTOTYPE( unsigned pci_inl, (U16_t port) );
_PROTOTYPE( void pci_outb, (U16_t port, U8_t value) );
_PROTOTYPE( void pci_outw, (U16_t port, U16_t value) );
_PROTOTYPE( void pci_outl, (U16_t port, U32_t value) );
#endif

View file

@ -1,138 +0,0 @@
SRC.o: ../../drivers.h
SRC.o: ../../libpci/pci.h
SRC.o: /usr/include/ansi.h
SRC.o: /usr/include/errno.h
SRC.o: /usr/include/ibm/bios.h
SRC.o: /usr/include/ibm/interrupt.h
SRC.o: /usr/include/ibm/ports.h
SRC.o: /usr/include/limits.h
SRC.o: /usr/include/minix/bitmap.h
SRC.o: /usr/include/minix/callnr.h
SRC.o: /usr/include/minix/com.h
SRC.o: /usr/include/minix/config.h
SRC.o: /usr/include/minix/const.h
SRC.o: /usr/include/minix/devio.h
SRC.o: /usr/include/minix/dmap.h
SRC.o: /usr/include/minix/ioctl.h
SRC.o: /usr/include/minix/ipc.h
SRC.o: /usr/include/minix/sys_config.h
SRC.o: /usr/include/minix/syslib.h
SRC.o: /usr/include/minix/sysutil.h
SRC.o: /usr/include/minix/type.h
SRC.o: /usr/include/signal.h
SRC.o: /usr/include/stddef.h
SRC.o: /usr/include/stdlib.h
SRC.o: /usr/include/string.h
SRC.o: /usr/include/sys/dir.h
SRC.o: /usr/include/sys/ioc_sound.h
SRC.o: /usr/include/sys/types.h
SRC.o: /usr/include/unistd.h
SRC.o: SRC.c
SRC.o: SRC.h
SRC.o: es1371.h
SRC.o: wait.h
codec.o: ../../drivers.h
codec.o: ../../libpci/pci.h
codec.o: ../AC97.h
codec.o: /usr/include/ansi.h
codec.o: /usr/include/errno.h
codec.o: /usr/include/ibm/bios.h
codec.o: /usr/include/ibm/interrupt.h
codec.o: /usr/include/ibm/ports.h
codec.o: /usr/include/limits.h
codec.o: /usr/include/minix/bitmap.h
codec.o: /usr/include/minix/callnr.h
codec.o: /usr/include/minix/com.h
codec.o: /usr/include/minix/config.h
codec.o: /usr/include/minix/const.h
codec.o: /usr/include/minix/devio.h
codec.o: /usr/include/minix/dmap.h
codec.o: /usr/include/minix/ioctl.h
codec.o: /usr/include/minix/ipc.h
codec.o: /usr/include/minix/sys_config.h
codec.o: /usr/include/minix/syslib.h
codec.o: /usr/include/minix/sysutil.h
codec.o: /usr/include/minix/type.h
codec.o: /usr/include/signal.h
codec.o: /usr/include/stddef.h
codec.o: /usr/include/stdlib.h
codec.o: /usr/include/string.h
codec.o: /usr/include/sys/dir.h
codec.o: /usr/include/sys/ioc_sound.h
codec.o: /usr/include/sys/types.h
codec.o: /usr/include/unistd.h
codec.o: SRC.h
codec.o: codec.c
codec.o: codec.h
codec.o: es1371.h
codec.o: wait.h
es1371.o: ../../drivers.h
es1371.o: ../../libpci/pci.h
es1371.o: ../AC97.h
es1371.o: ../framework/../../drivers.h
es1371.o: ../framework/audio_fw.h
es1371.o: /usr/include/ansi.h
es1371.o: /usr/include/errno.h
es1371.o: /usr/include/ibm/bios.h
es1371.o: /usr/include/ibm/interrupt.h
es1371.o: /usr/include/ibm/ports.h
es1371.o: /usr/include/limits.h
es1371.o: /usr/include/minix/bitmap.h
es1371.o: /usr/include/minix/callnr.h
es1371.o: /usr/include/minix/com.h
es1371.o: /usr/include/minix/config.h
es1371.o: /usr/include/minix/const.h
es1371.o: /usr/include/minix/devio.h
es1371.o: /usr/include/minix/dmap.h
es1371.o: /usr/include/minix/ioctl.h
es1371.o: /usr/include/minix/ipc.h
es1371.o: /usr/include/minix/sys_config.h
es1371.o: /usr/include/minix/syslib.h
es1371.o: /usr/include/minix/sysutil.h
es1371.o: /usr/include/minix/type.h
es1371.o: /usr/include/signal.h
es1371.o: /usr/include/stddef.h
es1371.o: /usr/include/stdlib.h
es1371.o: /usr/include/string.h
es1371.o: /usr/include/sys/dir.h
es1371.o: /usr/include/sys/ioc_sound.h
es1371.o: /usr/include/sys/types.h
es1371.o: /usr/include/unistd.h
es1371.o: SRC.h
es1371.o: codec.h
es1371.o: es1371.c
es1371.o: es1371.h
es1371.o: wait.h
wait.o: ../../drivers.h
wait.o: ../../libpci/pci.h
wait.o: /usr/include/ansi.h
wait.o: /usr/include/errno.h
wait.o: /usr/include/ibm/bios.h
wait.o: /usr/include/ibm/interrupt.h
wait.o: /usr/include/ibm/ports.h
wait.o: /usr/include/limits.h
wait.o: /usr/include/minix/bitmap.h
wait.o: /usr/include/minix/callnr.h
wait.o: /usr/include/minix/com.h
wait.o: /usr/include/minix/config.h
wait.o: /usr/include/minix/const.h
wait.o: /usr/include/minix/devio.h
wait.o: /usr/include/minix/dmap.h
wait.o: /usr/include/minix/ipc.h
wait.o: /usr/include/minix/sys_config.h
wait.o: /usr/include/minix/syslib.h
wait.o: /usr/include/minix/sysutil.h
wait.o: /usr/include/minix/type.h
wait.o: /usr/include/signal.h
wait.o: /usr/include/stddef.h
wait.o: /usr/include/stdlib.h
wait.o: /usr/include/string.h
wait.o: /usr/include/sys/dir.h
wait.o: /usr/include/sys/types.h
wait.o: /usr/include/time.h
wait.o: /usr/include/unistd.h
wait.o: wait.c

View file

@ -6,39 +6,51 @@ i = $u/include
s = $i/sys
m = $i/minix
b = $i/ibm
pci_dir = ../../libpci
gen_drv_dir = ../../gen_drivers/cyclic_dma
# programs, flags, etc.
CC = exec cc
CFLAGS = -I$i
CC = exec cc
CFLAGS = -I$i
LDFLAGS = -i
LIBS = -lsys -lsysutil
PCI = $(pci_dir)/pci.o $(pci_dir)/pci_table.o
LIBS = -lsys -lsysutil
PROGRAM_NAME = es1371
INSTALL_BIN = /usr/sbin/$(PROGRAM_NAME)
OBJ = es1371.o AC97.o audio_fw.o pci_helper.o wait.o sample_rate_converter.o
# build local binary
all: es1371
all: $(PROGRAM_NAME)
$(PROGRAM_NAME): $(OBJ)
$(CC) -o $@ $(LDFLAGS) $(OBJ) $(LIBS)
es1371: es1371.o SRC.o codec.o wait.o audio_fw.o $(PCI)
$(CC) -o $@ $(LDFLAGS) es1371.o SRC.o codec.o wait.o audio_fw.o $(PCI) $(LIBS)
audio_fw.o: ../framework/audio_fw.c ../framework/audio_fw.h
$(CC) -c ../framework/audio_fw.c
install: /usr/sbin/es1371
/usr/sbin/es1371: es1371
%.o: %.c
$(CC) $(CFLAGS) -c $<
install: $(INSTALL_BIN)
$(INSTALL_BIN): $(PROGRAM_NAME)
install -o root -S 1024k -c $? $@
$(PCI):
cd $(pci_dir) && $(MAKE)
# clean up local files
clean:
rm -f *.o *.bak core es1371
rm -f $(OBJ) $(PROGRAM_NAME) core
depend:
/usr/bin/mkdep "$(CC) -E $(CPPFLAGS)" *.c > .depend
# Include generated dependencies.
include .depend

File diff suppressed because it is too large Load diff

View file

@ -1,138 +1,128 @@
#ifndef ES1371_H
#define ES1371_H
/* best viewed with tabsize=4 */
#include <sys/types.h>
#include "../../drivers.h"
#include "../../libpci/pci.h"
#include <sys/ioc_sound.h>
#include <minix/sound.h>
#define DAC1_CHAN 0
#define ADC1_CHAN 1
#define MIXER 2
#define DAC2_CHAN 3
/* set your vendor and device ID's here */
#define VENDOR_ID 0x1274
#define DEVICE_ID 0x1371
/* Concert97 direct register offset defines */
#define CONC_bDEVCTL_OFF 0x00 /* Device control/enable */
#define CONC_bMISCCTL_OFF 0x01 /* Miscellaneous control */
#define CONC_bGPIO_OFF 0x02 /* General purpose I/O control */
#define CONC_bJOYCTL_OFF 0x03 /* Joystick control (decode) */
#define CONC_bINTSTAT_OFF 0x04 /* Device interrupt status */
#define CONC_bCODECSTAT_OFF 0x05 /* CODEC interface status */
#define CONC_bINTSUMM_OFF 0x07 /* Interrupt summary status */
#define CONC_b4SPKR_OFF 0x07 /* Also 4 speaker config reg */
#define CONC_bSPDIF_ROUTE_OFF 0x07 /* Also S/PDIF route control reg */
#define CONC_bUARTDATA_OFF 0x08 /* UART data R/W - read clears RX int */
#define CONC_bUARTCSTAT_OFF 0x09 /* UART control and status */
#define CONC_bUARTTEST_OFF 0x0a /* UART test control reg */
#define CONC_bMEMPAGE_OFF 0x0c /* Memory page select */
#define CONC_dSRCIO_OFF 0x10 /* I/O ctl/stat/data for SRC RAM */
#define CONC_dCODECCTL_OFF 0x14 /* CODEC control - u32_t read/write */
#define CONC_wNMISTAT_OFF 0x18 /* Legacy NMI status */
#define CONC_bNMIENA_OFF 0x1a /* Legacy NMI enable */
#define CONC_bNMICTL_OFF 0x1b /* Legacy control */
#define CONC_bSERFMT_OFF 0x20 /* Serial device format */
#define CONC_bSERCTL_OFF 0x21 /* Serial device control */
#define CONC_bSKIPC_OFF 0x22 /* DAC skip count reg */
#define CONC_wSYNIC_OFF 0x24 /* Synth int count in sample frames */
#define CONC_wSYNCIC_OFF 0x26 /* Synth current int count */
#define CONC_wDACIC_OFF 0x28 /* DAC int count in sample frames */
#define CONC_wDACCIC_OFF 0x2a /* DAC current int count */
#define CONC_wADCIC_OFF 0x2c /* ADC int count in sample frames */
#define CONC_wADCCIC_OFF 0x2e /* ADC current int count */
#define CONC_MEMBASE_OFF 0x30 /* Memory window base - 16 byte window */
/* Concert memory page-banked register offset defines */
#define CONC_dSYNPADDR_OFF 0x30 /* Synth host frame PCI phys addr */
#define CONC_wSYNFC_OFF 0x34 /* Synth host frame count in u32_t'S */
#define CONC_wSYNCFC_OFF 0x36 /* Synth host current frame count */
#define CONC_dDACPADDR_OFF 0x38 /* DAC host frame PCI phys addr */
#define CONC_wDACFC_OFF 0x3c /* DAC host frame count in u32_t'S */
#define CONC_wDACCFC_OFF 0x3e /* DAC host current frame count */
#define CONC_dADCPADDR_OFF 0x30 /* ADC host frame PCI phys addr */
#define CONC_wADCFC_OFF 0x34 /* ADC host frame count in u32_t'S */
#define CONC_wADCCFC_OFF 0x36 /* ADC host current frame count */
/* memory page number defines */
#define CONC_SYNRAM_PAGE 0x00 /* Synth host/serial I/F RAM */
#define CONC_DACRAM_PAGE 0x04 /* DAC host/serial I/F RAM */
#define CONC_ADCRAM_PAGE 0x08 /* ADC host/serial I/F RAM */
#define CONC_SYNCTL_PAGE 0x0c /* Page bank for synth host control */
#define CONC_DACCTL_PAGE 0x0c /* Page bank for DAC host control */
#define CONC_ADCCTL_PAGE 0x0d /* Page bank for ADC host control */
#define CONC_FIFO0_PAGE 0x0e /* page 0 of UART "FIFO" (rx stash) */
#define CONC_FIFO1_PAGE 0x0f /* page 1 of UART "FIFO" (rx stash) */
#define VENDOR_ID 0x1274
#define DEVICE_ID 0x1371
#define DRIVER_NAME "ES1371"
/* channels or subdevices */
#define DAC1_CHAN 0
#define ADC1_CHAN 1
#define MIXER 2
#define DAC2_CHAN 3
/* bits for Interrupt/Chip Select Control Register (offset 0x00)*/
#define DAC1_EN_BIT bit(6)
#define DAC2_EN_BIT bit(5)
#define ADC1_EN_BIT bit(4)
#define SYNC_RES_BIT bit(14)
/* bits for Interrupt/Chip Select Status Register (offset 0x04)*/
#define DAC1_INT_STATUS_BIT bit(2)
#define DAC2_INT_STATUS_BIT bit(1)
#define ADC1_INT_STATUS_BIT bit(0)
/* PCI command register defines */
#define SERR_EN 0x0100
#define PCI_MASTER 0x0004
#define IO_ACCESS 0x0001
/* some bits for Serial Interface Control Register (CONC_bSERFMT_OFF 20H) */
#define DAC1_STEREO_BIT bit(0) /* stereo or mono format */
#define DAC1_16_8_BIT bit(1) /* 16 or 8 bit format */
#define DAC2_STEREO_BIT bit(2)
#define DAC2_16_8_BIT bit(3)
#define ADC1_STEREO_BIT bit(4)
#define ADC1_16_8_BIT bit(5)
#define DAC1_INT_EN_BIT bit(8) /* interupt enable bits */
#define DAC2_INT_EN_BIT bit(9)
#define ADC1_INT_EN_BIT bit(10)
#define DAC1_PAUSE_BIT bit(11)
#define DAC2_PAUSE_BIT bit(12)
/* Some return values */
#define SRC_SUCCESS 0
#define CONC_SUCCESS 0
/* Timeout waiting for: */
#define SRC_ERR_NOT_BUSY_TIMEOUT -1 /* SRC not busy */
#define CONC_ERR_NO_PCI_BIOS -2
#define CONC_ERR_DEVICE_NOT_FOUND -3
#define CONC_ERR_SPDIF_NOT_AVAIL -4
#define CONC_ERR_SPDIF_ROUTING_NOT_AVAIL -5
#define CONC_ERR_4SPEAKER_NOT_AVAIL -6
#define CONC_ERR_ECHO_NOT_AVAIL -7
/* Interrupt/Chip Select Control */
#define CHIP_SEL_CTRL 0x00
#define ADC1_EN 0x0010
#define DAC1_EN 0x0040
#define DAC2_EN 0x0020
#define CCB_INTRM 0x0400
/* Interrupt/Chip Select Status */
#define INTERRUPT_STATUS 0x04
#define ADC 0x0001
#define DAC2 0x0002
#define DAC1 0x0004
#define INTR 0x80000000
/* Sample Rate Converter */
#define SAMPLE_RATE_CONV 0x10
/* CODEC Write/Read register */
#define CODEC_WRITE 0x14
#define CODEC_READ 0x14
/* Legacy address */
#define LEGACY 0x18
/* Memory related defines */
#define MEM_PAGE 0x0c
#define ADC_MEM_PAGE 0x0d
#define DAC_MEM_PAGE 0x0c /* for DAC1 and DAC2 */
#define MEMORY 0x30
#define ADC_BUFFER_SIZE 0x34
#define DAC1_BUFFER_SIZE 0x34
#define DAC2_BUFFER_SIZE 0X3c
#define ADC_PCI_ADDRESS 0x30
#define DAC1_PCI_ADDRESS 0x30
#define DAC2_PCI_ADDRESS 0x38
/* Serial Interface Control */
#define SERIAL_INTERFACE_CTRL 0x20
#define P1_S_MB 0x0001 /* DAC1 Stereo/Mono bit */
#define P1_S_EB 0x0002 /* DAC1 Sixteen/Eight bit */
#define P2_S_MB 0x0004 /* DAC2 Stereo/Mono bit */
#define P2_S_EB 0x0008 /* DAC2 Sixteen/Eight bit */
#define R1_S_MB 0x0010 /* ADC Stereo/Mono bit */
#define R1_S_EB 0x0020 /* ADC Sixteen/Eight bit */
#define P1_INTR_EN 0x0100
#define P2_INTR_EN 0x0200
#define R1_INT_EN 0x0400
#define P1_PAUSE 0x0800
#define P2_PAUSE 0x1000
#define DAC1_SAMP_CT 0x24
#define DAC1_CURR_SAMP_CT 0x26
#define DAC2_SAMP_CT 0x28
#define DAC2_CURR_SAMP_CT 0x2a
#define ADC_SAMP_CT 0x2c
#define ADC_CURR_SAMP_CT 0x2e
typedef struct {
u32_t stereo;
u16_t sample_rate;
u32_t nr_of_bits;
u32_t sign;
u32_t busy;
u32_t fragment_size;
u32_t stereo;
u16_t sample_rate;
u32_t nr_of_bits;
u32_t sign;
u32_t busy;
u32_t fragment_size;
} aud_sub_dev_conf_t;
/* Some defaults for the aud_sub_dev_conf_t*/
#define DEFAULT_RATE 44100 /* Sample rate */
#define DEFAULT_NR_OF_BITS 16 /* Nr. of bits per sample per channel*/
#define DEFAULT_SIGNED 0 /* 0 = unsigned, 1 = signed */
#define DEFAULT_STEREO 1 /* 0 = mono, 1 = stereo */
#define MAX_RATE 44100 /* Max sample speed in KHz */
#define MIN_RATE 4000 /* Min sample speed in KHz */
#define DEFAULT_NR_OF_BITS 16 /* Nr. of bits per sample per chan */
#define DEFAULT_SIGNED 0 /* 0 = unsigned, 1 = signed */
#define DEFAULT_STEREO 1 /* 0 = mono, 1 = stereo */
#define MAX_RATE 44100 /* Max sample speed in KHz */
#define MIN_RATE 4000 /* Min sample speed in KHz */
typedef struct DEVSTRUCT {
char* name;
u16_t v_id; /* vendor id */
u16_t d_id; /* device id */
u32_t devind; /* minix pci device id, for pci configuration space */
u32_t base; /* changed to 32 bits */
char irq;
char revision;/* version of the device */
char* name;
u16_t v_id; /* vendor id */
u16_t d_id; /* device id */
u32_t devind; /* minix pci device id, for
* pci configuration space */
u32_t base; /* changed to 32 bits */
char irq;
char revision; /* version of the device */
} DEV_STRUCT;
#define bit(n) 1UL << n
#define SRC_ERR_NOT_BUSY_TIMEOUT -1 /* SRC not busy */
#define SRC_SUCCESS 0
#endif /* ES1371_H */

View file

@ -1,7 +1,8 @@
#include "../../drivers.h"
#include <sys/types.h>
#include <time.h>
#include "../../libpci/pci.h"
#include "pci_helper.h"
int WaitBitd (int paddr, int bitno, int state, long tmout)
{

View file

@ -1,3 +1,5 @@
#ifndef WAIT_H
#define WAIT_H
/* WAIT.H
// General purpose waiting routines
@ -8,3 +10,4 @@ int WaitBitw (int paddr, int bitno, int state, long tmout);
int WaitBitd (int paddr, int bitno, int state, long tmout);
int MemWaitw (unsigned int volatile *gaddr, int bitno, int state, long tmout);
#endif

File diff suppressed because it is too large Load diff

View file

@ -5,8 +5,15 @@
#include <sys/ioc_sound.h>
/* change '(void)' to 'printf' to print debug info and error messages */
#define dprint (void)
/* change to DEBUG to 1 to print debug info and error messages */
#define DEBUG 0
#if DEBUG
#define dprint printf
#else
#define dprint (void)
#endif
#define error printf
@ -51,6 +58,7 @@ typedef struct {
int RevivePending; /* process waiting for this dev? */
int ReviveStatus; /* return val when proc unblocked */
int ReviveProcNr; /* the process to unblock */
cp_grant_id_t ReviveGrant; /* grant id associated with io */
void *UserBuf; /* address of user's data buffer */
int ReadyToRevive; /* are we ready to revive process?*/
int NotifyProcNr; /* process to send notify to (FS) */

View file

@ -1,68 +0,0 @@
mixer.o: ../framework/../../drivers.h
mixer.o: ../framework/audio_fw.h
mixer.o: /usr/include/ansi.h
mixer.o: /usr/include/errno.h
mixer.o: /usr/include/ibm/bios.h
mixer.o: /usr/include/ibm/interrupt.h
mixer.o: /usr/include/ibm/ports.h
mixer.o: /usr/include/limits.h
mixer.o: /usr/include/minix/bitmap.h
mixer.o: /usr/include/minix/callnr.h
mixer.o: /usr/include/minix/com.h
mixer.o: /usr/include/minix/config.h
mixer.o: /usr/include/minix/const.h
mixer.o: /usr/include/minix/devio.h
mixer.o: /usr/include/minix/dmap.h
mixer.o: /usr/include/minix/ioctl.h
mixer.o: /usr/include/minix/ipc.h
mixer.o: /usr/include/minix/sound.h
mixer.o: /usr/include/minix/sys_config.h
mixer.o: /usr/include/minix/syslib.h
mixer.o: /usr/include/minix/sysutil.h
mixer.o: /usr/include/minix/type.h
mixer.o: /usr/include/signal.h
mixer.o: /usr/include/stddef.h
mixer.o: /usr/include/stdlib.h
mixer.o: /usr/include/string.h
mixer.o: /usr/include/sys/dir.h
mixer.o: /usr/include/sys/ioc_sound.h
mixer.o: /usr/include/sys/types.h
mixer.o: /usr/include/unistd.h
mixer.o: mixer.c
mixer.o: mixer.h
mixer.o: sb16.h
sb16.o: ../framework/../../drivers.h
sb16.o: ../framework/audio_fw.h
sb16.o: /usr/include/ansi.h
sb16.o: /usr/include/errno.h
sb16.o: /usr/include/ibm/bios.h
sb16.o: /usr/include/ibm/interrupt.h
sb16.o: /usr/include/ibm/ports.h
sb16.o: /usr/include/limits.h
sb16.o: /usr/include/minix/bitmap.h
sb16.o: /usr/include/minix/callnr.h
sb16.o: /usr/include/minix/com.h
sb16.o: /usr/include/minix/config.h
sb16.o: /usr/include/minix/const.h
sb16.o: /usr/include/minix/devio.h
sb16.o: /usr/include/minix/dmap.h
sb16.o: /usr/include/minix/ioctl.h
sb16.o: /usr/include/minix/ipc.h
sb16.o: /usr/include/minix/sound.h
sb16.o: /usr/include/minix/sys_config.h
sb16.o: /usr/include/minix/syslib.h
sb16.o: /usr/include/minix/sysutil.h
sb16.o: /usr/include/minix/type.h
sb16.o: /usr/include/signal.h
sb16.o: /usr/include/stddef.h
sb16.o: /usr/include/stdlib.h
sb16.o: /usr/include/string.h
sb16.o: /usr/include/sys/dir.h
sb16.o: /usr/include/sys/ioc_sound.h
sb16.o: /usr/include/sys/types.h
sb16.o: /usr/include/unistd.h
sb16.o: mixer.h
sb16.o: sb16.c
sb16.o: sb16.h

View file

@ -241,4 +241,29 @@ driver orinoco
uid 0;
};
driver es1370
{
system
SAFECOPYFROM
SAFECOPYTO
UMAP
SETGRANT
IRQCTL # 19
DEVIO # 21
;
pci device 1274/5000;
};
driver es1371
{
system
SAFECOPYFROM
SAFECOPYTO
UMAP
SETGRANT
IRQCTL # 19
DEVIO # 21
;
pci device 1274/1371;
};

View file

@ -9,13 +9,17 @@
#include <minix/ioctl.h>
/* Soundcard DSP ioctls. */
#define DSPIORATE _IOR('s', 1, unsigned int)
#define DSPIOSTEREO _IOR('s', 2, unsigned int)
#define DSPIOSIZE _IOR('s', 3, unsigned int)
#define DSPIOBITS _IOR('s', 4, unsigned int)
#define DSPIOSIGN _IOR('s', 5, unsigned int)
#define DSPIOMAX _IOW('s', 6, unsigned int)
#define DSPIORESET _IO ('s', 7)
#define DSPIORATE _IOW('s', 1, unsigned int)
#define DSPIOSTEREO _IOW('s', 2, unsigned int)
#define DSPIOSIZE _IOW('s', 3, unsigned int)
#define DSPIOBITS _IOW('s', 4, unsigned int)
#define DSPIOSIGN _IOW('s', 5, unsigned int)
#define DSPIOMAX _IOR('s', 6, unsigned int)
#define DSPIORESET _IO ('s', 7)
#define DSPIOFREEBUF _IOR('s', 30, unsigned int)
#define DSPIOSAMPLESINBUF _IOR('s', 31, unsigned int)
#define DSPIOPAUSE _IO ('s', 32)
#define DSPIORESUME _IO ('s', 33)
/* Soundcard mixer ioctls. */
#define MIXIOGETVOLUME _IORW('s', 10, struct volume_level)
@ -27,7 +31,4 @@
#define MIXIOSETINPUTRIGHT _IORW('s', 22, struct inout_ctrl)
#define MIXIOSETOUTPUT _IORW('s', 23, struct inout_ctrl)
#define AC97READ _IOW('s', 8, u16_t[2])
#define AC97WRITE _IOR('s', 9, u16_t[2])
#endif /* _S_I_SOUND_H */