svn commit: r232798 - in stable/9: share/man/man4 sys/conf sys/dev/sound/pci/hda sys/dev/sound/pcm sys/modules/sound/driver/hda

Alexander Motin mav at FreeBSD.org
Sat Mar 10 21:58:09 UTC 2012


Author: mav
Date: Sat Mar 10 21:58:08 2012
New Revision: 232798
URL: http://svn.freebsd.org/changeset/base/232798

Log:
  MFC r230130, r230181, r230312, r230326, r230331, r230451, r230465, r230488,
  r230507, r230511, r230513, r230532, r230537, r230551, r230554, r230571,
  r230574, r230585, r230641, r230768, r230807, r231024:
  Sync snd_hda(4) driver with HEAD.
  
  This includes major code refactoring, HDMI support, new volume control,
  automatic recording source selection, runtime reconfigureation, support
  for more then 4 PCM devices on controller, multichannel recording,
  additional playback/record streams, higher bandwidths support, more
  informative device names and many other things.
  
  Sponsored by:	iXsystems, Inc.

Added:
  stable/9/sys/dev/sound/pci/hda/hdaa.c
     - copied, changed from r230130, head/sys/dev/sound/pci/hda/hdaa.c
  stable/9/sys/dev/sound/pci/hda/hdaa.h
     - copied, changed from r230130, head/sys/dev/sound/pci/hda/hdaa.h
  stable/9/sys/dev/sound/pci/hda/hdaa_patches.c
     - copied, changed from r230130, head/sys/dev/sound/pci/hda/hdaa_patches.c
  stable/9/sys/dev/sound/pci/hda/hdac_if.m
     - copied, changed from r230130, head/sys/dev/sound/pci/hda/hdac_if.m
  stable/9/sys/dev/sound/pci/hda/hdacc.c
     - copied, changed from r230130, head/sys/dev/sound/pci/hda/hdacc.c
Modified:
  stable/9/share/man/man4/snd_hda.4
  stable/9/sys/conf/files
  stable/9/sys/conf/kmod.mk
  stable/9/sys/dev/sound/pci/hda/hda_reg.h
  stable/9/sys/dev/sound/pci/hda/hdac.c
  stable/9/sys/dev/sound/pci/hda/hdac.h
  stable/9/sys/dev/sound/pci/hda/hdac_private.h
  stable/9/sys/dev/sound/pci/hda/hdac_reg.h
  stable/9/sys/dev/sound/pcm/channel.c
  stable/9/sys/modules/sound/driver/hda/Makefile
Directory Properties:
  stable/9/share/man/man4/   (props changed)
  stable/9/sys/   (props changed)
  stable/9/sys/conf/   (props changed)

Modified: stable/9/share/man/man4/snd_hda.4
==============================================================================
--- stable/9/share/man/man4/snd_hda.4	Sat Mar 10 21:08:07 2012	(r232797)
+++ stable/9/share/man/man4/snd_hda.4	Sat Mar 10 21:58:08 2012	(r232798)
@@ -25,7 +25,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd January 22, 2010
+.Dd January 25, 2012
 .Dt SND_HDA 4
 .Os
 .Sh NAME
@@ -53,8 +53,9 @@ support for several logical audio device
 .Pp
 The
 .Nm
-driver is a HDA bus controller driver and HDA codecs audio functions bridge
-driver that allows the generic audio driver,
+driver includes HDA bus controller driver (hdac), HDA codec driver (hdacc)
+and HDA codecs audio functions bridge driver (hdaa) that allows
+the generic audio driver,
 .Xr sound 4 ,
 to be used with this hardware.
 Only audio functions are supported by
@@ -77,7 +78,9 @@ For example, one device for main rear 7.
 for independent headset connectors at front and one device for SPDIF or
 HDMI audio input/output.
 The assignment of audio inputs and outputs may be tuned with
-.Xr device.hints 5 .
+.Xr device.hints 5
+or
+.Xr sysctl 8 .
 The driver's verbose boot messages provide a lot of information about
 the operation of the driver and present audio setup.
 .Pp
@@ -92,19 +95,26 @@ The following variables are available at
 file:
 .Bl -tag -width ".Va hint.hdac.%d.config"-offset indent
 .It Va hint.hdac.%d.config
-Configures a range of possible options.
+Configures a range of possible controller options.
 Possible values are:
+.Dq Li 64bit ,
 .Dq Li dmapos ,
+.Dq Li msi .
+An option prefixed with
+.Dq Li no ,
+such as
+.Dq Li nomsi ,
+will do the opposite and takes precedence.
+Options can be separated by whitespace and commas.
+.It Va hint.hdac.%d.msi
+Controls MSI (Message Signaled Interrupts) support.
+.It Va hint.hdac.%d.cad%d.nid%d.config
+Same as
+.Va hint.hdaa.%d.nid%d.config
+.It Va hint.hdaa.%d.config
+Configures a range of possible audio function options.
+Possible values are:
 .Dq Li eapdinv ,
-.Dq Li gpio0 ,
-.Dq Li gpio1 ,
-.Dq Li gpio2 ,
-.Dq Li gpio3 ,
-.Dq Li gpio4 ,
-.Dq Li gpio5 ,
-.Dq Li gpio6 ,
-.Dq Li gpio7 ,
-.Dq Li gpioflush ,
 .Dq Li ivref ,
 .Dq Li ivref50 ,
 .Dq Li ivref80 ,
@@ -126,27 +136,64 @@ such as
 will do the opposite and takes precedence.
 Options can be separated by whitespace and commas.
 .Pp
