added a settings file for auich
there is now an option for laptops for which no interrupt is available (ie stippi's one) : use_thread even when use_thread is active, it could be needed to use a higher value for buffer_frames (ie 512) git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@18406 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -34,8 +34,10 @@
|
||||
|
||||
#include <KernelExport.h>
|
||||
#include <PCI.h>
|
||||
#include <string.h>
|
||||
#include <driver_settings.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "auich.h"
|
||||
#include "debug.h"
|
||||
#include "config.h"
|
||||
@@ -62,8 +64,18 @@ auich_dev cards[NUM_CARDS];
|
||||
int32 num_names;
|
||||
char * names[NUM_CARDS*20+1];
|
||||
|
||||
volatile bool int_thread_exit = false;
|
||||
thread_id int_thread_id = -1;
|
||||
|
||||
extern device_hooks multi_hooks;
|
||||
|
||||
auich_settings current_settings = {
|
||||
48000, // sample rate
|
||||
256, // buffer frames
|
||||
4, // buffer count
|
||||
false // use thread
|
||||
};
|
||||
|
||||
/* The SIS7012 chipset has SR and PICB registers swapped when compared to Intel */
|
||||
#define GET_REG_PICB(x) (IS_SIS7012(x) ? AUICH_REG_X_SR : AUICH_REG_X_PICB)
|
||||
#define GET_REG_SR(x) (IS_SIS7012(x) ? AUICH_REG_X_PICB : AUICH_REG_X_SR)
|
||||
@@ -397,7 +409,7 @@ auich_int(void *arg)
|
||||
auich_stream *stream = NULL;
|
||||
uint16 sr, sta;
|
||||
|
||||
//TRACE(("auich_int(%p)\n", card));
|
||||
// TRACE(("auich_int(%p)\n", card));
|
||||
|
||||
sta = auich_reg_read_16(&card->config, AUICH_REG_GLOB_STA);
|
||||
if(sta & card->interrupt_mask) {
|
||||
@@ -451,6 +463,21 @@ auich_int(void *arg)
|
||||
return B_UNHANDLED_INTERRUPT;
|
||||
}
|
||||
|
||||
|
||||
static int32
|
||||
auich_int_thread(void *data)
|
||||
{
|
||||
cpu_status status;
|
||||
while (!int_thread_exit) {
|
||||
status = disable_interrupts();
|
||||
auich_int(data);
|
||||
restore_interrupts(status);
|
||||
snooze(1500);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* auich driver functions */
|
||||
|
||||
static status_t
|
||||
@@ -654,8 +681,13 @@ auich_setup(auich_dev * card)
|
||||
PRINT(("codec description = %s\n",ac97_get_vendor_id_description(&card->config)));
|
||||
PRINT(("codec 3d enhancement = %s\n",ac97_get_3d_stereo_enhancement(&card->config)));
|
||||
|
||||
PRINT(("installing interrupt : %lx\n", card->config.irq));
|
||||
install_io_interrupt_handler(card->config.irq, auich_int, card, 0);
|
||||
if (current_settings.use_thread) {
|
||||
int_thread_id = spawn_kernel_thread(auich_int_thread, "auich interrupt poller", B_REAL_TIME_PRIORITY, card);
|
||||
resume_thread(int_thread_id);
|
||||
} else {
|
||||
PRINT(("installing interrupt : %lx\n", card->config.irq));
|
||||
install_io_interrupt_handler(card->config.irq, auich_int, card, 0);
|
||||
}
|
||||
|
||||
/*PRINT(("codec master output = %#04x\n",auich_codec_read(&card->config, 0x02)));
|
||||
PRINT(("codec aux output = %#04x\n",auich_codec_read(&card->config, 0x04)));
|
||||
@@ -703,12 +735,37 @@ status_t
|
||||
init_driver(void)
|
||||
{
|
||||
int ix=0;
|
||||
void *settings_handle;
|
||||
|
||||
pci_info info;
|
||||
num_cards = 0;
|
||||
|
||||
PRINT(("init_driver()\n"));
|
||||
load_driver_symbols("auich");
|
||||
|
||||
// get driver settings
|
||||
settings_handle = load_driver_settings ("auich.settings");
|
||||
if (settings_handle != NULL) {
|
||||
const char *item;
|
||||
char *end;
|
||||
uint32 value;
|
||||
|
||||
item = get_driver_parameter (settings_handle, "sample_rate", "48000", "48000");
|
||||
value = strtoul (item, &end, 0);
|
||||
if (*end == '\0') current_settings.sample_rate = value;
|
||||
|
||||
item = get_driver_parameter (settings_handle, "buffer_frames", "256", "256");
|
||||
value = strtoul (item, &end, 0);
|
||||
if (*end == '\0') current_settings.buffer_frames = value;
|
||||
|
||||
item = get_driver_parameter (settings_handle, "buffer_count", "4", "4");
|
||||
value = strtoul (item, &end, 0);
|
||||
if (*end == '\0') current_settings.buffer_count = value;
|
||||
|
||||
current_settings.use_thread = get_driver_boolean_parameter (settings_handle, "use_thread", false, false);
|
||||
|
||||
unload_driver_settings (settings_handle);
|
||||
}
|
||||
|
||||
if (get_module(pci_name, (module_info **) &pci))
|
||||
return ENOSYS;
|
||||
@@ -775,8 +832,13 @@ auich_shutdown(auich_dev *card)
|
||||
PRINT(("shutdown(%p)\n", card));
|
||||
card->interrupt_mask = 0;
|
||||
|
||||
remove_io_interrupt_handler(card->config.irq, auich_int, card);
|
||||
|
||||
if (current_settings.use_thread) {
|
||||
status_t exit_value;
|
||||
int_thread_exit = true;
|
||||
wait_for_thread(int_thread_id, &exit_value);
|
||||
} else
|
||||
remove_io_interrupt_handler(card->config.irq, auich_int, card);
|
||||
|
||||
unmap_io_memory(&card->config);
|
||||
}
|
||||
|
||||
|
||||
@@ -168,6 +168,16 @@ typedef struct _auich_dev {
|
||||
multi_dev multi;
|
||||
} auich_dev;
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint32 sample_rate;
|
||||
uint32 buffer_frames;
|
||||
int32 buffer_count;
|
||||
bool use_thread;
|
||||
} auich_settings;
|
||||
|
||||
extern auich_settings current_settings;
|
||||
|
||||
extern int32 num_cards;
|
||||
extern auich_dev cards[NUM_CARDS];
|
||||
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
# Settings file for the auich driver
|
||||
#
|
||||
# This file should be moved to the directory
|
||||
# ~/config/settings/kernel/drivers/
|
||||
#
|
||||
|
||||
#sample_rate 48000
|
||||
#buffer_frames 256
|
||||
#buffer_count 4
|
||||
#use_thread false
|
||||
@@ -766,23 +766,23 @@ auich_get_buffers(auich_dev *card, multi_buffer_list *data)
|
||||
pchannels = card->pstream->channels;
|
||||
rchannels = card->rstream->channels;
|
||||
|
||||
if (data->request_playback_buffers < BUFFER_COUNT ||
|
||||
if (data->request_playback_buffers < current_settings.buffer_count ||
|
||||
data->request_playback_channels < (pchannels) ||
|
||||
data->request_record_buffers < BUFFER_COUNT ||
|
||||
data->request_record_buffers < current_settings.buffer_count ||
|
||||
data->request_record_channels < (rchannels)) {
|
||||
LOG(("not enough channels/buffers\n"));
|
||||
}
|
||||
|
||||
ASSERT(BUFFER_COUNT == 2);
|
||||
ASSERT(current_settings.buffer_count == 2);
|
||||
|
||||
data->flags = B_MULTI_BUFFER_PLAYBACK | B_MULTI_BUFFER_RECORD; // XXX ???
|
||||
// data->flags = 0;
|
||||
|
||||
data->return_playback_buffers = BUFFER_COUNT; /* playback_buffers[b][] */
|
||||
data->return_playback_buffers = current_settings.buffer_count; /* playback_buffers[b][] */
|
||||
data->return_playback_channels = pchannels; /* playback_buffers[][c] */
|
||||
data->return_playback_buffer_size = BUFFER_FRAMES; /* frames */
|
||||
data->return_playback_buffer_size = current_settings.buffer_frames; /* frames */
|
||||
|
||||
bufcount = BUFFER_COUNT;
|
||||
bufcount = current_settings.buffer_count;
|
||||
if(bufcount > data->request_playback_buffers)
|
||||
bufcount = data->request_playback_buffers;
|
||||
|
||||
@@ -792,11 +792,11 @@ auich_get_buffers(auich_dev *card, multi_buffer_list *data)
|
||||
&data->playback_buffers[i][j].base,
|
||||
&data->playback_buffers[i][j].stride);
|
||||
|
||||
data->return_record_buffers = BUFFER_COUNT;
|
||||
data->return_record_buffers = current_settings.buffer_count;
|
||||
data->return_record_channels = rchannels;
|
||||
data->return_record_buffer_size = BUFFER_FRAMES; /* frames */
|
||||
data->return_record_buffer_size = current_settings.buffer_frames; /* frames */
|
||||
|
||||
bufcount = BUFFER_COUNT;
|
||||
bufcount = current_settings.buffer_count;
|
||||
if(bufcount > data->request_record_buffers)
|
||||
bufcount = data->request_record_buffers;
|
||||
|
||||
@@ -818,7 +818,7 @@ auich_play_inth(void* inthparams)
|
||||
|
||||
acquire_spinlock(&slock);
|
||||
stream->real_time = system_time();
|
||||
stream->frames_count += BUFFER_FRAMES;
|
||||
stream->frames_count += current_settings.buffer_frames;
|
||||
stream->buffer_cycle = (stream->trigblk
|
||||
+ stream->blkmod - 1) % stream->blkmod;
|
||||
stream->update_needed = true;
|
||||
@@ -839,7 +839,7 @@ auich_record_inth(void* inthparams)
|
||||
|
||||
acquire_spinlock(&slock);
|
||||
stream->real_time = system_time();
|
||||
stream->frames_count += BUFFER_FRAMES;
|
||||
stream->frames_count += current_settings.buffer_frames;
|
||||
stream->buffer_cycle = (stream->trigblk
|
||||
+ stream->blkmod - 1) % stream->blkmod;
|
||||
stream->update_needed = true;
|
||||
@@ -1047,15 +1047,15 @@ auich_open(const char *name, uint32 flags, void** cookie)
|
||||
|
||||
LOG(("stream_new\n"));
|
||||
|
||||
card->rstream = auich_stream_new(card, AUICH_USE_RECORD, BUFFER_FRAMES, BUFFER_COUNT);
|
||||
card->pstream = auich_stream_new(card, AUICH_USE_PLAY, BUFFER_FRAMES, BUFFER_COUNT);
|
||||
card->rstream = auich_stream_new(card, AUICH_USE_RECORD, current_settings.buffer_frames, current_settings.buffer_count);
|
||||
card->pstream = auich_stream_new(card, AUICH_USE_PLAY, current_settings.buffer_frames, current_settings.buffer_count);
|
||||
|
||||
card->buffer_ready_sem = create_sem(0, "pbuffer ready");
|
||||
|
||||
LOG(("stream_setaudio\n"));
|
||||
|
||||
auich_stream_set_audioparms(card->pstream, 2, true, 48000);
|
||||
auich_stream_set_audioparms(card->rstream, 2, true, 48000);
|
||||
auich_stream_set_audioparms(card->pstream, 2, true, current_settings.sample_rate);
|
||||
auich_stream_set_audioparms(card->rstream, 2, true, current_settings.sample_rate);
|
||||
|
||||
card->pstream->first_channel = 0;
|
||||
card->rstream->first_channel = 2;
|
||||
|
||||
@@ -31,9 +31,6 @@
|
||||
#ifndef _MULTI_H_
|
||||
#define _MULTI_H_
|
||||
|
||||
#define BUFFER_FRAMES 256
|
||||
#define BUFFER_COUNT 4
|
||||
|
||||
typedef struct _multi_mixer_control {
|
||||
struct _multi_dev *multi;
|
||||
void (*get) (void *card, const void *cookie, int32 type, float *values);
|
||||
|
||||
Reference in New Issue
Block a user