| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: hdaudio.c,v 1.9.2.1 2020/12/28 20:18:09 martin Exp $ */ | | 1 | /* $NetBSD: hdaudio.c,v 1.9.2.2 2020/12/28 20:21:54 martin Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Copyright (c) 2009 Precedence Technologies Ltd <support@precedence.co.uk> | | 4 | * Copyright (c) 2009 Precedence Technologies Ltd <support@precedence.co.uk> |
5 | * Copyright (c) 2009 Jared D. McNeill <jmcneill@invisible.ca> | | 5 | * Copyright (c) 2009 Jared D. McNeill <jmcneill@invisible.ca> |
6 | * All rights reserved. | | 6 | * All rights reserved. |
7 | * | | 7 | * |
8 | * This code is derived from software contributed to The NetBSD Foundation | | 8 | * This code is derived from software contributed to The NetBSD Foundation |
9 | * by Precedence Technologies Ltd | | 9 | * by Precedence Technologies Ltd |
10 | * | | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | | 11 | * Redistribution and use in source and binary forms, with or without |
12 | * modification, are permitted provided that the following conditions | | 12 | * modification, are permitted provided that the following conditions |
13 | * are met: | | 13 | * are met: |
14 | * 1. Redistributions of source code must retain the above copyright | | 14 | * 1. Redistributions of source code must retain the above copyright |
| @@ -20,27 +20,27 @@ | | | @@ -20,27 +20,27 @@ |
20 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | | 20 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
21 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | | 21 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
22 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | | 22 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
23 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | | 23 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
24 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | | 24 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
25 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED | | 25 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
26 | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | | 26 | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
27 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | | 27 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
28 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | | 28 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
29 | * SUCH DAMAGE. | | 29 | * SUCH DAMAGE. |
30 | */ | | 30 | */ |
31 | | | 31 | |
32 | #include <sys/cdefs.h> | | 32 | #include <sys/cdefs.h> |
33 | __KERNEL_RCSID(0, "$NetBSD: hdaudio.c,v 1.9.2.1 2020/12/28 20:18:09 martin Exp $"); | | 33 | __KERNEL_RCSID(0, "$NetBSD: hdaudio.c,v 1.9.2.2 2020/12/28 20:21:54 martin Exp $"); |
34 | | | 34 | |
35 | #include <sys/types.h> | | 35 | #include <sys/types.h> |
36 | #include <sys/param.h> | | 36 | #include <sys/param.h> |
37 | #include <sys/systm.h> | | 37 | #include <sys/systm.h> |
38 | #include <sys/device.h> | | 38 | #include <sys/device.h> |
39 | #include <sys/conf.h> | | 39 | #include <sys/conf.h> |
40 | #include <sys/bus.h> | | 40 | #include <sys/bus.h> |
41 | #include <sys/kmem.h> | | 41 | #include <sys/kmem.h> |
42 | #include <sys/module.h> | | 42 | #include <sys/module.h> |
43 | | | 43 | |
44 | #include "hdaudiovar.h" | | 44 | #include "hdaudiovar.h" |
45 | #include "hdaudioreg.h" | | 45 | #include "hdaudioreg.h" |
46 | #include "hdaudioio.h" | | 46 | #include "hdaudioio.h" |
| @@ -703,53 +703,63 @@ hdaudio_attach_fg(struct hdaudio_functio | | | @@ -703,53 +703,63 @@ hdaudio_attach_fg(struct hdaudio_functio |
703 | prop_dictionary_set(args, "pin-config", config); | | 703 | prop_dictionary_set(args, "pin-config", config); |
704 | | | 704 | |
705 | locs[0] = fg->fg_nid; | | 705 | locs[0] = fg->fg_nid; |
706 | | | 706 | |
707 | fg->fg_device = config_found_sm_loc(sc->sc_dev, "hdaudiobus", | | 707 | fg->fg_device = config_found_sm_loc(sc->sc_dev, "hdaudiobus", |
708 | locs, args, hdaudio_config_print, config_stdsubmatch); | | 708 | locs, args, hdaudio_config_print, config_stdsubmatch); |
709 | | | 709 | |
710 | prop_object_release(args); | | 710 | prop_object_release(args); |
711 | } | | 711 | } |
712 | | | 712 | |
713 | static void | | 713 | static void |
714 | hdaudio_codec_attach(struct hdaudio_codec *co) | | 714 | hdaudio_codec_attach(struct hdaudio_codec *co) |
715 | { | | 715 | { |
| | | 716 | struct hdaudio_softc *sc = co->co_host; |
716 | struct hdaudio_function_group *fg; | | 717 | struct hdaudio_function_group *fg; |
717 | uint32_t vid, snc, fgrp; | | 718 | uint32_t vid, snc, fgrp; |
718 | int starting_node, num_nodes, nid; | | 719 | int starting_node, num_nodes, nid; |
719 | | | 720 | |
720 | if (co->co_valid == false) | | 721 | if (co->co_valid == false) |
721 | return; | | 722 | return; |
722 | | | 723 | |
723 | vid = hdaudio_command(co, 0, CORB_GET_PARAMETER, COP_VENDOR_ID); | | 724 | vid = hdaudio_command(co, 0, CORB_GET_PARAMETER, COP_VENDOR_ID); |
724 | snc = hdaudio_command(co, 0, CORB_GET_PARAMETER, | | 725 | snc = hdaudio_command(co, 0, CORB_GET_PARAMETER, |
725 | COP_SUBORDINATE_NODE_COUNT); | | 726 | COP_SUBORDINATE_NODE_COUNT); |
726 | | | 727 | |
727 | /* make sure the vendor and product IDs are valid */ | | 728 | /* make sure the vendor and product IDs are valid */ |
728 | if (vid == 0xffffffff || vid == 0x00000000) | | 729 | if (vid == 0xffffffff || vid == 0x00000000) |
729 | return; | | 730 | return; |
730 | | | 731 | |
731 | #ifdef HDAUDIO_DEBUG | | 732 | #ifdef HDAUDIO_DEBUG |
732 | struct hdaudio_softc *sc = co->co_host; | | | |
733 | uint32_t rid = hdaudio_command(co, 0, CORB_GET_PARAMETER, | | 733 | uint32_t rid = hdaudio_command(co, 0, CORB_GET_PARAMETER, |
734 | COP_REVISION_ID); | | 734 | COP_REVISION_ID); |
735 | hda_print(sc, "Codec%02X: %04X:%04X HDA %d.%d rev %d stepping %d\n", | | 735 | hda_print(sc, "Codec%02X: %04X:%04X HDA %d.%d rev %d stepping %d\n", |
736 | co->co_addr, vid >> 16, vid & 0xffff, | | 736 | co->co_addr, vid >> 16, vid & 0xffff, |
737 | (rid >> 20) & 0xf, (rid >> 16) & 0xf, | | 737 | (rid >> 20) & 0xf, (rid >> 16) & 0xf, |
738 | (rid >> 8) & 0xff, rid & 0xff); | | 738 | (rid >> 8) & 0xff, rid & 0xff); |
739 | #endif | | 739 | #endif |
740 | starting_node = (snc >> 16) & 0xff; | | 740 | starting_node = (snc >> 16) & 0xff; |
741 | num_nodes = snc & 0xff; | | 741 | num_nodes = snc & 0xff; |
742 | | | 742 | |
| | | 743 | /* |
| | | 744 | * If the total number of nodes is 0, there's nothing we can do. |
| | | 745 | * This shouldn't happen, so complain about it. |
| | | 746 | */ |
| | | 747 | if (num_nodes == 0) { |
| | | 748 | hda_error(sc, "Codec%02X: No subordinate nodes found (%08x)\n", |
| | | 749 | co->co_addr, snc); |
| | | 750 | return; |
| | | 751 | } |
| | | 752 | |
743 | co->co_nfg = num_nodes; | | 753 | co->co_nfg = num_nodes; |
744 | co->co_fg = kmem_zalloc(co->co_nfg * sizeof(*co->co_fg), KM_SLEEP); | | 754 | co->co_fg = kmem_zalloc(co->co_nfg * sizeof(*co->co_fg), KM_SLEEP); |
745 | | | 755 | |
746 | for (nid = starting_node; nid < starting_node + num_nodes; nid++) { | | 756 | for (nid = starting_node; nid < starting_node + num_nodes; nid++) { |
747 | fg = &co->co_fg[nid - starting_node]; | | 757 | fg = &co->co_fg[nid - starting_node]; |
748 | fg->fg_codec = co; | | 758 | fg->fg_codec = co; |
749 | fg->fg_nid = nid; | | 759 | fg->fg_nid = nid; |
750 | fg->fg_vendor = vid >> 16; | | 760 | fg->fg_vendor = vid >> 16; |
751 | fg->fg_product = vid & 0xffff; | | 761 | fg->fg_product = vid & 0xffff; |
752 | | | 762 | |
753 | fgrp = hdaudio_command(co, nid, CORB_GET_PARAMETER, | | 763 | fgrp = hdaudio_command(co, nid, CORB_GET_PARAMETER, |
754 | COP_FUNCTION_GROUP_TYPE); | | 764 | COP_FUNCTION_GROUP_TYPE); |
755 | switch (fgrp & 0xff) { | | 765 | switch (fgrp & 0xff) { |