+The
+.Dq Li eapdinv
+option inverts External Amplifier Power Down signal.
+The
+.Dq Li fixedrate
+denies all sampling rates except 48KHz.
+The
+.Dq Li forcestereo
+denies mono playback/recording.
+The
+.Dq Li senseinv
+option inverts jack sensing logic.
+The
+.Dq Li ivref Ns Ar X
+and
+.Dq Li ovref Ns Ar X
+options control the voltage used to power external microphones.
+.It Va hint.hdaa.%d.gpio_config
+Overrides audio function GPIO pins configuration set by BIOS.
+May be specified as a set of space-separated
+.Dq Ar num Ns = Ns Ar value
+pairs, where
+.Ar num
+is GPIO line number, and
+.Ar value
+is one of:
+.Dq Li keep ,
+.Dq Li set ,
+.Dq Li clear ,
+.Dq Li disable
+and
+.Dq Li input .
+.Pp
 .Dq Li GPIO Ns s
 are a codec's General Purpose I/O pins which system integrators sometimes
 use to control external muters, amplifiers and so on.
 If you have no sound, or sound volume is not adequate, you may have to
 experiment a bit with the GPIO setup to find the optimal setup for your
 system.
-.Pp
-The
-.Dq Li ivref Ns Ar X
-and
-.Dq Li ovref Ns Ar X
-options control the voltage used to power external microphones.
-.It Va hint.hdac.%d.msi
-Controls MSI (Message Signaled Interrupts) support.
-.It Va hint.hdac.%d.cad%d.nid%d.config
-Overrides codec pin configuration set by BIOS.
+.It Va hint.hdaa.%d.nid%d.config
+Overrides audio function pin configuration set by BIOS.
 May be specified as a 32-bit hexadecimal value with a leading
 .Dq 0x ,
 or as a set of space-separated
 .Dq Ar option Ns = Ns Ar value
 pairs.
+.It Va hint.pcm.%d.rec.autosrc
+Controls automatic recording source feature:
+.Bl -tag -compact
+.It 0
+disabled,
+.It 1
+once on attach,
+.It 2
+enabled.
+.El
+When enabled, driver will automatically set recording source of the mixer to
+connected input using jack presence detection statuses.
 .El
 .Pp
 Pin configuration is the UAA driver's main source of information about codec
@@ -165,7 +212,7 @@ The following options are supported:
 Association number.
 Associations are used to group individual pins to form a complex multi-pin
 device.
-For example, to group 4 connectors for 7.1 output, or to treat several
+For example, to group 4 connectors for 7.1 input/output, or to treat several
 input connectors as sources for the same input device.
 Association numbers can be specified as numeric values from 0 to 15.
 A value of 0 means disabled pin.
@@ -180,16 +227,22 @@ A unique, per-association number used to
 particular association.
 Sequence numbers can be specified as numeric values from 0 to 15.
 .Pp
-For output assotiations sequence numbers encode speaker pairs positions:
-0 - Front, 1 - Center/LFE, 2 - Back, 3 - Front Wide Center, 4 - Side.
-Standard combinations are: (0) - Stereo; (0, 2), (0, 4) - Quadro;
-(0, 1, 2), (0, 1, 4) - 5.1; (0, 1, 2, 4) - 7.1.
-.Pp
 The sequence number 15 has a special meaning for output associations.
 Output pins with this number and device type
 .Dq Ar Headphones
 will duplicate (with automatic mute if jack detection is supported) the
 first pin in that association.
+.Pp
+The sequence numbers 14 and 15 has a special meaning for input associations.
+Their presence in association defines it as multiplexed or mixed respectively.
+If none of them present and there are more then one pin in association,
+the association will provide multichannel input.
+.Pp
+For multichannel input/output assotiations sequence numbers encode
+channel pairs positions:
+0 - Front, 1 - Center/LFE, 2 - Back, 3 - Front Wide Center, 4 - Side.
+Standard combinations are: (0) - Stereo; (0, 2), (0, 4) - Quadro;
+(0, 1, 2), (0, 1, 4) - 5.1; (0, 1, 2, 4) - 7.1.
 .It Va device
 Device type.
 Can be specified as a number from 0 to 15 or as a name:
@@ -278,7 +331,11 @@ The following
 variables are available in addition to those available to all
 .Xr sound 4
 devices:
-.Bl -tag -width ".Va dev.hdac.%d.polling" -offset indent
+.Bl -tag -width ".Va dev.hdaa.%d.nid%d_original" -offset indent
+.It Va dev.hdac.%d.pindump
+Setting this to a non-zero value dumps the current pin configuration, main
+capabilities and jack sense status of all audio functions on the controller
+to console and syslog.
 .It Va dev.hdac.%d.polling
 Enables polling mode.
 In this mode the driver operates by querying the device state on timer
@@ -288,11 +345,40 @@ instead of interrupts.
 Polling is disabled by default.
 Do not enable it unless you are facing weird interrupt problems or if the
 device cannot generate interrupts at all.
-.It Va dev.hdac.%d.polling_interval
-Controller/Jack Sense polling interval (1-1000 ms)
-.It Va dev.hdac.%d.pindump
-Setting this to a non-zero value dumps the current pin configuration, main
-capabilities and jack sense status to console and syslog.
+.It Va dev.hdaa.%d.config
+Run-time equivalent of the
+.Va hint.hdaa.%d.config
+tunable.
+.It Va dev.hdaa.%d.gpi_state
+Current state of GPI lines.
+.It Va dev.hdaa.%d.gpio_state
+Current state of GPIO lines.
+.It Va dev.hdaa.%d.gpio_config
+Run-time equivalent of the
+.Va hint.hdaa.%d.gpio.config
+tunable.
+.It Va dev.hdaa.%d.gpo_state
+Current state of GPO lines.
+.It Va dev.hdaa.%d.nid%d_config
+Run-time equivalent of the
+.Va hint.hdaa.%d.nid%d.config
+tunable.
+.It Va dev.hdaa.%d.nid%d_original
+Original pin configuration written by BIOS.
+.It Va dev.hdaa.%d.reconfig
+Setting this to a non-zero value makes driver to destroy existing pcm devices
+and process new pins configuration set via
+.Va dev.hdaa.%d.nid%d_config.
+.It Va dev.pcm.%d.play.32bit , dev.pcm.%d.rec.32bit
+HDA controller uses 32bit representation for all samples of more then 16 bits.
+These variables allow to specify how many bits of these 32 should be
+used by CODEC.
+Depending on codec capabilities, possible values are 20, 24 and 32 bit.
+The default value is 24.
+.It Va dev.pcm.%d.rec.autosrc
+Run-time equivalent of the
+.Va hint.pcm.%d.rec.autosrc
+tunable.
 .El
 .Sh EXAMPLES
 Taking HP Compaq DX2300 with Realtek ALC888 HDA codec for example.
