Print this page
10619 audiohd ignores digital output pins such as HDMI/DP


   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