From b6340fcd761acf9249b3acbc95c4dc555d9beb07 Mon Sep 17 00:00:00 2001 From: Venkat Yekkirala Date: Mon, 24 Jul 2006 23:28:37 -0700 Subject: [MLSXFRM]: Add security sid to flowi This adds security to flow key for labeling of flows as also to allow for making flow cache lookups based on the security label seemless. Signed-off-by: Venkat Yekkirala Signed-off-by: David S. Miller --- Documentation/networking/secid.txt | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 Documentation/networking/secid.txt (limited to 'Documentation') diff --git a/Documentation/networking/secid.txt b/Documentation/networking/secid.txt new file mode 100644 index 000000000000..95ea06784333 --- /dev/null +++ b/Documentation/networking/secid.txt @@ -0,0 +1,14 @@ +flowi structure: + +The secid member in the flow structure is used in LSMs (e.g. SELinux) to indicate +the label of the flow. This label of the flow is currently used in selecting +matching labeled xfrm(s). + +If this is an outbound flow, the label is derived from the socket, if any, or +the incoming packet this flow is being generated as a response to (e.g. tcp +resets, timewait ack, etc.). It is also conceivable that the label could be +derived from other sources such as process context, device, etc., in special +cases, as may be appropriate. + +If this is an inbound flow, the label is derived from the IPSec security +associations, if any, used by the packet. -- cgit v1.2.3-59-g8ed1b From 8802f616f6de8576805f32e47602816f141118f2 Mon Sep 17 00:00:00 2001 From: Paul Moore Date: Thu, 3 Aug 2006 16:45:49 -0700 Subject: [NetLabel]: documentation Documentation for the NetLabel system, this includes a basic overview of how NetLabel works, how LSM developers can integrate it into their favorite LSM, as well as documentation on the CIPSO related sysctl variables. Also, due to the difficulty of finding expired IETF drafts, I am including the IETF CIPSO draft that is the basis of the NetLabel CIPSO implementation. Signed-off-by: Paul Moore Signed-off-by: David S. Miller --- CREDITS | 7 + Documentation/00-INDEX | 2 + Documentation/netlabel/00-INDEX | 10 + Documentation/netlabel/cipso_ipv4.txt | 48 ++ .../netlabel/draft-ietf-cipso-ipsecurity-01.txt | 791 +++++++++++++++++++++ Documentation/netlabel/introduction.txt | 46 ++ Documentation/netlabel/lsm_interface.txt | 47 ++ Documentation/networking/ip-sysctl.txt | 35 + 8 files changed, 986 insertions(+) create mode 100644 Documentation/netlabel/00-INDEX create mode 100644 Documentation/netlabel/cipso_ipv4.txt create mode 100644 Documentation/netlabel/draft-ietf-cipso-ipsecurity-01.txt create mode 100644 Documentation/netlabel/introduction.txt create mode 100644 Documentation/netlabel/lsm_interface.txt (limited to 'Documentation') diff --git a/CREDITS b/CREDITS index 0fe904ebb7c7..cc3453a55fb9 100644 --- a/CREDITS +++ b/CREDITS @@ -2384,6 +2384,13 @@ N: Thomas Molina E: tmolina@cablespeed.com D: bug fixes, documentation, minor hackery +N: Paul Moore +E: paul.moore@hp.com +D: NetLabel author +S: Hewlett-Packard +S: 110 Spit Brook Road +S: Nashua, NH 03062 + N: James Morris E: jmorris@namei.org W: http://namei.org/ diff --git a/Documentation/00-INDEX b/Documentation/00-INDEX index 5f7f7d7f77d2..02457ec9c94f 100644 --- a/Documentation/00-INDEX +++ b/Documentation/00-INDEX @@ -184,6 +184,8 @@ mtrr.txt - how to use PPro Memory Type Range Registers to increase performance. nbd.txt - info on a TCP implementation of a network block device. +netlabel/ + - directory with information on the NetLabel subsystem. networking/ - directory with info on various aspects of networking with Linux. nfsroot.txt diff --git a/Documentation/netlabel/00-INDEX b/Documentation/netlabel/00-INDEX new file mode 100644 index 000000000000..837bf35990e2 --- /dev/null +++ b/Documentation/netlabel/00-INDEX @@ -0,0 +1,10 @@ +00-INDEX + - this file. +cipso_ipv4.txt + - documentation on the IPv4 CIPSO protocol engine. +draft-ietf-cipso-ipsecurity-01.txt + - IETF draft of the CIPSO protocol, dated 16 July 1992. +introduction.txt + - NetLabel introduction, READ THIS FIRST. +lsm_interface.txt + - documentation on the NetLabel kernel security module API. diff --git a/Documentation/netlabel/cipso_ipv4.txt b/Documentation/netlabel/cipso_ipv4.txt new file mode 100644 index 000000000000..93dacb132c3c --- /dev/null +++ b/Documentation/netlabel/cipso_ipv4.txt @@ -0,0 +1,48 @@ +NetLabel CIPSO/IPv4 Protocol Engine +============================================================================== +Paul Moore, paul.moore@hp.com + +May 17, 2006 + + * Overview + +The NetLabel CIPSO/IPv4 protocol engine is based on the IETF Commercial IP +Security Option (CIPSO) draft from July 16, 1992. A copy of this draft can be +found in this directory, consult '00-INDEX' for the filename. While the IETF +draft never made it to an RFC standard it has become a de-facto standard for +labeled networking and is used in many trusted operating systems. + + * Outbound Packet Processing + +The CIPSO/IPv4 protocol engine applies the CIPSO IP option to packets by +adding the CIPSO label to the socket. This causes all packets leaving the +system through the socket to have the CIPSO IP option applied. The socket's +CIPSO label can be changed at any point in time, however, it is recommended +that it is set upon the socket's creation. The LSM can set the socket's CIPSO +label by using the NetLabel security module API; if the NetLabel "domain" is +configured to use CIPSO for packet labeling then a CIPSO IP option will be +generated and attached to the socket. + + * Inbound Packet Processing + +The CIPSO/IPv4 protocol engine validates every CIPSO IP option it finds at the +IP layer without any special handling required by the LSM. However, in order +to decode and translate the CIPSO label on the packet the LSM must use the +NetLabel security module API to extract the security attributes of the packet. +This is typically done at the socket layer using the 'socket_sock_rcv_skb()' +LSM hook. + + * Label Translation + +The CIPSO/IPv4 protocol engine contains a mechanism to translate CIPSO security +attributes such as sensitivity level and category to values which are +appropriate for the host. These mappings are defined as part of a CIPSO +Domain Of Interpretation (DOI) definition and are configured through the +NetLabel user space communication layer. Each DOI definition can have a +different security attribute mapping table. + + * Label Translation Cache + +The NetLabel system provides a framework for caching security attribute +mappings from the network labels to the corresponding LSM identifiers. The +CIPSO/IPv4 protocol engine supports this caching mechanism. diff --git a/Documentation/netlabel/draft-ietf-cipso-ipsecurity-01.txt b/Documentation/netlabel/draft-ietf-cipso-ipsecurity-01.txt new file mode 100644 index 000000000000..256c2c9d4f50 --- /dev/null +++ b/Documentation/netlabel/draft-ietf-cipso-ipsecurity-01.txt @@ -0,0 +1,791 @@ +IETF CIPSO Working Group +16 July, 1992 + + + + COMMERCIAL IP SECURITY OPTION (CIPSO 2.2) + + + +1. Status + +This Internet Draft provides the high level specification for a Commercial +IP Security Option (CIPSO). This draft reflects the version as approved by +the CIPSO IETF Working Group. Distribution of this memo is unlimited. + +This document is an Internet Draft. Internet Drafts are working documents +of the Internet Engineering Task Force (IETF), its Areas, and its Working +Groups. Note that other groups may also distribute working documents as +Internet Drafts. + +Internet Drafts are draft documents valid for a maximum of six months. +Internet Drafts may be updated, replaced, or obsoleted by other documents +at any time. It is not appropriate to use Internet Drafts as reference +material or to cite them other than as a "working draft" or "work in +progress." + +Please check the I-D abstract listing contained in each Internet Draft +directory to learn the current status of this or any other Internet Draft. + + + + +2. Background + +Currently the Internet Protocol includes two security options. One of +these options is the DoD Basic Security Option (BSO) (Type 130) which allows +IP datagrams to be labeled with security classifications. This option +provides sixteen security classifications and a variable number of handling +restrictions. To handle additional security information, such as security +categories or compartments, another security option (Type 133) exists and +is referred to as the DoD Extended Security Option (ESO). The values for +the fixed fields within these two options are administered by the Defense +Information Systems Agency (DISA). + +Computer vendors are now building commercial operating systems with +mandatory access controls and multi-level security. These systems are +no longer built specifically for a particular group in the defense or +intelligence communities. They are generally available commercial systems +for use in a variety of government and civil sector environments. + +The small number of ESO format codes can not support all the possible +applications of a commercial security option. The BSO and ESO were +designed to only support the United States DoD. CIPSO has been designed +to support multiple security policies. This Internet Draft provides the +format and procedures required to support a Mandatory Access Control +security policy. Support for additional security policies shall be +defined in future RFCs. + + + + +Internet Draft, Expires 15 Jan 93 [PAGE 1] + + + +CIPSO INTERNET DRAFT 16 July, 1992 + + + + +3. CIPSO Format + +Option type: 134 (Class 0, Number 6, Copy on Fragmentation) +Option length: Variable + +This option permits security related information to be passed between +systems within a single Domain of Interpretation (DOI). A DOI is a +collection of systems which agree on the meaning of particular values +in the security option. An authority that has been assigned a DOI +identifier will define a mapping between appropriate CIPSO field values +and their human readable equivalent. This authority will distribute that +mapping to hosts within the authority's domain. These mappings may be +sensitive, therefore a DOI authority is not required to make these +mappings available to anyone other than the systems that are included in +the DOI. + +This option MUST be copied on fragmentation. This option appears at most +once in a datagram. All multi-octet fields in the option are defined to be +transmitted in network byte order. The format of this option is as follows: + ++----------+----------+------//------+-----------//---------+ +| 10000110 | LLLLLLLL | DDDDDDDDDDDD | TTTTTTTTTTTTTTTTTTTT | ++----------+----------+------//------+-----------//---------+ + + TYPE=134 OPTION DOMAIN OF TAGS + LENGTH INTERPRETATION + + + Figure 1. CIPSO Format + + +3.1 Type + +This field is 1 octet in length. Its value is 134. + + +3.2 Length + +This field is 1 octet in length. It is the total length of the option +including the type and length fields. With the current IP header length +restriction of 40 octets the value of this field MUST not exceed 40. + + +3.3 Domain of Interpretation Identifier + +This field is an unsigned 32 bit integer. The value 0 is reserved and MUST +not appear as the DOI identifier in any CIPSO option. Implementations +should assume that the DOI identifier field is not aligned on any particular +byte boundary. + +To conserve space in the protocol, security levels and categories are +represented by numbers rather than their ASCII equivalent. This requires +a mapping table within CIPSO hosts to map these numbers to their +corresponding ASCII representations. Non-related groups of systems may + + + +Internet Draft, Expires 15 Jan 93 [PAGE 2] + + + +CIPSO INTERNET DRAFT 16 July, 1992 + + + +have their own unique mappings. For example, one group of systems may +use the number 5 to represent Unclassified while another group may use the +number 1 to represent that same security level. The DOI identifier is used +to identify which mapping was used for the values within the option. + + +3.4 Tag Types + +A common format for passing security related information is necessary +for interoperability. CIPSO uses sets of "tags" to contain the security +information relevant to the data in the IP packet. Each tag begins with +a tag type identifier followed by the length of the tag and ends with the +actual security information to be passed. All multi-octet fields in a tag +are defined to be transmitted in network byte order. Like the DOI +identifier field in the CIPSO header, implementations should assume that +all tags, as well as fields within a tag, are not aligned on any particular +octet boundary. The tag types defined in this document contain alignment +bytes to assist alignment of some information, however alignment can not +be guaranteed if CIPSO is not the first IP option. + +CIPSO tag types 0 through 127 are reserved for defining standard tag +formats. Their definitions will be published in RFCs. Tag types whose +identifiers are greater than 127 are defined by the DOI authority and may +only be meaningful in certain Domains of Interpretation. For these tag +types, implementations will require the DOI identifier as well as the tag +number to determine the security policy and the format associated with the +tag. Use of tag types above 127 are restricted to closed networks where +interoperability with other networks will not be an issue. Implementations +that support a tag type greater than 127 MUST support at least one DOI that +requires only tag types 1 to 127. + +Tag type 0 is reserved. Tag types 1, 2, and 5 are defined in this +Internet Draft. Types 3 and 4 are reserved for work in progress. +The standard format for all current and future CIPSO tags is shown below: + ++----------+----------+--------//--------+ +| TTTTTTTT | LLLLLLLL | IIIIIIIIIIIIIIII | ++----------+----------+--------//--------+ + TAG TAG TAG + TYPE LENGTH INFORMATION + + Figure 2: Standard Tag Format + +In the three tag types described in this document, the length and count +restrictions are based on the current IP limitation of 40 octets for all +IP options. If the IP header is later expanded, then the length and count +restrictions specified in this document may increase to use the full area +provided for IP options. + + +3.4.1 Tag Type Classes + +Tag classes consist of tag types that have common processing requirements +and support the same security policy. The three tags defined in this +Internet Draft belong to the Mandatory Access Control (MAC) Sensitivity + + + +Internet Draft, Expires 15 Jan 93 [PAGE 3] + + + +CIPSO INTERNET DRAFT 16 July, 1992 + + + +class and support the MAC Sensitivity security policy. + + +3.4.2 Tag Type 1 + +This is referred to as the "bit-mapped" tag type. Tag type 1 is included +in the MAC Sensitivity tag type class. The format of this tag type is as +follows: + ++----------+----------+----------+----------+--------//---------+ +| 00000001 | LLLLLLLL | 00000000 | LLLLLLLL | CCCCCCCCCCCCCCCCC | ++----------+----------+----------+----------+--------//---------+ + + TAG TAG ALIGNMENT SENSITIVITY BIT MAP OF + TYPE LENGTH OCTET LEVEL CATEGORIES + + Figure 3. Tag Type 1 Format + + +3.4.2.1 Tag Type + +This field is 1 octet in length and has a value of 1. + + +3.4.2.2 Tag Length + +This field is 1 octet in length. It is the total length of the tag type +including the type and length fields. With the current IP header length +restriction of 40 bytes the value within this field is between 4 and 34. + + +3.4.2.3 Alignment Octet + +This field is 1 octet in length and always has the value of 0. Its purpose +is to align the category bitmap field on an even octet boundary. This will +speed many implementations including router implementations. + + +3.4.2.4 Sensitivity Level + +This field is 1 octet in length. Its value is from 0 to 255. The values +are ordered with 0 being the minimum value and 255 representing the maximum +value. + + +3.4.2.5 Bit Map of Categories + +The length of this field is variable and ranges from 0 to 30 octets. This +provides representation of categories 0 to 239. The ordering of the bits +is left to right or MSB to LSB. For example category 0 is represented by +the most significant bit of the first byte and category 15 is represented +by the least significant bit of the second byte. Figure 4 graphically +shows this ordering. Bit N is binary 1 if category N is part of the label +for the datagram, and bit N is binary 0 if category N is not part of the +label. Except for the optimized tag 1 format described in the next section, + + + +Internet Draft, Expires 15 Jan 93 [PAGE 4] + + + +CIPSO INTERNET DRAFT 16 July, 1992 + + + +minimal encoding SHOULD be used resulting in no trailing zero octets in the +category bitmap. + + octet 0 octet 1 octet 2 octet 3 octet 4 octet 5 + XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX . . . +bit 01234567 89111111 11112222 22222233 33333333 44444444 +number 012345 67890123 45678901 23456789 01234567 + + Figure 4. Ordering of Bits in Tag 1 Bit Map + + +3.4.2.6 Optimized Tag 1 Format + +Routers work most efficiently when processing fixed length fields. To +support these routers there is an optimized form of tag type 1. The format +does not change. The only change is to the category bitmap which is set to +a constant length of 10 octets. Trailing octets required to fill out the 10 +octets are zero filled. Ten octets, allowing for 80 categories, was chosen +because it makes the total length of the CIPSO option 20 octets. If CIPSO +is the only option then the option will be full word aligned and additional +filler octets will not be required. + + +3.4.3 Tag Type 2 + +This is referred to as the "enumerated" tag type. It is used to describe +large but sparsely populated sets of categories. Tag type 2 is in the MAC +Sensitivity tag type class. The format of this tag type is as follows: + ++----------+----------+----------+----------+-------------//-------------+ +| 00000010 | LLLLLLLL | 00000000 | LLLLLLLL | CCCCCCCCCCCCCCCCCCCCCCCCCC | ++----------+----------+----------+----------+-------------//-------------+ + + TAG TAG ALIGNMENT SENSITIVITY ENUMERATED + TYPE LENGTH OCTET LEVEL CATEGORIES + + Figure 5. Tag Type 2 Format + + +3.4.3.1 Tag Type + +This field is one octet in length and has a value of 2. + + +3.4.3.2 Tag Length + +This field is 1 octet in length. It is the total length of the tag type +including the type and length fields. With the current IP header length +restriction of 40 bytes the value within this field is between 4 and 34. + + +3.4.3.3 Alignment Octet + +This field is 1 octet in length and always has the value of 0. Its purpose +is to align the category field on an even octet boundary. This will + + + +Internet Draft, Expires 15 Jan 93 [PAGE 5] + + + +CIPSO INTERNET DRAFT 16 July, 1992 + + + +speed many implementations including router implementations. + + +3.4.3.4 Sensitivity Level + +This field is 1 octet in length. Its value is from 0 to 255. The values +are ordered with 0 being the minimum value and 255 representing the +maximum value. + + +3.4.3.5 Enumerated Categories + +In this tag, categories are represented by their actual value rather than +by their position within a bit field. The length of each category is 2 +octets. Up to 15 categories may be represented by this tag. Valid values +for categories are 0 to 65534. Category 65535 is not a valid category +value. The categories MUST be listed in ascending order within the tag. + + +3.4.4 Tag Type 5 + +This is referred to as the "range" tag type. It is used to represent +labels where all categories in a range, or set of ranges, are included +in the sensitivity label. Tag type 5 is in the MAC Sensitivity tag type +class. The format of this tag type is as follows: + ++----------+----------+----------+----------+------------//-------------+ +| 00000101 | LLLLLLLL | 00000000 | LLLLLLLL | Top/Bottom | Top/Bottom | ++----------+----------+----------+----------+------------//-------------+ + + TAG TAG ALIGNMENT SENSITIVITY CATEGORY RANGES + TYPE LENGTH OCTET LEVEL + + Figure 6. Tag Type 5 Format + + +3.4.4.1 Tag Type + +This field is one octet in length and has a value of 5. + + +3.4.4.2 Tag Length + +This field is 1 octet in length. It is the total length of the tag type +including the type and length fields. With the current IP header length +restriction of 40 bytes the value within this field is between 4 and 34. + + +3.4.4.3 Alignment Octet + +This field is 1 octet in length and always has the value of 0. Its purpose +is to align the category range field on an even octet boundary. This will +speed many implementations including router implementations. + + + + + +Internet Draft, Expires 15 Jan 93 [PAGE 6] + + + +CIPSO INTERNET DRAFT 16 July, 1992 + + + +3.4.4.4 Sensitivity Level + +This field is 1 octet in length. Its value is from 0 to 255. The values +are ordered with 0 being the minimum value and 255 representing the maximum +value. + + +3.4.4.5 Category Ranges + +A category range is a 4 octet field comprised of the 2 octet index of the +highest numbered category followed by the 2 octet index of the lowest +numbered category. These range endpoints are inclusive within the range of +categories. All categories within a range are included in the sensitivity +label. This tag may contain a maximum of 7 category pairs. The bottom +category endpoint for the last pair in the tag MAY be omitted and SHOULD be +assumed to be 0. The ranges MUST be non-overlapping and be listed in +descending order. Valid values for categories are 0 to 65534. Category +65535 is not a valid category value. + + +3.4.5 Minimum Requirements + +A CIPSO implementation MUST be capable of generating at least tag type 1 in +the non-optimized form. In addition, a CIPSO implementation MUST be able +to receive any valid tag type 1 even those using the optimized tag type 1 +format. + + +4. Configuration Parameters + +The configuration parameters defined below are required for all CIPSO hosts, +gateways, and routers that support multiple sensitivity labels. A CIPSO +host is defined to be the origination or destination system for an IP +datagram. A CIPSO gateway provides IP routing services between two or more +IP networks and may be required to perform label translations between +networks. A CIPSO gateway may be an enhanced CIPSO host or it may just +provide gateway services with no end system CIPSO capabilities. A CIPSO +router is a dedicated IP router that routes IP datagrams between two or more +IP networks. + +An implementation of CIPSO on a host MUST have the capability to reject a +datagram for reasons that the information contained can not be adequately +protected by the receiving host or if acceptance may result in violation of +the host or network security policy. In addition, a CIPSO gateway or router +MUST be able to reject datagrams going to networks that can not provide +adequate protection or may violate the network's security policy. To +provide this capability the following minimal set of configuration +parameters are required for CIPSO implementations: + +HOST_LABEL_MAX - This parameter contains the maximum sensitivity label that +a CIPSO host is authorized to handle. All datagrams that have a label +greater than this maximum MUST be rejected by the CIPSO host. This +parameter does not apply to CIPSO gateways or routers. This parameter need +not be defined explicitly as it can be implicitly derived from the +PORT_LABEL_MAX parameters for the associated interfaces. + + + +Internet Draft, Expires 15 Jan 93 [PAGE 7] + + + +CIPSO INTERNET DRAFT 16 July, 1992 + + + + +HOST_LABEL_MIN - This parameter contains the minimum sensitivity label that +a CIPSO host is authorized to handle. All datagrams that have a label less +than this minimum MUST be rejected by the CIPSO host. This parameter does +not apply to CIPSO gateways or routers. This parameter need not be defined +explicitly as it can be implicitly derived from the PORT_LABEL_MIN +parameters for the associated interfaces. + +PORT_LABEL_MAX - This parameter contains the maximum sensitivity label for +all datagrams that may exit a particular network interface port. All +outgoing datagrams that have a label greater than this maximum MUST be +rejected by the CIPSO system. The label within this parameter MUST be +less than or equal to the label within the HOST_LABEL_MAX parameter. This +parameter does not apply to CIPSO hosts that support only one network port. + +PORT_LABEL_MIN - This parameter contains the minimum sensitivity label for +all datagrams that may exit a particular network interface port. All +outgoing datagrams that have a label less than this minimum MUST be +rejected by the CIPSO system. The label within this parameter MUST be +greater than or equal to the label within the HOST_LABEL_MIN parameter. +This parameter does not apply to CIPSO hosts that support only one network +port. + +PORT_DOI - This parameter is used to assign a DOI identifier value to a +particular network interface port. All CIPSO labels within datagrams +going out this port MUST use the specified DOI identifier. All CIPSO +hosts and gateways MUST support either this parameter, the NET_DOI +parameter, or the HOST_DOI parameter. + +NET_DOI - This parameter is used to assign a DOI identifier value to a +particular IP network address. All CIPSO labels within datagrams destined +for the particular IP network MUST use the specified DOI identifier. All +CIPSO hosts and gateways MUST support either this parameter, the PORT_DOI +parameter, or the HOST_DOI parameter. + +HOST_DOI - This parameter is used to assign a DOI identifier value to a +particular IP host address. All CIPSO labels within datagrams destined for +the particular IP host will use the specified DOI identifier. All CIPSO +hosts and gateways MUST support either this parameter, the PORT_DOI +parameter, or the NET_DOI parameter. + +This list represents the minimal set of configuration parameters required +to be compliant. Implementors are encouraged to add to this list to +provide enhanced functionality and control. For example, many security +policies may require both incoming and outgoing datagrams be checked against +the port and host label ranges. + + +4.1 Port Range Parameters + +The labels represented by the PORT_LABEL_MAX and PORT_LABEL_MIN parameters +MAY be in CIPSO or local format. Some CIPSO systems, such as routers, may +want to have the range parameters expressed in CIPSO format so that incoming +labels do not have to be converted to a local format before being compared +against the range. If multiple DOIs are supported by one of these CIPSO + + + +Internet Draft, Expires 15 Jan 93 [PAGE 8] + + + +CIPSO INTERNET DRAFT 16 July, 1992 + + + +systems then multiple port range parameters would be needed, one set for +each DOI supported on a particular port. + +The port range will usually represent the total set of labels that may +exist on the logical network accessed through the corresponding network +interface. It may, however, represent a subset of these labels that are +allowed to enter the CIPSO system. + + +4.2 Single Label CIPSO Hosts + +CIPSO implementations that support only one label are not required to +support the parameters described above. These limited implementations are +only required to support a NET_LABEL parameter. This parameter contains +the CIPSO label that may be inserted in datagrams that exit the host. In +addition, the host MUST reject any incoming datagram that has a label which +is not equivalent to the NET_LABEL parameter. + + +5. Handling Procedures + +This section describes the processing requirements for incoming and +outgoing IP datagrams. Just providing the correct CIPSO label format +is not enough. Assumptions will be made by one system on how a +receiving system will handle the CIPSO label. Wrong assumptions may +lead to non-interoperability or even a security incident. The +requirements described below represent the minimal set needed for +interoperability and that provide users some level of confidence. +Many other requirements could be added to increase user confidence, +however at the risk of restricting creativity and limiting vendor +participation. + + +5.1 Input Procedures + +All datagrams received through a network port MUST have a security label +associated with them, either contained in the datagram or assigned to the +receiving port. Without this label the host, gateway, or router will not +have the information it needs to make security decisions. This security +label will be obtained from the CIPSO if the option is present in the +datagram. See section 4.1.2 for handling procedures for unlabeled +datagrams. This label will be compared against the PORT (if appropriate) +and HOST configuration parameters defined in section 3. + +If any field within the CIPSO option, such as the DOI identifier, is not +recognized the IP datagram is discarded and an ICMP "parameter problem" +(type 12) is generated and returned. The ICMP code field is set to "bad +parameter" (code 0) and the pointer is set to the start of the CIPSO field +that is unrecognized. + +If the contents of the CIPSO are valid but the security label is +outside of the configured host or port label range, the datagram is +discarded and an ICMP "destination unreachable" (type 3) is generated +and returned. The code field of the ICMP is set to "communication with +destination network administratively prohibited" (code 9) or to + + + +Internet Draft, Expires 15 Jan 93 [PAGE 9] + + + +CIPSO INTERNET DRAFT 16 July, 1992 + + + +"communication with destination host administratively prohibited" +(code 10). The value of the code field used is dependent upon whether +the originator of the ICMP message is acting as a CIPSO host or a CIPSO +gateway. The recipient of the ICMP message MUST be able to handle either +value. The same procedure is performed if a CIPSO can not be added to an +IP packet because it is too large to fit in the IP options area. + +If the error is triggered by receipt of an ICMP message, the message +is discarded and no response is permitted (consistent with general ICMP +processing rules). + + +5.1.1 Unrecognized tag types + +The default condition for any CIPSO implementation is that an +unrecognized tag type MUST be treated as a "parameter problem" and +handled as described in section 4.1. A CIPSO implementation MAY allow +the system administrator to identify tag types that may safely be +ignored. This capability is an allowable enhancement, not a +requirement. + + +5.1.2 Unlabeled Packets + +A network port may be configured to not require a CIPSO label for all +incoming datagrams. For this configuration a CIPSO label must be +assigned to that network port and associated with all unlabeled IP +datagrams. This capability might be used for single level networks or +networks that have CIPSO and non-CIPSO hosts and the non-CIPSO hosts +all operate at the same label. + +If a CIPSO option is required and none is found, the datagram is +discarded and an ICMP "parameter problem" (type 12) is generated and +returned to the originator of the datagram. The code field of the ICMP +is set to "option missing" (code 1) and the ICMP pointer is set to 134 +(the value of the option type for the missing CIPSO option). + + +5.2 Output Procedures + +A CIPSO option MUST appear only once in a datagram. Only one tag type +from the MAC Sensitivity class MAY be included in a CIPSO option. Given +the current set of defined tag types, this means that CIPSO labels at +first will contain only one tag. + +All datagrams leaving a CIPSO system MUST meet the following condition: + + PORT_LABEL_MIN <= CIPSO label <= PORT_LABEL_MAX + +If this condition is not satisfied the datagram MUST be discarded. +If the CIPSO system only supports one port, the HOST_LABEL_MIN and the +HOST_LABEL_MAX parameters MAY be substituted for the PORT parameters in +the above condition. + +The DOI identifier to be used for all outgoing datagrams is configured by + + + +Internet Draft, Expires 15 Jan 93 [PAGE 10] + + + +CIPSO INTERNET DRAFT 16 July, 1992 + + + +the administrator. If port level DOI identifier assignment is used, then +the PORT_DOI configuration parameter MUST contain the DOI identifier to +use. If network level DOI assignment is used, then the NET_DOI parameter +MUST contain the DOI identifier to use. And if host level DOI assignment +is employed, then the HOST_DOI parameter MUST contain the DOI identifier +to use. A CIPSO implementation need only support one level of DOI +assignment. + + +5.3 DOI Processing Requirements + +A CIPSO implementation MUST support at least one DOI and SHOULD support +multiple DOIs. System and network administrators are cautioned to +ensure that at least one DOI is common within an IP network to allow for +broadcasting of IP datagrams. + +CIPSO gateways MUST be capable of translating a CIPSO option from one +DOI to another when forwarding datagrams between networks. For +efficiency purposes this capability is only a desired feature for CIPSO +routers. + + +5.4 Label of ICMP Messages + +The CIPSO label to be used on all outgoing ICMP messages MUST be equivalent +to the label of the datagram that caused the ICMP message. If the ICMP was +generated due to a problem associated with the original CIPSO label then the +following responses are allowed: + + a. Use the CIPSO label of the original IP datagram + b. Drop the original datagram with no return message generated + +In most cases these options will have the same effect. If you can not +interpret the label or if it is outside the label range of your host or +interface then an ICMP message with the same label will probably not be +able to exit the system. + + +6. Assignment of DOI Identifier Numbers = + +Requests for assignment of a DOI identifier number should be addressed to +the Internet Assigned Numbers Authority (IANA). + + +7. Acknowledgements + +Much of the material in this RFC is based on (and copied from) work +done by Gary Winiger of Sun Microsystems and published as Commercial +IP Security Option at the INTEROP 89, Commercial IPSO Workshop. + + +8. Author's Address + +To submit mail for distribution to members of the IETF CIPSO Working +Group, send mail to: cipso@wdl1.wdl.loral.com. + + + +Internet Draft, Expires 15 Jan 93 [PAGE 11] + + + +CIPSO INTERNET DRAFT 16 July, 1992 + + + + +To be added to or deleted from this distribution, send mail to: +cipso-request@wdl1.wdl.loral.com. + + +9. References + +RFC 1038, "Draft Revised IP Security Option", M. St. Johns, IETF, January +1988. + +RFC 1108, "U.S. Department of Defense Security Options +for the Internet Protocol", Stephen Kent, IAB, 1 March, 1991. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Internet Draft, Expires 15 Jan 93 [PAGE 12] + + + diff --git a/Documentation/netlabel/introduction.txt b/Documentation/netlabel/introduction.txt new file mode 100644 index 000000000000..a4ffba1694c8 --- /dev/null +++ b/Documentation/netlabel/introduction.txt @@ -0,0 +1,46 @@ +NetLabel Introduction +============================================================================== +Paul Moore, paul.moore@hp.com + +August 2, 2006 + + * Overview + +NetLabel is a mechanism which can be used by kernel security modules to attach +security attributes to outgoing network packets generated from user space +applications and read security attributes from incoming network packets. It +is composed of three main components, the protocol engines, the communication +layer, and the kernel security module API. + + * Protocol Engines + +The protocol engines are responsible for both applying and retrieving the +network packet's security attributes. If any translation between the network +security attributes and those on the host are required then the protocol +engine will handle those tasks as well. Other kernel subsystems should +refrain from calling the protocol engines directly, instead they should use +the NetLabel kernel security module API described below. + +Detailed information about each NetLabel protocol engine can be found in this +directory, consult '00-INDEX' for filenames. + + * Communication Layer + +The communication layer exists to allow NetLabel configuration and monitoring +from user space. The NetLabel communication layer uses a message based +protocol built on top of the Generic NETLINK transport mechanism. The exact +formatting of these NetLabel messages as well as the Generic NETLINK family +names can be found in the the 'net/netlabel/' directory as comments in the +header files as well as in 'include/net/netlabel.h'. + + * Security Module API + +The purpose of the NetLabel security module API is to provide a protocol +independent interface to the underlying NetLabel protocol engines. In addition +to protocol independence, the security module API is designed to be completely +LSM independent which should allow multiple LSMs to leverage the same code +base. + +Detailed information about the NetLabel security module API can be found in the +'include/net/netlabel.h' header file as well as the 'lsm_interface.txt' file +found in this directory. diff --git a/Documentation/netlabel/lsm_interface.txt b/Documentation/netlabel/lsm_interface.txt new file mode 100644 index 000000000000..98dd9f7430f2 --- /dev/null +++ b/Documentation/netlabel/lsm_interface.txt @@ -0,0 +1,47 @@ +NetLabel Linux Security Module Interface +============================================================================== +Paul Moore, paul.moore@hp.com + +May 17, 2006 + + * Overview + +NetLabel is a mechanism which can set and retrieve security attributes from +network packets. It is intended to be used by LSM developers who want to make +use of a common code base for several different packet labeling protocols. +The NetLabel security module API is defined in 'include/net/netlabel.h' but a +brief overview is given below. + + * NetLabel Security Attributes + +Since NetLabel supports multiple different packet labeling protocols and LSMs +it uses the concept of security attributes to refer to the packet's security +labels. The NetLabel security attributes are defined by the +'netlbl_lsm_secattr' structure in the NetLabel header file. Internally the +NetLabel subsystem converts the security attributes to and from the correct +low-level packet label depending on the NetLabel build time and run time +configuration. It is up to the LSM developer to translate the NetLabel +security attributes into whatever security identifiers are in use for their +particular LSM. + + * NetLabel LSM Protocol Operations + +These are the functions which allow the LSM developer to manipulate the labels +on outgoing packets as well as read the labels on incoming packets. Functions +exist to operate both on sockets as well as the sk_buffs directly. These high +level functions are translated into low level protocol operations based on how +the administrator has configured the NetLabel subsystem. + + * NetLabel Label Mapping Cache Operations + +Depending on the exact configuration, translation between the network packet +label and the internal LSM security identifier can be time consuming. The +NetLabel label mapping cache is a caching mechanism which can be used to +sidestep much of this overhead once a mapping has been established. Once the +LSM has received a packet, used NetLabel to decode it's security attributes, +and translated the security attributes into a LSM internal identifier the LSM +can use the NetLabel caching functions to associate the LSM internal +identifier with the network packet's label. This means that in the future +when a incoming packet matches a cached value not only are the internal +NetLabel translation mechanisms bypassed but the LSM translation mechanisms are +bypassed as well which should result in a significant reduction in overhead. diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt index 90ed78110fd4..307cd4ec8edd 100644 --- a/Documentation/networking/ip-sysctl.txt +++ b/Documentation/networking/ip-sysctl.txt @@ -375,6 +375,41 @@ tcp_slow_start_after_idle - BOOLEAN be timed out after an idle period. Default: 1 +CIPSOv4 Variables: + +cipso_cache_enable - BOOLEAN + If set, enable additions to and lookups from the CIPSO label mapping + cache. If unset, additions are ignored and lookups always result in a + miss. However, regardless of the setting the cache is still + invalidated when required when means you can safely toggle this on and + off and the cache will always be "safe". + Default: 1 + +cipso_cache_bucket_size - INTEGER + The CIPSO label cache consists of a fixed size hash table with each + hash bucket containing a number of cache entries. This variable limits + the number of entries in each hash bucket; the larger the value the + more CIPSO label mappings that can be cached. When the number of + entries in a given hash bucket reaches this limit adding new entries + causes the oldest entry in the bucket to be removed to make room. + Default: 10 + +cipso_rbm_optfmt - BOOLEAN + Enable the "Optimized Tag 1 Format" as defined in section 3.4.2.6 of + the CIPSO draft specification (see Documentation/netlabel for details). + This means that when set the CIPSO tag will be padded with empty + categories in order to make the packet data 32-bit aligned. + Default: 0 + +cipso_rbm_structvalid - BOOLEAN + If set, do a very strict check of the CIPSO option when + ip_options_compile() is called. If unset, relax the checks done during + ip_options_compile(). Either way is "safe" as errors are caught else + where in the CIPSO processing code but setting this to 0 (False) should + result in less work (i.e. it should be faster) but could cause problems + with other implementations that require strict checking. + Default: 0 + IP Variables: ip_local_port_range - 2 INTEGERS -- cgit v1.2.3-59-g8ed1b From fbea49e1e2404baa2d88ab47e2db89e49551b53b Mon Sep 17 00:00:00 2001 From: YOSHIFUJI Hideaki Date: Fri, 22 Sep 2006 14:43:49 -0700 Subject: [IPV6] NDISC: Add proxy_ndp sysctl. We do not always need proxy NDP functionality even we enable forwarding. Signed-off-by: YOSHIFUJI Hideaki Signed-off-by: David S. Miller --- Documentation/networking/ip-sysctl.txt | 3 +++ include/linux/ipv6.h | 2 ++ include/linux/sysctl.h | 1 + net/ipv6/addrconf.c | 11 +++++++++++ net/ipv6/ip6_output.c | 4 +++- net/ipv6/ndisc.c | 8 +++++++- 6 files changed, 27 insertions(+), 2 deletions(-) (limited to 'Documentation') diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt index 307cd4ec8edd..935e298f674a 100644 --- a/Documentation/networking/ip-sysctl.txt +++ b/Documentation/networking/ip-sysctl.txt @@ -765,6 +765,9 @@ conf/all/forwarding - BOOLEAN This referred to as global forwarding. +proxy_ndp - BOOLEAN + Do proxy ndp. + conf/interface/*: Change special settings per interface. diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h index 1d6d3ccc9413..caca57df0d7d 100644 --- a/include/linux/ipv6.h +++ b/include/linux/ipv6.h @@ -176,6 +176,7 @@ struct ipv6_devconf { __s32 accept_ra_rt_info_max_plen; #endif #endif + __s32 proxy_ndp; void *sysctl; }; @@ -203,6 +204,7 @@ enum { DEVCONF_ACCEPT_RA_RTR_PREF, DEVCONF_RTR_PROBE_INTERVAL, DEVCONF_ACCEPT_RA_RT_INFO_MAX_PLEN, + DEVCONF_PROXY_NDP, DEVCONF_MAX }; diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h index af61d9235409..736ed917a4f8 100644 --- a/include/linux/sysctl.h +++ b/include/linux/sysctl.h @@ -556,6 +556,7 @@ enum { NET_IPV6_ACCEPT_RA_RTR_PREF=20, NET_IPV6_RTR_PROBE_INTERVAL=21, NET_IPV6_ACCEPT_RA_RT_INFO_MAX_PLEN=22, + NET_IPV6_PROXY_NDP=23, __NET_IPV6_MAX }; diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 1e5a296d0a82..825a291d5aa5 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -175,6 +175,7 @@ struct ipv6_devconf ipv6_devconf __read_mostly = { .accept_ra_rt_info_max_plen = 0, #endif #endif + .proxy_ndp = 0, }; static struct ipv6_devconf ipv6_devconf_dflt __read_mostly = { @@ -205,6 +206,7 @@ static struct ipv6_devconf ipv6_devconf_dflt __read_mostly = { .accept_ra_rt_info_max_plen = 0, #endif #endif + .proxy_ndp = 0, }; /* IPv6 Wildcard Address and Loopback Address defined by RFC2553 */ @@ -3337,6 +3339,7 @@ static void inline ipv6_store_devconf(struct ipv6_devconf *cnf, array[DEVCONF_ACCEPT_RA_RT_INFO_MAX_PLEN] = cnf->accept_ra_rt_info_max_plen; #endif #endif + array[DEVCONF_PROXY_NDP] = cnf->proxy_ndp; } /* Maximum length of ifinfomsg attributes */ @@ -3859,6 +3862,14 @@ static struct addrconf_sysctl_table }, #endif #endif + { + .ctl_name = NET_IPV6_PROXY_NDP, + .procname = "proxy_ndp", + .data = &ipv6_devconf.proxy_ndp, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec, + }, { .ctl_name = 0, /* sentinel */ } diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index b2be749d2217..66716911962e 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c @@ -412,7 +412,9 @@ int ip6_forward(struct sk_buff *skb) return -ETIMEDOUT; } - if (pneigh_lookup(&nd_tbl, &hdr->daddr, skb->dev, 0)) { + /* XXX: idev->cnf.proxy_ndp? */ + if (ipv6_devconf.proxy_ndp && + pneigh_lookup(&nd_tbl, &hdr->daddr, skb->dev, 0)) { int proxied = ip6_forward_proxy_check(skb); if (proxied > 0) return ip6_input(skb); diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index ddf038636f01..76517a5f6576 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c @@ -824,6 +824,7 @@ static void ndisc_recv_ns(struct sk_buff *skb) if (ipv6_chk_acast_addr(dev, &msg->target) || (idev->cnf.forwarding && + (ipv6_devconf.proxy_ndp || idev->cnf.proxy_ndp) && (pneigh = pneigh_lookup(&nd_tbl, &msg->target, dev, 0)) != NULL)) { if (!(NEIGH_CB(skb)->flags & LOCALLY_ENQUEUED) && @@ -966,8 +967,13 @@ static void ndisc_recv_na(struct sk_buff *skb) * has already sent a NA to us. */ if (lladdr && !memcmp(lladdr, dev->dev_addr, dev->addr_len) && - pneigh_lookup(&nd_tbl, &msg->target, dev, 0)) + ipv6_devconf.forwarding && ipv6_devconf.proxy_ndp && + pneigh_lookup(&nd_tbl, &msg->target, dev, 0)) { + /* XXX: idev->cnf.prixy_ndp */ + WARN_ON(skb->dst != NULL && + ((struct rt6_info *)skb->dst)->rt6i_idev); goto out; + } neigh_update(neigh, lladdr, msg->icmph.icmp6_solicited ? NUD_REACHABLE : NUD_STALE, -- cgit v1.2.3-59-g8ed1b From 2b29b13c5794f648cd5e839796496704d787f5a6 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 23 Jun 2006 14:38:26 +0200 Subject: [ALSA] Deprecate snd_card_free_in_thread() Deprecated snd_card_free_in_thread(), replaced with snd_card_free_when_closed(). Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- .../sound/alsa/DocBook/writing-an-alsa-driver.tmpl | 5 +- include/sound/core.h | 3 -- sound/core/init.c | 56 ++-------------------- sound/drivers/mpu401/mpu401.c | 2 +- sound/pcmcia/pdaudiocf/pdaudiocf.c | 2 +- sound/pcmcia/vx/vxpocket.c | 4 +- 6 files changed, 9 insertions(+), 63 deletions(-) (limited to 'Documentation') diff --git a/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl b/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl index b8dc51ca776c..4807ef79a94d 100644 --- a/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl +++ b/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl @@ -1054,9 +1054,8 @@ For a device which allows hotplugging, you can use - snd_card_free_in_thread. This one will - postpone the destruction and wait in a kernel-thread until all - devices are closed. + snd_card_free_when_closed. This one will + postpone the destruction until all devices are closed. diff --git a/include/sound/core.h b/include/sound/core.h index cf4001cf6248..1359c532b68e 100644 --- a/include/sound/core.h +++ b/include/sound/core.h @@ -25,7 +25,6 @@ #include /* wake_up() */ #include /* struct mutex */ #include /* struct rw_semaphore */ -#include /* struct workqueue_struct */ #include /* pm_message_t */ /* forward declarations */ @@ -132,7 +131,6 @@ struct snd_card { int shutdown; /* this card is going down */ int free_on_last_close; /* free in context of file_release */ wait_queue_head_t shutdown_sleep; - struct work_struct free_workq; /* for free in workqueue */ struct device *dev; #ifdef CONFIG_PM @@ -245,7 +243,6 @@ struct snd_card *snd_card_new(int idx, const char *id, int snd_card_disconnect(struct snd_card *card); int snd_card_free(struct snd_card *card); int snd_card_free_when_closed(struct snd_card *card); -int snd_card_free_in_thread(struct snd_card *card); int snd_card_register(struct snd_card *card); int snd_card_info_init(void); int snd_card_info_done(void); diff --git a/sound/core/init.c b/sound/core/init.c index 5850d99d21e3..d7607a25acdf 100644 --- a/sound/core/init.c +++ b/sound/core/init.c @@ -81,8 +81,6 @@ static inline int init_info_for_card(struct snd_card *card) #define init_info_for_card(card) #endif -static void snd_card_free_thread(void * __card); - /** * snd_card_new - create and initialize a soundcard structure * @idx: card index (address) [0 ... (SNDRV_CARDS-1)] @@ -145,7 +143,6 @@ struct snd_card *snd_card_new(int idx, const char *xid, INIT_LIST_HEAD(&card->ctl_files); spin_lock_init(&card->files_lock); init_waitqueue_head(&card->shutdown_sleep); - INIT_WORK(&card->free_workq, snd_card_free_thread, card); #ifdef CONFIG_PM mutex_init(&card->power_lock); init_waitqueue_head(&card->power_sleep); @@ -413,53 +410,6 @@ int snd_card_free(struct snd_card *card) EXPORT_SYMBOL(snd_card_free); -static void snd_card_free_thread(void * __card) -{ - struct snd_card *card = __card; - struct module * module = card->module; - - if (!try_module_get(module)) { - snd_printk(KERN_ERR "unable to lock toplevel module for card %i in free thread\n", card->number); - module = NULL; - } - - snd_card_free(card); - - module_put(module); -} - -/** - * snd_card_free_in_thread - call snd_card_free() in thread - * @card: soundcard structure - * - * This function schedules the call of snd_card_free() function in a - * work queue. When all devices are released (non-busy), the work - * is woken up and calls snd_card_free(). - * - * When a card can be disconnected at any time by hotplug service, - * this function should be used in disconnect (or detach) callback - * instead of calling snd_card_free() directly. - * - * Returns - zero otherwise a negative error code if the start of thread failed. - */ -int snd_card_free_in_thread(struct snd_card *card) -{ - if (card->files == NULL) { - snd_card_free(card); - return 0; - } - - if (schedule_work(&card->free_workq)) - return 0; - - snd_printk(KERN_ERR "schedule_work() failed in snd_card_free_in_thread for card %i\n", card->number); - /* try to free the structure immediately */ - snd_card_free(card); - return -EFAULT; -} - -EXPORT_SYMBOL(snd_card_free_in_thread); - static void choose_default_id(struct snd_card *card) { int i, len, idx_flag = 0, loops = SNDRV_CARDS; @@ -742,9 +692,9 @@ EXPORT_SYMBOL(snd_card_file_add); * * This function removes the file formerly added to the card via * snd_card_file_add() function. - * If all files are removed and the release of the card is - * scheduled, it will wake up the the thread to call snd_card_free() - * (see snd_card_free_in_thread() function). + * If all files are removed and snd_card_free_when_closed() was + * called beforehand, it processes the pending release of + * resources. * * Returns zero or a negative error code. */ diff --git a/sound/drivers/mpu401/mpu401.c b/sound/drivers/mpu401/mpu401.c index 17cc105b26fc..2de181ad0b05 100644 --- a/sound/drivers/mpu401/mpu401.c +++ b/sound/drivers/mpu401/mpu401.c @@ -211,7 +211,7 @@ static void __devexit snd_mpu401_pnp_remove(struct pnp_dev *dev) struct snd_card *card = (struct snd_card *) pnp_get_drvdata(dev); snd_card_disconnect(card); - snd_card_free_in_thread(card); + snd_card_free_when_closed(card); } static struct pnp_driver snd_mpu401_pnp_driver = { diff --git a/sound/pcmcia/pdaudiocf/pdaudiocf.c b/sound/pcmcia/pdaudiocf/pdaudiocf.c index 1c09e5f49da8..fd3590fcaedb 100644 --- a/sound/pcmcia/pdaudiocf/pdaudiocf.c +++ b/sound/pcmcia/pdaudiocf/pdaudiocf.c @@ -206,7 +206,7 @@ static void snd_pdacf_detach(struct pcmcia_device *link) snd_pdacf_powerdown(chip); chip->chip_status |= PDAUDIOCF_STAT_IS_STALE; /* to be sure */ snd_card_disconnect(chip->card); - snd_card_free_in_thread(chip->card); + snd_card_free_when_closed(chip->card); } /* diff --git a/sound/pcmcia/vx/vxpocket.c b/sound/pcmcia/vx/vxpocket.c index cafe6640cc1a..76c85cffb40e 100644 --- a/sound/pcmcia/vx/vxpocket.c +++ b/sound/pcmcia/vx/vxpocket.c @@ -65,7 +65,7 @@ static void vxpocket_release(struct pcmcia_device *link) } /* - * destructor, called from snd_card_free_in_thread() + * destructor, called from snd_card_free_when_closed() */ static int snd_vxpocket_dev_free(struct snd_device *device) { @@ -363,7 +363,7 @@ static void vxpocket_detach(struct pcmcia_device *link) chip->chip_status |= VX_STAT_IS_STALE; /* to be sure */ snd_card_disconnect(chip->card); vxpocket_release(link); - snd_card_free_in_thread(chip->card); + snd_card_free_when_closed(chip->card); } /* -- cgit v1.2.3-59-g8ed1b From 5a053d012d0576e9306009939ca81a86547ef35a Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 25 Jul 2006 14:51:15 +0200 Subject: [ALSA] Add model entry for Clevo m665n laptop Added the proper model entry for Clevo m665n laptop with ALC880 codec. Also, added a model string 'clevo' to enable the clevo-type model option. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- Documentation/sound/alsa/ALSA-Configuration.txt | 1 + sound/pci/hda/patch_realtek.c | 9 +++++++-- 2 files changed, 8 insertions(+), 2 deletions(-) (limited to 'Documentation') diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt index f61af23dd85d..74ea66d33cf9 100644 --- a/Documentation/sound/alsa/ALSA-Configuration.txt +++ b/Documentation/sound/alsa/ALSA-Configuration.txt @@ -783,6 +783,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. F1734 2-jack lg LG laptop (m1 express dual) lg-lw LG LW20 laptop + clevo Clevo laptops (m520G, m665n) test for testing/debugging purpose, almost all controls can be adjusted. Appearing only when compiled with $CONFIG_SND_DEBUG=y diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 18d105263fea..f4c96aa43be7 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -2156,8 +2156,13 @@ static struct hda_board_config alc880_cfg_tbl[] = { { .modelname = "3stack-digout", .config = ALC880_3ST_DIG }, { .pci_subvendor = 0x8086, .pci_subdevice = 0xe308, .config = ALC880_3ST_DIG }, { .pci_subvendor = 0x1025, .pci_subdevice = 0x0070, .config = ALC880_3ST_DIG }, - /* Clevo m520G NB */ - { .pci_subvendor = 0x1558, .pci_subdevice = 0x0520, .config = ALC880_CLEVO }, + + /* Clevo laptops */ + { .modelname = "clevo", .config = ALC880_CLEVO }, + { .pci_subvendor = 0x1558, .pci_subdevice = 0x0520, + .config = ALC880_CLEVO }, /* Clevo m520G NB */ + { .pci_subvendor = 0x1558, .pci_subdevice = 0x0660, + .config = ALC880_CLEVO }, /* Clevo m665n */ /* Back 3 jack plus 1 SPDIF out jack, front 2 jack (Internal add Aux-In)*/ { .pci_subvendor = 0x8086, .pci_subdevice = 0xe305, .config = ALC880_3ST_DIG }, -- cgit v1.2.3-59-g8ed1b From 6d177ba7839dd7ed391c2f36b121eb09d1eaee4c Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 25 Jul 2006 14:51:15 +0200 Subject: [ALSA] Add hp-bpc model type for HP laptops Added 'hp-bpc' model type for HP xw4400-compatible laptops. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- Documentation/sound/alsa/ALSA-Configuration.txt | 1 + sound/pci/hda/patch_realtek.c | 1 + 2 files changed, 2 insertions(+) (limited to 'Documentation') diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt index 74ea66d33cf9..c595acb3bf80 100644 --- a/Documentation/sound/alsa/ALSA-Configuration.txt +++ b/Documentation/sound/alsa/ALSA-Configuration.txt @@ -798,6 +798,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. ALC262 fujitsu Fujitsu Laptop + hp-bpc HP xw4400/6400/8400/9400 laptops basic fixed pin assignment w/o SPDIF auto auto-config reading BIOS (default) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index f4c96aa43be7..51f76eef9353 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -5774,6 +5774,7 @@ static struct hda_board_config alc262_cfg_tbl[] = { { .modelname = "fujitsu", .config = ALC262_FUJITSU }, { .pci_subvendor = 0x10cf, .pci_subdevice = 0x1397, .config = ALC262_FUJITSU }, + { .modelname = "hp-bpc", .config = ALC262_HP_BPC }, { .pci_subvendor = 0x103c, .pci_subdevice = 0x208c, .config = ALC262_HP_BPC }, /* xw4400 */ { .pci_subvendor = 0x103c, .pci_subdevice = 0x3014, -- cgit v1.2.3-59-g8ed1b From 304dcaac91f0d26543b31fd7e63726f096c826ee Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 25 Jul 2006 14:51:16 +0200 Subject: [ALSA] Add support of Benq laptop with ALC262 Added the support of Benq laptop with ALC262 codec. A model string 'benq' is added, too. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- Documentation/sound/alsa/ALSA-Configuration.txt | 1 + sound/pci/hda/patch_realtek.c | 21 +++++++++++++++++++++ 2 files changed, 22 insertions(+) (limited to 'Documentation') diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt index c595acb3bf80..885d2ed88fd0 100644 --- a/Documentation/sound/alsa/ALSA-Configuration.txt +++ b/Documentation/sound/alsa/ALSA-Configuration.txt @@ -799,6 +799,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. ALC262 fujitsu Fujitsu Laptop hp-bpc HP xw4400/6400/8400/9400 laptops + benq Benq ED8 basic fixed pin assignment w/o SPDIF auto auto-config reading BIOS (default) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 51f76eef9353..42c4f90a92b8 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -79,6 +79,7 @@ enum { ALC262_BASIC, ALC262_FUJITSU, ALC262_HP_BPC, + ALC262_BENQ_ED8, ALC262_AUTO, ALC262_MODEL_LAST /* last tag */ }; @@ -5504,6 +5505,13 @@ static struct snd_kcontrol_new alc262_fujitsu_mixer[] = { { } /* end */ }; +/* additional init verbs for Benq laptops */ +static struct hda_verb alc262_EAPD_verbs[] = { + {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, + {0x20, AC_VERB_SET_PROC_COEF, 0x3070}, + {} +}; + /* add playback controls from the parsed DAC table */ static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec, const struct auto_pin_cfg *cfg) { @@ -5783,6 +5791,9 @@ static struct hda_board_config alc262_cfg_tbl[] = { .config = ALC262_HP_BPC }, /* xw8400 */ { .pci_subvendor = 0x103c, .pci_subdevice = 0x12fe, .config = ALC262_HP_BPC }, /* xw9400 */ + { .modelname = "benq", .config = ALC262_BENQ_ED8 }, + { .pci_subvendor = 0x17ff, .pci_subdevice = 0x0560, + .config = ALC262_BENQ_ED8 }, { .modelname = "auto", .config = ALC262_AUTO }, {} }; @@ -5820,6 +5831,16 @@ static struct alc_config_preset alc262_presets[] = { .channel_mode = alc262_modes, .input_mux = &alc262_HP_capture_source, }, + [ALC262_BENQ_ED8] = { + .mixers = { alc262_base_mixer }, + .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs }, + .num_dacs = ARRAY_SIZE(alc262_dac_nids), + .dac_nids = alc262_dac_nids, + .hp_nid = 0x03, + .num_channel_mode = ARRAY_SIZE(alc262_modes), + .channel_mode = alc262_modes, + .input_mux = &alc262_capture_source, + }, }; static int patch_alc262(struct hda_codec *codec) -- cgit v1.2.3-59-g8ed1b From 68ab801e32bbe2caac8b8c6e6e94f41fe7d687ad Mon Sep 17 00:00:00 2001 From: Matthias Koenig Date: Thu, 27 Jul 2006 16:59:23 +0200 Subject: [ALSA] Add snd-mts64 driver for ESI Miditerminal 4140 Added snd-mts64 driver for Ego Systems (ESI) Miditerminal 4140 by Matthias Koenig . The driver requires parport (CONFIG_PARPORT). Signed-off-by: Matthias Koenig Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- Documentation/sound/alsa/ALSA-Configuration.txt | 8 + sound/drivers/Kconfig | 13 + sound/drivers/Makefile | 2 + sound/drivers/mts64.c | 1091 +++++++++++++++++++++++ 4 files changed, 1114 insertions(+) create mode 100644 sound/drivers/mts64.c (limited to 'Documentation') diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt index 885d2ed88fd0..7344815b855e 100644 --- a/Documentation/sound/alsa/ALSA-Configuration.txt +++ b/Documentation/sound/alsa/ALSA-Configuration.txt @@ -1216,6 +1216,14 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. Module supports only 1 card. This module has no enable option. + Module snd-mts64 + ---------------- + + Module for Ego Systems (ESI) Miditerminal 4140 + + This module supports multiple devices. + Requires parport (CONFIG_PARPORT). + Module snd-nm256 ---------------- diff --git a/sound/drivers/Kconfig b/sound/drivers/Kconfig index 897dc2dfd7dd..952c7f170101 100644 --- a/sound/drivers/Kconfig +++ b/sound/drivers/Kconfig @@ -73,6 +73,19 @@ config SND_MTPAV To compile this driver as a module, choose M here: the module will be called snd-mtpav. +config SND_MTS64 + tristate "ESI Miditerminal 4140 driver" + depends on SND && PARPORT + select SND_RAWMIDI + help + The ESI Miditerminal 4140 is a 4 In 4 Out MIDI Interface with + additional SMPTE Timecode capabilities for the parallel port. + + Say 'Y' to include support for this device. + + To compile this driver as a module, chose 'M' here: the module + will be called snd-mts64. + config SND_SERIAL_U16550 tristate "UART16550 serial MIDI driver" depends on SND diff --git a/sound/drivers/Makefile b/sound/drivers/Makefile index cb98c3d662be..c9bad6d67e73 100644 --- a/sound/drivers/Makefile +++ b/sound/drivers/Makefile @@ -5,6 +5,7 @@ snd-dummy-objs := dummy.o snd-mtpav-objs := mtpav.o +snd-mts64-objs := mts64.o snd-serial-u16550-objs := serial-u16550.o snd-virmidi-objs := virmidi.o @@ -13,5 +14,6 @@ obj-$(CONFIG_SND_DUMMY) += snd-dummy.o obj-$(CONFIG_SND_VIRMIDI) += snd-virmidi.o obj-$(CONFIG_SND_SERIAL_U16550) += snd-serial-u16550.o obj-$(CONFIG_SND_MTPAV) += snd-mtpav.o +obj-$(CONFIG_SND_MTS64) += snd-mts64.o obj-$(CONFIG_SND) += opl3/ opl4/ mpu401/ vx/ diff --git a/sound/drivers/mts64.c b/sound/drivers/mts64.c new file mode 100644 index 000000000000..169987302ae4 --- /dev/null +++ b/sound/drivers/mts64.c @@ -0,0 +1,1091 @@ +/* + * ALSA Driver for Ego Systems Inc. (ESI) Miditerminal 4140 + * Copyright (c) 2006 by Matthias König + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define CARD_NAME "Miditerminal 4140" +#define DRIVER_NAME "MTS64" +#define PLATFORM_DRIVER "snd_mts64" + +static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; +static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; +static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; + +static struct platform_device *platform_devices[SNDRV_CARDS]; +static int device_count; + +module_param_array(index, int, NULL, S_IRUGO); +MODULE_PARM_DESC(index, "Index value for " CARD_NAME " soundcard."); +module_param_array(id, charp, NULL, S_IRUGO); +MODULE_PARM_DESC(id, "ID string for " CARD_NAME " soundcard."); +module_param_array(enable, bool, NULL, S_IRUGO); +MODULE_PARM_DESC(enable, "Enable " CARD_NAME " soundcard."); + +MODULE_AUTHOR("Matthias Koenig "); +MODULE_DESCRIPTION("ESI Miditerminal 4140"); +MODULE_LICENSE("GPL"); +MODULE_SUPPORTED_DEVICE("{{ESI,Miditerminal 4140}}"); + +/********************************************************************* + * Chip specific + *********************************************************************/ +#define MTS64_NUM_INPUT_PORTS 5 +#define MTS64_NUM_OUTPUT_PORTS 4 +#define MTS64_SMPTE_SUBSTREAM 4 + +struct mts64 { + spinlock_t lock; + struct snd_card *card; + struct snd_rawmidi *rmidi; + struct pardevice *pardev; + int pardev_claimed; + + int open_count; + int current_midi_output_port; + int current_midi_input_port; + u8 mode[MTS64_NUM_INPUT_PORTS]; + struct snd_rawmidi_substream *midi_input_substream[MTS64_NUM_INPUT_PORTS]; + int smpte_switch; + u8 time[4]; /* [0]=hh, [1]=mm, [2]=ss, [3]=ff */ + u8 fps; +}; + +static int snd_mts64_free(struct mts64 *mts) +{ + kfree(mts); + return 0; +} + +static int __devinit snd_mts64_create(struct snd_card *card, + struct pardevice *pardev, + struct mts64 **rchip) +{ + struct mts64 *mts; + + *rchip = NULL; + + mts = kzalloc(sizeof(struct mts64), GFP_KERNEL); + if (mts == NULL) + return -ENOMEM; + + /* Init chip specific data */ + spin_lock_init(&mts->lock); + mts->card = card; + mts->pardev = pardev; + mts->current_midi_output_port = -1; + mts->current_midi_input_port = -1; + + *rchip = mts; + + return 0; +} + +/********************************************************************* + * HW register related constants + *********************************************************************/ + +/* Status Bits */ +#define MTS64_STAT_BSY 0x80 +#define MTS64_STAT_BIT_SET 0x20 /* readout process, bit is set */ +#define MTS64_STAT_PORT 0x10 /* read byte is a port number */ + +/* Control Bits */ +#define MTS64_CTL_READOUT 0x08 /* enable readout */ +#define MTS64_CTL_WRITE_CMD 0x06 +#define MTS64_CTL_WRITE_DATA 0x02 +#define MTS64_CTL_STROBE 0x01 + +/* Command */ +#define MTS64_CMD_RESET 0xfe +#define MTS64_CMD_PROBE 0x8f /* Used in probing procedure */ +#define MTS64_CMD_SMPTE_SET_TIME 0xe8 +#define MTS64_CMD_SMPTE_SET_FPS 0xee +#define MTS64_CMD_SMPTE_STOP 0xef +#define MTS64_CMD_SMPTE_FPS_24 0xe3 +#define MTS64_CMD_SMPTE_FPS_25 0xe2 +#define MTS64_CMD_SMPTE_FPS_2997 0xe4 +#define MTS64_CMD_SMPTE_FPS_30D 0xe1 +#define MTS64_CMD_SMPTE_FPS_30 0xe0 +#define MTS64_CMD_COM_OPEN 0xf8 /* setting the communication mode */ +#define MTS64_CMD_COM_CLOSE1 0xff /* clearing communication mode */ +#define MTS64_CMD_COM_CLOSE2 0xf5 + +/********************************************************************* + * Hardware specific functions + *********************************************************************/ +static void mts64_enable_readout(struct parport *p); +static void mts64_disable_readout(struct parport *p); +static int mts64_device_ready(struct parport *p); +static int mts64_device_init(struct parport *p); +static int mts64_device_open(struct mts64 *mts); +static int mts64_device_close(struct mts64 *mts); +static u8 mts64_map_midi_input(u8 c); +static int mts64_probe(struct parport *p); +static u16 mts64_read(struct parport *p); +static u8 mts64_read_char(struct parport *p); +static void mts64_smpte_start(struct parport *p, + u8 hours, u8 minutes, + u8 seconds, u8 frames, + u8 idx); +static void mts64_smpte_stop(struct parport *p); +static void mts64_write_command(struct parport *p, u8 c); +static void mts64_write_data(struct parport *p, u8 c); +static void mts64_write_midi(struct mts64 *mts, u8 c, int midiport); + + +/* Enables the readout procedure + * + * Before we can read a midi byte from the device, we have to set + * bit 3 of control port. + */ +static void mts64_enable_readout(struct parport *p) +{ + u8 c; + + c = parport_read_control(p); + c |= MTS64_CTL_READOUT; + parport_write_control(p, c); +} + +/* Disables readout + * + * Readout is disabled by clearing bit 3 of control + */ +static void mts64_disable_readout(struct parport *p) +{ + u8 c; + + c = parport_read_control(p); + c &= ~MTS64_CTL_READOUT; + parport_write_control(p, c); +} + +/* waits for device ready + * + * Checks if BUSY (Bit 7 of status) is clear + * 1 device ready + * 0 failure + */ +static int mts64_device_ready(struct parport *p) +{ + int i; + u8 c; + + for (i = 0; i < 0xffff; ++i) { + c = parport_read_status(p); + c &= MTS64_STAT_BSY; + if (c != 0) + return 1; + } + + return 0; +} + +/* Init device (LED blinking startup magic) + * + * Returns: + * 0 init ok + * -EIO failure + */ +static int __devinit mts64_device_init(struct parport *p) +{ + int i; + + mts64_write_command(p, MTS64_CMD_RESET); + + for (i = 0; i < 64; ++i) { + msleep(100); + + if (mts64_probe(p) == 0) { + /* success */ + mts64_disable_readout(p); + return 0; + } + } + mts64_disable_readout(p); + + return -EIO; +} + +/* + * Opens the device (set communication mode) + */ +static int mts64_device_open(struct mts64 *mts) +{ + int i; + struct parport *p = mts->pardev->port; + + for (i = 0; i < 5; ++i) + mts64_write_command(p, MTS64_CMD_COM_OPEN); + + return 0; +} + +/* + * Close device (clear communication mode) + */ +static int mts64_device_close(struct mts64 *mts) +{ + int i; + struct parport *p = mts->pardev->port; + + for (i = 0; i < 5; ++i) { + mts64_write_command(p, MTS64_CMD_COM_CLOSE1); + mts64_write_command(p, MTS64_CMD_COM_CLOSE2); + } + + return 0; +} + +/* map hardware port to substream number + * + * When reading a byte from the device, the device tells us + * on what port the byte is. This HW port has to be mapped to + * the midiport (substream number). + * substream 0-3 are Midiports 1-4 + * substream 4 is SMPTE Timecode + * The mapping is done by the table: + * HW | 0 | 1 | 2 | 3 | 4 + * SW | 0 | 1 | 4 | 2 | 3 + */ +static u8 mts64_map_midi_input(u8 c) +{ + static u8 map[] = { 0, 1, 4, 2, 3 }; + + return map[c]; +} + + +/* Probe parport for device + * + * Do we have a Miditerminal 4140 on parport? + * Returns: + * 0 device found + * -ENODEV no device + */ +static int __devinit mts64_probe(struct parport *p) +{ + u8 c; + + mts64_smpte_stop(p); + mts64_write_command(p, MTS64_CMD_PROBE); + + msleep(50); + + c = mts64_read(p); + + c &= 0x00ff; + if (c != MTS64_CMD_PROBE) + return -ENODEV; + else + return 0; + +} + +/* Read byte incl. status from device + * + * Returns: + * data in lower 8 bits and status in upper 8 bits + */ +static u16 mts64_read(struct parport *p) +{ + u8 data, status; + + mts64_device_ready(p); + mts64_enable_readout(p); + status = parport_read_status(p); + data = mts64_read_char(p); + mts64_disable_readout(p); + + return (status << 8) | data; +} + +/* Read a byte from device + * + * Note, that readout mode has to be enabled. + * readout procedure is as follows: + * - Write number of the Bit to read to DATA + * - Read STATUS + * - Bit 5 of STATUS indicates if Bit is set + * + * Returns: + * Byte read from device + */ +static u8 mts64_read_char(struct parport *p) +{ + u8 c = 0; + u8 status; + u8 i; + + for (i = 0; i < 8; ++i) { + parport_write_data(p, i); + c >>= 1; + status = parport_read_status(p); + if (status & MTS64_STAT_BIT_SET) + c |= 0x80; + } + + return c; +} + +/* Starts SMPTE Timecode generation + * + * The device creates SMPTE Timecode by hardware. + * 0 24 fps + * 1 25 fps + * 2 29.97 fps + * 3 30 fps (Drop-frame) + * 4 30 fps + */ +static void mts64_smpte_start(struct parport *p, + u8 hours, u8 minutes, + u8 seconds, u8 frames, + u8 idx) +{ + static u8 fps[5] = { MTS64_CMD_SMPTE_FPS_24, + MTS64_CMD_SMPTE_FPS_25, + MTS64_CMD_SMPTE_FPS_2997, + MTS64_CMD_SMPTE_FPS_30D, + MTS64_CMD_SMPTE_FPS_30 }; + + mts64_write_command(p, MTS64_CMD_SMPTE_SET_TIME); + mts64_write_command(p, frames); + mts64_write_command(p, seconds); + mts64_write_command(p, minutes); + mts64_write_command(p, hours); + + mts64_write_command(p, MTS64_CMD_SMPTE_SET_FPS); + mts64_write_command(p, fps[idx]); +} + +/* Stops SMPTE Timecode generation + */ +static void mts64_smpte_stop(struct parport *p) +{ + mts64_write_command(p, MTS64_CMD_SMPTE_STOP); +} + +/* Write a command byte to device + */ +static void mts64_write_command(struct parport *p, u8 c) +{ + mts64_device_ready(p); + + parport_write_data(p, c); + + parport_write_control(p, MTS64_CTL_WRITE_CMD); + parport_write_control(p, MTS64_CTL_WRITE_CMD | MTS64_CTL_STROBE); + parport_write_control(p, MTS64_CTL_WRITE_CMD); +} + +/* Write a data byte to device + */ +static void mts64_write_data(struct parport *p, u8 c) +{ + mts64_device_ready(p); + + parport_write_data(p, c); + + parport_write_control(p, MTS64_CTL_WRITE_DATA); + parport_write_control(p, MTS64_CTL_WRITE_DATA | MTS64_CTL_STROBE); + parport_write_control(p, MTS64_CTL_WRITE_DATA); +} + +/* Write a MIDI byte to midiport + * + * midiport ranges from 0-3 and maps to Ports 1-4 + * assumptions: communication mode is on + */ +static void mts64_write_midi(struct mts64 *mts, u8 c, + int midiport) +{ + struct parport *p = mts->pardev->port; + + /* check current midiport */ + if (mts->current_midi_output_port != midiport) + mts64_write_command(p, midiport); + + /* write midi byte */ + mts64_write_data(p, c); +} + +/********************************************************************* + * Control elements + *********************************************************************/ + +/* SMPTE Switch */ +static int snd_mts64_ctl_smpte_switch_info(struct snd_kcontrol *kctl, + struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; + uinfo->count = 1; + uinfo->value.integer.min = 0; + uinfo->value.integer.max = 1; + return 0; +} + +static int snd_mts64_ctl_smpte_switch_get(struct snd_kcontrol* kctl, + struct snd_ctl_elem_value *uctl) +{ + struct mts64 *mts = snd_kcontrol_chip(kctl); + + spin_lock_irq(&mts->lock); + uctl->value.integer.value[0] = mts->smpte_switch; + spin_unlock_irq(&mts->lock); + + return 0; +} + +/* smpte_switch is not accessed from IRQ handler, so we just need + to protect the HW access */ +static int snd_mts64_ctl_smpte_switch_put(struct snd_kcontrol* kctl, + struct snd_ctl_elem_value *uctl) +{ + struct mts64 *mts = snd_kcontrol_chip(kctl); + int changed = 0; + + spin_lock_irq(&mts->lock); + if (mts->smpte_switch == uctl->value.integer.value[0]) + goto __out; + + changed = 1; + mts->smpte_switch = uctl->value.integer.value[0]; + if (mts->smpte_switch) { + mts64_smpte_start(mts->pardev->port, + mts->time[0], mts->time[1], + mts->time[2], mts->time[3], + mts->fps); + } else { + mts64_smpte_stop(mts->pardev->port); + } +__out: + spin_unlock_irq(&mts->lock); + return changed; +} + +static struct snd_kcontrol_new mts64_ctl_smpte_switch __devinitdata = { + .iface = SNDRV_CTL_ELEM_IFACE_RAWMIDI, + .name = "SMPTE Playback Switch", + .index = 0, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .private_value = 0, + .info = snd_mts64_ctl_smpte_switch_info, + .get = snd_mts64_ctl_smpte_switch_get, + .put = snd_mts64_ctl_smpte_switch_put +}; + +/* Time */ +static int snd_mts64_ctl_smpte_time_h_info(struct snd_kcontrol *kctl, + struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->count = 1; + uinfo->value.integer.min = 0; + uinfo->value.integer.max = 23; + return 0; +} + +static int snd_mts64_ctl_smpte_time_f_info(struct snd_kcontrol *kctl, + struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->count = 1; + uinfo->value.integer.min = 0; + uinfo->value.integer.max = 99; + return 0; +} + +static int snd_mts64_ctl_smpte_time_info(struct snd_kcontrol *kctl, + struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->count = 1; + uinfo->value.integer.min = 0; + uinfo->value.integer.max = 59; + return 0; +} + +static int snd_mts64_ctl_smpte_time_get(struct snd_kcontrol *kctl, + struct snd_ctl_elem_value *uctl) +{ + struct mts64 *mts = snd_kcontrol_chip(kctl); + int idx = kctl->private_value; + + spin_lock_irq(&mts->lock); + uctl->value.integer.value[0] = mts->time[idx]; + spin_unlock_irq(&mts->lock); + + return 0; +} + +static int snd_mts64_ctl_smpte_time_put(struct snd_kcontrol *kctl, + struct snd_ctl_elem_value *uctl) +{ + struct mts64 *mts = snd_kcontrol_chip(kctl); + int idx = kctl->private_value; + int changed = 0; + + spin_lock_irq(&mts->lock); + if (mts->time[idx] != uctl->value.integer.value[0]) { + changed = 1; + mts->time[idx] = uctl->value.integer.value[0]; + } + spin_unlock_irq(&mts->lock); + + return changed; +} + +static struct snd_kcontrol_new mts64_ctl_smpte_time_hours __devinitdata = { + .iface = SNDRV_CTL_ELEM_IFACE_RAWMIDI, + .name = "SMPTE Time Hours", + .index = 0, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .private_value = 0, + .info = snd_mts64_ctl_smpte_time_h_info, + .get = snd_mts64_ctl_smpte_time_get, + .put = snd_mts64_ctl_smpte_time_put +}; + +static struct snd_kcontrol_new mts64_ctl_smpte_time_minutes __devinitdata = { + .iface = SNDRV_CTL_ELEM_IFACE_RAWMIDI, + .name = "SMPTE Time Minutes", + .index = 0, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .private_value = 1, + .info = snd_mts64_ctl_smpte_time_info, + .get = snd_mts64_ctl_smpte_time_get, + .put = snd_mts64_ctl_smpte_time_put +}; + +static struct snd_kcontrol_new mts64_ctl_smpte_time_seconds __devinitdata = { + .iface = SNDRV_CTL_ELEM_IFACE_RAWMIDI, + .name = "SMPTE Time Seconds", + .index = 0, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .private_value = 2, + .info = snd_mts64_ctl_smpte_time_info, + .get = snd_mts64_ctl_smpte_time_get, + .put = snd_mts64_ctl_smpte_time_put +}; + +static struct snd_kcontrol_new mts64_ctl_smpte_time_frames __devinitdata = { + .iface = SNDRV_CTL_ELEM_IFACE_RAWMIDI, + .name = "SMPTE Time Frames", + .index = 0, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .private_value = 3, + .info = snd_mts64_ctl_smpte_time_f_info, + .get = snd_mts64_ctl_smpte_time_get, + .put = snd_mts64_ctl_smpte_time_put +}; + +/* FPS */ +static int snd_mts64_ctl_smpte_fps_info(struct snd_kcontrol *kctl, + struct snd_ctl_elem_info *uinfo) +{ + static char *texts[5] = { "24", + "25", + "29.97", + "30D", + "30" }; + + uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; + uinfo->count = 1; + uinfo->value.enumerated.items = 5; + if (uinfo->value.enumerated.item > 4) + uinfo->value.enumerated.item = 4; + strcpy(uinfo->value.enumerated.name, + texts[uinfo->value.enumerated.item]); + + return 0; +} + +static int snd_mts64_ctl_smpte_fps_get(struct snd_kcontrol *kctl, + struct snd_ctl_elem_value *uctl) +{ + struct mts64 *mts = snd_kcontrol_chip(kctl); + + spin_lock_irq(&mts->lock); + uctl->value.enumerated.item[0] = mts->fps; + spin_unlock_irq(&mts->lock); + + return 0; +} + +static int snd_mts64_ctl_smpte_fps_put(struct snd_kcontrol *kctl, + struct snd_ctl_elem_value *uctl) +{ + struct mts64 *mts = snd_kcontrol_chip(kctl); + int changed = 0; + + spin_lock_irq(&mts->lock); + if (mts->fps != uctl->value.enumerated.item[0]) { + changed = 1; + mts->fps = uctl->value.enumerated.item[0]; + } + spin_unlock_irq(&mts->lock); + + return changed; +} + +static struct snd_kcontrol_new mts64_ctl_smpte_fps __devinitdata = { + .iface = SNDRV_CTL_ELEM_IFACE_RAWMIDI, + .name = "SMPTE Fps", + .index = 0, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .private_value = 0, + .info = snd_mts64_ctl_smpte_fps_info, + .get = snd_mts64_ctl_smpte_fps_get, + .put = snd_mts64_ctl_smpte_fps_put +}; + + +static int __devinit snd_mts64_ctl_create(struct snd_card *card, + struct mts64 *mts) +{ + int err, i; + static struct snd_kcontrol_new *control[] = { + &mts64_ctl_smpte_switch, + &mts64_ctl_smpte_time_hours, + &mts64_ctl_smpte_time_minutes, + &mts64_ctl_smpte_time_seconds, + &mts64_ctl_smpte_time_frames, + &mts64_ctl_smpte_fps, + 0 }; + + for (i = 0; control[i]; ++i) { + err = snd_ctl_add(card, snd_ctl_new1(control[i], mts)); + if (err < 0) { + snd_printd("Cannot create control: %s\n", + control[i]->name); + return err; + } + } + + return 0; +} + +/********************************************************************* + * Rawmidi + *********************************************************************/ +#define MTS64_MODE_INPUT_TRIGGERED 0x01 + +static int snd_mts64_rawmidi_open(struct snd_rawmidi_substream *substream) +{ + struct mts64 *mts = substream->rmidi->private_data; + + if (mts->open_count == 0) { + /* We don't need a spinlock here, because this is just called + if the device has not been opened before. + So there aren't any IRQs from the device */ + mts64_device_open(mts); + + msleep(50); + } + ++(mts->open_count); + + return 0; +} + +static int snd_mts64_rawmidi_close(struct snd_rawmidi_substream *substream) +{ + struct mts64 *mts = substream->rmidi->private_data; + unsigned long flags; + + --(mts->open_count); + if (mts->open_count == 0) { + /* We need the spinlock_irqsave here because we can still + have IRQs at this point */ + spin_lock_irqsave(&mts->lock, flags); + mts64_device_close(mts); + spin_unlock_irqrestore(&mts->lock, flags); + + msleep(500); + + } else if (mts->open_count < 0) + mts->open_count = 0; + + return 0; +} + +static void snd_mts64_rawmidi_output_trigger(struct snd_rawmidi_substream *substream, + int up) +{ + struct mts64 *mts = substream->rmidi->private_data; + u8 data; + unsigned long flags; + + spin_lock_irqsave(&mts->lock, flags); + while (snd_rawmidi_transmit_peek(substream, &data, 1) == 1) { + mts64_write_midi(mts, data, substream->number+1); + snd_rawmidi_transmit_ack(substream, 1); + } + spin_unlock_irqrestore(&mts->lock, flags); +} + +static void snd_mts64_rawmidi_input_trigger(struct snd_rawmidi_substream *substream, + int up) +{ + struct mts64 *mts = substream->rmidi->private_data; + unsigned long flags; + + spin_lock_irqsave(&mts->lock, flags); + if (up) + mts->mode[substream->number] |= MTS64_MODE_INPUT_TRIGGERED; + else + mts->mode[substream->number] &= ~MTS64_MODE_INPUT_TRIGGERED; + + spin_unlock_irqrestore(&mts->lock, flags); +} + +static struct snd_rawmidi_ops snd_mts64_rawmidi_output_ops = { + .open = snd_mts64_rawmidi_open, + .close = snd_mts64_rawmidi_close, + .trigger = snd_mts64_rawmidi_output_trigger +}; + +static struct snd_rawmidi_ops snd_mts64_rawmidi_input_ops = { + .open = snd_mts64_rawmidi_open, + .close = snd_mts64_rawmidi_close, + .trigger = snd_mts64_rawmidi_input_trigger +}; + +/* Create and initialize the rawmidi component */ +static int __devinit snd_mts64_rawmidi_create(struct snd_card *card) +{ + struct mts64 *mts = card->private_data; + struct snd_rawmidi *rmidi; + struct snd_rawmidi_substream *substream; + struct list_head *list; + int err; + + err = snd_rawmidi_new(card, CARD_NAME, 0, + MTS64_NUM_OUTPUT_PORTS, + MTS64_NUM_INPUT_PORTS, + &rmidi); + if (err < 0) + return err; + + rmidi->private_data = mts; + strcpy(rmidi->name, CARD_NAME); + rmidi->info_flags = SNDRV_RAWMIDI_INFO_OUTPUT | + SNDRV_RAWMIDI_INFO_INPUT | + SNDRV_RAWMIDI_INFO_DUPLEX; + + mts->rmidi = rmidi; + + /* register rawmidi ops */ + snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, + &snd_mts64_rawmidi_output_ops); + snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, + &snd_mts64_rawmidi_input_ops); + + /* name substreams */ + /* output */ + list_for_each(list, + &rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT].substreams) { + substream = list_entry(list, struct snd_rawmidi_substream, list); + sprintf(substream->name, + "Miditerminal %d", substream->number+1); + } + /* input */ + list_for_each(list, + &rmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT].substreams) { + substream = list_entry(list, struct snd_rawmidi_substream, list); + mts->midi_input_substream[substream->number] = substream; + switch(substream->number) { + case MTS64_SMPTE_SUBSTREAM: + strcpy(substream->name, "Miditerminal SMPTE"); + break; + default: + sprintf(substream->name, + "Miditerminal %d", substream->number+1); + } + } + + /* controls */ + err = snd_mts64_ctl_create(card, mts); + + return err; +} + +/********************************************************************* + * parport stuff + *********************************************************************/ +static void snd_mts64_interrupt(int irq, void *private, struct pt_regs *r) +{ + struct mts64 *mts = ((struct snd_card*)private)->private_data; + u16 ret; + u8 status, data; + struct snd_rawmidi_substream *substream; + + spin_lock(&mts->lock); + ret = mts64_read(mts->pardev->port); + data = ret & 0x00ff; + status = ret >> 8; + + if (status & MTS64_STAT_PORT) { + mts->current_midi_input_port = mts64_map_midi_input(data); + } else { + if (mts->current_midi_input_port == -1) + goto __out; + substream = mts->midi_input_substream[mts->current_midi_input_port]; + if (mts->mode[substream->number] & MTS64_MODE_INPUT_TRIGGERED) + snd_rawmidi_receive(substream, &data, 1); + } +__out: + spin_unlock(&mts->lock); +} + +static int __devinit snd_mts64_probe_port(struct parport *p) +{ + struct pardevice *pardev; + int res; + + pardev = parport_register_device(p, DRIVER_NAME, + NULL, NULL, NULL, + 0, NULL); + if (!pardev) + return -EIO; + + if (parport_claim(pardev)) { + parport_unregister_device(pardev); + return -EIO; + } + + res = mts64_probe(p); + + parport_release(pardev); + parport_unregister_device(pardev); + + return res; +} + +static void __devinit snd_mts64_attach(struct parport *p) +{ + struct platform_device *device; + + device = platform_device_alloc(PLATFORM_DRIVER, device_count); + if (!device) + return; + + /* Temporary assignment to forward the parport */ + platform_set_drvdata(device, p); + + if (platform_device_register(device) < 0) { + platform_device_put(device); + return; + } + + /* Since we dont get the return value of probe + * We need to check if device probing succeeded or not */ + if (!platform_get_drvdata(device)) { + platform_device_unregister(device); + return; + } + + /* register device in global table */ + platform_devices[device_count] = device; + device_count++; +} + +static void snd_mts64_detach(struct parport *p) +{ + /* nothing to do here */ +} + +static struct parport_driver mts64_parport_driver = { + .name = "mts64", + .attach = snd_mts64_attach, + .detach = snd_mts64_detach +}; + +/********************************************************************* + * platform stuff + *********************************************************************/ +static void snd_mts64_card_private_free(struct snd_card *card) +{ + struct mts64 *mts = card->private_data; + struct pardevice *pardev = mts->pardev; + + if (pardev) { + if (mts->pardev_claimed) + parport_release(pardev); + parport_unregister_device(pardev); + } + + snd_mts64_free(mts); +} + +static int __devinit snd_mts64_probe(struct platform_device *pdev) +{ + struct pardevice *pardev; + struct parport *p; + int dev = pdev->id; + struct snd_card *card = NULL; + struct mts64 *mts = NULL; + int err; + + p = platform_get_drvdata(pdev); + platform_set_drvdata(pdev, NULL); + + if (dev >= SNDRV_CARDS) + return -ENODEV; + if (!enable[dev]) + return -ENOENT; + if ((err = snd_mts64_probe_port(p)) < 0) + return err; + + card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); + if (card == NULL) { + snd_printd("Cannot create card\n"); + return -ENOMEM; + } + strcpy(card->driver, DRIVER_NAME); + strcpy(card->shortname, "ESI " CARD_NAME); + sprintf(card->longname, "%s at 0x%lx, irq %i", + card->shortname, p->base, p->irq); + + pardev = parport_register_device(p, /* port */ + DRIVER_NAME, /* name */ + NULL, /* preempt */ + NULL, /* wakeup */ + snd_mts64_interrupt, /* ISR */ + PARPORT_DEV_EXCL, /* flags */ + (void *)card); /* private */ + if (pardev == NULL) { + snd_printd("Cannot register pardevice\n"); + err = -EIO; + goto __err; + } + + if ((err = snd_mts64_create(card, pardev, &mts)) < 0) { + snd_printd("Cannot create main component\n"); + parport_unregister_device(pardev); + goto __err; + } + card->private_data = mts; + card->private_free = snd_mts64_card_private_free; + + if ((err = snd_mts64_rawmidi_create(card)) < 0) { + snd_printd("Creating Rawmidi component failed\n"); + goto __err; + } + + /* claim parport */ + if (parport_claim(pardev)) { + snd_printd("Cannot claim parport 0x%lx\n", pardev->port->base); + err = -EIO; + goto __err; + } + mts->pardev_claimed = 1; + + /* init device */ + if ((err = mts64_device_init(p)) < 0) + goto __err; + + platform_set_drvdata(pdev, card); + + /* At this point card will be usable */ + if ((err = snd_card_register(card)) < 0) { + snd_printd("Cannot register card\n"); + goto __err; + } + + snd_printk("ESI Miditerminal 4140 on 0x%lx\n", p->base); + return 0; + +__err: + snd_card_free(card); + return err; +} + +static int snd_mts64_remove(struct platform_device *pdev) +{ + struct snd_card *card = platform_get_drvdata(pdev); + + if (card) + snd_card_free(card); + + return 0; +} + + +static struct platform_driver snd_mts64_driver = { + .probe = snd_mts64_probe, + .remove = snd_mts64_remove, + .driver = { + .name = PLATFORM_DRIVER + } +}; + +/********************************************************************* + * module init stuff + *********************************************************************/ +static void snd_mts64_unregister_all(void) +{ + int i; + + for (i = 0; i < SNDRV_CARDS; ++i) { + if (platform_devices[i]) { + platform_device_unregister(platform_devices[i]); + platform_devices[i] = NULL; + } + } + platform_driver_unregister(&snd_mts64_driver); + parport_unregister_driver(&mts64_parport_driver); +} + +static int __init snd_mts64_module_init(void) +{ + int err; + + if ((err = platform_driver_register(&snd_mts64_driver)) < 0) + return err; + + if (parport_register_driver(&mts64_parport_driver) != 0) { + platform_driver_unregister(&snd_mts64_driver); + return -EIO; + } + + if (device_count == 0) { + snd_mts64_unregister_all(); + return -ENODEV; + } + + return 0; +} + +static void __exit snd_mts64_module_exit(void) +{ + snd_mts64_unregister_all(); +} + +module_init(snd_mts64_module_init); +module_exit(snd_mts64_module_exit); -- cgit v1.2.3-59-g8ed1b From 4b146cb087b4a668511f6c991da1dc40e2e04b0d Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 28 Jul 2006 14:42:36 +0200 Subject: [ALSA] Misc fixes for Realtek HD-audio codecs - Added model=arima for Arima W820Di1 with ALC882 codec chip - Added EAPD-control verbs to TCL S700 init verbs - Added missing model strings for Realtek codecs (to be specified via module option explicitly for testing/debugging) Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- Documentation/sound/alsa/ALSA-Configuration.txt | 13 +++++-- sound/pci/hda/patch_realtek.c | 48 +++++++++++++++++++++---- 2 files changed, 52 insertions(+), 9 deletions(-) (limited to 'Documentation') diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt index 7344815b855e..d0dbc3fb20c2 100644 --- a/Documentation/sound/alsa/ALSA-Configuration.txt +++ b/Documentation/sound/alsa/ALSA-Configuration.txt @@ -778,11 +778,15 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. 6stack-digout 6-jack with a SPDIF out w810 3-jack z71v 3-jack (HP shared SPDIF) - asus 3-jack + asus 3-jack (ASUS Mobo) + asus-w1v ASUS W1V + asus-dig ASUS with SPDIF out + asus-dig2 ASUS with SPDIF out (using GPIO2) uniwill 3-jack F1734 2-jack lg LG laptop (m1 express dual) lg-lw LG LW20 laptop + tcl TCL S700 clevo Clevo laptops (m520G, m665n) test for testing/debugging purpose, almost all controls can be adjusted. Appearing only when compiled with @@ -791,6 +795,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. ALC260 hp HP machines + hp-3013 HP machines (3013-variant) fujitsu Fujitsu S7020 acer Acer TravelMate basic fixed pin assignment (old default model) @@ -806,18 +811,22 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. ALC882/885 3stack-dig 3-jack with SPDIF I/O 6stck-dig 6-jack digital with SPDIF I/O + arima Arima W820Di1 auto auto-config reading BIOS (default) ALC883/888 3stack-dig 3-jack with SPDIF I/O 6stack-dig 6-jack digital with SPDIF I/O - 6stack-dig-demo 6-stack digital for Intel demo board + 3stack-6ch 3-jack 6-channel + 3stack-6ch-dig 3-jack 6-channel with SPDIF I/O + 6stack-dig-demo 6-jack digital for Intel demo board auto auto-config reading BIOS (default) ALC861/660 3stack 3-jack 3stack-dig 3-jack with SPDIF I/O 6stack-dig 6-jack with SPDIF I/O + 3stack-660 3-jack (for ALC660) auto auto-config reading BIOS (default) CMI9880 diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 42c4f90a92b8..378e5f111e34 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -98,6 +98,7 @@ enum { enum { ALC882_3ST_DIG, ALC882_6ST_DIG, + ALC882_ARIMA, ALC882_AUTO, ALC882_MODEL_LAST, }; @@ -1349,6 +1350,10 @@ static struct hda_verb alc880_pin_clevo_init_verbs[] = { }; static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = { + /* change to EAPD mode */ + {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, + {0x20, AC_VERB_SET_PROC_COEF, 0x3060}, + /* Headphone output */ {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, /* Front output*/ @@ -2146,6 +2151,7 @@ static struct hda_board_config alc880_cfg_tbl[] = { { .pci_subvendor = 0x107b, .pci_subdevice = 0x4040, .config = ALC880_3ST }, { .pci_subvendor = 0x107b, .pci_subdevice = 0x4041, .config = ALC880_3ST }, /* TCL S700 */ + { .modelname = "tcl", .config = ALC880_TCL_S700 }, { .pci_subvendor = 0x19db, .pci_subdevice = 0x4188, .config = ALC880_TCL_S700 }, /* Back 3 jack, front 2 jack (Internal add Aux-In) */ @@ -2232,8 +2238,11 @@ static struct hda_board_config alc880_cfg_tbl[] = { { .pci_subvendor = 0x1043, .pci_subdevice = 0x1133, .config = ALC880_ASUS }, { .pci_subvendor = 0x1043, .pci_subdevice = 0x1123, .config = ALC880_ASUS_DIG }, { .pci_subvendor = 0x1043, .pci_subdevice = 0x1143, .config = ALC880_ASUS }, + { .modelname = "asus-w1v", .config = ALC880_ASUS_W1V }, { .pci_subvendor = 0x1043, .pci_subdevice = 0x10b3, .config = ALC880_ASUS_W1V }, + { .modelname = "asus-dig", .config = ALC880_ASUS_DIG }, { .pci_subvendor = 0x1043, .pci_subdevice = 0x8181, .config = ALC880_ASUS_DIG }, /* ASUS P4GPL-X */ + { .modelname = "asus-dig2", .config = ALC880_ASUS_DIG2 }, { .pci_subvendor = 0x1558, .pci_subdevice = 0x5401, .config = ALC880_ASUS_DIG2 }, { .modelname = "uniwill", .config = ALC880_UNIWILL_DIG }, @@ -3906,6 +3915,7 @@ static struct hda_board_config alc260_cfg_tbl[] = { { .pci_subvendor = 0x152d, .pci_subdevice = 0x0729, .config = ALC260_BASIC }, /* CTL Travel Master U553W */ { .modelname = "hp", .config = ALC260_HP }, + { .modelname = "hp-3013", .config = ALC260_HP_3013 }, { .pci_subvendor = 0x103c, .pci_subdevice = 0x3010, .config = ALC260_HP }, { .pci_subvendor = 0x103c, .pci_subdevice = 0x3011, .config = ALC260_HP }, { .pci_subvendor = 0x103c, .pci_subdevice = 0x3012, .config = ALC260_HP_3013 }, @@ -4272,6 +4282,13 @@ static struct hda_verb alc882_init_verbs[] = { { } }; +static struct hda_verb alc882_eapd_verbs[] = { + /* change to EAPD mode */ + {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, + {0x20, AC_VERB_SET_PROC_COEF, 0x3060}, + { } +}; + /* * generic initialization of ADC, input mixers and output mixers */ @@ -4403,6 +4420,9 @@ static struct hda_board_config alc882_cfg_tbl[] = { .config = ALC882_6ST_DIG }, /* Foxconn */ { .pci_subvendor = 0x1019, .pci_subdevice = 0x6668, .config = ALC882_6ST_DIG }, /* ECS to Intel*/ + { .modelname = "arima", .config = ALC882_ARIMA }, + { .pci_subvendor = 0x161f, .pci_subdevice = 0x2054, + .config = ALC882_ARIMA }, /* Arima W820Di1 */ { .modelname = "auto", .config = ALC882_AUTO }, {} }; @@ -4430,6 +4450,15 @@ static struct alc_config_preset alc882_presets[] = { .channel_mode = alc882_sixstack_modes, .input_mux = &alc882_capture_source, }, + [ALC882_ARIMA] = { + .mixers = { alc882_base_mixer, alc882_chmode_mixer }, + .init_verbs = { alc882_init_verbs, alc882_eapd_verbs }, + .num_dacs = ARRAY_SIZE(alc882_dac_nids), + .dac_nids = alc882_dac_nids, + .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes), + .channel_mode = alc882_sixstack_modes, + .input_mux = &alc882_capture_source, + }, }; @@ -5005,16 +5034,18 @@ static struct snd_kcontrol_new alc883_capture_mixer[] = { */ static struct hda_board_config alc883_cfg_tbl[] = { { .modelname = "3stack-dig", .config = ALC883_3ST_2ch_DIG }, + { .modelname = "3stack-6ch-dig", .config = ALC883_3ST_6ch_DIG }, + { .pci_subvendor = 0x1019, .pci_subdevice = 0x6668, + .config = ALC883_3ST_6ch_DIG }, /* ECS to Intel*/ + { .modelname = "3stack-6ch", .config = ALC883_3ST_6ch }, + { .pci_subvendor = 0x108e, .pci_subdevice = 0x534d, + .config = ALC883_3ST_6ch }, { .modelname = "6stack-dig", .config = ALC883_6ST_DIG }, - { .modelname = "6stack-dig-demo", .config = ALC888_DEMO_BOARD }, { .pci_subvendor = 0x1462, .pci_subdevice = 0x6668, .config = ALC883_6ST_DIG }, /* MSI */ { .pci_subvendor = 0x105b, .pci_subdevice = 0x6668, .config = ALC883_6ST_DIG }, /* Foxconn */ - { .pci_subvendor = 0x1019, .pci_subdevice = 0x6668, - .config = ALC883_3ST_6ch_DIG }, /* ECS to Intel*/ - { .pci_subvendor = 0x108e, .pci_subdevice = 0x534d, - .config = ALC883_3ST_6ch }, + { .modelname = "6stack-dig-demo", .config = ALC888_DEMO_BOARD }, { .modelname = "auto", .config = ALC883_AUTO }, {} }; @@ -5223,8 +5254,10 @@ static int patch_alc883(struct hda_codec *codec) spec->stream_digital_playback = &alc883_pcm_digital_playback; spec->stream_digital_capture = &alc883_pcm_digital_capture; - spec->adc_nids = alc883_adc_nids; - spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids); + if (! spec->adc_nids && spec->input_mux) { + spec->adc_nids = alc883_adc_nids; + spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids); + } codec->patch_ops = alc_patch_ops; if (board_config == ALC883_AUTO) @@ -6504,6 +6537,7 @@ static struct hda_board_config alc861_cfg_tbl[] = { { .modelname = "3stack", .config = ALC861_3ST }, { .pci_subvendor = 0x8086, .pci_subdevice = 0xd600, .config = ALC861_3ST }, + { .modelname = "3stack-660", .config = ALC660_3ST }, { .pci_subvendor = 0x1043, .pci_subdevice = 0x81e7, .config = ALC660_3ST }, { .modelname = "3stack-dig", .config = ALC861_3ST_DIG }, -- cgit v1.2.3-59-g8ed1b From 22309c3e0c8911865cad0aa94f53a9afadaad7ee Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 9 Aug 2006 16:57:28 +0200 Subject: [ALSA] Added model for Uniwill laptop with ALC861 Added a new model 'uniwill-m31' for Uniwill laptops with ALC861 codec chip. The patch is taken from ALSA bug#2035, and modifeid. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- Documentation/sound/alsa/ALSA-Configuration.txt | 1 + sound/pci/hda/patch_realtek.c | 137 ++++++++++++++++++++++++ 2 files changed, 138 insertions(+) (limited to 'Documentation') diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt index d0dbc3fb20c2..74be228596ad 100644 --- a/Documentation/sound/alsa/ALSA-Configuration.txt +++ b/Documentation/sound/alsa/ALSA-Configuration.txt @@ -827,6 +827,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. 3stack-dig 3-jack with SPDIF I/O 6stack-dig 6-jack with SPDIF I/O 3stack-660 3-jack (for ALC660) + uniwill-m31 Uniwill M31 laptop auto auto-config reading BIOS (default) CMI9880 diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index a91757316765..f857e963ff45 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -90,6 +90,7 @@ enum { ALC660_3ST, ALC861_3ST_DIG, ALC861_6ST_DIG, + ALC861_UNIWILL_M31, ALC861_AUTO, ALC861_MODEL_LAST, }; @@ -6021,6 +6022,23 @@ static struct hda_channel_mode alc861_threestack_modes[2] = { { 2, alc861_threestack_ch2_init }, { 6, alc861_threestack_ch6_init }, }; +/* Set mic1 as input and unmute the mixer */ +static struct hda_verb alc861_uniwill_m31_ch2_init[] = { + { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, + { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/ + { } /* end */ +}; +/* Set mic1 as output and mute mixer */ +static struct hda_verb alc861_uniwill_m31_ch4_init[] = { + { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, + { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/ + { } /* end */ +}; + +static struct hda_channel_mode alc861_uniwill_m31_modes[2] = { + { 2, alc861_uniwill_m31_ch2_init }, + { 4, alc861_uniwill_m31_ch4_init }, +}; /* patch-ALC861 */ @@ -6099,6 +6117,47 @@ static struct snd_kcontrol_new alc861_3ST_mixer[] = { }, { } /* end */ }; +static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = { + /* output mixer control */ + HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT), + HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT), + HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT), + HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT), + /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */ + + /* Input mixer control */ + /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT), + HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */ + HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT), + HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT), + HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT), + HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), + HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT), + HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT), + + /* Capture mixer control */ + HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), + HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Capture Source", + .count = 1, + .info = alc_mux_enum_info, + .get = alc_mux_enum_get, + .put = alc_mux_enum_put, + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Channel Mode", + .info = alc_ch_mode_info, + .get = alc_ch_mode_get, + .put = alc_ch_mode_put, + .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes), + }, + { } /* end */ +}; /* * generic initialization of ADC, input mixers and output mixers @@ -6227,6 +6286,67 @@ static struct hda_verb alc861_threestack_init_verbs[] = { {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, { } }; + +static struct hda_verb alc861_uniwill_m31_init_verbs[] = { + /* + * Unmute ADC0 and set the default input to mic-in + */ + /* port-A for surround (rear panel) */ + { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, + /* port-B for mic-in (rear panel) with vref */ + { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, + /* port-C for line-in (rear panel) */ + { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, + /* port-D for Front */ + { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, + { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 }, + /* port-E for HP out (front panel) */ + { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, // this has to be set to VREF80 + /* route front PCM to HP */ + { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x01 }, + /* port-F for mic-in (front panel) with vref */ + { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, + /* port-G for CLFE (rear panel) */ + { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, + /* port-H for side (rear panel) */ + { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, + /* CD-in */ + { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, + /* route front mic to ADC1*/ + {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, + {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + /* Unmute DAC0~3 & spdif out*/ + {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, + {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, + {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, + {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, + {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, + + /* Unmute Mixer 14 (mic) 1c (Line in)*/ + {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, + {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, + + /* Unmute Stereo Mixer 15 */ + {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, + {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, + {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c }, //Output 0~12 step + + {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, + {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, + {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, + {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, + {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, // hp used DAC 3 (Front) + {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, + { } +}; + /* * generic initialization of ADC, input mixers and output mixers */ @@ -6561,6 +6681,9 @@ static struct hda_board_config alc861_cfg_tbl[] = { .config = ALC660_3ST }, { .modelname = "3stack-dig", .config = ALC861_3ST_DIG }, { .modelname = "6stack-dig", .config = ALC861_6ST_DIG }, + { .modelname = "uniwill-m31", .config = ALC861_UNIWILL_M31}, + { .pci_subvendor = 0x1584, .pci_subdevice = 0x9072, + .config = ALC861_UNIWILL_M31 }, { .modelname = "auto", .config = ALC861_AUTO }, {} }; @@ -6615,6 +6738,20 @@ static struct alc_config_preset alc861_presets[] = { .adc_nids = alc861_adc_nids, .input_mux = &alc861_capture_source, }, + [ALC861_UNIWILL_M31] = { + .mixers = { alc861_uniwill_m31_mixer }, + .init_verbs = { alc861_uniwill_m31_init_verbs }, + .num_dacs = ARRAY_SIZE(alc861_dac_nids), + .dac_nids = alc861_dac_nids, + .dig_out_nid = ALC861_DIGOUT_NID, + .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes), + .channel_mode = alc861_uniwill_m31_modes, + .need_dac_fix = 1, + .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), + .adc_nids = alc861_adc_nids, + .input_mux = &alc861_capture_source, + }, + }; -- cgit v1.2.3-59-g8ed1b From 99ccc560b73ff7381153dc1391d18391373931d3 Mon Sep 17 00:00:00 2001 From: Guillaume Munch Date: Wed, 16 Aug 2006 19:35:12 +0200 Subject: [ALSA] Add support for Sony Vaio AR 11B This patch adds automatic detection for Sigmatel ID 7664, the sound chip in Sony Vaio AR 11B (european name). - patch_stac7661 becomes patch_stac766x - .id = 0x83847664 is added Signed-off-by: Guillaume Munch Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- Documentation/sound/alsa/ALSA-Configuration.txt | 6 ++--- sound/pci/hda/patch_sigmatel.c | 29 ++++++++++++++----------- 2 files changed, 19 insertions(+), 16 deletions(-) (limited to 'Documentation') diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt index 74be228596ad..d7e95f144569 100644 --- a/Documentation/sound/alsa/ALSA-Configuration.txt +++ b/Documentation/sound/alsa/ALSA-Configuration.txt @@ -856,10 +856,10 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. 3stack-dig ditto with SPDIF laptop 3-jack with hp-jack automute laptop-dig ditto with SPDIF - auto auto-confgi reading BIOS (default) + auto auto-config reading BIOS (default) - STAC7661(?) - vaio Setup for VAIO FE550G/SZ110 + STAC7664/7661(?) + vaio Setup for VAIO FE550G/SZ110/AR11B If the default configuration doesn't work and one of the above matches with your device, report it together with the PCI diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index d572f030c3e9..7eaf755b014b 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -1449,10 +1449,10 @@ static int patch_stac9205(struct hda_codec *codec) } /* - * STAC 7661(?) hack + * STAC 7661(?) and 7664 hack */ -/* static config for Sony VAIO FE550G */ +/* static config for Sony VAIO FE550G and Sony VAIO AR */ static hda_nid_t vaio_dacs[] = { 0x2 }; #define VAIO_HP_DAC 0x5 static hda_nid_t vaio_adcs[] = { 0x8 /*,0x6*/ }; @@ -1552,7 +1552,7 @@ static struct snd_kcontrol_new vaio_mixer[] = { {} }; -static struct hda_codec_ops stac7661_patch_ops = { +static struct hda_codec_ops stac766x_patch_ops = { .build_controls = stac92xx_build_controls, .build_pcms = stac92xx_build_pcms, .init = stac92xx_init, @@ -1562,23 +1562,25 @@ static struct hda_codec_ops stac7661_patch_ops = { #endif }; -enum { STAC7661_VAIO }; +enum { STAC766x_VAIO }; -static struct hda_board_config stac7661_cfg_tbl[] = { - { .modelname = "vaio", .config = STAC7661_VAIO }, +static struct hda_board_config stac766x_cfg_tbl[] = { + { .modelname = "vaio", .config = STAC766x_VAIO }, { .pci_subvendor = 0x104d, .pci_subdevice = 0x81e6, - .config = STAC7661_VAIO }, + .config = STAC766x_VAIO }, { .pci_subvendor = 0x104d, .pci_subdevice = 0x81ef, - .config = STAC7661_VAIO }, + .config = STAC766x_VAIO }, + { .pci_subvendor = 0x104d, .pci_subdevice = 0x81fd, + .config = STAC766x_VAIO }, {} }; -static int patch_stac7661(struct hda_codec *codec) +static int patch_stac766x(struct hda_codec *codec) { struct sigmatel_spec *spec; int board_config; - board_config = snd_hda_check_board_config(codec, stac7661_cfg_tbl); + board_config = snd_hda_check_board_config(codec, stac766x_cfg_tbl); if (board_config < 0) /* unknown config, let generic-parser do its job... */ return snd_hda_parse_generic_codec(codec); @@ -1589,7 +1591,7 @@ static int patch_stac7661(struct hda_codec *codec) codec->spec = spec; switch (board_config) { - case STAC7661_VAIO: + case STAC766x_VAIO: spec->mixer = vaio_mixer; spec->init = vaio_init; spec->multiout.max_channels = 2; @@ -1603,7 +1605,7 @@ static int patch_stac7661(struct hda_codec *codec) break; } - codec->patch_ops = stac7661_patch_ops; + codec->patch_ops = stac766x_patch_ops; return 0; } @@ -1635,7 +1637,7 @@ struct hda_codec_preset snd_hda_preset_sigmatel[] = { { .id = 0x83847627, .name = "STAC9271D", .patch = patch_stac927x }, { .id = 0x83847628, .name = "STAC9274X5NH", .patch = patch_stac927x }, { .id = 0x83847629, .name = "STAC9274D5NH", .patch = patch_stac927x }, - { .id = 0x83847661, .name = "STAC7661", .patch = patch_stac7661 }, + { .id = 0x83847661, .name = "STAC7661", .patch = patch_stac766x }, { .id = 0x838476a0, .name = "STAC9205", .patch = patch_stac9205 }, { .id = 0x838476a1, .name = "STAC9205D", .patch = patch_stac9205 }, { .id = 0x838476a2, .name = "STAC9204", .patch = patch_stac9205 }, @@ -1644,5 +1646,6 @@ struct hda_codec_preset snd_hda_preset_sigmatel[] = { { .id = 0x838476a5, .name = "STAC9255D", .patch = patch_stac9205 }, { .id = 0x838476a6, .name = "STAC9254", .patch = patch_stac9205 }, { .id = 0x838476a7, .name = "STAC9254D", .patch = patch_stac9205 }, + { .id = 0x83847664, .name = "STAC7664", .patch = patch_stac766x }, {} /* terminator */ }; -- cgit v1.2.3-59-g8ed1b From bab282b912baf372d8f705357946ef691b621899 Mon Sep 17 00:00:00 2001 From: Vladimir Avdonin Date: Tue, 22 Aug 2006 13:31:58 +0200 Subject: [ALSA] hda-codec - Fix for Acer laptops with ALC883 codec Patch enables the internal speaker on acer laptops with ALC883. Signed-off-by: Vladimir Avdonin Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- Documentation/sound/alsa/ALSA-Configuration.txt | 1 + sound/pci/hda/patch_realtek.c | 21 +++++++++++++++++++++ 2 files changed, 22 insertions(+) (limited to 'Documentation') diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt index d7e95f144569..504ebbceafbc 100644 --- a/Documentation/sound/alsa/ALSA-Configuration.txt +++ b/Documentation/sound/alsa/ALSA-Configuration.txt @@ -820,6 +820,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. 3stack-6ch 3-jack 6-channel 3stack-6ch-dig 3-jack 6-channel with SPDIF I/O 6stack-dig-demo 6-jack digital for Intel demo board + acer Acer laptops (Travelmate 3012WTMi, Aspire 5600, etc) auto auto-config reading BIOS (default) ALC861/660 diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 53aa57f5a1a1..65903812b307 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -111,6 +111,7 @@ enum { ALC883_3ST_6ch, ALC883_6ST_DIG, ALC888_DEMO_BOARD, + ALC883_ACER, ALC883_AUTO, ALC883_MODEL_LAST, }; @@ -5069,6 +5070,9 @@ static struct hda_board_config alc883_cfg_tbl[] = { { .pci_subvendor = 0x105b, .pci_subdevice = 0x6668, .config = ALC883_6ST_DIG }, /* Foxconn */ { .modelname = "6stack-dig-demo", .config = ALC888_DEMO_BOARD }, + { .modelname = "acer", .config = ALC883_ACER }, + { .pci_subvendor = 0x1025, .pci_subdevice = 0/*0x0102*/, + .config = ALC883_ACER }, { .modelname = "auto", .config = ALC883_AUTO }, {} }; @@ -5139,6 +5143,23 @@ static struct alc_config_preset alc883_presets[] = { .channel_mode = alc883_sixstack_modes, .input_mux = &alc883_capture_source, }, + [ALC883_ACER] = { + .mixers = { alc883_base_mixer, + alc883_chmode_mixer }, + /* On TravelMate laptops, GPIO 0 enables the internal speaker + * and the headphone jack. Turn this on and rely on the + * standard mute methods whenever the user wants to turn + * these outputs off. + */ + .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs }, + .num_dacs = ARRAY_SIZE(alc883_dac_nids), + .dac_nids = alc883_dac_nids, + .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), + .adc_nids = alc883_adc_nids, + .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), + .channel_mode = alc883_3ST_2ch_modes, + .input_mux = &alc883_capture_source, + }, }; -- cgit v1.2.3-59-g8ed1b From 6d8590650eb81d2c869c7adf4b469071cec11eee Mon Sep 17 00:00:00 2001 From: Guillaume Munch Date: Tue, 22 Aug 2006 17:15:47 +0200 Subject: [ALSA] hda-codec - Support for SigmaTel 9872 - AR11M and AR11S uses the same chip hence we claim to support the AR Series. - Added commentary about STAC9225s which shares the same id as CXD9872RD. - Added entry for 7662 but won't work automatically until pci_subdevice is known. - 'vaio' model now corresponds to CXD9872RD_VAIO for backward compat. - Replaced STAC766x_VAIO with CXD9872RD_VAIO, STAC9872AK_VAIO, STAC9872K_VAIO and CXD9872AKD_VAIO - Added 'vaio-ar' model for potential future modifications. Signed-off-by: Guillaume Munch Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- Documentation/sound/alsa/ALSA-Configuration.txt | 5 +- sound/pci/hda/patch_sigmatel.c | 109 ++++++++++++++++++++---- 2 files changed, 97 insertions(+), 17 deletions(-) (limited to 'Documentation') diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt index 504ebbceafbc..48d3bdf2a7cd 100644 --- a/Documentation/sound/alsa/ALSA-Configuration.txt +++ b/Documentation/sound/alsa/ALSA-Configuration.txt @@ -859,8 +859,9 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. laptop-dig ditto with SPDIF auto auto-config reading BIOS (default) - STAC7664/7661(?) - vaio Setup for VAIO FE550G/SZ110/AR11B + STAC9872 + vaio Setup for VAIO FE550G/SZ110 + vaio-ar Setup for VAIO AR If the default configuration doesn't work and one of the above matches with your device, report it together with the PCI diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 73ca566e9eb7..139d73e18a3c 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -1563,7 +1563,7 @@ static int patch_stac9205(struct hda_codec *codec) } /* - * STAC 7661(?) and 7664 hack + * STAC9872 hack */ /* static config for Sony VAIO FE550G and Sony VAIO AR */ @@ -1597,6 +1597,23 @@ static struct hda_verb vaio_init[] = { {} }; +static struct hda_verb vaio_ar_init[] = { + {0x0a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP <- 0x2 */ + {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Speaker <- 0x5 */ + {0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? (<- 0x2) */ + {0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD */ +/* {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },*/ /* Optical Out */ + {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? */ + {0x15, AC_VERB_SET_CONNECT_SEL, 0x2}, /* mic-sel: 0a,0d,14,02 */ + {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* HP */ + {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Speaker */ +/* {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},*/ /* Optical Out */ + {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* capture sw/vol -> 0x8 */ + {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, /* CD-in -> 0x6 */ + {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Mic-in -> 0x9 */ + {} +}; + /* bind volumes of both NID 0x02 and 0x05 */ static int vaio_master_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) @@ -1667,7 +1684,40 @@ static struct snd_kcontrol_new vaio_mixer[] = { {} }; -static struct hda_codec_ops stac766x_patch_ops = { +static struct snd_kcontrol_new vaio_ar_mixer[] = { + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Master Playback Volume", + .info = snd_hda_mixer_amp_volume_info, + .get = snd_hda_mixer_amp_volume_get, + .put = vaio_master_vol_put, + .private_value = HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT), + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Master Playback Switch", + .info = snd_hda_mixer_amp_switch_info, + .get = snd_hda_mixer_amp_switch_get, + .put = vaio_master_sw_put, + .private_value = HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT), + }, + /* HDA_CODEC_VOLUME("CD Capture Volume", 0x07, 0, HDA_INPUT), */ + HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_INPUT), + HDA_CODEC_MUTE("Capture Switch", 0x09, 0, HDA_INPUT), + /*HDA_CODEC_MUTE("Optical Out Switch", 0x10, 0, HDA_OUTPUT), + HDA_CODEC_VOLUME("Optical Out Volume", 0x10, 0, HDA_OUTPUT),*/ + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Capture Source", + .count = 1, + .info = stac92xx_mux_enum_info, + .get = stac92xx_mux_enum_get, + .put = stac92xx_mux_enum_put, + }, + {} +}; + +static struct hda_codec_ops stac9872_patch_ops = { .build_controls = stac92xx_build_controls, .build_pcms = stac92xx_build_pcms, .init = stac92xx_init, @@ -1677,25 +1727,34 @@ static struct hda_codec_ops stac766x_patch_ops = { #endif }; -enum { STAC766x_VAIO }; - -static struct hda_board_config stac766x_cfg_tbl[] = { - { .modelname = "vaio", .config = STAC766x_VAIO }, +enum { /* FE and SZ series. id=0x83847661 and subsys=0x104D0700 or 104D1000. */ + CXD9872RD_VAIO, + /* Unknown. id=0x83847662 and subsys=0x104D1200 or 104D1000. */ + STAC9872AK_VAIO, + /* Unknown. id=0x83847661 and subsys=0x104D1200. */ + STAC9872K_VAIO, + /* AR Series. id=0x83847664 and subsys=104D1300 */ + CXD9872AKD_VAIO + }; + +static struct hda_board_config stac9872_cfg_tbl[] = { + { .modelname = "vaio", .config = CXD9872RD_VAIO }, + { .modelname = "vaio-ar", .config = CXD9872AKD_VAIO }, { .pci_subvendor = 0x104d, .pci_subdevice = 0x81e6, - .config = STAC766x_VAIO }, + .config = CXD9872RD_VAIO }, { .pci_subvendor = 0x104d, .pci_subdevice = 0x81ef, - .config = STAC766x_VAIO }, + .config = CXD9872RD_VAIO }, { .pci_subvendor = 0x104d, .pci_subdevice = 0x81fd, - .config = STAC766x_VAIO }, + .config = CXD9872AKD_VAIO }, {} }; -static int patch_stac766x(struct hda_codec *codec) +static int patch_stac9872(struct hda_codec *codec) { struct sigmatel_spec *spec; int board_config; - board_config = snd_hda_check_board_config(codec, stac766x_cfg_tbl); + board_config = snd_hda_check_board_config(codec, stac9872_cfg_tbl); if (board_config < 0) /* unknown config, let generic-parser do its job... */ return snd_hda_parse_generic_codec(codec); @@ -1706,7 +1765,9 @@ static int patch_stac766x(struct hda_codec *codec) codec->spec = spec; switch (board_config) { - case STAC766x_VAIO: + case CXD9872RD_VAIO: + case STAC9872AK_VAIO: + case STAC9872K_VAIO: spec->mixer = vaio_mixer; spec->init = vaio_init; spec->multiout.max_channels = 2; @@ -1718,9 +1779,22 @@ static int patch_stac766x(struct hda_codec *codec) spec->input_mux = &vaio_mux; spec->mux_nids = vaio_mux_nids; break; + + case CXD9872AKD_VAIO: + spec->mixer = vaio_ar_mixer; + spec->init = vaio_ar_init; + spec->multiout.max_channels = 2; + spec->multiout.num_dacs = ARRAY_SIZE(vaio_dacs); + spec->multiout.dac_nids = vaio_dacs; + spec->multiout.hp_nid = VAIO_HP_DAC; + spec->num_adcs = ARRAY_SIZE(vaio_adcs); + spec->adc_nids = vaio_adcs; + spec->input_mux = &vaio_mux; + spec->mux_nids = vaio_mux_nids; + break; } - codec->patch_ops = stac766x_patch_ops; + codec->patch_ops = stac9872_patch_ops; return 0; } @@ -1752,7 +1826,13 @@ struct hda_codec_preset snd_hda_preset_sigmatel[] = { { .id = 0x83847627, .name = "STAC9271D", .patch = patch_stac927x }, { .id = 0x83847628, .name = "STAC9274X5NH", .patch = patch_stac927x }, { .id = 0x83847629, .name = "STAC9274D5NH", .patch = patch_stac927x }, - { .id = 0x83847661, .name = "STAC7661", .patch = patch_stac766x }, + /* The following does not take into account .id=0x83847661 when subsys = + * 104D0C00 which is STAC9225s. Because of this, some SZ Notebooks are + * currently not fully supported. + */ + { .id = 0x83847661, .name = "CXD9872RD/K", .patch = patch_stac9872 }, + { .id = 0x83847662, .name = "STAC9872AK", .patch = patch_stac9872 }, + { .id = 0x83847664, .name = "CXD9872AKD", .patch = patch_stac9872 }, { .id = 0x838476a0, .name = "STAC9205", .patch = patch_stac9205 }, { .id = 0x838476a1, .name = "STAC9205D", .patch = patch_stac9205 }, { .id = 0x838476a2, .name = "STAC9204", .patch = patch_stac9205 }, @@ -1761,6 +1841,5 @@ struct hda_codec_preset snd_hda_preset_sigmatel[] = { { .id = 0x838476a5, .name = "STAC9255D", .patch = patch_stac9205 }, { .id = 0x838476a6, .name = "STAC9254", .patch = patch_stac9205 }, { .id = 0x838476a7, .name = "STAC9254D", .patch = patch_stac9205 }, - { .id = 0x83847664, .name = "STAC7664", .patch = patch_stac766x }, {} /* terminator */ }; -- cgit v1.2.3-59-g8ed1b From 93ed150375187ae7917ed1e3b9b830b9d4065bad Mon Sep 17 00:00:00 2001 From: Tobin Davis Date: Fri, 1 Sep 2006 21:03:12 +0200 Subject: [ALSA] hda-codec - Add 5 stack audio support for Intel 965 systems This patch renames the 965_2112 function ids to 965_3ST, and adds functional support for 965_5ST (5 stack 7.1 surround). Signed-off-by: Tobin Davis Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- Documentation/sound/alsa/ALSA-Configuration.txt | 10 ++ sound/pci/hda/patch_sigmatel.c | 152 +++++++++++++----------- 2 files changed, 91 insertions(+), 71 deletions(-) (limited to 'Documentation') diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt index 48d3bdf2a7cd..a788dd7bc790 100644 --- a/Documentation/sound/alsa/ALSA-Configuration.txt +++ b/Documentation/sound/alsa/ALSA-Configuration.txt @@ -859,6 +859,16 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. laptop-dig ditto with SPDIF auto auto-config reading BIOS (default) + STAC9200/9205/9220/9221/9254 + ref Reference board + 3stack D945 3stack + 5stack D945 5stack + SPDIF + + STAC9227/9228/9229/927x + ref Reference board + 3stack D965 3stack + 5stack D965 5stack + SPDIF + STAC9872 vaio Setup for VAIO FE550G/SZ110 vaio-ar Setup for VAIO AR diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 8d5ad7c0db07..87169032be1f 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -42,9 +42,10 @@ #define STAC_D945GTP3 1 #define STAC_D945GTP5 2 #define STAC_MACMINI 3 -#define STAC_D965_2112 4 -#define STAC_D965_284B 5 -#define STAC_922X_MODELS 6 /* number of 922x models */ +#define STAC_922X_MODELS 4 /* number of 922x models */ +#define STAC_D965_3ST 4 +#define STAC_D965_5ST 5 +#define STAC_927X_MODELS 6 /* number of 922x models */ struct sigmatel_spec { struct snd_kcontrol_new *mixers[4]; @@ -111,24 +112,10 @@ static hda_nid_t stac922x_adc_nids[2] = { 0x06, 0x07, }; -static hda_nid_t stac9227_adc_nids[2] = { - 0x07, 0x08, -}; - -#if 0 -static hda_nid_t d965_2112_dac_nids[3] = { - 0x02, 0x03, 0x05, -}; -#endif - static hda_nid_t stac922x_mux_nids[2] = { 0x12, 0x13, }; -static hda_nid_t stac9227_mux_nids[2] = { - 0x15, 0x16, -}; - static hda_nid_t stac927x_adc_nids[3] = { 0x07, 0x08, 0x09 }; @@ -146,7 +133,8 @@ static hda_nid_t stac9205_mux_nids[2] = { }; static hda_nid_t stac9200_pin_nids[8] = { - 0x08, 0x09, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, + 0x08, 0x09, 0x0d, 0x0e, + 0x0f, 0x10, 0x11, 0x12, }; static hda_nid_t stac922x_pin_nids[10] = { @@ -206,17 +194,9 @@ static struct hda_verb stac922x_core_init[] = { {} }; -static struct hda_verb stac9227_core_init[] = { - /* set master volume and direct control */ - { 0x16, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, - /* unmute node 0x1b */ - { 0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, - {} -}; - -static struct hda_verb d965_2112_core_init[] = { +static struct hda_verb d965_core_init[] = { /* set master volume and direct control */ - { 0x16, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, + { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, /* unmute node 0x1b */ { 0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, /* select node 0x03 as DAC */ @@ -386,6 +366,8 @@ static unsigned int *stac922x_brd_tbl[STAC_922X_MODELS] = { }; static struct hda_board_config stac922x_cfg_tbl[] = { + { .modelname = "5stack", .config = STAC_D945GTP5 }, + { .modelname = "3stack", .config = STAC_D945GTP3 }, { .modelname = "ref", .pci_subvendor = PCI_VENDOR_ID_INTEL, .pci_subdevice = 0x2668, /* DFI LanParty */ @@ -471,99 +453,127 @@ static struct hda_board_config stac922x_cfg_tbl[] = { { .pci_subvendor = 0x8384, .pci_subdevice = 0x7680, .config = STAC_MACMINI }, /* Apple Mac Mini (early 2006) */ - { .pci_subvendor = PCI_VENDOR_ID_INTEL, - .pci_subdevice = 0x2112, - .config = STAC_D965_2112 }, - { .pci_subvendor = PCI_VENDOR_ID_INTEL, - .pci_subdevice = 0x284b, - .config = STAC_D965_284B }, {} /* terminator */ }; static unsigned int ref927x_pin_configs[14] = { - 0x01813122, 0x01a19021, 0x01014010, 0x01016011, - 0x01012012, 0x01011014, 0x40000100, 0x40000100, - 0x40000100, 0x40000100, 0x40000100, 0x01441030, - 0x01c41030, 0x40000100, + 0x02214020, 0x02a19080, 0x0181304e, 0x01014010, + 0x01a19040, 0x01011012, 0x01016011, 0x0101201f, + 0x183301f0, 0x18a001f0, 0x18a001f0, 0x01442070, + 0x01c42190, 0x40000100, }; -static unsigned int d965_2112_pin_configs[14] = { +static unsigned int d965_3st_pin_configs[14] = { 0x0221401f, 0x02a19120, 0x40000100, 0x01014011, 0x01a19021, 0x01813024, 0x40000100, 0x40000100, 0x40000100, 0x40000100, 0x40000100, 0x40000100, 0x40000100, 0x40000100 }; -static unsigned int *stac927x_brd_tbl[] = { +static unsigned int d965_5st_pin_configs[14] = { + 0x02214020, 0x02a19080, 0x0181304e, 0x01014010, + 0x01a19040, 0x01011012, 0x01016011, 0x40000100, + 0x40000100, 0x40000100, 0x40000100, 0x01442070, + 0x40000100, 0x40000100 +}; + +static unsigned int *stac927x_brd_tbl[STAC_927X_MODELS] = { [STAC_REF] = ref927x_pin_configs, - [STAC_D965_2112] = d965_2112_pin_configs, + [STAC_D965_3ST] = d965_3st_pin_configs, + [STAC_D965_5ST] = d965_5st_pin_configs, }; static struct hda_board_config stac927x_cfg_tbl[] = { + { .modelname = "5stack", .config = STAC_D965_5ST }, + { .modelname = "3stack", .config = STAC_D965_3ST }, { .modelname = "ref", .pci_subvendor = PCI_VENDOR_ID_INTEL, .pci_subdevice = 0x2668, /* DFI LanParty */ .config = STAC_REF }, /* SigmaTel reference board */ - /* SigmaTel 9227 reference board */ - { .pci_subvendor = PCI_VENDOR_ID_INTEL, - .pci_subdevice = 0x284b, - .config = STAC_D965_284B }, /* Intel 946 based systems */ { .pci_subvendor = PCI_VENDOR_ID_INTEL, .pci_subdevice = 0x3d01, - .config = STAC_D965_2112 }, /* D946 configuration */ + .config = STAC_D965_3ST }, /* D946 configuration */ { .pci_subvendor = PCI_VENDOR_ID_INTEL, .pci_subdevice = 0xa301, - .config = STAC_D965_2112 }, /* Intel D946GZT - 3 stack */ - /* 965 based systems */ + .config = STAC_D965_3ST }, /* Intel D946GZT - 3 stack */ + /* 965 based 3 stack systems */ { .pci_subvendor = PCI_VENDOR_ID_INTEL, .pci_subdevice = 0x2116, - .config = STAC_D965_2112 }, /* Intel D965 3Stack config */ + .config = STAC_D965_3ST }, /* Intel D965 3Stack config */ { .pci_subvendor = PCI_VENDOR_ID_INTEL, .pci_subdevice = 0x2115, - .config = STAC_D965_2112 }, /* Intel DQ965WC - 3 Stack */ + .config = STAC_D965_3ST }, /* Intel DQ965WC - 3 Stack */ { .pci_subvendor = PCI_VENDOR_ID_INTEL, .pci_subdevice = 0x2114, - .config = STAC_D965_2112 }, /* Intel D965 3Stack config */ + .config = STAC_D965_3ST }, /* Intel D965 3Stack config */ { .pci_subvendor = PCI_VENDOR_ID_INTEL, .pci_subdevice = 0x2113, - .config = STAC_D965_2112 }, /* Intel D965 3Stack config */ + .config = STAC_D965_3ST }, /* Intel D965 3Stack config */ { .pci_subvendor = PCI_VENDOR_ID_INTEL, .pci_subdevice = 0x2112, - .config = STAC_D965_2112 }, /* Intel DG965MS - 3 Stack */ + .config = STAC_D965_3ST }, /* Intel DG965MS - 3 Stack */ { .pci_subvendor = PCI_VENDOR_ID_INTEL, .pci_subdevice = 0x2111, - .config = STAC_D965_2112 }, /* Intel D965 3Stack config */ + .config = STAC_D965_3ST }, /* Intel D965 3Stack config */ { .pci_subvendor = PCI_VENDOR_ID_INTEL, .pci_subdevice = 0x2110, - .config = STAC_D965_2112 }, /* Intel D965 3Stack config */ + .config = STAC_D965_3ST }, /* Intel D965 3Stack config */ { .pci_subvendor = PCI_VENDOR_ID_INTEL, .pci_subdevice = 0x2009, - .config = STAC_D965_2112 }, /* Intel D965 3Stack config */ + .config = STAC_D965_3ST }, /* Intel D965 3Stack config */ { .pci_subvendor = PCI_VENDOR_ID_INTEL, .pci_subdevice = 0x2008, - .config = STAC_D965_2112 }, /* Intel DQ965GF - 3 Stack */ + .config = STAC_D965_3ST }, /* Intel DQ965GF - 3 Stack */ { .pci_subvendor = PCI_VENDOR_ID_INTEL, .pci_subdevice = 0x2007, - .config = STAC_D965_2112 }, /* Intel D965 3Stack config */ + .config = STAC_D965_3ST }, /* Intel D965 3Stack config */ { .pci_subvendor = PCI_VENDOR_ID_INTEL, .pci_subdevice = 0x2006, - .config = STAC_D965_2112 }, /* Intel D965 3Stack config */ + .config = STAC_D965_3ST }, /* Intel D965 3Stack config */ { .pci_subvendor = PCI_VENDOR_ID_INTEL, .pci_subdevice = 0x2005, - .config = STAC_D965_2112 }, /* Intel D965 3Stack config */ + .config = STAC_D965_3ST }, /* Intel D965 3Stack config */ { .pci_subvendor = PCI_VENDOR_ID_INTEL, .pci_subdevice = 0x2004, - .config = STAC_D965_2112 }, /* Intel D965 3Stack config */ + .config = STAC_D965_3ST }, /* Intel D965 3Stack config */ { .pci_subvendor = PCI_VENDOR_ID_INTEL, .pci_subdevice = 0x2003, - .config = STAC_D965_2112 }, /* Intel D965 3Stack config */ + .config = STAC_D965_3ST }, /* Intel D965 3Stack config */ { .pci_subvendor = PCI_VENDOR_ID_INTEL, .pci_subdevice = 0x2002, - .config = STAC_D965_2112 }, /* Intel D965 3Stack config */ + .config = STAC_D965_3ST }, /* Intel D965 3Stack config */ { .pci_subvendor = PCI_VENDOR_ID_INTEL, .pci_subdevice = 0x2001, - .config = STAC_D965_2112 }, /* Intel DQ965GF - 3 Stackg */ + .config = STAC_D965_3ST }, /* Intel DQ965GF - 3 Stack */ + /* 965 based 5 stack systems */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x2301, + .config = STAC_D965_5ST }, /* Intel DG965 - 5 Stack */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x2302, + .config = STAC_D965_5ST }, /* Intel DG965 - 5 Stack */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x2303, + .config = STAC_D965_5ST }, /* Intel DG965 - 5 Stack */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x2304, + .config = STAC_D965_5ST }, /* Intel DG965 - 5 Stack */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x2305, + .config = STAC_D965_5ST }, /* Intel DG965 - 5 Stack */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x2501, + .config = STAC_D965_5ST }, /* Intel DG965MQ - 5 Stack */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x2502, + .config = STAC_D965_5ST }, /* Intel DG965 - 5 Stack */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x2503, + .config = STAC_D965_5ST }, /* Intel DG965 - 5 Stack */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x2504, + .config = STAC_D965_5ST }, /* Intel DQ965GF - 5 Stack */ {} /* terminator */ }; @@ -1546,18 +1556,18 @@ static int patch_stac927x(struct hda_codec *codec) } switch (spec->board_config) { - case STAC_D965_2112: + case STAC_D965_3ST: spec->adc_nids = stac927x_adc_nids; spec->mux_nids = stac927x_mux_nids; spec->num_muxes = 3; - spec->init = d965_2112_core_init; + spec->init = d965_core_init; spec->mixer = stac9227_mixer; break; - case STAC_D965_284B: - spec->adc_nids = stac9227_adc_nids; - spec->mux_nids = stac9227_mux_nids; - spec->num_muxes = 2; - spec->init = stac9227_core_init; + case STAC_D965_5ST: + spec->adc_nids = stac927x_adc_nids; + spec->mux_nids = stac927x_mux_nids; + spec->num_muxes = 3; + spec->init = d965_core_init; spec->mixer = stac9227_mixer; break; default: -- cgit v1.2.3-59-g8ed1b From cd417d4fe89638a2848980cb389b9781d4913173 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 6 Sep 2006 16:03:11 +0200 Subject: [ALSA] hda-codec - Add support for LG LW25 laptop Added the support for LG LW25 laptop with ALC880 codec. It's the same codec model as LG LW20 (model=lg-lw). Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- Documentation/sound/alsa/ALSA-Configuration.txt | 2 +- sound/pci/hda/patch_realtek.c | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt index a788dd7bc790..1b749947233c 100644 --- a/Documentation/sound/alsa/ALSA-Configuration.txt +++ b/Documentation/sound/alsa/ALSA-Configuration.txt @@ -785,7 +785,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. uniwill 3-jack F1734 2-jack lg LG laptop (m1 express dual) - lg-lw LG LW20 laptop + lg-lw LG LW20/LW25 laptop tcl TCL S700 clevo Clevo laptops (m520G, m665n) test for testing/debugging purpose, almost all controls can be diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 65903812b307..d037051b66b4 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -2270,6 +2270,7 @@ static struct hda_board_config alc880_cfg_tbl[] = { { .modelname = "lg-lw", .config = ALC880_LG_LW }, { .pci_subvendor = 0x1854, .pci_subdevice = 0x0018, .config = ALC880_LG_LW }, + { .pci_subvendor = 0x1854, .pci_subdevice = 0x0077, .config = ALC880_LG_LW }, #ifdef CONFIG_SND_DEBUG { .modelname = "test", .config = ALC880_TEST }, -- cgit v1.2.3-59-g8ed1b From dafbbb1fdbf103b24d0f7aa645625b6bd558c896 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 7 Sep 2006 12:40:00 +0200 Subject: [ALSA] hda-intel - Fix pci_disable_msi() call Fix the order to call pci_disable_msi() to be after free_irq(). (Otherwise pci_disable_msi() bugs you.) Also, added a description of disable_msi option to documentation. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- Documentation/sound/alsa/ALSA-Configuration.txt | 1 + sound/pci/hda/hda_intel.c | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt index 1b749947233c..e6b57dd46a4f 100644 --- a/Documentation/sound/alsa/ALSA-Configuration.txt +++ b/Documentation/sound/alsa/ALSA-Configuration.txt @@ -758,6 +758,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. position_fix - Fix DMA pointer (0 = auto, 1 = none, 2 = POSBUF, 3 = FIFO size) single_cmd - Use single immediate commands to communicate with codecs (for debugging only) + disable_msi - Disable Message Signaled Interrupt (MSI) This module supports one card and autoprobe. diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index cc50d13ee90c..bfd74a526b85 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -1422,8 +1422,9 @@ static int azx_free(struct azx *chip) } if (chip->irq >= 0) { - pci_disable_msi(chip->pci); free_irq(chip->irq, (void*)chip); + if (!disable_msi) + pci_disable_msi(chip->pci); } if (chip->remap_addr) iounmap(chip->remap_addr); -- cgit v1.2.3-59-g8ed1b