@@ -307,22 +393,23 @@ So high codec uniformity and flexibility
 different ways, depending on requested pins usage described by pins configuration.
 The driver reports such default pin configuration when verbose messages enabled:
 .Bd -literal
-hdac0: nid 20 0x01014020 as  2 seq  0   Line-out  Jack jack 1 loc  1 color   Green misc 0
-hdac0: nid 21 0x99130110 as  1 seq  0    Speaker Fixed jack 3 loc 25 color Unknown misc 1
-hdac0: nid 22 0x411111f0 as 15 seq  0    Speaker  None jack 1 loc  1 color   Black misc 1
-hdac0: nid 23 0x411111f0 as 15 seq  0    Speaker  None jack 1 loc  1 color   Black misc 1
-hdac0: nid 24 0x01a19830 as  3 seq  0        Mic  Jack jack 1 loc  1 color    Pink misc 8
-hdac0: nid 25 0x02a1983f as  3 seq 15        Mic  Jack jack 1 loc  2 color    Pink misc 8
-hdac0: nid 26 0x01813031 as  3 seq  1    Line-in  Jack jack 1 loc  1 color    Blue misc 0
-hdac0: nid 27 0x0221401f as  1 seq 15 Headphones  Jack jack 1 loc  2 color   Green misc 0
-hdac0: nid 28 0x411111f0 as 15 seq  0    Speaker  None jack 1 loc  1 color   Black misc 1
-hdac0: nid 30 0x411111f0 as 15 seq  0    Speaker  None jack 1 loc  1 color   Black misc 1
-hdac0: nid 31 0x411111f0 as 15 seq  0    Speaker  None jack 1 loc  1 color   Black misc 1
+hdaa0: nid   0x    as seq device       conn  jack    loc        color   misc
+hdaa0: 20 01014020 2  0  Line-out      Jack  1/8     Rear       Green   0
+hdaa0: 21 99130110 1  0  Speaker       Fixed ATAPI   Onboard    Unknown 1
+hdaa0: 22 411111f0 15 0  Speaker       None  1/8     Rear       Black   1 DISA
+hdaa0: 23 411111f0 15 0  Speaker       None  1/8     Rear       Black   1 DISA
+hdaa0: 24 01a19830 3  0  Mic           Jack  1/8     Rear       Pink    8
+hdaa0: 25 02a1983f 3  15 Mic           Jack  1/8     Front      Pink    8
+hdaa0: 26 01813031 3  1  Line-in       Jack  1/8     Rear       Blue    0
+hdaa0: 27 0221401f 1  15 Headphones    Jack  1/8     Front      Green   0
+hdaa0: 28 411111f0 15 0  Speaker       None  1/8     Rear       Black   1 DISA
+hdaa0: 30 411111f0 15 0  Speaker       None  1/8     Rear       Black   1 DISA
+hdaa0: 31 411111f0 15 0  Speaker       None  1/8     Rear       Black   1 DISA
 .Ed
 .Pp
 Here we can see, that the nodes with ID (nid) 25 and 27 are front panel
-connectors (Jack, loc 2), nids 20, 24 and 26 are rear panel connectors
-(Jack, loc 1) and nid 21 is a built-in speaker (Fixed, loc 25).
+connectors (Jack, Front), nids 20, 24 and 26 are rear panel connectors
+(Jack, Rear) and nid 21 is a built-in speaker (Fixed, Onboard).
 Pins with nids 22, 23, 28, 30 and 31 will be disabled by driver due to "None"
 connectivity. So the pin count and description matches to connectors that
 we have.
@@ -330,15 +417,15 @@ we have.
 Using association (as) and sequence (seq) fields values pins are grouped into
 3 associations:
 .Bd -literal
-hdac0: Association 0 (1) out:
-hdac0:   Pin nid=21 seq=0
-hdac0:   Pin nid=27 seq=15
-hdac0: Association 1 (2) out:
-hdac0:   Pin nid=20 seq=0
-hdac0: Association 2 (3) in:
-hdac0:   Pin nid=24 seq=0
-hdac0:   Pin nid=26 seq=1
-hdac0:   Pin nid=25 seq=15
+hdaa0: Association 0 (1) out:
+hdaa0:   Pin nid=21 seq=0
+hdaa0:   Pin nid=27 seq=15
+hdaa0: Association 1 (2) out:
+hdaa0:   Pin nid=20 seq=0
+hdaa0: Association 2 (3) in:
+hdaa0:   Pin nid=24 seq=0
+hdaa0:   Pin nid=26 seq=1
+hdaa0:   Pin nid=25 seq=15
 .Ed
 .Pp
 Each
@@ -497,148 +584,14 @@ Most of controls use logarithmic scale.
 .Sh HARDWARE
 The
 .Nm
-driver supports many Intel HDA compatible audio chipsets including the
-following:
+driver supports controllers having PCI class 4 (multimedia) and
+subclass 3 (HDA), compatible with Intel HDA specification.
 .Pp
