From e7d7efa1c72bd671bd5aa5758443440279975cf0 Mon Sep 17 00:00:00 2001 From: "Ithamar R. Adema" Date: Fri, 11 Jan 2008 16:50:53 +0000 Subject: [PATCH] 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 --- src/add-ons/kernel/drivers/audio/hda/driver.c | 3 ++ src/add-ons/kernel/drivers/audio/hda/driver.h | 40 ++++++++------- .../kernel/drivers/audio/hda/hda_codec.c | 49 +++++++++++-------- .../kernel/drivers/audio/hda/hda_controller.c | 43 ++++++++-------- .../drivers/audio/hda/hda_multi_audio.c | 6 ++- 5 files changed, 80 insertions(+), 61 deletions(-) diff --git a/src/add-ons/kernel/drivers/audio/hda/driver.c b/src/add-ons/kernel/drivers/audio/hda/driver.c index a46d32d0e6..1a72ddbe14 100644 --- a/src/add-ons/kernel/drivers/audio/hda/driver.c +++ b/src/add-ons/kernel/drivers/audio/hda/driver.c @@ -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; } diff --git a/src/add-ons/kernel/drivers/audio/hda/driver.h b/src/add-ons/kernel/drivers/audio/hda/driver.h index e62918098c..897ad0e918 100644 --- a/src/add-ons/kernel/drivers/audio/hda/driver.h +++ b/src/add-ons/kernel/drivers/audio/hda/driver.h @@ -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; diff --git a/src/add-ons/kernel/drivers/audio/hda/hda_codec.c b/src/add-ons/kernel/drivers/audio/hda/hda_codec.c index 74757297ae..651670fed9 100644 --- a/src/add-ons/kernel/drivers/audio/hda/hda_codec.c +++ b/src/add-ons/kernel/drivers/audio/hda/hda_codec.c @@ -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; diff --git a/src/add-ons/kernel/drivers/audio/hda/hda_controller.c b/src/add-ons/kernel/drivers/audio/hda/hda_controller.c index 002dd50660..6fabae034f 100644 --- a/src/add-ons/kernel/drivers/audio/hda/hda_controller.c +++ b/src/add-ons/kernel/drivers/audio/hda/hda_controller.c @@ -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; diff --git a/src/add-ons/kernel/drivers/audio/hda/hda_multi_audio.c b/src/add-ons/kernel/drivers/audio/hda/hda_multi_audio.c index 69cc787790..d27db83192 100644 --- a/src/add-ons/kernel/drivers/audio/hda/hda_multi_audio.c +++ b/src/add-ons/kernel/drivers/audio/hda/hda_multi_audio.c @@ -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);