Some minor fixes; lots of debugging output still in there; not perfect yet

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@23404 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ithamar R. Adema
2008-01-11 16:50:53 +00:00
parent c2a6cd96bc
commit e7d7efa1c7
5 changed files with 80 additions and 61 deletions
@@ -74,6 +74,7 @@ void
uninit_driver (void)
{
long i;
dprintf("IRA: %s\n", __func__);
for (i=0; i < num_cards; i++) {
free((void*)cards[i].devfs_path);
cards[i].devfs_path = NULL;
@@ -91,6 +92,7 @@ publish_devices(void)
static const char* devs[MAXCARDS+1];
long i;
dprintf("IRA: %s\n", __func__);
for (i=0; i < num_cards; i++)
devs[i] = cards[i].devfs_path;
@@ -102,5 +104,6 @@ publish_devices(void)
device_hooks*
find_device(const char* name)
{
dprintf("IRA: %s\n", __func__);
return &driver_hooks;
}
+21 -19
View File
@@ -22,13 +22,13 @@
#define MAXCARDS 4
/* values for the class_sub field for class_base = 0x04 (multimedia device) */
#define PCI_hd_audio 3
#define PCI_hd_audio 3
#define HDA_MAXAFGS 15
#define HDA_MAXAFGS 15
#define HDA_MAXCODECS 15
#define HDA_MAXSTREAMS 16
#define MAX_CODEC_RESPONSES 10
#define MAXINPUTS 32
#define MAXINPUTS 32
/* FIXME: Find out why we need so much! */
#define DEFAULT_FRAMESPERBUF 4096
@@ -52,31 +52,33 @@ enum {
*/
typedef struct hda_stream_info_s {
uint32 id; /* HDA controller stream # */
uint32 off; /* HDA I/O/B descriptor offset */
bool running; /* Is this stream active? */
spinlock lock; /* Write lock */
uint32 pin_wid; /* PIN Widget ID */
uint32 io_wid; /* Input/Output Converter Widget ID */
uint32 id; /* HDA controller stream # */
uint32 off; /* HDA I/O/B descriptor offset */
bool running; /* Is this stream active? */
spinlock lock; /* Write lock */
uint32 pin_wid; /* PIN Widget ID */
uint32 io_wid; /* Input/Output Converter Widget ID */
uint32 samplerate;
uint32 sampleformat;
uint32 num_buffers;
uint32 num_channels;
uint32 buffer_length; /* size of buffer in samples */
uint32 sample_size;
void* buffers[STRMAXBUF]; /* Virtual addresses for buffer */
uint32 buffers_pa[STRMAXBUF]; /* Physical addresses for buffer */
uint32 buffers_pa[STRMAXBUF]; /* Physical addresses for buffer */
sem_id buffer_ready_sem;
bigtime_t real_time;
uint32 frames_count;
uint32 buffer_cycle;
uint32 rate, bps; /* Samplerate & bits per sample */
area_id buffer_area;
area_id bdl_area;
uint32 bdl_pa; /* BDL physical address */
uint32 bdl_pa; /* BDL physical address */
} hda_stream;
/* hda_afg
@@ -96,12 +98,12 @@ struct hda_afg_s {
uint32 root_nid,
wid_start,
wid_count;
wid_start,
wid_count;
uint32 deffmts,
defrates,
defpm;
defrates,
defpm;
struct {
uint32 num_inputs;
@@ -124,8 +126,8 @@ struct hda_afg_s {
struct {
} mixer;
struct {
uint32 output;
uint32 input;
uint32 output;
uint32 input;
pin_dev_type device;
} pin;
} d;
@@ -74,8 +74,8 @@ hda_widget_get_stream_support(hda_codec* codec, uint32 nid, uint32* fmts, uint32
if (resp[1] & (1<<20)) *fmts |= B_FMT_32BIT;
}
if (resp[0] & (1 << 1)) *fmts |= B_FMT_FLOAT;
if (resp[0] & (1 << 2)) /* Sort out how to handle AC3 */;
//FIXME: if (resp[0] & (1 << 1)) *fmts |= B_FMT_FLOAT;
//FIXME: if (resp[0] & (1 << 2)) /* Sort out how to handle AC3 */;
}
return rc;
@@ -147,7 +147,17 @@ hda_codec_parse_afg(hda_afg* afg)
off = 0;
if (resp[0] & (1 << 11)) off += sprintf(buf+off, "[L-R Swap] ");
if (resp[0] & (1 << 10)) off += sprintf(buf+off, "[Power] ");
if (resp[0] & (1 << 10)) {
corb_t verb;
uint32 resp;
off += sprintf(buf+off, "[Power] ");
/* We support power; switch us on! */
verb = MAKE_VERB(afg->codec->addr,wid,VID_SET_POWERSTATE,0);
hda_send_verbs(afg->codec, &verb, &resp, 1);
}
if (resp[0] & (1 << 9)) off += sprintf(buf+off, "[Digital] ");
if (resp[0] & (1 << 7)) off += sprintf(buf+off, "[Unsol Capable] ");
if (resp[0] & (1 << 6)) off += sprintf(buf+off, "[Proc Widget] ");
@@ -354,20 +364,16 @@ hda_codec_afg_new(hda_codec* codec, uint32 afg_nid)
we cannot find any output Pin Widgets */
rc = ENODEV;
dprintf("%s: Scanning all %ld widgets for outputs/inputs....\n",
__func__, afg->wid_count);
/* Try to locate all input/output channels */
for (idx=0; idx < afg->wid_count; idx++) {
uint32 output_wid = 0, input_wid = 0;
int32 iidx;
if (afg->widgets[idx].type == WT_PIN_COMPLEX && afg->widgets[idx].d.pin.output) {
if (afg->widgets[idx].d.pin.device != PIN_DEV_HP_OUT &&
afg->widgets[idx].d.pin.device != PIN_DEV_SPEAKER &&
afg->widgets[idx].d.pin.device != PIN_DEV_LINE_OUT)
continue;
if (afg->playback_stream == NULL && afg->widgets[idx].type == WT_PIN_COMPLEX && afg->widgets[idx].d.pin.output) {
if (afg->widgets[idx].d.pin.device == PIN_DEV_HP_OUT ||
afg->widgets[idx].d.pin.device == PIN_DEV_SPEAKER ||
afg->widgets[idx].d.pin.device == PIN_DEV_LINE_OUT)
{
iidx = afg->widgets[idx].active_input;
if (iidx != -1) {
output_wid = hda_codec_afg_find_path(afg, afg->widgets[idx].inputs[iidx], WT_AUDIO_OUTPUT, 0);
@@ -385,7 +391,7 @@ hda_codec_afg_new(hda_codec* codec, uint32 afg_nid)
if (output_wid) {
if (!afg->playback_stream) {
corb_t verb;
corb_t verb[2];
/* Setup playback/record streams for Multi Audio API */
afg->playback_stream = hda_stream_new(afg->codec->ctrlr, STRM_PLAYBACK);
@@ -394,16 +400,19 @@ hda_codec_afg_new(hda_codec* codec, uint32 afg_nid)
afg->playback_stream->pin_wid = idx + afg->wid_start;
afg->playback_stream->io_wid = output_wid;
/* FIXME: Force Pin Widget to unmute */
verb = MAKE_VERB(codec->addr, afg->playback_stream->pin_wid,
/* FIXME: Force Pin Widget to unmute; enable hp/output */
verb[0] = MAKE_VERB(codec->addr, afg->playback_stream->pin_wid,
VID_SET_AMPGAINMUTE, (1 << 15) | (1 << 13) | (1 << 12));
hda_send_verbs(codec, &verb, NULL, 1);
verb[1] = MAKE_VERB(codec->addr, afg->playback_stream->pin_wid,
VID_SET_PINWCTRL, (1 << 7) | (1 << 6));
hda_send_verbs(codec, verb, NULL, 2);
dprintf("%s: Found output PIN (%s) connected to output CONV wid:%ld\n",
__func__, defdev[afg->widgets[idx].d.pin.device], output_wid);
}
dprintf("%s: Found output PIN (%s) connected to output CONV wid:%ld\n",
__func__, defdev[afg->widgets[idx].d.pin.device], output_wid);
}
}
}
}
if (afg->widgets[idx].type == WT_AUDIO_INPUT) {
iidx = afg->widgets[idx].active_input;
@@ -183,38 +183,41 @@ hda_stream_setup_buffers(hda_afg* afg, hda_stream* s, const char* desc)
dprintf("%s(%s): Allocated %ld bytes for %ld BDLEs\n", __func__, desc,
alloc, s->num_buffers);
/* Setup BDL entries */
for (idx=0; idx < s->num_buffers; idx++, bdl++) {
bdl->address = buffer_pa + (idx*buffer_size);
bdl->length = s->sample_size * s->num_channels * s->buffer_length;
bdl->address = s->buffers_pa[idx];
bdl->length = buffer_size;
bdl->ioc = 1;
}
/* Configure stream registers */
wfmt = s->num_channels -1;
switch(s->sampleformat) {
case B_FMT_8BIT_S: wfmt |= (0 << 4); break;
case B_FMT_16BIT: wfmt |= (1 << 4); break;
case B_FMT_24BIT: wfmt |= (3 << 4); break;
case B_FMT_32BIT: wfmt |= (4 << 4); break;
default: dprintf("%s: Invalid sample format: 0x%lx\n", __func__, s->sampleformat); break;
case B_FMT_8BIT_S: wfmt |= (0 << 4); s->bps = 8; break;
case B_FMT_16BIT: wfmt |= (1 << 4); s->bps = 16; break;
case B_FMT_24BIT: wfmt |= (3 << 4); s->bps = 24; break;
case B_FMT_32BIT: wfmt |= (4 << 4); s->bps = 32; break;
default: dprintf("%s: Invalid sample format: 0x%lx\n", __func__, s->sampleformat); break;
}
switch(s->samplerate) {
case B_SR_8000: wfmt |= (7 << 8); break;
case B_SR_11025: wfmt |= (67 << 8); break;
case B_SR_16000: wfmt |= (2 << 8); break;
case B_SR_22050: wfmt |= (65 << 8); break;
case B_SR_32000: wfmt |= (10 << 8); break;
case B_SR_44100: wfmt |= (64 << 8); break;
case B_SR_48000: wfmt |= (0 << 8); break;
case B_SR_88200: wfmt |= (72 << 8); break;
case B_SR_96000: wfmt |= (8 << 8); break;
case B_SR_176400: wfmt |= (88 << 8); break;
case B_SR_192000: wfmt |= (24 << 8); break;
default: dprintf("%s: Invalid sample rate: 0x%lx\n", __func__, s->samplerate); break;
case B_SR_8000: wfmt |= (0 << 14) | (0 << 11) | (5 << 8); s->rate=8000; break;
case B_SR_11025: wfmt |= (1 << 14) | (0 << 11) | (3 << 8); s->rate=11025; break;
case B_SR_16000: wfmt |= (0 << 14) | (0 << 11) | (2 << 8); s->rate=16000; break;
case B_SR_22050: wfmt |= (1 << 14) | (0 << 11) | (1 << 8); s->rate=22050; break;
case B_SR_32000: wfmt |= (0 << 14) | (1 << 11) | (2 << 8); s->rate=32000; break;
case B_SR_44100: wfmt |= (1 << 14) | (0 << 11) | (0 << 8); s->rate=44100; break;
case B_SR_48000: wfmt |= (0 << 14) | (0 << 11) | (0 << 8); s->rate=48000; break;
case B_SR_88200: wfmt |= (1 << 14) | (1 << 11) | (0 << 8); s->rate=88200; break;
case B_SR_96000: wfmt |= (0 << 14) | (2 << 11) | (0 << 8); s->rate=96000; break;
case B_SR_176400: wfmt |= (1 << 14) | (3 << 11) | (0 << 8); s->rate=176400; break;
case B_SR_192000: wfmt |= (0 << 14) | (3 << 11) | (0 << 8); s->rate=192000; break;
default: dprintf("%s: Invalid sample rate: 0x%lx\n", __func__, s->samplerate); break;
}
dprintf("IRA: %s: setup stream %ld: SR=%ld, SF=%ld\n", __func__, s->id, s->rate, s->bps);
OREG16(afg->codec->ctrlr,s->off,FMT) = wfmt;
OREG32(afg->codec->ctrlr,s->off,BDPL) = s->bdl_pa;
OREG32(afg->codec->ctrlr,s->off,BDPU) = 0;
@@ -173,7 +173,7 @@ get_buffers(hda_afg* afg, multi_buffer_list* data)
/* ... from here on, we can assume again that a reasonable request is being made */
data->flags = 0;
data->flags = B_MULTI_BUFFER_PLAYBACK;
/* Copy the requested settings into the streams */
afg->playback_stream->num_buffers = data->request_playback_buffers;
@@ -218,6 +218,8 @@ get_buffers(hda_afg* afg, multi_buffer_list* data)
return B_OK;
}
/* playback_buffer_cycle is the buffer we want to have played */
static status_t
buffer_exchange(hda_afg* afg, multi_buffer_info* data)
{
@@ -258,7 +260,7 @@ static status_t
buffer_force_stop(hda_afg* afg)
{
hda_stream_stop(afg->codec->ctrlr, afg->playback_stream);
hda_stream_stop(afg->codec->ctrlr, afg->record_stream);
//hda_stream_stop(afg->codec->ctrlr, afg->record_stream);
delete_sem(afg->playback_stream->buffer_ready_sem);
// delete_sem(afg->record_stream->buffer_ready_sem);