-.Bl -bullet -compact
-.It
-ATI SB450
-.It
-ATI SB600
-.It
-Intel 631x/632xESB
-.It
-Intel 82801F (ICH6)
-.It
-Intel 82801G (ICH7)
-.It
-Intel 82801H (ICH8)
-.It
-Intel 82801I (ICH9)
-.It
-Intel 82801J (ICH10)
-.It
-Intel US15W (SCH)
-.It
-nVidia MCP51
-.It
-nVidia MCP55
-.It
-nVidia MCP61A
-.It
-nVidia MCP61B
-.It
-nVidia MCP63
-.It
-nVidia MCP65A
-.It
-nVidia MCP65B
-.It
-nVidia MCP67A
-.It
-nVidia MCP67B
-.It
-nVidia MCP68
-.It
-nVidia MCP69
-.It
-nVidia MCP73
-.It
-nVidia MCP78
-.It
-nVidia MCP79
-.It
-nVidia MCP89
-.It
-SiS 966
-.It
-VIA VT8251/8237A
-.El
-.Pp
-The following and many other codecs have been verified to work:
-.Pp
-.Bl -bullet -compact
-.It
-Analog Devices AD1981HD
-.It
-Analog Devices AD1983
-.It
-Analog Devices AD1984
-.It
-Analog Devices AD1986A
-.It
-Analog Devices AD1988
-.It
-Analog Devices AD1988B
-.It
-CMedia CMI9880
-.It
-Conexant CX20549 (Venice)
-.It
-Conexant CX20551 (Waikiki)
-.It
-Conexant CX20561 (Hermosa)
-.It
-Realtek ALC260
-.It
-Realtek ALC262
-.It
-Realtek ALC268
-.It
-Realtek ALC660
-.It
-Realtek ALC861
-.It
-Realtek ALC861VD
-.It
-Realtek ALC880
-.It
-Realtek ALC882
-.It
-Realtek ALC883
-.It
-Realtek ALC885
-.It
-Realtek ALC888
-.It
-Realtek ALC889
-.It
-Sigmatel STAC9205
-.It
-Sigmatel STAC9220
-.It
-Sigmatel STAC9220D / 9223D
-.It
-Sigmatel STAC9221
-.It
-Sigmatel STAC9221D
-.It
-Sigmatel STAC9227D
-.It
-Sigmatel STAC9227X
-.It
-Sigmatel STAC9228D
-.It
-Sigmatel STAC9228X
-.It
-Sigmatel STAC9229D
-.It
-Sigmatel STAC9229X
-.It
-Sigmatel STAC9230D
-.It
-Sigmatel STAC9230X
-.It
-Sigmatel STAC9271D
-.It
-Sigmatel STAC9872AK
-.It
-VIA VT1708
-.It
-VIA VT1708B
-.It
-VIA VT1709
-.El
+The
+.Nm
+driver supports more then two hundred different controllers and CODECs.
+There is no sense to list all of them here, as in most cases specific CODEC
+configuration and wiring are more important then type of the CODEC itself.
 .Sh SEE ALSO
 .Xr sound 4 ,
 .Xr snd_ich 4 ,
@@ -665,19 +618,17 @@ This manual page was written by
 and
 .An Giorgos Keramidas Aq keramida at FreeBSD.org .
 .Sh BUGS
-A few Hardware/OEM vendors tend to screw up BIOS settings, thus
-rendering the
-.Nm
-driver useless.
-This usually results in a state where the
+Some Hardware/OEM vendors tend to screw up BIOS settings or use custom
+unusual CODEC wiring that create problems to the driver.
+This may result in missing pcm devices, or a state where the
 .Nm
 driver seems to attach and work, but no sound is played.
 Some cases can be solved by tuning
 .Pa loader.conf
 variables.
-Before trying to fix problem that way, make sure that there really is a problem
-and that the PCM audio device in use really corresponds to the expected
-audio connector.
+But before trying to fix problem that way, make sure that there really is
+a problem and that the PCM audio device in use really corresponds to the
+expected audio connector.
 .Pp
 Some vendors use non-standardized General Purpose I/O (GPIO) pins of the codec
 to control external amplifiers.

Modified: stable/9/sys/conf/files
==============================================================================
--- stable/9/sys/conf/files	Sat Mar 10 21:08:07 2012	(r232797)
+++ stable/9/sys/conf/files	Sat Mar 10 21:58:08 2012	(r232798)
@@ -1749,7 +1749,11 @@ dev/sound/pci/t4dwave.c		optional snd_t4
 dev/sound/pci/via8233.c		optional snd_via8233 pci
 dev/sound/pci/via82c686.c	optional snd_via82c686 pci
 dev/sound/pci/vibes.c		optional snd_vibes pci
+dev/sound/pci/hda/hdaa.c	optional snd_hda pci
+dev/sound/pci/hda/hdaa_patches.c	optional snd_hda pci
 dev/sound/pci/hda/hdac.c	optional snd_hda pci
+dev/sound/pci/hda/hdac_if.m	optional snd_hda pci
+dev/sound/pci/hda/hdacc.c	optional snd_hda pci
 dev/sound/pcm/ac97.c		optional sound
 dev/sound/pcm/ac97_if.m		optional sound
 dev/sound/pcm/ac97_patch.c	optional sound

Modified: stable/9/sys/conf/kmod.mk
==============================================================================
--- stable/9/sys/conf/kmod.mk	Sat Mar 10 21:08:07 2012	(r232797)
+++ stable/9/sys/conf/kmod.mk	Sat Mar 10 21:58:08 2012	(r232798)
@@ -348,6 +348,7 @@ MFILES?= dev/acpica/acpi_if.m dev/acpi_s
 	dev/mii/miibus_if.m dev/mvs/mvs_if.m dev/ofw/ofw_bus_if.m \
 	dev/pccard/card_if.m dev/pccard/power_if.m dev/pci/pci_if.m \
 	dev/pci/pcib_if.m dev/ppbus/ppbus_if.m dev/smbus/smbus_if.m \
+	dev/sound/pci/hda/hdac_if.m \
 	dev/sound/pcm/ac97_if.m dev/sound/pcm/channel_if.m \
 	dev/sound/pcm/feeder_if.m dev/sound/pcm/mixer_if.m \
 	dev/sound/midi/mpu_if.m dev/sound/midi/mpufoi_if.m \

Modified: stable/9/sys/dev/sound/pci/hda/hda_reg.h
==============================================================================
--- stable/9/sys/dev/sound/pci/hda/hda_reg.h	Sat Mar 10 21:08:07 2012	(r232797)
+++ stable/9/sys/dev/sound/pci/hda/hda_reg.h	Sat Mar 10 21:58:08 2012	(r232798)
@@ -400,7 +400,7 @@
     HDA_CMD_GET_UNSOLICITED_RESPONSE_TAG_SHIFT)
 
 #define HDA_CMD_SET_UNSOLICITED_RESPONSE_ENABLE		0x80
