diff options
author | Yang-Rong Jerry Zhou <Yangrong.Zhou@Sun.COM> | 2009-06-11 09:17:20 +0800 |
---|---|---|
committer | Yang-Rong Jerry Zhou <Yangrong.Zhou@Sun.COM> | 2009-06-11 09:17:20 +0800 |
commit | c6e681c099c367c8efe8b12cf5965d8bf0b1921a (patch) | |
tree | 44d8ba9fe406ddf925540b74d592cbd2ce6b2fa7 | |
parent | 57f4a14abf7408570afb91750e10e4b57f721549 (diff) | |
download | illumos-gate-c6e681c099c367c8efe8b12cf5965d8bf0b1921a.tar.gz |
6848264 Sound distorts when recording with the built-in MIC on Toshiba M9
6847499 A common "destroy" function is needed to release audiohd source
6847503 The elements of array statep->path[] are not released
6849183 AUDIO_FAILURE/AUDIO_SUCCESS should be replaced with DDI_FAILURE/DDI_SUCCESS
-rw-r--r-- | usr/src/uts/common/io/audio/drv/audiohd/audiohd.c | 372 | ||||
-rw-r--r-- | usr/src/uts/common/io/audio/drv/audiohd/audiohd.h | 18 |
2 files changed, 170 insertions, 220 deletions
diff --git a/usr/src/uts/common/io/audio/drv/audiohd/audiohd.c b/usr/src/uts/common/io/audio/drv/audiohd/audiohd.c index a9a460821c..d53989b86e 100644 --- a/usr/src/uts/common/io/audio/drv/audiohd/audiohd.c +++ b/usr/src/uts/common/io/audio/drv/audiohd/audiohd.c @@ -76,6 +76,7 @@ static int audiohd_add_controls(audiohd_state_t *statep); static void audiohd_get_channels(audiohd_state_t *statep); static void audiohd_init_path(audiohd_state_t *statep); static void audiohd_del_controls(audiohd_state_t *statep); +static void audiohd_destroy(audiohd_state_t *statep); static ddi_device_acc_attr_t hda_dev_accattr = { DDI_DEVICE_ATTR_V0, @@ -226,31 +227,31 @@ audiohd_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) ddi_set_driver_private(dip, statep); /* interrupt cookie and initialize mutex */ - if (audiohd_init_state(statep, dip) != AUDIO_SUCCESS) { + if (audiohd_init_state(statep, dip) != DDI_SUCCESS) { cmn_err(CE_NOTE, "audiohd_init_state failed"); - goto err_attach_exit3; + goto error; } /* Set PCI command register to enable bus master and memeory I/O */ - if (audiohd_init_pci(statep, &hda_dev_accattr) != AUDIO_SUCCESS) { + if (audiohd_init_pci(statep, &hda_dev_accattr) != DDI_SUCCESS) { audio_dev_warn(statep->adev, "couldn't init pci regs"); - goto err_attach_exit4; + goto error; } audiohd_set_chipset_info(statep); - if (audiohd_init_controller(statep) != AUDIO_SUCCESS) { + if (audiohd_init_controller(statep) != DDI_SUCCESS) { audio_dev_warn(statep->adev, "couldn't init controller"); - goto err_attach_exit5; + goto error; } - if (audiohd_create_codec(statep) != AUDIO_SUCCESS) { + if (audiohd_create_codec(statep) != DDI_SUCCESS) { audio_dev_warn(statep->adev, "couldn't create codec"); - goto err_attach_exit6; + goto error; } audiohd_build_path(statep); @@ -258,7 +259,7 @@ audiohd_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) audiohd_get_channels(statep); if (audiohd_allocate_port(statep) != DDI_SUCCESS) { audio_dev_warn(statep->adev, "allocate port failure"); - goto err_attach_exit7; + goto error; } audiohd_init_path(statep); /* set up kernel statistics */ @@ -277,8 +278,9 @@ audiohd_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) DDI_SUCCESS) { audio_dev_warn(statep->adev, "bad interrupt specification "); - goto err_attach_exit8; + goto error; } + statep->intr_added = B_TRUE; /* * Register audio controls. @@ -286,12 +288,12 @@ audiohd_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) if (audiohd_add_controls(statep) == DDI_FAILURE) { audio_dev_warn(statep->adev, "unable to allocate controls"); - goto err_attach_exit9; + goto error; } if (audio_dev_register(statep->adev) != DDI_SUCCESS) { audio_dev_warn(statep->adev, "unable to register with framework"); - goto err_attach_exit9; + goto error; } ddi_report_dev(dip); @@ -300,32 +302,8 @@ audiohd_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) AUDIOHD_INTCTL_BIT_GIE | AUDIOHD_INTCTL_BIT_SIE); return (DDI_SUCCESS); -err_attach_exit9: - audiohd_del_controls(statep); - -err_attach_exit8: - if (statep->hda_ksp) - kstat_delete(statep->hda_ksp); - audiohd_free_port(statep); - -err_attach_exit7: - audiohd_destroy_codec(statep); - -err_attach_exit6: - audiohd_fini_controller(statep); - -err_attach_exit5: - audiohd_fini_pci(statep); - -err_attach_exit4: - mutex_destroy(&statep->hda_mutex); - -err_attach_exit3: - (void) audio_dev_unregister(statep->adev); - -err_attach_exit2: -err_attach_exit1: - +error: + audiohd_destroy(statep); return (DDI_FAILURE); } @@ -350,22 +328,7 @@ audiohd_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) if (audio_dev_unregister(statep->adev) != DDI_SUCCESS) return (DDI_FAILURE); - mutex_enter(&statep->hda_mutex); - audiohd_stop_dma(statep); - audiohd_disable_intr(statep); - mutex_exit(&statep->hda_mutex); - ddi_remove_intr(dip, 0, statep->hda_intr_cookie); - if (statep->hda_ksp) - kstat_delete(statep->hda_ksp); - audiohd_free_port(statep); - audiohd_destroy_codec(statep); - audiohd_del_controls(statep); - audiohd_fini_controller(statep); - audiohd_fini_pci(statep); - mutex_destroy(&statep->hda_mutex); - if (statep->adev) - audio_dev_free(statep->adev); - kmem_free(statep, sizeof (*statep)); + audiohd_destroy(statep); return (DDI_SUCCESS); } @@ -451,7 +414,44 @@ audiohd_engine_rate(void *arg) return (48000); } +static void +audiohd_free_path(audiohd_state_t *statep) +{ + audiohd_path_t *path; + int i; + + for (i = 0; i < statep->pathnum; i++) { + if (statep->path[i]) { + path = statep->path[i]; + kmem_free(path, sizeof (audiohd_path_t)); + } + } +} +static void +audiohd_destroy(audiohd_state_t *statep) +{ + dev_info_t *dip = statep->hda_dip; + mutex_enter(&statep->hda_mutex); + audiohd_stop_dma(statep); + audiohd_disable_intr(statep); + mutex_exit(&statep->hda_mutex); + if (statep->intr_added) { + ddi_remove_intr(dip, 0, statep->hda_intr_cookie); + } + if (statep->hda_ksp) + kstat_delete(statep->hda_ksp); + audiohd_free_port(statep); + audiohd_free_path(statep); + audiohd_destroy_codec(statep); + audiohd_del_controls(statep); + audiohd_fini_controller(statep); + audiohd_fini_pci(statep); + mutex_destroy(&statep->hda_mutex); + if (statep->adev) + audio_dev_free(statep->adev); + kmem_free(statep, sizeof (*statep)); +} /* * get the max channels the hardware supported */ @@ -701,7 +701,7 @@ audiohd_reset_port(audiohd_port_t *port) if (!bTmp) { audio_dev_warn(statep->adev, "Failed to reset stream %d", port->index); - return (AUDIO_FAILURE); + return (DDI_FAILURE); } /* Empirical testing time, which works well */ @@ -724,7 +724,7 @@ audiohd_reset_port(audiohd_port_t *port) audio_dev_warn(statep->adev, "Failed to exit reset state for" " stream %d, bTmp=0x%02x", port->index, bTmp); - return (AUDIO_FAILURE); + return (DDI_FAILURE); } AUDIOHD_REG_SET32(regbase + AUDIOHD_SDREG_OFFSET_BDLPL, @@ -749,7 +749,7 @@ audiohd_reset_port(audiohd_port_t *port) AUDIOHD_PLAY_CTL_OFF, (port->index) << AUDIOHD_PLAY_TAG_OFF); - return (AUDIO_SUCCESS); + return (DDI_SUCCESS); } static int audiohd_engine_open(void *arg, int flag, @@ -976,7 +976,7 @@ audiohd_set_output_gain(audiohd_state_t *statep) static void audiohd_do_set_pin_volume(audiohd_state_t *statep, audiohd_path_t *path, - audiohd_pin_t *pin, uint64_t val) + uint64_t val) { uint8_t l, r; uint_t tmp; @@ -986,9 +986,9 @@ audiohd_do_set_pin_volume(audiohd_state_t *statep, audiohd_path_t *path, (void) audioha_codec_4bit_verb_get( statep, path->codec->index, - pin->mute_wid, + path->mute_wid, AUDIOHDC_VERB_SET_AMP_MUTE, - pin->mute_dir | + path->mute_dir | AUDIOHDC_AMP_SET_LNR | AUDIOHDC_AMP_SET_MUTE); return; @@ -997,36 +997,36 @@ audiohd_do_set_pin_volume(audiohd_state_t *statep, audiohd_path_t *path, l = (val & 0xff00) >> 8; r = (val & 0xff); - tmp = l * pin->gain_bits / 100; + tmp = l * path->gain_bits / 100; (void) audioha_codec_4bit_verb_get(statep, path->codec->index, - pin->gain_wid, + path->gain_wid, AUDIOHDC_VERB_SET_AMP_MUTE, - AUDIOHDC_AMP_SET_LEFT | pin->gain_dir | + AUDIOHDC_AMP_SET_LEFT | path->gain_dir | tmp); - tmp = r * pin->gain_bits / 100; + tmp = r * path->gain_bits / 100; (void) audioha_codec_4bit_verb_get(statep, path->codec->index, - pin->gain_wid, + path->gain_wid, AUDIOHDC_VERB_SET_AMP_MUTE, - AUDIOHDC_AMP_SET_RIGHT | pin->gain_dir | + AUDIOHDC_AMP_SET_RIGHT | path->gain_dir | tmp); - if (pin->mute_wid != pin->gain_wid) { + if (path->mute_wid != path->gain_wid) { gain = AUDIOHDC_GAIN_MAX; (void) audioha_codec_4bit_verb_get( statep, path->codec->index, - pin->mute_wid, + path->mute_wid, AUDIOHDC_VERB_SET_AMP_MUTE, - pin->mute_dir | + path->mute_dir | AUDIOHDC_AMP_SET_LEFT | gain); (void) audioha_codec_4bit_verb_get( statep, path->codec->index, - pin->mute_wid, + path->mute_wid, AUDIOHDC_VERB_SET_AMP_MUTE, - pin->mute_dir | + path->mute_dir | AUDIOHDC_AMP_SET_RIGHT | gain); } @@ -1086,9 +1086,8 @@ audiohd_set_pin_volume(audiohd_state_t *statep, audiohda_device_type_t type) wid = path->pin_wid[j]; widget = codec->widget[wid]; pin = (audiohd_pin_t *)widget->priv; - if ((pin->device == type) && pin->gain_wid) { - audiohd_do_set_pin_volume(statep, path, - pin, val); + if ((pin->device == type) && path->gain_wid) { + audiohd_do_set_pin_volume(statep, path, val); } } } @@ -1153,9 +1152,8 @@ audiohd_set_pin_volume_by_color(audiohd_state_t *statep, pin = (audiohd_pin_t *)widget->priv; clr = (pin->config >> AUDIOHD_PIN_CLR_OFF) & AUDIOHD_PIN_CLR_MASK; - if ((clr == color) && pin->gain_wid) { - audiohd_do_set_pin_volume(statep, path, - pin, val); + if ((clr == color) && path->gain_wid) { + audiohd_do_set_pin_volume(statep, path, val); } } } @@ -1897,9 +1895,10 @@ audiohd_init_state(audiohd_state_t *statep, dev_info_t *dip) if ((adev = audio_dev_alloc(dip, 0)) == NULL) { cmn_err(CE_WARN, "unable to allocate audio dev"); - return (AUDIO_FAILURE); + return (DDI_FAILURE); } statep->adev = adev; + statep->intr_added = B_FALSE; /* set device information */ audio_dev_set_description(adev, AUDIOHD_DEV_CONFIG); @@ -1909,18 +1908,14 @@ audiohd_init_state(audiohd_state_t *statep, dev_info_t *dip) DDI_SUCCESS) { audio_dev_warn(statep->adev, "cannot get iblock cookie"); - goto error; + return (DDI_FAILURE); } mutex_init(&statep->hda_mutex, NULL, MUTEX_DRIVER, statep->hda_intr_cookie); statep->hda_rirb_rp = 0; - return (AUDIO_SUCCESS); -error: - if (statep->adev != NULL) - audio_dev_free(statep->adev); - return (AUDIO_FAILURE); + return (DDI_SUCCESS); } /* audiohd_init_state() */ /* @@ -1942,14 +1937,14 @@ audiohd_init_pci(audiohd_state_t *statep, ddi_device_acc_attr_t *acc_attr) if (pci_config_setup(dip, &statep->hda_pci_handle) == DDI_FAILURE) { audio_dev_warn(ahandle, "pci config mapping failed"); - goto err_init_pci_exit1; + return (DDI_FAILURE); } if (ddi_regs_map_setup(dip, 1, &statep->hda_reg_base, 0, 0, acc_attr, &statep->hda_reg_handle) != DDI_SUCCESS) { audio_dev_warn(ahandle, "memory I/O mapping failed"); - goto err_init_pci_exit2; + return (DDI_FAILURE); } /* @@ -2007,14 +2002,7 @@ audiohd_init_pci(audiohd_state_t *statep, ddi_device_acc_attr_t *acc_attr) break; } - return (AUDIO_SUCCESS); - -err_init_pci_exit2: - pci_config_teardown(&statep->hda_pci_handle); - -err_init_pci_exit1: - return (AUDIO_FAILURE); - + return (DDI_SUCCESS); } /* audiohd_init_pci() */ @@ -2106,7 +2094,7 @@ audiohd_reset_controller(audiohd_state_t *statep) if ((gctl & AUDIOHDR_GCTL_CRST) != 0) { audio_dev_warn(statep->adev, "failed to enter reset state"); - return (AUDIO_FAILURE); + return (DDI_FAILURE); } /* Empirical testing time:300 */ @@ -2126,7 +2114,7 @@ audiohd_reset_controller(audiohd_state_t *statep) if ((gctl & AUDIOHDR_GCTL_CRST) == 0) { audio_dev_warn(statep->adev, "failed to exit reset state"); - return (AUDIO_FAILURE); + return (DDI_FAILURE); } /* HD spec requires to wait 250us at least. we use 500us */ @@ -2136,7 +2124,7 @@ audiohd_reset_controller(audiohd_state_t *statep) AUDIOHD_REG_SET32(AUDIOHD_REG_GCTL, gctl | AUDIOHDR_GCTL_URESPE); - return (AUDIO_SUCCESS); + return (DDI_SUCCESS); } /* audiohd_reset_controller() */ @@ -2160,7 +2148,7 @@ audiohd_alloc_dma_mem(audiohd_state_t *statep, audiohd_dma_t *pdma, NULL, &pdma->ad_dmahdl) != DDI_SUCCESS) { audio_dev_warn(ahandle, "ddi_dma_alloc_handle failed"); - goto error_alloc_dma_exit1; + return (DDI_FAILURE); } if (ddi_dma_mem_alloc(pdma->ad_dmahdl, memsize, &hda_dev_accattr, @@ -2170,7 +2158,7 @@ audiohd_alloc_dma_mem(audiohd_state_t *statep, audiohd_dma_t *pdma, &pdma->ad_acchdl) != DDI_SUCCESS) { audio_dev_warn(ahandle, "ddi_dma_mem_alloc failed"); - goto error_alloc_dma_exit2; + return (DDI_FAILURE); } if (ddi_dma_addr_bind_handle(pdma->ad_dmahdl, NULL, @@ -2178,23 +2166,13 @@ audiohd_alloc_dma_mem(audiohd_state_t *statep, audiohd_dma_t *pdma, DDI_DMA_SLEEP, NULL, &cookie, &count) != DDI_DMA_MAPPED) { audio_dev_warn(ahandle, "ddi_dma_addr_bind_handle failed"); - goto error_alloc_dma_exit3; + return (DDI_FAILURE); } pdma->ad_paddr = (uint64_t)(cookie.dmac_laddress); pdma->ad_req_sz = memsize; - return (AUDIO_SUCCESS); - -error_alloc_dma_exit3: - ddi_dma_mem_free(&pdma->ad_acchdl); - -error_alloc_dma_exit2: - ddi_dma_free_handle(&pdma->ad_dmahdl); - -error_alloc_dma_exit1: - return (AUDIO_FAILURE); - + return (DDI_SUCCESS); } /* audiohd_alloc_dma_mem() */ /* @@ -2238,8 +2216,8 @@ audiohd_reinit_hda(audiohd_state_t *statep) (void) audiohd_init_pci(statep, &hda_dev_accattr); /* reset controller */ - if (audiohd_reset_controller(statep) != AUDIO_SUCCESS) - return (AUDIO_FAILURE); + if (audiohd_reset_controller(statep) != DDI_SUCCESS) + return (DDI_FAILURE); AUDIOHD_REG_SET32(AUDIOHD_REG_SYNC, 0); /* needn't sync stream */ /* Initialize controller RIRB */ @@ -2267,7 +2245,7 @@ audiohd_reinit_hda(audiohd_state_t *statep) audiohd_restore_path(statep); audiohd_init_path(statep); - return (AUDIO_SUCCESS); + return (DDI_SUCCESS); } /* audiohd_reinit_hda */ /* @@ -2326,35 +2304,35 @@ audiohd_init_controller(audiohd_state_t *statep) /* stop all dma before starting to reset controller */ audiohd_stop_dma(statep); - if (audiohd_reset_controller(statep) != AUDIO_SUCCESS) - return (AUDIO_FAILURE); + if (audiohd_reset_controller(statep) != DDI_SUCCESS) + return (DDI_FAILURE); /* check codec */ statep->hda_codec_mask = AUDIOHD_REG_GET16(AUDIOHD_REG_STATESTS); - if (! statep->hda_codec_mask) { + if (!statep->hda_codec_mask) { audio_dev_warn(statep->adev, "no codec exists"); - goto err_init_ctlr_exit1; + return (DDI_FAILURE); } /* allocate DMA for CORB */ retval = audiohd_alloc_dma_mem(statep, &statep->hda_dma_corb, AUDIOHD_CDBIO_CORB_LEN, &dma_attr, DDI_DMA_WRITE | DDI_DMA_STREAMING); - if (retval != AUDIO_SUCCESS) { + if (retval != DDI_SUCCESS) { audio_dev_warn(statep->adev, "failed to alloc DMA for CORB"); - goto err_init_ctlr_exit1; + return (DDI_FAILURE); } /* allocate DMA for RIRB */ retval = audiohd_alloc_dma_mem(statep, &statep->hda_dma_rirb, AUDIOHD_CDBIO_RIRB_LEN, &dma_attr, DDI_DMA_READ | DDI_DMA_STREAMING); - if (retval != AUDIO_SUCCESS) { + if (retval != DDI_SUCCESS) { audio_dev_warn(statep->adev, "failed to alloc DMA for RIRB"); - goto err_init_ctlr_exit2; + return (DDI_FAILURE); } @@ -2381,17 +2359,7 @@ audiohd_init_controller(audiohd_state_t *statep) AUDIOHD_REG_SET16(AUDIOHD_REG_CORBRP, 0); AUDIOHD_REG_SET8(AUDIOHD_REG_CORBCTL, AUDIOHDR_CORBCTL_DMARUN); - return (AUDIO_SUCCESS); - -err_init_ctlr_exit3: - audiohd_release_dma_mem(&(statep->hda_dma_rirb)); - -err_init_ctlr_exit2: - audiohd_release_dma_mem(&(statep->hda_dma_corb)); - -err_init_ctlr_exit1: - return (AUDIO_FAILURE); - + return (DDI_SUCCESS); } /* audiohd_init_controller() */ /* @@ -3086,7 +3054,7 @@ audiohd_create_codec(audiohd_state_t *statep) (void) audiohd_create_widgets(codec); } - return (AUDIO_SUCCESS); + return (DDI_SUCCESS); } /* audiohd_create_codec() */ @@ -3147,14 +3115,14 @@ audiohd_find_dac(hda_codec_t *codec, wid_t wid, int exclusive, int depth) { audiohd_widget_t *widget = codec->widget[wid]; - wid_t wdac = (uint32_t)(AUDIO_FAILURE); + wid_t wdac = (uint32_t)(DDI_FAILURE); wid_t retval; if (depth > AUDIOHD_MAX_DEPTH) - return (uint32_t)(AUDIO_FAILURE); + return (uint32_t)(DDI_FAILURE); if (widget == NULL) - return (uint32_t)(AUDIO_FAILURE); + return (uint32_t)(DDI_FAILURE); /* * If exclusive is true, we try to find a path which doesn't @@ -3162,7 +3130,7 @@ audiohd_find_dac(hda_codec_t *codec, wid_t wid, */ if (exclusive) { if (widget->path_flags & AUDIOHD_PATH_DAC) - return (uint32_t)(AUDIO_FAILURE); + return (uint32_t)(DDI_FAILURE); } else { if (widget->path_flags & AUDIOHD_PATH_DAC) return (wid); @@ -3172,7 +3140,7 @@ audiohd_find_dac(hda_codec_t *codec, wid_t wid, case WTYPE_AUDIO_OUT: /* We need mixer widget, but the the mixer num is 0, failed */ if (mixer && !*mixernum) - return (uint32_t)(AUDIO_FAILURE); + return (uint32_t)(DDI_FAILURE); widget->path_flags |= AUDIOHD_PATH_DAC; widget->out_weight++; wdac = widget->wid_wid; @@ -3187,7 +3155,7 @@ audiohd_find_dac(hda_codec_t *codec, wid_t wid, widget->avail_conn[i], mixer, mixernum, exclusive, depth + 1); - if (retval != (uint32_t)AUDIO_FAILURE) { + if (retval != (uint32_t)DDI_FAILURE) { if (widget->selconn == AUDIOHD_NULL_CONN) { widget->selconn = i; wdac = retval; @@ -3251,7 +3219,7 @@ audiohd_do_build_output_path(hda_codec_t *codec, int mixer, int *mnum, /* * If a dac found, the return value is the wid of the * widget on the path, or the return value is - * AUDIO_FAILURE + * DDI_FAILURE */ wid = audiohd_find_dac(codec, widget->avail_conn[i], mixer, mnum, exclusive, @@ -3259,7 +3227,7 @@ audiohd_do_build_output_path(hda_codec_t *codec, int mixer, int *mnum, /* * A dac was not found */ - if (wid == (wid_t)AUDIO_FAILURE) + if (wid == (wid_t)DDI_FAILURE) continue; if (pin->device != DTYPE_SPEAKER) statep->chann[pin->assoc] += 2; @@ -3611,20 +3579,20 @@ audiohd_find_input_pins(hda_codec_t *codec, wid_t wid, int allowmixer, uint32_t pinctrl; if (depth > AUDIOHD_MAX_DEPTH) - return (uint32_t)(AUDIO_FAILURE); + return (uint32_t)(DDI_FAILURE); if (widget == NULL) - return (uint32_t)(AUDIO_FAILURE); + return (uint32_t)(DDI_FAILURE); /* we don't share widgets */ if (widget->path_flags & AUDIOHD_PATH_ADC || widget->path_flags & AUDIOHD_PATH_DAC) - return (uint32_t)(AUDIO_FAILURE); + return (uint32_t)(DDI_FAILURE); switch (widget->type) { case WTYPE_PIN: pin = (audiohd_pin_t *)widget->priv; if (pin->no_phys_conn) - return (uint32_t)(AUDIO_FAILURE); + return (uint32_t)(DDI_FAILURE); /* enable the pins' input capability */ pinctrl = audioha_codec_verb_get(statep, caddr, wid, AUDIOHDC_VERB_GET_PIN_CTRL, 0); @@ -3645,7 +3613,7 @@ audiohd_find_input_pins(hda_codec_t *codec, wid_t wid, int allowmixer, widget->in_weight++; path->pin_wid[path->pin_nums++] = wid; pin->adc_dac_wid = path->adda_wid; - return (AUDIO_SUCCESS); + return (DDI_SUCCESS); } break; case WTYPE_AUDIO_MIX: @@ -3659,7 +3627,7 @@ audiohd_find_input_pins(hda_codec_t *codec, wid_t wid, int allowmixer, retval = audiohd_find_input_pins(codec, widget->avail_conn[0], allowmixer, depth + 1, path); - if (retval != AUDIO_FAILURE) { + if (retval != DDI_FAILURE) { widget->path_flags |= AUDIOHD_PATH_ADC; widget->in_weight++; } @@ -3676,7 +3644,7 @@ audiohd_find_input_pins(hda_codec_t *codec, wid_t wid, int allowmixer, retval = audiohd_find_input_pins(codec, widget->avail_conn[i], 0, depth + 1, path); - if (retval != AUDIO_FAILURE) { + if (retval != DDI_FAILURE) { widget->in_weight++; num = path->pin_nums - 1; path->sum_selconn[num] = i; @@ -3692,7 +3660,7 @@ audiohd_find_input_pins(hda_codec_t *codec, wid_t wid, int allowmixer, /* return SUCCESS if we found at least one input path */ if (path->pin_nums > 0) - retval = AUDIO_SUCCESS; + retval = DDI_SUCCESS; } else { /* * We had already found a real sum before this one since @@ -3702,7 +3670,7 @@ audiohd_find_input_pins(hda_codec_t *codec, wid_t wid, int allowmixer, retval = audiohd_find_input_pins(codec, widget->avail_conn[i], 0, depth + 1, path); - if (retval != AUDIO_FAILURE) { + if (retval != DDI_FAILURE) { widget->selconn = i; widget->path_flags |= AUDIOHD_PATH_ADC; widget->in_weight++; @@ -3764,7 +3732,7 @@ audiohd_build_input_path(hda_codec_t *codec) for (i = 0; i < widget->nconns; i++) { retval = audiohd_find_input_pins(codec, widget->avail_conn[i], 1, 0, path); - if (retval == AUDIO_SUCCESS) { + if (retval == DDI_SUCCESS) { path->codec = codec; path->statep = statep; path->path_type = RECORD; @@ -4105,42 +4073,42 @@ audiohd_find_inpin_for_monitor(hda_codec_t *codec, wid = id; widget = codec->widget[wid]; if (widget == NULL) - return (uint32_t)(AUDIO_FAILURE); + return (uint32_t)(DDI_FAILURE); if (widget->type == WTYPE_PIN) { pin = (audiohd_pin_t *)widget->priv; if (pin->no_phys_conn) - return (uint32_t)(AUDIO_FAILURE); + return (uint32_t)(DDI_FAILURE); switch (pin->device) { case DTYPE_SPDIF_IN: widget->path_flags |= AUDIOHD_PATH_MON; - return (AUDIO_SUCCESS); + return (DDI_SUCCESS); case DTYPE_CD: widget->path_flags |= AUDIOHD_PATH_MON; - return (AUDIO_SUCCESS); + return (DDI_SUCCESS); case DTYPE_LINE_IN: widget->path_flags |= AUDIOHD_PATH_MON; - return (AUDIO_SUCCESS); + return (DDI_SUCCESS); case DTYPE_MIC_IN: widget->path_flags |= AUDIOHD_PATH_MON; - return (AUDIO_SUCCESS); + return (DDI_SUCCESS); case DTYPE_AUX: widget->path_flags |= AUDIOHD_PATH_MON; - return (AUDIO_SUCCESS); + return (DDI_SUCCESS); default: - return (uint32_t)(AUDIO_FAILURE); + return (uint32_t)(DDI_FAILURE); } } /* the widget has been visited and can't be directed to input pin */ if (widget->path_flags & AUDIOHD_PATH_NOMON) { - return (uint32_t)(AUDIO_FAILURE); + return (uint32_t)(DDI_FAILURE); } /* the widget has been used by the monitor path, and we can share it */ if (widget->path_flags & AUDIOHD_PATH_MON) { if (mixer) - return (AUDIO_SUCCESS); + return (DDI_SUCCESS); else - return (uint32_t)(AUDIO_FAILURE); + return (uint32_t)(DDI_FAILURE); } switch (widget->type) { case WTYPE_AUDIO_MIX: @@ -4151,7 +4119,7 @@ audiohd_find_inpin_for_monitor(hda_codec_t *codec, if (audiohd_find_inpin_for_monitor(codec, path, widget->avail_conn[i], mixer) == - AUDIO_SUCCESS) { + DDI_SUCCESS) { widget->selmon[widget->used++] = i; widget->path_flags |= AUDIOHD_PATH_MON; find = 1; @@ -4167,10 +4135,10 @@ audiohd_find_inpin_for_monitor(hda_codec_t *codec, path, widget->avail_conn[i], mixer) == - AUDIO_SUCCESS) { + DDI_SUCCESS) { widget->selmon[0] = i; widget->path_flags |= AUDIOHD_PATH_MON; - return (AUDIO_SUCCESS); + return (DDI_SUCCESS); } } default: @@ -4178,10 +4146,10 @@ audiohd_find_inpin_for_monitor(hda_codec_t *codec, } if (!find) { widget->path_flags |= AUDIOHD_PATH_NOMON; - return (uint32_t)(AUDIO_FAILURE); + return (uint32_t)(DDI_FAILURE); } else - return (AUDIO_SUCCESS); + return (DDI_SUCCESS); } /* audiohd_find_inpin_for_monitor */ /* @@ -4251,7 +4219,7 @@ audiohd_build_monitor_path(hda_codec_t *codec) codec, path, widget->avail_conn[k], 0) == - AUDIO_SUCCESS) { + DDI_SUCCESS) { path->mon_wid[j][l] = wid; widget->selmon[widget->used++] = k; @@ -4263,7 +4231,7 @@ audiohd_build_monitor_path(hda_codec_t *codec) codec, path, widget->avail_conn[k], 1) == - AUDIO_SUCCESS) { + DDI_SUCCESS) { path->mon_wid[j][l] = wid; widget->selmon[widget->used++] = k; @@ -4606,7 +4574,7 @@ audiohd_allocate_port(audiohd_state_t *statep) if (rc != DDI_SUCCESS) { audio_dev_warn(adev, "ddi_dma_alloc_handle failed: %d", rc); - goto error_alloc_dma_exit1; + return (DDI_FAILURE); } /* allocate DMA buffer */ rc = ddi_dma_mem_alloc(port->samp_dmah, port->samp_size * @@ -4617,7 +4585,7 @@ audiohd_allocate_port(audiohd_state_t *statep) &real_size, &port->samp_acch); if (rc == DDI_FAILURE) { audio_dev_warn(adev, "dma_mem_alloc failed"); - goto error_alloc_dma_exit2; + return (DDI_FAILURE); } /* bind DMA buffer */ @@ -4627,7 +4595,7 @@ audiohd_allocate_port(audiohd_state_t *statep) if ((rc != DDI_DMA_MAPPED) || (count != 1)) { audio_dev_warn(adev, "ddi_dma_addr_bind_handle failed: %d", rc); - goto error_alloc_dma_exit3; + return (DDI_FAILURE); } port->samp_paddr = (uint64_t)cookie.dmac_laddress; @@ -4641,7 +4609,7 @@ audiohd_allocate_port(audiohd_state_t *statep) if (rc != DDI_SUCCESS) { audio_dev_warn(adev, "ddi_dma_alloc_handle(bdlist) failed"); - goto error_alloc_dma_exit3; + return (DDI_FAILURE); } /* @@ -4655,7 +4623,7 @@ audiohd_allocate_port(audiohd_state_t *statep) if (rc != DDI_SUCCESS) { audio_dev_warn(adev, "ddi_dma_mem_alloc(bdlist) failed"); - goto error_alloc_dma_exit4; + return (DDI_FAILURE); } rc = ddi_dma_addr_bind_handle(port->bdl_dmah, NULL, @@ -4665,7 +4633,7 @@ audiohd_allocate_port(audiohd_state_t *statep) NULL, &cookie, &count); if ((rc != DDI_DMA_MAPPED) || (count != 1)) { audio_dev_warn(adev, "addr_bind_handle failed"); - goto error_alloc_dma_exit5; + return (DDI_FAILURE); } port->bdl_paddr = (uint64_t)cookie.dmac_laddress; @@ -4685,8 +4653,7 @@ audiohd_allocate_port(audiohd_state_t *statep) port->engine = audio_engine_alloc(&audiohd_engine_ops, caps); if (port->engine == NULL) { - audio_dev_warn(adev, "audio_engine_alloc failed"); - goto error_alloc_dma_exit5; + return (DDI_FAILURE); } audio_engine_set_private(port->engine, port); @@ -4694,21 +4661,6 @@ audiohd_allocate_port(audiohd_state_t *statep) } return (DDI_SUCCESS); -error_alloc_dma_exit5: - ddi_dma_mem_free(&port->bdl_acch); - -error_alloc_dma_exit4: - ddi_dma_free_handle(&port->bdl_dmah); - -error_alloc_dma_exit3: - ddi_dma_mem_free(&port->samp_acch); - -error_alloc_dma_exit2: - ddi_dma_free_handle(&port->samp_dmah); - -error_alloc_dma_exit1: - return (AUDIO_FAILURE); - } static void @@ -4942,7 +4894,7 @@ audiohd_resume(audiohd_state_t *statep) mutex_enter(&statep->hda_mutex); statep->suspended = B_FALSE; /* Restore the hda state */ - if (audiohd_reinit_hda(statep) == AUDIO_FAILURE) { + if (audiohd_reinit_hda(statep) == DDI_FAILURE) { audio_dev_warn(statep->adev, "hda reinit failed"); mutex_exit(&statep->hda_mutex); @@ -4996,7 +4948,7 @@ static int audiohd_disable_pin(audiohd_state_t *statep, int caddr, wid_t wid) { AUDIOHD_DISABLE_PIN_OUT(statep, caddr, wid); - return (AUDIO_SUCCESS); + return (DDI_SUCCESS); } /* @@ -5006,7 +4958,7 @@ static int audiohd_enable_pin(audiohd_state_t *statep, int caddr, wid_t wid) { AUDIOHD_ENABLE_PIN_OUT(statep, caddr, wid); - return (AUDIO_SUCCESS); + return (DDI_SUCCESS); } /* * audiohd_change_speaker_state() @@ -5280,7 +5232,7 @@ audiohd_intr(caddr_t arg) for (i = 0; i < AUDIOHD_TEST_TIMES; i++) { ret = audiohd_response_from_codec(statep, &resp, &respex); - if ((ret == AUDIO_SUCCESS) && + if ((ret == DDI_SUCCESS) && (respex & AUDIOHD_RIRB_UR_MASK)) { /* * A pin may generate more than one ur rirb, @@ -5293,7 +5245,7 @@ audiohd_intr(caddr_t arg) break; } } - if ((ret == AUDIO_SUCCESS) && + if ((ret == DDI_SUCCESS) && (respex & AUDIOHD_RIRB_UR_MASK)) { audiohd_pin_sense(statep, resp, respex); } @@ -5379,7 +5331,7 @@ audiohd_12bit_verb_to_codec(audiohd_state_t *statep, uint8_t caddr, /* overflow */ if (wptr == rptr) { - return (AUDIO_FAILURE); + return (DDI_FAILURE); } verb = (caddr & 0x0f) << AUDIOHD_VERB_ADDR_OFF; @@ -5392,7 +5344,7 @@ audiohd_12bit_verb_to_codec(audiohd_state_t *statep, uint8_t caddr, sizeof (sd_bdle_t) * AUDIOHD_BDLE_NUMS, DDI_DMA_SYNC_FORDEV); AUDIOHD_REG_SET16(AUDIOHD_REG_CORBWP, wptr); - return (AUDIO_SUCCESS); + return (DDI_SUCCESS); } /* audiohd_12bit_verb_to_codec() */ @@ -5421,7 +5373,7 @@ audiohd_4bit_verb_to_codec(audiohd_state_t *statep, uint8_t caddr, /* overflow */ if (wptr == rptr) { - return (AUDIO_FAILURE); + return (DDI_FAILURE); } verb = (caddr & 0x0f) << AUDIOHD_VERB_ADDR_OFF; @@ -5432,7 +5384,7 @@ audiohd_4bit_verb_to_codec(audiohd_state_t *statep, uint8_t caddr, *((uint32_t *)(statep->hda_dma_corb.ad_vaddr) + wptr) = verb; AUDIOHD_REG_SET16(AUDIOHD_REG_CORBWP, wptr); - return (AUDIO_SUCCESS); + return (DDI_SUCCESS); } /* audiohd_4bit_verb_to_codec() */ @@ -5454,7 +5406,7 @@ audiohd_response_from_codec(audiohd_state_t *statep, uint32_t *resp, rptr = statep->hda_rirb_rp; if (rptr == wptr) { - return (AUDIO_FAILURE); + return (DDI_FAILURE); } rptr++; @@ -5466,7 +5418,7 @@ audiohd_response_from_codec(audiohd_state_t *statep, uint32_t *resp, statep->hda_rirb_rp = rptr; - return (AUDIO_SUCCESS); + return (DDI_SUCCESS); } /* audiohd_response_from_codec() */ @@ -5486,7 +5438,7 @@ audioha_codec_verb_get(void *arg, uint8_t caddr, uint8_t wid, int i; ret = audiohd_12bit_verb_to_codec(statep, caddr, wid, verb, param); - if (ret != AUDIO_SUCCESS) { + if (ret != DDI_SUCCESS) { return (uint32_t)(-1); } @@ -5499,13 +5451,13 @@ audioha_codec_verb_get(void *arg, uint8_t caddr, uint8_t wid, ret = audiohd_response_from_codec(statep, &resp, &respex); if (((respex & AUDIOHD_BDLE_RIRB_SDI) == caddr) && ((respex & AUDIOHD_BDLE_RIRB_UNSOLICIT) == 0) && - (ret == AUDIO_SUCCESS)) + (ret == DDI_SUCCESS)) break; /* Empirical testing time, which works well */ drv_usecwait(30); } - if (ret == AUDIO_SUCCESS) { + if (ret == DDI_SUCCESS) { return (resp); } @@ -5532,7 +5484,7 @@ audioha_codec_4bit_verb_get(void *arg, uint8_t caddr, uint8_t wid, int i; ret = audiohd_4bit_verb_to_codec(statep, caddr, wid, verb, param); - if (ret != AUDIO_SUCCESS) { + if (ret != DDI_SUCCESS) { return (uint32_t)(-1); } @@ -5540,13 +5492,13 @@ audioha_codec_4bit_verb_get(void *arg, uint8_t caddr, uint8_t wid, ret = audiohd_response_from_codec(statep, &resp, &respex); if (((respex & AUDIOHD_BDLE_RIRB_SDI) == caddr) && ((respex & AUDIOHD_BDLE_RIRB_UNSOLICIT) == 0) && - (ret == AUDIO_SUCCESS)) + (ret == DDI_SUCCESS)) break; /* Empirical testing time, which works well */ drv_usecwait(30); } - if (ret == AUDIO_SUCCESS) { + if (ret == DDI_SUCCESS) { return (resp); } diff --git a/usr/src/uts/common/io/audio/drv/audiohd/audiohd.h b/usr/src/uts/common/io/audio/drv/audiohd/audiohd.h index 75330e6efd..3e1db3027b 100644 --- a/usr/src/uts/common/io/audio/drv/audiohd/audiohd.h +++ b/usr/src/uts/common/io/audio/drv/audiohd/audiohd.h @@ -44,9 +44,6 @@ extern "C" { #define AUDIOHD_CODECID_SONY1 0x10ec0260 #define AUDIOHD_CODECID_SONY2 0x10ec0262 -#define AUDIO_SUCCESS (0) -#define AUDIO_FAILURE (-1) - #define AUDIOHD_INTS 50 #define AUDIOHD_MAX_INTS 1500 #define AUDIOHD_MIN_INTS 32 @@ -774,6 +771,7 @@ struct audiohd_state { uint32_t hda_flags; boolean_t soft_volume; + boolean_t intr_added; caddr_t hda_reg_base; ddi_acc_handle_t hda_pci_handle; @@ -887,13 +885,13 @@ struct audiohd_state { lTmp = audioha_codec_verb_get(statep, caddr, wid, \ AUDIOHDC_VERB_GET_PIN_CTRL, 0); \ if (lTmp == AUDIOHD_CODEC_FAILURE) \ - return (AUDIO_FAILURE); \ + return (DDI_FAILURE); \ lTmp = audioha_codec_verb_get(statep, caddr, wid, \ AUDIOHDC_VERB_SET_PIN_CTRL, \ (lTmp | AUDIOHDC_PIN_CONTROL_OUT_ENABLE | \ AUDIOHDC_PIN_CONTROL_HP_ENABLE)); \ if (lTmp == AUDIOHD_CODEC_FAILURE) \ - return (AUDIO_FAILURE); \ + return (DDI_FAILURE); \ } /* @@ -906,12 +904,12 @@ struct audiohd_state { lTmp = audioha_codec_verb_get(statep, caddr, wid, \ AUDIOHDC_VERB_GET_PIN_CTRL, 0); \ if (lTmp == AUDIOHD_CODEC_FAILURE) \ - return (AUDIO_FAILURE); \ + return (DDI_FAILURE); \ lTmp = audioha_codec_verb_get(statep, caddr, wid, \ AUDIOHDC_VERB_SET_PIN_CTRL, \ (lTmp & ~AUDIOHDC_PIN_CONTROL_OUT_ENABLE)); \ if (lTmp == AUDIOHD_CODEC_FAILURE) \ - return (AUDIO_FAILURE); \ + return (DDI_FAILURE); \ } /* @@ -934,12 +932,12 @@ struct audiohd_state { lTmp = audioha_codec_verb_get(statep, caddr, wid, \ AUDIOHDC_VERB_GET_PIN_CTRL, 0); \ if (lTmp == AUDIOHD_CODEC_FAILURE) \ - return (AUDIO_FAILURE); \ + return (DDI_FAILURE); \ lTmp = audioha_codec_verb_get(statep, caddr, wid, \ AUDIOHDC_VERB_SET_PIN_CTRL, \ (lTmp & ~AUDIOHDC_PIN_CONTROL_IN_ENABLE)); \ if (lTmp == AUDIOHD_CODEC_FAILURE) \ - return (AUDIO_FAILURE); \ + return (DDI_FAILURE); \ } /* @@ -951,7 +949,7 @@ struct audiohd_state { caddr, wid, AUDIOHDC_VERB_SET_AMP_MUTE, \ AUDIOHDC_AMP_SET_LR_OUTPUT | AUDIOHDC_GAIN_MAX) == \ AUDIOHD_CODEC_FAILURE) \ - return (AUDIO_FAILURE); \ + return (DDI_FAILURE); \ } #ifdef __cplusplus |