9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
23 */
24
25 #include <sys/audio/audio_driver.h>
26 #include <sys/note.h>
27 #include <sys/beep.h>
28 #include <sys/pci.h>
29 #include "audiohd.h"
30
31 #define DRVNAME "audiohd"
32
33 /*
34 * Module linkage routines for the kernel
35 */
36 static int audiohd_attach(dev_info_t *, ddi_attach_cmd_t);
37 static int audiohd_detach(dev_info_t *, ddi_detach_cmd_t);
38 static int audiohd_quiesce(dev_info_t *);
39 static int audiohd_resume(audiohd_state_t *);
40 static int audiohd_suspend(audiohd_state_t *);
41
42 /*
43 * Local routines
44 */
45 static int audiohd_init_state(audiohd_state_t *, dev_info_t *);
46 static int audiohd_init_pci(audiohd_state_t *, ddi_device_acc_attr_t *);
47 static void audiohd_fini_pci(audiohd_state_t *);
48 static int audiohd_reset_controller(audiohd_state_t *);
67 static void audiohd_change_speaker_state(audiohd_state_t *, int);
68 static int audiohd_allocate_port(audiohd_state_t *);
69 static void audiohd_free_port(audiohd_state_t *);
70 static void audiohd_restore_path(audiohd_state_t *);
71 static void audiohd_create_controls(audiohd_state_t *);
72 static void audiohd_get_channels(audiohd_state_t *);
73 static void audiohd_init_path(audiohd_state_t *);
74 static void audiohd_del_controls(audiohd_state_t *);
75 static void audiohd_destroy(audiohd_state_t *);
76 static void audiohd_beep_on(void *);
77 static void audiohd_beep_off(void *);
78 static void audiohd_beep_freq(void *, int);
79 static wid_t audiohd_find_beep(hda_codec_t *, wid_t, int);
80 static void audiohd_build_beep_path(hda_codec_t *);
81 static void audiohd_build_beep_amp(hda_codec_t *);
82 static void audiohd_finish_beep_path(hda_codec_t *);
83 static void audiohd_do_set_beep_volume(audiohd_state_t *,
84 audiohd_path_t *, uint64_t);
85 static void audiohd_set_beep_volume(audiohd_state_t *);
86 static int audiohd_set_beep(void *, uint64_t);
87 static void audiohd_pin_sense(audiohd_state_t *, uint32_t, uint32_t);
88
89 static int audiohd_beep;
90 static int audiohd_beep_divider;
91 static int audiohd_beep_vol = 1;
92
93 /* Warlock annotation */
94 _NOTE(SCHEME_PROTECTS_DATA("unshared data", audiohd_beep))
95 _NOTE(SCHEME_PROTECTS_DATA("unshared data", audiohd_beep_divider))
96 _NOTE(SCHEME_PROTECTS_DATA("unshared data", audiohd_beep_vol))
97
98 static ddi_device_acc_attr_t hda_dev_accattr = {
99 DDI_DEVICE_ATTR_V0,
100 DDI_STRUCTURE_LE_ACC,
101 DDI_STRICTORDER_ACC
102 };
103
104 static const char *audiohd_dtypes[] = {
105 AUDIO_PORT_LINEOUT,
106 AUDIO_PORT_SPEAKER,
316 ASSERT(statep != NULL);
317 return (audiohd_resume(statep));
318
319 default:
320 return (DDI_FAILURE);
321 }
322
323 /* allocate the soft state structure */
324 statep = kmem_zalloc(sizeof (*statep), KM_SLEEP);
325 ddi_set_driver_private(dip, statep);
326
327 mutex_init(&statep->hda_mutex, NULL, MUTEX_DRIVER, 0);
328 mutex_enter(&statep->hda_mutex);
329
330 /* interrupt cookie and initialize mutex */
331 if (audiohd_init_state(statep, dip) != DDI_SUCCESS) {
332 audio_dev_warn(NULL, "audiohd_init_state failed");
333 goto error;
334 }
335
336 /* Set PCI command register to enable bus master and memeory I/O */
337 if (audiohd_init_pci(statep, &hda_dev_accattr) != DDI_SUCCESS) {
338 audio_dev_warn(statep->adev,
339 "couldn't init pci regs");
340 goto error;
341 }
342
343 audiohd_set_chipset_info(statep);
344
345 if (audiohd_init_controller(statep) != DDI_SUCCESS) {
346 audio_dev_warn(statep->adev,
347 "couldn't init controller");
348 goto error;
349 }
350
351 if (audiohd_create_codec(statep) != DDI_SUCCESS) {
352 audio_dev_warn(statep->adev,
353 "couldn't create codec");
354 goto error;
355 }
356
565 static void
566 audiohd_init_play_path(audiohd_path_t *path)
567 {
568 int i;
569 uint32_t ctrl;
570 uint8_t ctrl8;
571 uint8_t nchann;
572 audiohd_widget_t *widget;
573 audiohd_pin_t *pin;
574 wid_t wid;
575 audiohd_pin_color_t color;
576
577 audiohd_state_t *statep = path->statep;
578 hda_codec_t *codec = path->codec;
579
580 /* enable SPDIF output */
581 for (i = 0; i < path->pin_nums; i++) {
582 wid = path->pin_wid[i];
583 widget = codec->widget[wid];
584 pin = (audiohd_pin_t *)widget->priv;
585 if (pin->device == DTYPE_SPDIF_OUT) {
586 ctrl = audioha_codec_verb_get(
587 statep,
588 codec->index,
589 path->adda_wid,
590 AUDIOHDC_VERB_GET_SPDIF_CTL,
591 0);
592 ctrl |= AUDIOHD_SPDIF_ON;
593 ctrl8 = ctrl &
594 AUDIOHD_SPDIF_MASK;
595 (void) audioha_codec_verb_get(
596 statep,
597 codec->index,
598 path->adda_wid,
599 AUDIOHDC_VERB_SET_SPDIF_LCL,
600 ctrl8);
601 /*
602 * We find that on intel ICH10 chipset with codec
603 * ALC888, audio is scratchy if we set the tag on the
604 * SPDIF path. So we just return here without setting
605 * the tag for the path as a workaround.
649 break;
650 default:
651 nchann = 0;
652 break;
653 }
654 (void) audioha_codec_verb_get(statep,
655 codec->index,
656 path->adda_wid,
657 AUDIOHDC_VERB_SET_STREAM_CHANN,
658 statep->port[PORT_DAC]->index <<
659 AUDIOHD_PLAY_TAG_OFF |
660 nchann);
661 (void) audioha_codec_4bit_verb_get(
662 statep,
663 codec->index,
664 path->adda_wid,
665 AUDIOHDC_VERB_SET_CONV_FMT,
666 statep->port[PORT_DAC]->format << 4 |
667 statep->pchan - 1);
668 }
669 }
670 static void
671 audiohd_init_record_path(audiohd_path_t *path)
672 {
673 audiohd_state_t *statep = path->statep;
674 hda_codec_t *codec = path->codec;
675 int i;
676 wid_t wid;
677 audiohd_pin_t *pin;
678 audiohd_widget_t *widget;
679
680 for (i = 0; i < path->pin_nums; i++) {
681 wid = path->pin_wid[i];
682 widget = codec->widget[wid];
683 pin = (audiohd_pin_t *)widget->priv;
684 /*
685 * Since there is no SPDIF input device available for test,
686 * we will use this code in the future to support SPDIF input
687 */
688 #if 0
689 if (pin->device == DTYPE_SPDIF_IN) {
2125
2126 if (ddi_regs_map_setup(dip, 1, &statep->hda_reg_base, 0,
2127 0, acc_attr, &statep->hda_reg_handle) != DDI_SUCCESS) {
2128 audio_dev_warn(adev,
2129 "memory I/O mapping failed");
2130 return (DDI_FAILURE);
2131 }
2132
2133 /*
2134 * HD audio control uses memory I/O only, enable it here.
2135 */
2136 cmdreg = pci_config_get16(statep->hda_pci_handle, PCI_CONF_COMM);
2137 pci_config_put16(statep->hda_pci_handle, PCI_CONF_COMM,
2138 cmdreg | PCI_COMM_MAE | PCI_COMM_ME);
2139
2140 vid = pci_config_get16(statep->hda_pci_handle, PCI_CONF_VENID);
2141 switch (vid) {
2142 case AUDIOHD_VID_INTEL:
2143 /*
2144 * Currently, Intel (G)MCH and ICHx chipsets support PCI
2145 * Express QoS. It implemenets two VCs(virtual channels)
2146 * and allows OS software to map 8 traffic classes to the
2147 * two VCs. Some BIOSes initialize HD audio hardware to
2148 * use TC7 (traffic class 7) and to map TC7 to VC1 as Intel
2149 * recommended. However, solaris doesn't support PCI express
2150 * QoS yet. As a result, this driver can not work for those
2151 * hardware without touching PCI express control registers.
2152 * Here, we set TCSEL to 0 so as to use TC0/VC0 (VC0 is
2153 * always enabled and TC0 is always mapped to VC0) for all
2154 * Intel HD audio controllers.
2155 */
2156 cTmp = pci_config_get8(statep->hda_pci_handle,
2157 AUDIOHD_INTEL_PCI_TCSEL);
2158 pci_config_put8(statep->hda_pci_handle,
2159 AUDIOHD_INTEL_PCI_TCSEL, (cTmp & AUDIOHD_INTEL_TCS_MASK));
2160 break;
2161 case AUDIOHD_VID_ATI:
2162 /*
2163 * Refer to ATI SB450 datesheet. We set snoop for SB450
2164 * like hardware.
2165 */
2707 pin->finish = 0;
2708
2709 vrefbits = (cap >> AUDIOHD_PIN_VREF_OFF) & AUDIOHD_PIN_VREF_MASK;
2710 if (vrefbits & AUDIOHD_PIN_VREF_L1)
2711 pin->vrefvalue = 0x5;
2712 else if (vrefbits & AUDIOHD_PIN_VREF_L2)
2713 pin->vrefvalue = 0x4;
2714 else if (vrefbits & AUDIOHD_PIN_VREF_L3)
2715 pin->vrefvalue = 0x2;
2716 else
2717 pin->vrefvalue = 0x1;
2718
2719 pin->seq = config & AUDIOHD_PIN_SEQ_MASK;
2720 pin->assoc = (config & AUDIOHD_PIN_ASO_MASK) >> AUDIOHD_PIN_ASO_OFF;
2721 pin->device = (config & AUDIOHD_PIN_DEV_MASK) >> AUDIOHD_PIN_DEV_OFF;
2722
2723 /* enable the unsolicited response of the pin */
2724 if ((widget->widget_cap & AUDIOHD_URCAP_MASK) &&
2725 (pin->cap & AUDIOHD_DTCCAP_MASK) &&
2726 ((pin->device == DTYPE_LINEOUT) ||
2727 (pin->device == DTYPE_SPDIF_OUT) ||
2728 (pin->device == DTYPE_HP_OUT) ||
2729 (pin->device == DTYPE_MIC_IN))) {
2730 urctrl = (uint8_t)(1 << (AUDIOHD_UR_ENABLE_OFF - 1));
2731 urctrl |= (wid & AUDIOHD_UR_TAG_MASK);
2732 (void) audioha_codec_verb_get(statep, caddr,
2733 wid, AUDIOHDC_VERB_SET_UNS_ENABLE, urctrl);
2734 }
2735 /* accommodate all the pins in a link list sorted by assoc and seq */
2736 if (codec->first_pin == NULL) {
2737 codec->first_pin = pin;
2738 } else {
2739 prev = NULL;
2740 p = codec->first_pin;
2741 while (p) {
2742 if (p->assoc > pin->assoc)
2743 break;
2744 if ((p->assoc == pin->assoc) &&
2745 (p->seq > pin->seq))
2746 break;
3223 audiohd_do_build_output_path(hda_codec_t *codec, int mixer, int *mnum,
3224 int exclusive, int depth)
3225 {
3226 audiohd_pin_t *pin;
3227 audiohd_widget_t *widget, *wdac;
3228 audiohd_path_t *path;
3229 wid_t wid;
3230 audiohd_state_t *statep;
3231 int i;
3232
3233 statep = codec->statep;
3234
3235 for (pin = codec->first_pin; pin; pin = pin->next) {
3236 if ((pin->cap & AUDIOHD_PIN_CAP_MASK) == 0)
3237 continue;
3238 if ((pin->config & AUDIOHD_PIN_CONF_MASK) ==
3239 AUDIOHD_PIN_NO_CONN)
3240 continue;
3241 if ((pin->device != DTYPE_LINEOUT) &&
3242 (pin->device != DTYPE_SPEAKER) &&
3243 (pin->device != DTYPE_SPDIF_OUT) &&
3244 (pin->device != DTYPE_HP_OUT))
3245 continue;
3246 if (pin->finish)
3247 continue;
3248 widget = codec->widget[pin->wid];
3249
3250 widget->inamp_cap = 0;
3251 for (i = 0; i < widget->nconns; i++) {
3252 /*
3253 * If a dac found, the return value is the wid of the
3254 * widget on the path, or the return value is
3255 * DDI_FAILURE
3256 */
3257 wid = audiohd_find_dac(codec,
3258 widget->avail_conn[i], mixer, mnum, exclusive,
3259 depth);
3260 /*
3261 * A dac was not found
3262 */
3737 audiohd_widget_t *widget;
3738 audiohd_path_t *path = NULL;
3739 wid_t wid;
3740 int i;
3741 int retval;
3742 uint8_t rtag = 0;
3743 audiohd_state_t *statep = codec->statep;
3744
3745 for (wid = codec->first_wid; wid <= codec->last_wid; wid++) {
3746
3747 widget = codec->widget[wid];
3748
3749 /* check if it is an ADC widget */
3750 if (widget == NULL || widget->type != WTYPE_AUDIO_IN)
3751 continue;
3752
3753 if (path == NULL)
3754 path = kmem_zalloc(sizeof (audiohd_path_t),
3755 KM_SLEEP);
3756 else
3757 bzero(path, sizeof (audiohd_port_t));
3758
3759 path->adda_wid = wid;
3760
3761 /*
3762 * Is there any ADC widget which has more than one input ??
3763 * I don't believe. Anyway, we carefully deal with this. But
3764 * if hardware vendors embed a selector in a ADC, we just use
3765 * the first available input, which has connection to input pin
3766 * widget. Because selector cannot perform mixer functionality,
3767 * and we just permit one selector or mixer in a recording path,
3768 * if we use the selector embedded in ADC,we cannot use possible
3769 * mixer during path searching.
3770 */
3771 for (i = 0; i < widget->nconns; i++) {
3772 retval = audiohd_find_input_pins(codec,
3773 widget->avail_conn[i], 1, 0, path);
3774 if (retval == DDI_SUCCESS) {
3775 path->codec = codec;
3776 path->statep = statep;
3777 path->path_type = RECORD;
4536 audiohd_build_beep_path(hda_codec_t *codec)
4537 {
4538 audiohd_pin_t *pin;
4539 audiohd_widget_t *widget;
4540 audiohd_path_t *path;
4541 wid_t wid;
4542 audiohd_state_t *statep;
4543 int i;
4544 boolean_t beeppath = B_FALSE;
4545
4546 statep = codec->statep;
4547
4548 for (pin = codec->first_pin; pin; pin = pin->next) {
4549 if ((pin->cap & AUDIOHD_PIN_CAP_MASK) == 0)
4550 continue;
4551 if ((pin->config & AUDIOHD_PIN_CONF_MASK) ==
4552 AUDIOHD_PIN_NO_CONN)
4553 continue;
4554 if ((pin->device != DTYPE_LINEOUT) &&
4555 (pin->device != DTYPE_SPEAKER) &&
4556 (pin->device != DTYPE_SPDIF_OUT) &&
4557 (pin->device != DTYPE_HP_OUT))
4558 continue;
4559 widget = codec->widget[pin->wid];
4560
4561 widget->inamp_cap = 0;
4562 for (i = 0; i < widget->nconns; i++) {
4563 /*
4564 * If a beep found, the return value is the wid of the
4565 * widget on the path, or the return value is
4566 * DDI_FAILURE
4567 */
4568 wid = audiohd_find_beep(codec,
4569 widget->avail_conn[i], 0);
4570 /*
4571 * A beep was not found
4572 */
4573 if (wid == (wid_t)DDI_FAILURE)
4574 continue;
4575 if (widget->output_path_next != AUDIOHD_NULL_CONN)
4808
4809 if (depth > AUDIOHD_MAX_DEPTH)
4810 return (retval);
4811 if (widget == NULL)
4812 return (retval);
4813
4814 switch (widget->type) {
4815 case WTYPE_PIN:
4816 pin = (audiohd_pin_t *)widget->priv;
4817 if (pin->no_phys_conn)
4818 return (DDI_FAILURE);
4819
4820 switch (pin->device) {
4821 case DTYPE_LINE_IN:
4822 /* Connection between line-in and output pins */
4823 path->pin_wid[path->pin_nums++] = wid;
4824 break;
4825 case DTYPE_LINEOUT:
4826 case DTYPE_HP_OUT:
4827 case DTYPE_SPDIF_OUT:
4828 widget->path_flags |= AUDIOHD_PATH_LOOPBACK;
4829 widget->in_weight++;
4830 pin->adc_wid = path->adda_wid;
4831 path->pin_wid[path->pin_nums++] = wid;
4832 retval = (DDI_SUCCESS);
4833 break;
4834 default:
4835 break;
4836 }
4837 break;
4838 case WTYPE_AUDIO_MIX:
4839 case WTYPE_AUDIO_SEL:
4840 /*
4841 * If the sum widget has only one input, we don't
4842 * consider it as a real sum widget.
4843 */
4844 if (widget->nconns == 1) {
4845 widget->loopback_path_next = 0;
4846 retval = audiohd_find_output_pins(codec,
4847 widget->avail_conn[0], depth + 1, path);
4876 static void
4877 audiohd_build_loopback_path(hda_codec_t *codec)
4878 {
4879 audiohd_state_t *statep = codec->statep;
4880 audiohd_widget_t *widget;
4881 audiohd_path_t *path = NULL;
4882 wid_t wid;
4883 int i, retval;
4884 uint8_t rtag = 0;
4885
4886 for (wid = codec->first_wid; wid <= codec->last_wid; wid++) {
4887 widget = codec->widget[wid];
4888
4889 /* check if it is an ADC widget */
4890 if (widget == NULL || widget->type != WTYPE_AUDIO_IN)
4891 continue;
4892
4893 if (path == NULL)
4894 path = kmem_zalloc(sizeof (audiohd_path_t), KM_SLEEP);
4895 else
4896 bzero(path, sizeof (audiohd_port_t));
4897 path->adda_wid = wid;
4898
4899 for (i = 0; i < widget->nconns; i++) {
4900 retval = audiohd_find_output_pins(codec,
4901 widget->avail_conn[i], 0, path);
4902 if (retval == (DDI_SUCCESS)) {
4903 path->codec = codec;
4904 path->statep = statep;
4905 path->path_type = LOOPBACK;
4906 path->tag = ++rtag;
4907 codec->nistream++;
4908 statep->path[statep->pathnum++] = path;
4909 widget->loopback_path_next = i;
4910 widget->priv = path;
4911 path = NULL;
4912 statep->loopback_supported = B_TRUE;
4913 break;
4914 }
4915 }
4916 }
5270 audiohd_reset_pins_ur_cap(audiohd_state_t *statep)
5271 {
5272 hda_codec_t *codec;
5273 audiohd_pin_t *pin;
5274 audiohd_widget_t *widget;
5275 uint32_t urctrl;
5276 int i;
5277
5278 for (i = 0; i < AUDIOHD_CODEC_MAX; i++) {
5279 codec = statep->codec[i];
5280 if (codec == NULL)
5281 continue;
5282 pin = codec->first_pin;
5283 while (pin) {
5284 /* enable the unsolicited response of the pin */
5285 widget = codec->widget[pin->wid];
5286 if ((widget->widget_cap &
5287 (AUDIOHD_URCAP_MASK) &&
5288 (pin->cap & AUDIOHD_DTCCAP_MASK)) &&
5289 ((pin->device == DTYPE_LINEOUT) ||
5290 (pin->device == DTYPE_SPDIF_OUT) ||
5291 (pin->device == DTYPE_HP_OUT) ||
5292 (pin->device == DTYPE_MIC_IN))) {
5293 urctrl = (uint8_t)(1 <<
5294 (AUDIOHD_UR_ENABLE_OFF - 1));
5295 urctrl |= (pin->wid & AUDIOHD_UR_TAG_MASK);
5296 (void) audioha_codec_verb_get(statep,
5297 codec->index,
5298 pin->wid,
5299 AUDIOHDC_VERB_SET_UNS_ENABLE, urctrl);
5300 }
5301 pin = pin->next;
5302 }
5303 }
5304 }
5305 static void
5306 audiohd_restore_codec_gpio(audiohd_state_t *statep)
5307 {
5308 int i;
5309 wid_t wid;
5602 AUDIOHD_PIN_CONTP_OFF) &
5603 AUDIOHD_PIN_CONTP_MASK) ==
5604 AUDIOHD_PIN_CON_JACK)) {
5605 statep->port[PORT_ADC]->index =
5606 path->tag;
5607 return;
5608 } else if (!select &&
5609 pin->device == DTYPE_MIC_IN &&
5610 (((pin->config >>
5611 AUDIOHD_PIN_CONTP_OFF) &
5612 AUDIOHD_PIN_CONTP_MASK) ==
5613 AUDIOHD_PIN_CON_FIXED)) {
5614 statep->port[PORT_ADC]->index =
5615 path->tag;
5616 return;
5617 }
5618 }
5619 }
5620 }
5621 }
5622 /*
5623 * audiohd_pin_sense()
5624 *
5625 * Description
5626 *
5627 * When the earphone is plugged into the jack associtated with the pin
5628 * complex, we disable the built in speaker. When the earphone is plugged
5629 * out of the jack, we enable the built in speaker.
5630 */
5631 static void
5632 audiohd_pin_sense(audiohd_state_t *statep, uint32_t resp, uint32_t respex)
5633 {
5634 uint8_t index;
5635 uint8_t id;
5636 uint32_t rs;
5637 audiohd_widget_t *widget;
5638 audiohd_pin_t *pin;
5639 hda_codec_t *codec;
5640
5641 index = respex & AUDIOHD_RIRB_CODEC_MASK;
5642 id = resp >> (AUDIOHD_RIRB_WID_OFF - 1);
5643
5644 codec = statep->codec[index];
5645 if (codec == NULL)
5646 return;
5647 widget = codec->widget[id];
5648 if (widget == NULL)
5649 return;
5650
5651 rs = audioha_codec_verb_get(statep, index, id,
5652 AUDIOHDC_VERB_GET_PIN_SENSE, 0);
5653 if (rs & AUDIOHD_PIN_PRES_MASK) {
5654 /* A MIC is plugged in, we select the MIC as input */
5655 if ((widget->type == WTYPE_PIN) &&
5656 (pin = (audiohd_pin_t *)widget->priv) &&
5657 (pin->device == DTYPE_MIC_IN)) {
5658 audiohd_select_mic(statep, index, id, 1);
5659 return;
5660 }
5661 /* output pin is plugged */
5662 audiohd_change_speaker_state(statep, AUDIOHD_SP_OFF);
5663 } else {
5664 /*
5665 * A MIC is unplugged, we select the built in MIC
5666 * as input.
5667 */
5668 if ((widget->type == WTYPE_PIN) &&
5669 (pin = (audiohd_pin_t *)widget->priv) &&
5670 (pin->device == DTYPE_MIC_IN)) {
5671 audiohd_select_mic(statep, index, id, 0);
5672 return;
5673 }
5674 /* output pin is unplugged */
5675 audiohd_change_speaker_state(statep, AUDIOHD_SP_ON);
5676 }
5677
|
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
23 */
24
25 #include <sys/audio/audio_driver.h>
26 #include <sys/note.h>
27 #include <sys/beep.h>
28 #include <sys/pci.h>
29 #include <sys/stddef.h>
30 #include <sys/sysmacros.h>
31 #include "audiohd.h"
32
33 #define DRVNAME "audiohd"
34
35 /*
36 * Module linkage routines for the kernel
37 */
38 static int audiohd_attach(dev_info_t *, ddi_attach_cmd_t);
39 static int audiohd_detach(dev_info_t *, ddi_detach_cmd_t);
40 static int audiohd_quiesce(dev_info_t *);
41 static int audiohd_resume(audiohd_state_t *);
42 static int audiohd_suspend(audiohd_state_t *);
43
44 /*
45 * Local routines
46 */
47 static int audiohd_init_state(audiohd_state_t *, dev_info_t *);
48 static int audiohd_init_pci(audiohd_state_t *, ddi_device_acc_attr_t *);
49 static void audiohd_fini_pci(audiohd_state_t *);
50 static int audiohd_reset_controller(audiohd_state_t *);
69 static void audiohd_change_speaker_state(audiohd_state_t *, int);
70 static int audiohd_allocate_port(audiohd_state_t *);
71 static void audiohd_free_port(audiohd_state_t *);
72 static void audiohd_restore_path(audiohd_state_t *);
73 static void audiohd_create_controls(audiohd_state_t *);
74 static void audiohd_get_channels(audiohd_state_t *);
75 static void audiohd_init_path(audiohd_state_t *);
76 static void audiohd_del_controls(audiohd_state_t *);
77 static void audiohd_destroy(audiohd_state_t *);
78 static void audiohd_beep_on(void *);
79 static void audiohd_beep_off(void *);
80 static void audiohd_beep_freq(void *, int);
81 static wid_t audiohd_find_beep(hda_codec_t *, wid_t, int);
82 static void audiohd_build_beep_path(hda_codec_t *);
83 static void audiohd_build_beep_amp(hda_codec_t *);
84 static void audiohd_finish_beep_path(hda_codec_t *);
85 static void audiohd_do_set_beep_volume(audiohd_state_t *,
86 audiohd_path_t *, uint64_t);
87 static void audiohd_set_beep_volume(audiohd_state_t *);
88 static int audiohd_set_beep(void *, uint64_t);
89 static void audiohd_setup_hdmi_dp(audiohd_state_t *, uint8_t, uint8_t,
90 boolean_t);
91 static audiohd_eld_t *audiohd_get_eld(audiohd_state_t *, uint8_t, uint8_t);
92 static void audiohd_pin_sense(audiohd_state_t *, uint32_t, uint32_t);
93
94 static int audiohd_beep;
95 static int audiohd_beep_divider;
96 static int audiohd_beep_vol = 1;
97
98 /* Warlock annotation */
99 _NOTE(SCHEME_PROTECTS_DATA("unshared data", audiohd_beep))
100 _NOTE(SCHEME_PROTECTS_DATA("unshared data", audiohd_beep_divider))
101 _NOTE(SCHEME_PROTECTS_DATA("unshared data", audiohd_beep_vol))
102
103 static ddi_device_acc_attr_t hda_dev_accattr = {
104 DDI_DEVICE_ATTR_V0,
105 DDI_STRUCTURE_LE_ACC,
106 DDI_STRICTORDER_ACC
107 };
108
109 static const char *audiohd_dtypes[] = {
110 AUDIO_PORT_LINEOUT,
111 AUDIO_PORT_SPEAKER,
321 ASSERT(statep != NULL);
322 return (audiohd_resume(statep));
323
324 default:
325 return (DDI_FAILURE);
326 }
327
328 /* allocate the soft state structure */
329 statep = kmem_zalloc(sizeof (*statep), KM_SLEEP);
330 ddi_set_driver_private(dip, statep);
331
332 mutex_init(&statep->hda_mutex, NULL, MUTEX_DRIVER, 0);
333 mutex_enter(&statep->hda_mutex);
334
335 /* interrupt cookie and initialize mutex */
336 if (audiohd_init_state(statep, dip) != DDI_SUCCESS) {
337 audio_dev_warn(NULL, "audiohd_init_state failed");
338 goto error;
339 }
340
341 /* Set PCI command register to enable bus master and memory I/O */
342 if (audiohd_init_pci(statep, &hda_dev_accattr) != DDI_SUCCESS) {
343 audio_dev_warn(statep->adev,
344 "couldn't init pci regs");
345 goto error;
346 }
347
348 audiohd_set_chipset_info(statep);
349
350 if (audiohd_init_controller(statep) != DDI_SUCCESS) {
351 audio_dev_warn(statep->adev,
352 "couldn't init controller");
353 goto error;
354 }
355
356 if (audiohd_create_codec(statep) != DDI_SUCCESS) {
357 audio_dev_warn(statep->adev,
358 "couldn't create codec");
359 goto error;
360 }
361
570 static void
571 audiohd_init_play_path(audiohd_path_t *path)
572 {
573 int i;
574 uint32_t ctrl;
575 uint8_t ctrl8;
576 uint8_t nchann;
577 audiohd_widget_t *widget;
578 audiohd_pin_t *pin;
579 wid_t wid;
580 audiohd_pin_color_t color;
581
582 audiohd_state_t *statep = path->statep;
583 hda_codec_t *codec = path->codec;
584
585 /* enable SPDIF output */
586 for (i = 0; i < path->pin_nums; i++) {
587 wid = path->pin_wid[i];
588 widget = codec->widget[wid];
589 pin = (audiohd_pin_t *)widget->priv;
590 if (pin->device == DTYPE_SPDIF_OUT ||
591 pin->device == DTYPE_DIGIT_OUT) {
592 ctrl = audioha_codec_verb_get(
593 statep,
594 codec->index,
595 path->adda_wid,
596 AUDIOHDC_VERB_GET_SPDIF_CTL,
597 0);
598 ctrl |= AUDIOHD_SPDIF_ON;
599 ctrl8 = ctrl &
600 AUDIOHD_SPDIF_MASK;
601 (void) audioha_codec_verb_get(
602 statep,
603 codec->index,
604 path->adda_wid,
605 AUDIOHDC_VERB_SET_SPDIF_LCL,
606 ctrl8);
607 /*
608 * We find that on intel ICH10 chipset with codec
609 * ALC888, audio is scratchy if we set the tag on the
610 * SPDIF path. So we just return here without setting
611 * the tag for the path as a workaround.
655 break;
656 default:
657 nchann = 0;
658 break;
659 }
660 (void) audioha_codec_verb_get(statep,
661 codec->index,
662 path->adda_wid,
663 AUDIOHDC_VERB_SET_STREAM_CHANN,
664 statep->port[PORT_DAC]->index <<
665 AUDIOHD_PLAY_TAG_OFF |
666 nchann);
667 (void) audioha_codec_4bit_verb_get(
668 statep,
669 codec->index,
670 path->adda_wid,
671 AUDIOHDC_VERB_SET_CONV_FMT,
672 statep->port[PORT_DAC]->format << 4 |
673 statep->pchan - 1);
674 }
675
676 /* Setup HDMI/DP output pin */
677 if (pin->device == DTYPE_DIGIT_OUT) {
678 pin->eld = audiohd_get_eld(statep, codec->index, pin->wid);
679 if (pin->eld != NULL &&
680 (pin->eld->eld_conn_type & 0x3) != 0)
681 audiohd_setup_hdmi_dp(statep, codec->index, pin->wid,
682 pin->eld->eld_conn_type == AUDIOHD_ELD_CONN_HDMI);
683 }
684 }
685
686 static void
687 audiohd_init_record_path(audiohd_path_t *path)
688 {
689 audiohd_state_t *statep = path->statep;
690 hda_codec_t *codec = path->codec;
691 int i;
692 wid_t wid;
693 audiohd_pin_t *pin;
694 audiohd_widget_t *widget;
695
696 for (i = 0; i < path->pin_nums; i++) {
697 wid = path->pin_wid[i];
698 widget = codec->widget[wid];
699 pin = (audiohd_pin_t *)widget->priv;
700 /*
701 * Since there is no SPDIF input device available for test,
702 * we will use this code in the future to support SPDIF input
703 */
704 #if 0
705 if (pin->device == DTYPE_SPDIF_IN) {
2141
2142 if (ddi_regs_map_setup(dip, 1, &statep->hda_reg_base, 0,
2143 0, acc_attr, &statep->hda_reg_handle) != DDI_SUCCESS) {
2144 audio_dev_warn(adev,
2145 "memory I/O mapping failed");
2146 return (DDI_FAILURE);
2147 }
2148
2149 /*
2150 * HD audio control uses memory I/O only, enable it here.
2151 */
2152 cmdreg = pci_config_get16(statep->hda_pci_handle, PCI_CONF_COMM);
2153 pci_config_put16(statep->hda_pci_handle, PCI_CONF_COMM,
2154 cmdreg | PCI_COMM_MAE | PCI_COMM_ME);
2155
2156 vid = pci_config_get16(statep->hda_pci_handle, PCI_CONF_VENID);
2157 switch (vid) {
2158 case AUDIOHD_VID_INTEL:
2159 /*
2160 * Currently, Intel (G)MCH and ICHx chipsets support PCI
2161 * Express QoS. It implements two VCs (virtual channels)
2162 * and allows OS software to map 8 traffic classes to the
2163 * two VCs. Some BIOSes initialize HD audio hardware to
2164 * use TC7 (traffic class 7) and to map TC7 to VC1 as Intel
2165 * recommended. However, solaris doesn't support PCI express
2166 * QoS yet. As a result, this driver can not work for those
2167 * hardware without touching PCI express control registers.
2168 * Here, we set TCSEL to 0 so as to use TC0/VC0 (VC0 is
2169 * always enabled and TC0 is always mapped to VC0) for all
2170 * Intel HD audio controllers.
2171 */
2172 cTmp = pci_config_get8(statep->hda_pci_handle,
2173 AUDIOHD_INTEL_PCI_TCSEL);
2174 pci_config_put8(statep->hda_pci_handle,
2175 AUDIOHD_INTEL_PCI_TCSEL, (cTmp & AUDIOHD_INTEL_TCS_MASK));
2176 break;
2177 case AUDIOHD_VID_ATI:
2178 /*
2179 * Refer to ATI SB450 datesheet. We set snoop for SB450
2180 * like hardware.
2181 */
2723 pin->finish = 0;
2724
2725 vrefbits = (cap >> AUDIOHD_PIN_VREF_OFF) & AUDIOHD_PIN_VREF_MASK;
2726 if (vrefbits & AUDIOHD_PIN_VREF_L1)
2727 pin->vrefvalue = 0x5;
2728 else if (vrefbits & AUDIOHD_PIN_VREF_L2)
2729 pin->vrefvalue = 0x4;
2730 else if (vrefbits & AUDIOHD_PIN_VREF_L3)
2731 pin->vrefvalue = 0x2;
2732 else
2733 pin->vrefvalue = 0x1;
2734
2735 pin->seq = config & AUDIOHD_PIN_SEQ_MASK;
2736 pin->assoc = (config & AUDIOHD_PIN_ASO_MASK) >> AUDIOHD_PIN_ASO_OFF;
2737 pin->device = (config & AUDIOHD_PIN_DEV_MASK) >> AUDIOHD_PIN_DEV_OFF;
2738
2739 /* enable the unsolicited response of the pin */
2740 if ((widget->widget_cap & AUDIOHD_URCAP_MASK) &&
2741 (pin->cap & AUDIOHD_DTCCAP_MASK) &&
2742 ((pin->device == DTYPE_LINEOUT) ||
2743 (pin->device == DTYPE_DIGIT_OUT) ||
2744 (pin->device == DTYPE_SPDIF_OUT) ||
2745 (pin->device == DTYPE_HP_OUT) ||
2746 (pin->device == DTYPE_MIC_IN))) {
2747 urctrl = (uint8_t)(1 << (AUDIOHD_UR_ENABLE_OFF - 1));
2748 urctrl |= (wid & AUDIOHD_UR_TAG_MASK);
2749 (void) audioha_codec_verb_get(statep, caddr,
2750 wid, AUDIOHDC_VERB_SET_UNS_ENABLE, urctrl);
2751 }
2752 /* accommodate all the pins in a link list sorted by assoc and seq */
2753 if (codec->first_pin == NULL) {
2754 codec->first_pin = pin;
2755 } else {
2756 prev = NULL;
2757 p = codec->first_pin;
2758 while (p) {
2759 if (p->assoc > pin->assoc)
2760 break;
2761 if ((p->assoc == pin->assoc) &&
2762 (p->seq > pin->seq))
2763 break;
3240 audiohd_do_build_output_path(hda_codec_t *codec, int mixer, int *mnum,
3241 int exclusive, int depth)
3242 {
3243 audiohd_pin_t *pin;
3244 audiohd_widget_t *widget, *wdac;
3245 audiohd_path_t *path;
3246 wid_t wid;
3247 audiohd_state_t *statep;
3248 int i;
3249
3250 statep = codec->statep;
3251
3252 for (pin = codec->first_pin; pin; pin = pin->next) {
3253 if ((pin->cap & AUDIOHD_PIN_CAP_MASK) == 0)
3254 continue;
3255 if ((pin->config & AUDIOHD_PIN_CONF_MASK) ==
3256 AUDIOHD_PIN_NO_CONN)
3257 continue;
3258 if ((pin->device != DTYPE_LINEOUT) &&
3259 (pin->device != DTYPE_SPEAKER) &&
3260 (pin->device != DTYPE_DIGIT_OUT) &&
3261 (pin->device != DTYPE_SPDIF_OUT) &&
3262 (pin->device != DTYPE_HP_OUT))
3263 continue;
3264 if (pin->finish)
3265 continue;
3266 widget = codec->widget[pin->wid];
3267
3268 widget->inamp_cap = 0;
3269 for (i = 0; i < widget->nconns; i++) {
3270 /*
3271 * If a dac found, the return value is the wid of the
3272 * widget on the path, or the return value is
3273 * DDI_FAILURE
3274 */
3275 wid = audiohd_find_dac(codec,
3276 widget->avail_conn[i], mixer, mnum, exclusive,
3277 depth);
3278 /*
3279 * A dac was not found
3280 */
3755 audiohd_widget_t *widget;
3756 audiohd_path_t *path = NULL;
3757 wid_t wid;
3758 int i;
3759 int retval;
3760 uint8_t rtag = 0;
3761 audiohd_state_t *statep = codec->statep;
3762
3763 for (wid = codec->first_wid; wid <= codec->last_wid; wid++) {
3764
3765 widget = codec->widget[wid];
3766
3767 /* check if it is an ADC widget */
3768 if (widget == NULL || widget->type != WTYPE_AUDIO_IN)
3769 continue;
3770
3771 if (path == NULL)
3772 path = kmem_zalloc(sizeof (audiohd_path_t),
3773 KM_SLEEP);
3774 else
3775 bzero(path, sizeof (audiohd_path_t));
3776
3777 path->adda_wid = wid;
3778
3779 /*
3780 * Is there any ADC widget which has more than one input ??
3781 * I don't believe. Anyway, we carefully deal with this. But
3782 * if hardware vendors embed a selector in a ADC, we just use
3783 * the first available input, which has connection to input pin
3784 * widget. Because selector cannot perform mixer functionality,
3785 * and we just permit one selector or mixer in a recording path,
3786 * if we use the selector embedded in ADC,we cannot use possible
3787 * mixer during path searching.
3788 */
3789 for (i = 0; i < widget->nconns; i++) {
3790 retval = audiohd_find_input_pins(codec,
3791 widget->avail_conn[i], 1, 0, path);
3792 if (retval == DDI_SUCCESS) {
3793 path->codec = codec;
3794 path->statep = statep;
3795 path->path_type = RECORD;
4554 audiohd_build_beep_path(hda_codec_t *codec)
4555 {
4556 audiohd_pin_t *pin;
4557 audiohd_widget_t *widget;
4558 audiohd_path_t *path;
4559 wid_t wid;
4560 audiohd_state_t *statep;
4561 int i;
4562 boolean_t beeppath = B_FALSE;
4563
4564 statep = codec->statep;
4565
4566 for (pin = codec->first_pin; pin; pin = pin->next) {
4567 if ((pin->cap & AUDIOHD_PIN_CAP_MASK) == 0)
4568 continue;
4569 if ((pin->config & AUDIOHD_PIN_CONF_MASK) ==
4570 AUDIOHD_PIN_NO_CONN)
4571 continue;
4572 if ((pin->device != DTYPE_LINEOUT) &&
4573 (pin->device != DTYPE_SPEAKER) &&
4574 (pin->device != DTYPE_DIGIT_OUT) &&
4575 (pin->device != DTYPE_SPDIF_OUT) &&
4576 (pin->device != DTYPE_HP_OUT))
4577 continue;
4578 widget = codec->widget[pin->wid];
4579
4580 widget->inamp_cap = 0;
4581 for (i = 0; i < widget->nconns; i++) {
4582 /*
4583 * If a beep found, the return value is the wid of the
4584 * widget on the path, or the return value is
4585 * DDI_FAILURE
4586 */
4587 wid = audiohd_find_beep(codec,
4588 widget->avail_conn[i], 0);
4589 /*
4590 * A beep was not found
4591 */
4592 if (wid == (wid_t)DDI_FAILURE)
4593 continue;
4594 if (widget->output_path_next != AUDIOHD_NULL_CONN)
4827
4828 if (depth > AUDIOHD_MAX_DEPTH)
4829 return (retval);
4830 if (widget == NULL)
4831 return (retval);
4832
4833 switch (widget->type) {
4834 case WTYPE_PIN:
4835 pin = (audiohd_pin_t *)widget->priv;
4836 if (pin->no_phys_conn)
4837 return (DDI_FAILURE);
4838
4839 switch (pin->device) {
4840 case DTYPE_LINE_IN:
4841 /* Connection between line-in and output pins */
4842 path->pin_wid[path->pin_nums++] = wid;
4843 break;
4844 case DTYPE_LINEOUT:
4845 case DTYPE_HP_OUT:
4846 case DTYPE_SPDIF_OUT:
4847 case DTYPE_DIGIT_OUT:
4848 widget->path_flags |= AUDIOHD_PATH_LOOPBACK;
4849 widget->in_weight++;
4850 pin->adc_wid = path->adda_wid;
4851 path->pin_wid[path->pin_nums++] = wid;
4852 retval = (DDI_SUCCESS);
4853 break;
4854 default:
4855 break;
4856 }
4857 break;
4858 case WTYPE_AUDIO_MIX:
4859 case WTYPE_AUDIO_SEL:
4860 /*
4861 * If the sum widget has only one input, we don't
4862 * consider it as a real sum widget.
4863 */
4864 if (widget->nconns == 1) {
4865 widget->loopback_path_next = 0;
4866 retval = audiohd_find_output_pins(codec,
4867 widget->avail_conn[0], depth + 1, path);
4896 static void
4897 audiohd_build_loopback_path(hda_codec_t *codec)
4898 {
4899 audiohd_state_t *statep = codec->statep;
4900 audiohd_widget_t *widget;
4901 audiohd_path_t *path = NULL;
4902 wid_t wid;
4903 int i, retval;
4904 uint8_t rtag = 0;
4905
4906 for (wid = codec->first_wid; wid <= codec->last_wid; wid++) {
4907 widget = codec->widget[wid];
4908
4909 /* check if it is an ADC widget */
4910 if (widget == NULL || widget->type != WTYPE_AUDIO_IN)
4911 continue;
4912
4913 if (path == NULL)
4914 path = kmem_zalloc(sizeof (audiohd_path_t), KM_SLEEP);
4915 else
4916 bzero(path, sizeof (audiohd_path_t));
4917 path->adda_wid = wid;
4918
4919 for (i = 0; i < widget->nconns; i++) {
4920 retval = audiohd_find_output_pins(codec,
4921 widget->avail_conn[i], 0, path);
4922 if (retval == (DDI_SUCCESS)) {
4923 path->codec = codec;
4924 path->statep = statep;
4925 path->path_type = LOOPBACK;
4926 path->tag = ++rtag;
4927 codec->nistream++;
4928 statep->path[statep->pathnum++] = path;
4929 widget->loopback_path_next = i;
4930 widget->priv = path;
4931 path = NULL;
4932 statep->loopback_supported = B_TRUE;
4933 break;
4934 }
4935 }
4936 }
5290 audiohd_reset_pins_ur_cap(audiohd_state_t *statep)
5291 {
5292 hda_codec_t *codec;
5293 audiohd_pin_t *pin;
5294 audiohd_widget_t *widget;
5295 uint32_t urctrl;
5296 int i;
5297
5298 for (i = 0; i < AUDIOHD_CODEC_MAX; i++) {
5299 codec = statep->codec[i];
5300 if (codec == NULL)
5301 continue;
5302 pin = codec->first_pin;
5303 while (pin) {
5304 /* enable the unsolicited response of the pin */
5305 widget = codec->widget[pin->wid];
5306 if ((widget->widget_cap &
5307 (AUDIOHD_URCAP_MASK) &&
5308 (pin->cap & AUDIOHD_DTCCAP_MASK)) &&
5309 ((pin->device == DTYPE_LINEOUT) ||
5310 (pin->device == DTYPE_DIGIT_OUT) ||
5311 (pin->device == DTYPE_SPDIF_OUT) ||
5312 (pin->device == DTYPE_HP_OUT) ||
5313 (pin->device == DTYPE_MIC_IN))) {
5314 urctrl = (uint8_t)(1 <<
5315 (AUDIOHD_UR_ENABLE_OFF - 1));
5316 urctrl |= (pin->wid & AUDIOHD_UR_TAG_MASK);
5317 (void) audioha_codec_verb_get(statep,
5318 codec->index,
5319 pin->wid,
5320 AUDIOHDC_VERB_SET_UNS_ENABLE, urctrl);
5321 }
5322 pin = pin->next;
5323 }
5324 }
5325 }
5326 static void
5327 audiohd_restore_codec_gpio(audiohd_state_t *statep)
5328 {
5329 int i;
5330 wid_t wid;
5623 AUDIOHD_PIN_CONTP_OFF) &
5624 AUDIOHD_PIN_CONTP_MASK) ==
5625 AUDIOHD_PIN_CON_JACK)) {
5626 statep->port[PORT_ADC]->index =
5627 path->tag;
5628 return;
5629 } else if (!select &&
5630 pin->device == DTYPE_MIC_IN &&
5631 (((pin->config >>
5632 AUDIOHD_PIN_CONTP_OFF) &
5633 AUDIOHD_PIN_CONTP_MASK) ==
5634 AUDIOHD_PIN_CON_FIXED)) {
5635 statep->port[PORT_ADC]->index =
5636 path->tag;
5637 return;
5638 }
5639 }
5640 }
5641 }
5642 }
5643
5644 /*
5645 * audiohd_setup_hdmi_dp()
5646 *
5647 * Description
5648 *
5649 * Set up a basic channel mapping and a audio infoframe for a
5650 * HDMI/DisplayPort pin widget. Due to lack of testing hardware
5651 * this is limited to 2 channels for now.
5652 */
5653 static void
5654 audiohd_setup_hdmi_dp(audiohd_state_t *statep, uint8_t index, uint8_t id,
5655 boolean_t hdmi)
5656 {
5657 uint8_t chanmap[] = { 0, 1, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf };
5658 uint8_t dp_infoframe[] = { 0x84, 0x1b, 0x44, 0x01, 0x00, 0x00, 0x02 };
5659 uint8_t hdmi_infoframe[] = { 0x84, 0x01, 0x0a,
5660 (-(0x84 + 0x01 + 0x0a + 0x01 + 0x02)) & 0xff,
5661 0x01, 0x00, 0x00, 0x02 };
5662 uint8_t *infoframe;
5663 size_t infolen;
5664 int i;
5665
5666 if (hdmi) {
5667 infoframe = hdmi_infoframe;
5668 infolen = sizeof (hdmi_infoframe);
5669 } else {
5670 infoframe = dp_infoframe;
5671 infolen = sizeof (dp_infoframe);
5672 }
5673
5674 /*
5675 * Setup channel mapping. Only 2 channels supported for now.
5676 */
5677 for (i = 0; i != sizeof (chanmap); i++)
5678 (void) audioha_codec_verb_get(statep, index, id,
5679 AUDIOHDC_VERB_SET_ASP_CHMAP, (chanmap[i] << 4) | i);
5680
5681 /*
5682 * Send audio infoframe.
5683 */
5684 (void) audioha_codec_verb_get(statep, index, id,
5685 AUDIOHDC_VERB_SET_DIP_INDEX, 0);
5686 (void) audioha_codec_verb_get(statep, index, id,
5687 AUDIOHDC_VERB_SET_DIP_XMIT, AUDIOHD_DIP_XMIT_STOP);
5688
5689 (void) audioha_codec_verb_get(statep, index, id,
5690 AUDIOHDC_VERB_SET_DIP_INDEX, 0);
5691 for (i = 0; i != AUDIOHD_DIP_DATA_LEN; i++)
5692 (void) audioha_codec_verb_get(statep, index, id,
5693 AUDIOHDC_VERB_SET_DIP_DATA, 0);
5694
5695 (void) audioha_codec_verb_get(statep, index, id,
5696 AUDIOHDC_VERB_SET_DIP_INDEX, 0);
5697 for (i = 0; i != infolen; i++)
5698 (void) audioha_codec_verb_get(statep, index, id,
5699 AUDIOHDC_VERB_SET_DIP_DATA, infoframe[i]);
5700
5701 (void) audioha_codec_verb_get(statep, index, id,
5702 AUDIOHDC_VERB_SET_DIP_INDEX, 0);
5703 (void) audioha_codec_verb_get(statep, index, id,
5704 AUDIOHDC_VERB_SET_DIP_XMIT, AUDIOHD_DIP_XMIT_BEST_EFFORT);
5705
5706 }
5707
5708 /*
5709 * audiohd_get_eld()
5710 *
5711 * Description
5712 *
5713 * Fetch the EDID-like data (ELD) from a pin that is a HDMI/DP
5714 * display sink device. The data is coming tightly packed from
5715 * hardware, unpack it into a audiohd_eld_t structure for easy
5716 * access. We get the complete ELD, but we completely ignore the
5717 * vendor specific part.
5718 */
5719 static audiohd_eld_t *
5720 audiohd_get_eld(audiohd_state_t *statep, uint8_t index, uint8_t id)
5721 {
5722 uint8_t *buf;
5723 audiohd_eld_t *eld;
5724 off_t sad_off;
5725 uint32_t rs;
5726 size_t eldsz;
5727 size_t i;
5728
5729 rs = audioha_codec_verb_get(statep, index, id,
5730 AUDIOHDC_VERB_GET_DIP_SIZE, AUDIOHD_DIP_SIZE_ELD);
5731
5732 eldsz = (rs & AUDIOHD_DIP_SIZE_ELD_MASK) + 1;
5733 if (eldsz < AUDIOHD_ELD_HDR_LEN)
5734 return (NULL);
5735
5736 eldsz = MAX(eldsz, sizeof (audiohd_eld_t));
5737
5738 buf = kmem_zalloc(eldsz, KM_SLEEP);
5739 eld = (audiohd_eld_t *)buf;
5740
5741 /*
5742 * The device will return 0 for any offset that is beyond the length of
5743 * ELD, so we don't have to check whether the size returned by DIP SIZE
5744 * is less than sizeof (audiohd_eld_t).
5745 */
5746 for (i = 0; i != eldsz; i++)
5747 buf[i] = audioha_codec_verb_get(statep, index, id,
5748 AUDIOHDC_VERB_GET_ELD, i);
5749
5750 if (eld->eld_ver != AUDIOHD_ELD_VER_2 &&
5751 eld->eld_ver != AUDIOHD_ELD_VER_NODRV) {
5752 kmem_free(buf, eldsz);
5753 return (NULL);
5754 }
5755
5756 eld->eld_size = eldsz;
5757
5758 /* move the CEA SADs to eld_cea_sad */
5759 sad_off = offsetof(audiohd_eld_t, eld_monitor_name) + eld->eld_mnl;
5760 bcopy(buf + sad_off, (void *)eld->eld_cea_sad,
5761 sizeof (audiohd_sad_t) * eld->eld_sad_count);
5762 bzero(buf + sad_off, offsetof(audiohd_eld_t, eld_cea_sad) - sad_off);
5763
5764 return (eld);
5765 }
5766
5767 /*
5768 * audiohd_pin_sense()
5769 *
5770 * Description
5771 *
5772 * When the earphone is plugged into the jack associtated with the pin
5773 * complex, we disable the built in speaker. When the earphone is plugged
5774 * out of the jack, we enable the built in speaker.
5775 *
5776 * When a digital pin complex reports valid EDID-like data (ELD), update
5777 * it.
5778 */
5779 static void
5780 audiohd_pin_sense(audiohd_state_t *statep, uint32_t resp, uint32_t respex)
5781 {
5782 audiohd_pin_t *pin = NULL;
5783 uint8_t index;
5784 uint8_t id;
5785 uint32_t rs;
5786 audiohd_widget_t *widget;
5787 hda_codec_t *codec;
5788
5789 index = respex & AUDIOHD_RIRB_CODEC_MASK;
5790 id = resp >> (AUDIOHD_RIRB_WID_OFF - 1);
5791
5792 codec = statep->codec[index];
5793 if (codec == NULL)
5794 return;
5795 widget = codec->widget[id];
5796 if (widget == NULL)
5797 return;
5798
5799 if (widget->type == WTYPE_PIN)
5800 pin = (audiohd_pin_t *)widget->priv;
5801
5802 rs = audioha_codec_verb_get(statep, index, id,
5803 AUDIOHDC_VERB_GET_PIN_SENSE, 0);
5804
5805 if ((widget->widget_cap & AUDIOHD_WIDCAP_DIGIT) != 0 &&
5806 (rs & AUDIOHD_PIN_ELDV_MASK) != 0) {
5807 /* updated EDID-like data */
5808 if (pin != NULL) {
5809 if (pin->eld != NULL)
5810 kmem_free(pin->eld, pin->eld->eld_size);
5811 pin->eld = audiohd_get_eld(statep, index, id);
5812 }
5813 } else if (rs & AUDIOHD_PIN_PRES_MASK) {
5814 /* A MIC is plugged in, we select the MIC as input */
5815 if (pin != NULL && pin->device == DTYPE_MIC_IN) {
5816 audiohd_select_mic(statep, index, id, 1);
5817 return;
5818 }
5819 /* output pin is plugged */
5820 audiohd_change_speaker_state(statep, AUDIOHD_SP_OFF);
5821 } else {
5822 /*
5823 * A MIC is unplugged, we select the built in MIC
5824 * as input.
5825 */
5826 if ((widget->type == WTYPE_PIN) &&
5827 (pin = (audiohd_pin_t *)widget->priv) &&
5828 (pin->device == DTYPE_MIC_IN)) {
5829 audiohd_select_mic(statep, index, id, 0);
5830 return;
5831 }
5832 /* output pin is unplugged */
5833 audiohd_change_speaker_state(statep, AUDIOHD_SP_ON);
5834 }
5835
|