-#define HDA_CMD_SET_UNSOLICITED_RESPONSE_TAG_MASK	0x1f
+#define HDA_CMD_SET_UNSOLICITED_RESPONSE_TAG_MASK	0x3f
 #define HDA_CMD_SET_UNSOLICITED_RESPONSE_TAG_SHIFT	0
 
 #define HDA_CMD_SET_UNSOLICITED_RESPONSE_TAG(param)			\
@@ -418,14 +418,11 @@
     (HDA_CMD_12BIT((cad), (nid),					\
     HDA_CMD_VERB_SET_PIN_SENSE, (payload)))
 
-#define HDA_CMD_GET_PIN_SENSE_PRESENCE_DETECT_MASK	0x80000000
-#define HDA_CMD_GET_PIN_SENSE_PRESENCE_DETECT_SHIFT	31
+#define HDA_CMD_GET_PIN_SENSE_PRESENCE_DETECT		0x80000000
+#define HDA_CMD_GET_PIN_SENSE_ELD_VALID			0x40000000
 #define HDA_CMD_GET_PIN_SENSE_IMP_SENSE_MASK		0x7fffffff
 #define HDA_CMD_GET_PIN_SENSE_IMP_SENSE_SHIFT		0
 
-#define HDA_CMD_GET_PIN_SENSE_PRESENCE_DETECT(rsp)			\
-    (((rsp) & HDA_CMD_GET_PIN_SENSE_PRESENCE_DETECT_MASK) >>		\
-    HDA_CMD_GET_PIN_SENSE_PRESENCE_DETECT_SHIFT)
 #define HDA_CMD_GET_PIN_SENSE_IMP_SENSE(rsp)				\
     (((rsp) & HDA_CMD_GET_PIN_SENSE_IMP_SENSE_MASK) >>			\
     HDA_CMD_GET_PIN_SENSE_IMP_SENSE_SHIFT)
@@ -679,17 +676,47 @@
     HDA_CMD_VERB_SET_CONV_CHAN_COUNT, (payload)))
 
 #define HDA_CMD_VERB_GET_HDMI_DIP_SIZE			0xf2e 
+
+#define HDA_CMD_GET_HDMI_DIP_SIZE(cad, nid, arg)			\
+    (HDA_CMD_12BIT((cad), (nid),					\
+    HDA_CMD_VERB_GET_HDMI_DIP_SIZE, (arg)))
+
 #define HDA_CMD_VERB_GET_HDMI_ELDD			0xf2f 
 
+#define HDA_CMD_GET_HDMI_ELDD(cad, nid, off)				\
+    (HDA_CMD_12BIT((cad), (nid),					\
+    HDA_CMD_VERB_GET_HDMI_ELDD, (off)))
+
 #define HDA_CMD_VERB_GET_HDMI_DIP_INDEX			0xf30 
 #define HDA_CMD_VERB_SET_HDMI_DIP_INDEX			0x730 
 
+#define HDA_CMD_GET_HDMI_DIP_INDEX(cad, nid)				\
+    (HDA_CMD_12BIT((cad), (nid),					\
+    HDA_CMD_VERB_GET_HDMI_DIP_INDEX, 0x0))
+#define HDA_CMD_SET_HDMI_DIP_INDEX(cad, nid, payload)			\
+    (HDA_CMD_12BIT((cad), (nid),					\
+    HDA_CMD_VERB_SET_HDMI_DIP_INDEX, (payload)))
+
 #define HDA_CMD_VERB_GET_HDMI_DIP_DATA			0xf31 
 #define HDA_CMD_VERB_SET_HDMI_DIP_DATA			0x731 
 
+#define HDA_CMD_GET_HDMI_DIP_DATA(cad, nid)				\
+    (HDA_CMD_12BIT((cad), (nid),					\
+    HDA_CMD_VERB_GET_HDMI_DIP_DATA, 0x0))
+#define HDA_CMD_SET_HDMI_DIP_DATA(cad, nid, payload)			\
+    (HDA_CMD_12BIT((cad), (nid),					\
+    HDA_CMD_VERB_SET_HDMI_DIP_DATA, (payload)))
+
 #define HDA_CMD_VERB_GET_HDMI_DIP_XMIT			0xf32 
 #define HDA_CMD_VERB_SET_HDMI_DIP_XMIT			0x732 
 
+#define HDA_CMD_GET_HDMI_DIP_XMIT(cad, nid)				\
+    (HDA_CMD_12BIT((cad), (nid),					\
+    HDA_CMD_VERB_GET_HDMI_DIP_XMIT, 0x0))
+#define HDA_CMD_SET_HDMI_DIP_XMIT(cad, nid, payload)			\
+    (HDA_CMD_12BIT((cad), (nid),					\
+    HDA_CMD_VERB_SET_HDMI_DIP_XMIT, (payload)))
+
 #define HDA_CMD_VERB_GET_HDMI_CP_CTRL			0xf33 
 #define HDA_CMD_VERB_SET_HDMI_CP_CTRL			0x733 
 
@@ -703,6 +730,23 @@
     (HDA_CMD_12BIT((cad), (nid),					\
     HDA_CMD_VERB_SET_HDMI_CHAN_SLOT, (payload)))
 
+#define	HDA_HDMI_CODING_TYPE_REF_STREAM_HEADER		0
+#define	HDA_HDMI_CODING_TYPE_LPCM			1
+#define	HDA_HDMI_CODING_TYPE_AC3			2
+#define	HDA_HDMI_CODING_TYPE_MPEG1			3
+#define	HDA_HDMI_CODING_TYPE_MP3			4
+#define	HDA_HDMI_CODING_TYPE_MPEG2			5
+#define	HDA_HDMI_CODING_TYPE_AACLC			6
+#define	HDA_HDMI_CODING_TYPE_DTS			7
+#define	HDA_HDMI_CODING_TYPE_ATRAC			8
+#define	HDA_HDMI_CODING_TYPE_SACD			9
+#define	HDA_HDMI_CODING_TYPE_EAC3			10
+#define	HDA_HDMI_CODING_TYPE_DTS_HD			11
+#define	HDA_HDMI_CODING_TYPE_MLP			12
+#define	HDA_HDMI_CODING_TYPE_DST			13
+#define	HDA_HDMI_CODING_TYPE_WMAPRO			14
+#define	HDA_HDMI_CODING_TYPE_REF_CTX			15
+
 /* Function Reset */
 #define HDA_CMD_VERB_FUNCTION_RESET			0x7ff
 

Copied and modified: stable/9/sys/dev/sound/pci/hda/hdaa.c (from r230130, head/sys/dev/sound/pci/hda/hdaa.c)
==============================================================================
--- head/sys/dev/sound/pci/hda/hdaa.c	Sun Jan 15 13:21:36 2012	(r230130, copy source)
+++ stable/9/sys/dev/sound/pci/hda/hdaa.c	Sat Mar 10 21:58:08 2012	(r232798)
@@ -74,17 +74,6 @@ static const struct {
 #define HDAA_QUIRKS_TAB_LEN	\
 		(sizeof(hdaa_quirks_tab) / sizeof(hdaa_quirks_tab[0]))
 
-#define HDA_BDL_MIN	2
-#define HDA_BDL_MAX	256
-#define HDA_BDL_DEFAULT	HDA_BDL_MIN
-
-#define HDA_BLK_MIN	HDA_DMA_ALIGNMENT
-#define HDA_BLK_ALIGN	(~(HDA_BLK_MIN - 1))
-
-#define HDA_BUFSZ_MIN		4096
-#define HDA_BUFSZ_MAX		65536
-#define HDA_BUFSZ_DEFAULT	16384
-
 #define HDA_PARSE_MAXDEPTH	10
 
 MALLOC_DEFINE(M_HDAA, "hdaa", "HDA Audio");
@@ -116,6 +105,12 @@ const char *HDA_LOCS[64] = {
 const char *HDA_GPIO_ACTIONS[8] = {
     "keep", "set", "clear", "disable", "input", "0x05", "0x06", "0x07"};
 
+const char *HDA_HDMI_CODING_TYPES[18] = {
+    "undefined", "LPCM", "AC-3", "MPEG1", "MP3", "MPEG2", "AAC-LC", "DTS",
+    "ATRAC", "DSD", "E-AC-3", "DTS-HD", "MLP", "DST", "WMAPro", "HE-AAC",
+    "HE-AACv2", "MPEG-Surround"
+};
+
 /* Default */
 static uint32_t hdaa_fmt[] = {
 	SND_FORMAT(AFMT_S16_LE, 2, 0),
@@ -169,6 +164,8 @@ static const struct {
 };
 #define HDA_RATE_TAB_LEN (sizeof(hda_rate_tab) / sizeof(hda_rate_tab[0]))
 
+const static char *ossnames[] = SOUND_DEVICE_NAMES;
+
 /****************************************************************************
  * Function prototypes
  ****************************************************************************/
@@ -187,7 +184,6 @@ static void	hdaa_dump_pin_config(struct 
 static char *
 hdaa_audio_ctl_ossmixer_mask2allname(uint32_t mask, char *buf, size_t len)
 {
-	static char *ossname[] = SOUND_DEVICE_NAMES;
 	int i, first = 1;
 
 	bzero(buf, len);
@@ -195,7 +191,7 @@ hdaa_audio_ctl_ossmixer_mask2allname(uin
 		if (mask & (1 << i)) {
 			if (first == 0)
 				strlcat(buf, ", ", len);
-			strlcat(buf, ossname[i], len);
+			strlcat(buf, ossnames[i], len);
 			first = 0;
 		}
 	}
@@ -243,49 +239,30 @@ hdaa_audio_ctl_amp_get(struct hdaa_devin
 }
 
 /*
- * Jack detection (Speaker/HP redirection) event handler.
+ * Headphones redirection change handler.
  */
 static void
-hdaa_hp_switch_handler(struct hdaa_devinfo *devinfo, int asid)
+hdaa_hpredir_handler(struct hdaa_widget *w)
 {
-	struct hdaa_audio_as *as;
-	struct hdaa_widget *w;
+	struct hdaa_devinfo *devinfo = w->devinfo;
+	struct hdaa_audio_as *as = &devinfo->as[w->bindas];
+	struct hdaa_widget *w1;
 	struct hdaa_audio_ctl *ctl;
-	uint32_t val, res;
-	int j;
-
-	as = &devinfo->as[asid];
-	if (as->hpredir < 0)
-		return;
-
-	w = hdaa_widget_get(devinfo, as->pins[15]);
-	if (w == NULL || w->enable == 0 || w->type !=
-	    HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX)
-		return;
-
-	res = hda_command(devinfo->dev,
-	    HDA_CMD_GET_PIN_SENSE(0, as->pins[15]));
-
-	HDA_BOOTVERBOSE(
-		device_printf(devinfo->dev,
-		    "Pin sense: nid=%d sence=0x%08x",
-		    as->pins[15], res);
-	);
-
-	res = (res & HDA_CMD_GET_PIN_SENSE_PRESENCE_DETECT) != 0;
-	if (devinfo->quirks & HDAA_QUIRK_SENSEINV)
-		res ^= 1;
+	uint32_t val;
+	int j, connected = w->wclass.pin.connected;
 
 	HDA_BOOTVERBOSE(
-		printf(" %sconnected\n", res == 0 ? "dis" : "");
+		device_printf((as->pdevinfo && as->pdevinfo->dev) ?
+		    as->pdevinfo->dev : devinfo->dev,
+		    "Redirect output to: %s\n",
+		    connected ? "headphones": "main");
 	);
-
 	/* (Un)Mute headphone pin. */
 	ctl = hdaa_audio_ctl_amp_get(devinfo,
-	    as->pins[15], HDAA_CTL_IN, -1, 1);
+	    w->nid, HDAA_CTL_IN, -1, 1);
 	if (ctl != NULL && ctl->mute) {
 		/* If pin has muter - use it. */
-		val = (res != 0) ? 0 : 1;
+		val = connected ? 0 : 1;
 		if (val != ctl->forcemute) {
 			ctl->forcemute = val;
 			hdaa_audio_ctl_amp_set(ctl,
@@ -294,21 +271,17 @@ hdaa_hp_switch_handler(struct hdaa_devin
 		}
 	} else {
 		/* If there is no muter - disable pin output. */
-		w = hdaa_widget_get(devinfo, as->pins[15]);
-		if (w != NULL && w->type ==
-		    HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX) {
-			if (res != 0)
-				val = w->wclass.pin.ctrl |
-				    HDA_CMD_SET_PIN_WIDGET_CTRL_OUT_ENABLE;
-			else
-				val = w->wclass.pin.ctrl &
-				    ~HDA_CMD_SET_PIN_WIDGET_CTRL_OUT_ENABLE;
-			if (val != w->wclass.pin.ctrl) {
-				w->wclass.pin.ctrl = val;
-				hda_command(devinfo->dev,
-				    HDA_CMD_SET_PIN_WIDGET_CTRL(0,
-				    w->nid, w->wclass.pin.ctrl));
-			}
+		if (connected)
+			val = w->wclass.pin.ctrl |
+			    HDA_CMD_SET_PIN_WIDGET_CTRL_OUT_ENABLE;
+		else
+			val = w->wclass.pin.ctrl &
+			    ~HDA_CMD_SET_PIN_WIDGET_CTRL_OUT_ENABLE;
+		if (val != w->wclass.pin.ctrl) {
+			w->wclass.pin.ctrl = val;
+			hda_command(devinfo->dev,
+			    HDA_CMD_SET_PIN_WIDGET_CTRL(0,
+			    w->nid, w->wclass.pin.ctrl));
 		}
 	}
 	/* (Un)Mute other pins. */
@@ -319,7 +292,7 @@ hdaa_hp_switch_handler(struct hdaa_devin
 		    as->pins[j], HDAA_CTL_IN, -1, 1);
 		if (ctl != NULL && ctl->mute) {
 			/* If pin has muter - use it. */
-			val = (res != 0) ? 1 : 0;
+			val = connected ? 1 : 0;
 			if (val == ctl->forcemute)
 				continue;
 			ctl->forcemute = val;
@@ -329,32 +302,142 @@ hdaa_hp_switch_handler(struct hdaa_devin
 			continue;
 		}
 		/* If there is no muter - disable pin output. */
-		w = hdaa_widget_get(devinfo, as->pins[j]);
-		if (w != NULL && w->type ==
-		    HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX) {
-			if (res != 0)
-				val = w->wclass.pin.ctrl &
+		w1 = hdaa_widget_get(devinfo, as->pins[j]);
+		if (w1 != NULL) {
+			if (connected)
+				val = w1->wclass.pin.ctrl &
 				    ~HDA_CMD_SET_PIN_WIDGET_CTRL_OUT_ENABLE;
 			else
-				val = w->wclass.pin.ctrl |
+				val = w1->wclass.pin.ctrl |
 				    HDA_CMD_SET_PIN_WIDGET_CTRL_OUT_ENABLE;
-			if (val != w->wclass.pin.ctrl) {
-				w->wclass.pin.ctrl = val;
+			if (val != w1->wclass.pin.ctrl) {
+				w1->wclass.pin.ctrl = val;
 				hda_command(devinfo->dev,
 				    HDA_CMD_SET_PIN_WIDGET_CTRL(0,
-				    w->nid, w->wclass.pin.ctrl));
+				    w1->nid, w1->wclass.pin.ctrl));
 			}
 		}
 	}
 }
 
 /*
- * Callback for poll based jack detection.
+ * Recording source change handler.
+ */
+static void
+hdaa_autorecsrc_handler(struct hdaa_audio_as *as, struct hdaa_widget *w)
+{
+	struct hdaa_pcm_devinfo *pdevinfo = as->pdevinfo;
+	struct hdaa_devinfo *devinfo;
+	struct hdaa_widget *w1;
+	int i, mask, fullmask, prio, bestprio;
+	char buf[128];
+
+	if (!as->mixed || pdevinfo == NULL || pdevinfo->mixer == NULL)
+		return;
+	/* Don't touch anything if we asked not to. */
+	if (pdevinfo->autorecsrc == 0 ||
+	    (pdevinfo->autorecsrc == 1 && w != NULL))
+		return;
+	/* Don't touch anything if "mix" or "speaker" selected. */
+	if (pdevinfo->recsrc & (SOUND_MASK_IMIX | SOUND_MASK_SPEAKER))
+		return;
+	/* Don't touch anything if several selected. */
+	if (ffs(pdevinfo->recsrc) != fls(pdevinfo->recsrc))
+		return;
+	devinfo = pdevinfo->devinfo;
+	mask = fullmask = 0;
+	bestprio = 0;
+	for (i = 0; i < 16; i++) {
+		if (as->pins[i] <= 0)
+			continue;
+		w1 = hdaa_widget_get(devinfo, as->pins[i]);
+		if (w1 == NULL || w1->enable == 0)
+			continue;
+		if (w1->wclass.pin.connected == 0)
+			continue;
+		prio = (w1->wclass.pin.connected == 1) ? 2 : 1;
+		if (prio < bestprio)
+			continue;
+		if (prio > bestprio) {
+			mask = 0;
+			bestprio = prio;
+		}
+		mask |= (1 << w1->ossdev);
+		fullmask |= (1 << w1->ossdev);
+	}
+	if (mask == 0)
+		return;
+	/* Prefer newly connected input. */
+	if (w != NULL && (mask & (1 << w->ossdev)))
+		mask = (1 << w->ossdev);
+	/* Prefer previously selected input */
+	if (mask & pdevinfo->recsrc)
+		mask &= pdevinfo->recsrc;
+	/* Prefer mic. */
+	if (mask & SOUND_MASK_MIC)
+		mask = SOUND_MASK_MIC;
+	/* Prefer monitor (2nd mic). */
+	if (mask & SOUND_MASK_MONITOR)
+		mask = SOUND_MASK_MONITOR;
+	/* Just take first one. */
+	mask = (1 << (ffs(mask) - 1));
+	HDA_BOOTVERBOSE(
+		hdaa_audio_ctl_ossmixer_mask2allname(mask, buf, sizeof(buf));
+		device_printf(pdevinfo->dev,
+		    "Automatically set rec source to: %s\n", buf);
+	);
+	hdaa_unlock(devinfo);
+	mix_setrecsrc(pdevinfo->mixer, mask);
+	hdaa_lock(devinfo);
+}
+
+/*
+ * Jack presence detection event handler.
+ */
+static void
+hdaa_presence_handler(struct hdaa_widget *w)
+{
+	struct hdaa_devinfo *devinfo = w->devinfo;
+	struct hdaa_audio_as *as;
+	uint32_t res;
+	int connected;
+
+	if (w->enable == 0 || w->type !=
+	    HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX)
+		return;
+
+	if (HDA_PARAM_PIN_CAP_PRESENCE_DETECT_CAP(w->wclass.pin.cap) == 0 ||
+	    (HDA_CONFIG_DEFAULTCONF_MISC(w->wclass.pin.config) & 1) != 0)
+		return;
+
+	res = hda_command(devinfo->dev, HDA_CMD_GET_PIN_SENSE(0, w->nid));
+	connected = (res & HDA_CMD_GET_PIN_SENSE_PRESENCE_DETECT) != 0;
+	if (devinfo->quirks & HDAA_QUIRK_SENSEINV)
+		connected = !connected;
+	if (connected == w->wclass.pin.connected)
+		return;
+	w->wclass.pin.connected = connected;
+	HDA_BOOTVERBOSE(
+		device_printf(devinfo->dev,
+		    "Pin sense: nid=%d sence=0x%08x (%sconnected)\n",
+		    w->nid, res, !w->wclass.pin.connected ? "dis" : "");
+	);
+
+	as = &devinfo->as[w->bindas];
+	if (as->hpredir >= 0 && as->pins[15] == w->nid)
+		hdaa_hpredir_handler(w);
+	if (as->dir == HDAA_CTL_IN)
+		hdaa_autorecsrc_handler(as, w);
+}
+
+/*
+ * Callback for poll based presence detection.
  */
 static void
 hdaa_jack_poll_callback(void *arg)
 {
 	struct hdaa_devinfo *devinfo = arg;
+	struct hdaa_widget *w;
 	int i;
 
 	hdaa_lock(devinfo);
@@ -365,56 +448,203 @@ hdaa_jack_poll_callback(void *arg)
 	for (i = 0; i < devinfo->ascnt; i++) {
 		if (devinfo->as[i].hpredir < 0)
 			continue;
-		hdaa_hp_switch_handler(devinfo, i);
+		w = hdaa_widget_get(devinfo, devinfo->as[i].pins[15]);
+		if (w == NULL || w->enable == 0 || w->type !=
+		    HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX)
+			continue;
+		hdaa_presence_handler(w);
 	}
 	callout_reset(&devinfo->poll_jack, devinfo->poll_ival,
 	    hdaa_jack_poll_callback, devinfo);
 	hdaa_unlock(devinfo);
 }
 
+static void
+hdaa_eld_dump(struct hdaa_widget *w)
+{
+	struct hdaa_devinfo *devinfo = w->devinfo;
+	device_t dev = devinfo->dev;
+	uint8_t *sad;
+	int len, mnl, i, sadc, fmt;
+
+	if (w->eld == NULL || w->eld_len < 4)
+		return;
+	device_printf(dev,
+	    "ELD nid=%d: ELD_Ver=%u Baseline_ELD_Len=%u\n",
+	    w->nid, w->eld[0] >> 3, w->eld[2]);
+	if ((w->eld[0] >> 3) != 0x02)
+		return;
+	len = min(w->eld_len, (u_int)w->eld[2] * 4);
+	mnl = w->eld[4] & 0x1f;
+	device_printf(dev,
+	    "ELD nid=%d: CEA_EDID_Ver=%u MNL=%u\n",
+	    w->nid, w->eld[4] >> 5, mnl);
+	sadc = w->eld[5] >> 4;
+	device_printf(dev,
+	    "ELD nid=%d: SAD_Count=%u Conn_Type=%u S_AI=%u HDCP=%u\n",
+	    w->nid, sadc, (w->eld[5] >> 2) & 0x3,
+	    (w->eld[5] >> 1) & 0x1, w->eld[5] & 0x1);
+	device_printf(dev,
+	    "ELD nid=%d: Aud_Synch_Delay=%ums\n",
+	    w->nid, w->eld[6] * 2);
+	device_printf(dev,
+	    "ELD nid=%d: Channels=0x%b\n",
+	    w->nid, w->eld[7],
+	    "\020\07RLRC\06FLRC\05RC\04RLR\03FC\02LFE\01FLR");
+	device_printf(dev,
+	    "ELD nid=%d: Port_ID=0x%02x%02x%02x%02x%02x%02x%02x%02x\n",
+	    w->nid, w->eld[8], w->eld[9], w->eld[10], w->eld[11],
+	    w->eld[12], w->eld[13], w->eld[14], w->eld[15]);
+	device_printf(dev,
+	    "ELD nid=%d: Manufacturer_Name=0x%02x%02x\n",
+	    w->nid, w->eld[16], w->eld[17]);
+	device_printf(dev,
+	    "ELD nid=%d: Product_Code=0x%02x%02x\n",
+	    w->nid, w->eld[18], w->eld[19]);
+	device_printf(dev,
+	    "ELD nid=%d: Monitor_Name_String='%.*s'\n",
+	    w->nid, mnl, &w->eld[20]);
+	for (i = 0; i < sadc; i++) {
+		sad = &w->eld[20 + mnl + i * 3];
+		fmt = (sad[0] >> 3) & 0x0f;
+		if (fmt == HDA_HDMI_CODING_TYPE_REF_CTX) {
+			fmt = (sad[2] >> 3) & 0x1f;
+			if (fmt < 1 || fmt > 3)
+				fmt = 0;
+			else
+				fmt += 14;
+		}
+		device_printf(dev,
+		    "ELD nid=%d: %s %dch freqs=0x%b",

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***


More information about the svn-src-all mailing list