Merge tag 'to-linus' of git://github.com/rustyrussell/linux
* tag 'to-linus' of git://github.com/rustyrussell/linux: (24 commits)
lguest: Make sure interrupt is allocated ok by lguest_setup_irq
lguest: move the lguest tool to the tools directory
lguest: switch segment-voodoo-numbers to readable symbols
virtio: balloon: Add freeze, restore handlers to support S4
virtio: balloon: Move vq initialization into separate function
virtio: net: Add freeze, restore handlers to support S4
virtio: net: Move vq and vq buf removal into separate function
virtio: net: Move vq initialization into separate function
virtio: blk: Add freeze, restore handlers to support S4
virtio: blk: Move vq initialization to separate function
virtio: console: Disable callbacks for virtqueues at start of S4 freeze
virtio: console: Add freeze and restore handlers to support S4
virtio: console: Move vq and vq buf removal into separate functions
virtio: pci: add PM notification handlers for restore, freeze, thaw, poweroff
virtio: pci: switch to new PM API
virtio_blk: fix config handler race
virtio: add debugging if driver doesn't kick.
virtio: expose added descriptors immediately.
virtio: avoid modulus operation.
virtio: support unlocked queue kick
...
diff --git a/Documentation/DocBook/writing-an-alsa-driver.tmpl b/Documentation/DocBook/writing-an-alsa-driver.tmpl
index 5de23c0..cab4ec5 100644
--- a/Documentation/DocBook/writing-an-alsa-driver.tmpl
+++ b/Documentation/DocBook/writing-an-alsa-driver.tmpl
@@ -404,7 +404,7 @@
/* SNDRV_CARDS: maximum number of cards supported by this module */
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 bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
/* definition of the chip-specific record */
struct mychip {
diff --git a/Documentation/devicetree/bindings/power_supply/olpc_battery.txt b/Documentation/devicetree/bindings/power_supply/olpc_battery.txt
new file mode 100644
index 0000000..c8901b3
--- /dev/null
+++ b/Documentation/devicetree/bindings/power_supply/olpc_battery.txt
@@ -0,0 +1,5 @@
+OLPC battery
+~~~~~~~~~~~~
+
+Required properties:
+ - compatible : "olpc,xo1-battery"
diff --git a/Documentation/devicetree/bindings/power_supply/sbs_sbs-battery.txt b/Documentation/devicetree/bindings/power_supply/sbs_sbs-battery.txt
new file mode 100644
index 0000000..c40e892
--- /dev/null
+++ b/Documentation/devicetree/bindings/power_supply/sbs_sbs-battery.txt
@@ -0,0 +1,23 @@
+SBS sbs-battery
+~~~~~~~~~~
+
+Required properties :
+ - compatible : "sbs,sbs-battery"
+
+Optional properties :
+ - sbs,i2c-retry-count : The number of times to retry i2c transactions on i2c
+ IO failure.
+ - sbs,poll-retry-count : The number of times to try looking for new status
+ after an external change notification.
+ - sbs,battery-detect-gpios : The gpio which signals battery detection and
+ a flag specifying its polarity.
+
+Example:
+
+ bq20z75@b {
+ compatible = "sbs,sbs-battery";
+ reg = < 0xb >;
+ sbs,i2c-retry-count = <2>;
+ sbs,poll-retry-count = <10>;
+ sbs,battery-detect-gpios = <&gpio-controller 122 1>;
+ }
diff --git a/Documentation/devicetree/bindings/sound/tegra-audio-wm8903.txt b/Documentation/devicetree/bindings/sound/tegra-audio-wm8903.txt
new file mode 100644
index 0000000..d5b0da8
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/tegra-audio-wm8903.txt
@@ -0,0 +1,71 @@
+NVIDIA Tegra audio complex
+
+Required properties:
+- compatible : "nvidia,tegra-audio-wm8903"
+- nvidia,model : The user-visible name of this sound complex.
+- nvidia,audio-routing : A list of the connections between audio components.
+ Each entry is a pair of strings, the first being the connection's sink,
+ the second being the connection's source. Valid names for sources and
+ sinks are the WM8903's pins, and the jacks on the board:
+
+ WM8903 pins:
+
+ * IN1L
+ * IN1R
+ * IN2L
+ * IN2R
+ * IN3L
+ * IN3R
+ * DMICDAT
+ * HPOUTL
+ * HPOUTR
+ * LINEOUTL
+ * LINEOUTR
+ * LOP
+ * LON
+ * ROP
+ * RON
+ * MICBIAS
+
+ Board connectors:
+
+ * Headphone Jack
+ * Int Spk
+ * Mic Jack
+
+- nvidia,i2s-controller : The phandle of the Tegra I2S1 controller
+- nvidia,audio-codec : The phandle of the WM8903 audio codec
+
+Optional properties:
+- nvidia,spkr-en-gpios : The GPIO that enables the speakers
+- nvidia,hp-mute-gpios : The GPIO that mutes the headphones
+- nvidia,hp-det-gpios : The GPIO that detect headphones are plugged in
+- nvidia,int-mic-en-gpios : The GPIO that enables the internal microphone
+- nvidia,ext-mic-en-gpios : The GPIO that enables the external microphone
+
+Example:
+
+sound {
+ compatible = "nvidia,tegra-audio-wm8903-harmony",
+ "nvidia,tegra-audio-wm8903"
+ nvidia,model = "tegra-wm8903-harmony";
+
+ nvidia,audio-routing =
+ "Headphone Jack", "HPOUTR",
+ "Headphone Jack", "HPOUTL",
+ "Int Spk", "ROP",
+ "Int Spk", "RON",
+ "Int Spk", "LOP",
+ "Int Spk", "LON",
+ "Mic Jack", "MICBIAS",
+ "IN1L", "Mic Jack";
+
+ nvidia,i2s-controller = <&i2s1>;
+ nvidia,audio-codec = <&wm8903>;
+
+ nvidia,spkr-en-gpios = <&codec 2 0>;
+ nvidia,hp-det-gpios = <&gpio 178 0>; /* gpio PW2 */
+ nvidia,int-mic-en-gpios = <&gpio 184 0>; /*gpio PX0 */
+ nvidia,ext-mic-en-gpios = <&gpio 185 0>; /* gpio PX1 */
+};
+
diff --git a/Documentation/devicetree/bindings/sound/tegra20-das.txt b/Documentation/devicetree/bindings/sound/tegra20-das.txt
new file mode 100644
index 0000000..6de3a7e
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/tegra20-das.txt
@@ -0,0 +1,12 @@
+NVIDIA Tegra 20 DAS (Digital Audio Switch) controller
+
+Required properties:
+- compatible : "nvidia,tegra20-das"
+- reg : Should contain DAS registers location and length
+
+Example:
+
+das@70000c00 {
+ compatible = "nvidia,tegra20-das";
+ reg = <0x70000c00 0x80>;
+};
diff --git a/Documentation/devicetree/bindings/sound/tegra20-i2s.txt b/Documentation/devicetree/bindings/sound/tegra20-i2s.txt
new file mode 100644
index 0000000..0df2b5c
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/tegra20-i2s.txt
@@ -0,0 +1,17 @@
+NVIDIA Tegra 20 I2S controller
+
+Required properties:
+- compatible : "nvidia,tegra20-i2s"
+- reg : Should contain I2S registers location and length
+- interrupts : Should contain I2S interrupt
+- nvidia,dma-request-selector : The Tegra DMA controller's phandle and
+ request selector for this I2S controller
+
+Example:
+
+i2s@70002800 {
+ compatible = "nvidia,tegra20-i2s";
+ reg = <0x70002800 0x200>;
+ interrupts = < 45 >;
+ nvidia,dma-request-selector = < &apbdma 2 >;
+};
diff --git a/Documentation/devicetree/bindings/sound/wm8903.txt b/Documentation/devicetree/bindings/sound/wm8903.txt
new file mode 100644
index 0000000..f102cbc
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/wm8903.txt
@@ -0,0 +1,50 @@
+WM8903 audio CODEC
+
+This device supports I2C only.
+
+Required properties:
+
+ - compatible : "wlf,wm8903"
+
+ - reg : the I2C address of the device.
+
+ - gpio-controller : Indicates this device is a GPIO controller.
+
+ - #gpio-cells : Should be two. The first cell is the pin number and the
+ second cell is used to specify optional parameters (currently unused).
+
+Optional properties:
+
+ - interrupts : The interrupt line the codec is connected to.
+
+ - micdet-cfg : Default register value for R6 (Mic Bias). If absent, the
+ default is 0.
+
+ - micdet-delay : The debounce delay for microphone detection in mS. If
+ absent, the default is 100.
+
+ - gpio-cfg : A list of GPIO configuration register values. The list must
+ be 5 entries long. If absent, no configuration of these registers is
+ performed. If any entry has the value 0xffffffff, that GPIO's
+ configuration will not be modified.
+
+Example:
+
+codec: wm8903@1a {
+ compatible = "wlf,wm8903";
+ reg = <0x1a>;
+ interrupts = < 347 >;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ micdet-cfg = <0>;
+ micdet-delay = <100>;
+ gpio-cfg = <
+ 0x0600 /* DMIC_LR, output */
+ 0x0680 /* DMIC_DAT, input */
+ 0x0000 /* GPIO, output, low */
+ 0x0200 /* Interrupt, output */
+ 0x01a0 /* BCLK, input, active high */
+ >;
+};
diff --git a/Documentation/devicetree/bindings/sound/wm8994.txt b/Documentation/devicetree/bindings/sound/wm8994.txt
new file mode 100644
index 0000000..7a7eb1e
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/wm8994.txt
@@ -0,0 +1,18 @@
+WM1811/WM8994/WM8958 audio CODEC
+
+These devices support both I2C and SPI (configured with pin strapping
+on the board).
+
+Required properties:
+
+ - compatible : "wlf,wm1811", "wlf,wm8994", "wlf,wm8958"
+
+ - reg : the I2C address of the device for I2C, the chip select
+ number for SPI.
+
+Example:
+
+codec: wm8994@1a {
+ compatible = "wlf,wm8994";
+ reg = <0x1a>;
+};
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt
index 1862696..ecc6a6c 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.txt
+++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
@@ -34,6 +34,7 @@
qcom Qualcomm, Inc.
ramtron Ramtron International
samsung Samsung Semiconductor
+sbs Smart Battery System
schindler Schindler
sil Silicon Image
simtek
@@ -41,4 +42,5 @@
st STMicroelectronics
stericsson ST-Ericsson
ti Texas Instruments
+wlf Wolfson Microelectronics
xlnx Xilinx
diff --git a/Documentation/digsig.txt b/Documentation/digsig.txt
new file mode 100644
index 0000000..3f68288
--- /dev/null
+++ b/Documentation/digsig.txt
@@ -0,0 +1,96 @@
+Digital Signature Verification API
+
+CONTENTS
+
+1. Introduction
+2. API
+3. User-space utilities
+
+
+1. Introduction
+
+Digital signature verification API provides a method to verify digital signature.
+Currently digital signatures are used by the IMA/EVM integrity protection subsystem.
+
+Digital signature verification is implemented using cut-down kernel port of
+GnuPG multi-precision integers (MPI) library. The kernel port provides
+memory allocation errors handling, has been refactored according to kernel
+coding style, and checkpatch.pl reported errors and warnings have been fixed.
+
+Public key and signature consist of header and MPIs.
+
+struct pubkey_hdr {
+ uint8_t version; /* key format version */
+ time_t timestamp; /* key made, always 0 for now */
+ uint8_t algo;
+ uint8_t nmpi;
+ char mpi[0];
+} __packed;
+
+struct signature_hdr {
+ uint8_t version; /* signature format version */
+ time_t timestamp; /* signature made */
+ uint8_t algo;
+ uint8_t hash;
+ uint8_t keyid[8];
+ uint8_t nmpi;
+ char mpi[0];
+} __packed;
+
+keyid equals to SHA1[12-19] over the total key content.
+Signature header is used as an input to generate a signature.
+Such approach insures that key or signature header could not be changed.
+It protects timestamp from been changed and can be used for rollback
+protection.
+
+2. API
+
+API currently includes only 1 function:
+
+ digsig_verify() - digital signature verification with public key
+
+
+/**
+ * digsig_verify() - digital signature verification with public key
+ * @keyring: keyring to search key in
+ * @sig: digital signature
+ * @sigen: length of the signature
+ * @data: data
+ * @datalen: length of the data
+ * @return: 0 on success, -EINVAL otherwise
+ *
+ * Verifies data integrity against digital signature.
+ * Currently only RSA is supported.
+ * Normally hash of the content is used as a data for this function.
+ *
+ */
+int digsig_verify(struct key *keyring, const char *sig, int siglen,
+ const char *data, int datalen);
+
+3. User-space utilities
+
+The signing and key management utilities evm-utils provide functionality
+to generate signatures, to load keys into the kernel keyring.
+Keys can be in PEM or converted to the kernel format.
+When the key is added to the kernel keyring, the keyid defines the name
+of the key: 5D2B05FC633EE3E8 in the example bellow.
+
+Here is example output of the keyctl utility.
+
+$ keyctl show
+Session Keyring
+ -3 --alswrv 0 0 keyring: _ses
+603976250 --alswrv 0 -1 \_ keyring: _uid.0
+817777377 --alswrv 0 0 \_ user: kmk
+891974900 --alswrv 0 0 \_ encrypted: evm-key
+170323636 --alswrv 0 0 \_ keyring: _module
+548221616 --alswrv 0 0 \_ keyring: _ima
+128198054 --alswrv 0 0 \_ keyring: _evm
+
+$ keyctl list 128198054
+1 key in keyring:
+620789745: --alswrv 0 0 user: 5D2B05FC633EE3E8
+
+
+Dmitry Kasatkin
+06.10.2011
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index 5575759..d49c2ec 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -544,3 +544,15 @@
Why: The iwlagn module has been renamed iwlwifi. The alias will be around
for backward compatibility for several cycles and then dropped.
Who: Don Fry <donald.h.fry@intel.com>
+
+----------------------------
+
+What: pci_scan_bus_parented()
+When: 3.5
+Why: The pci_scan_bus_parented() interface creates a new root bus. The
+ bus is created with default resources (ioport_resource and
+ iomem_resource) that are always wrong, so we rely on arch code to
+ correct them later. Callers of pci_scan_bus_parented() should
+ convert to using pci_scan_root_bus() so they can supply a list of
+ bus resources when the bus is created.
+Who: Bjorn Helgaas <bhelgaas@google.com>
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index c92b153..eb93fd0 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -1824,6 +1824,10 @@
nomfgpt [X86-32] Disable Multi-Function General Purpose
Timer usage (for AMD Geode machines).
+ nonmi_ipi [X86] Disable using NMI IPIs during panic/reboot to
+ shutdown the other cpus. Instead use the REBOOT_VECTOR
+ irq.
+
nopat [X86] Disable PAT (page attribute table extension of
pagetables) support.
@@ -2395,6 +2399,12 @@
slram= [HW,MTD]
+ slab_max_order= [MM, SLAB]
+ Determines the maximum allowed order for slabs.
+ A high setting may cause OOMs due to memory
+ fragmentation. Defaults to 1 for systems with
+ more than 32MB of RAM, 0 otherwise.
+
slub_debug[=options[,slabs]] [MM, SLUB]
Enabling slub_debug allows one to determine the
culprit if slab objects become corrupted. Enabling
diff --git a/Documentation/power/charger-manager.txt b/Documentation/power/charger-manager.txt
new file mode 100644
index 0000000..fdcca99
--- /dev/null
+++ b/Documentation/power/charger-manager.txt
@@ -0,0 +1,163 @@
+Charger Manager
+ (C) 2011 MyungJoo Ham <myungjoo.ham@samsung.com>, GPL
+
+Charger Manager provides in-kernel battery charger management that
+requires temperature monitoring during suspend-to-RAM state
+and where each battery may have multiple chargers attached and the userland
+wants to look at the aggregated information of the multiple chargers.
+
+Charger Manager is a platform_driver with power-supply-class entries.
+An instance of Charger Manager (a platform-device created with Charger-Manager)
+represents an independent battery with chargers. If there are multiple
+batteries with their own chargers acting independently in a system,
+the system may need multiple instances of Charger Manager.
+
+1. Introduction
+===============
+
+Charger Manager supports the following:
+
+* Support for multiple chargers (e.g., a device with USB, AC, and solar panels)
+ A system may have multiple chargers (or power sources) and some of
+ they may be activated at the same time. Each charger may have its
+ own power-supply-class and each power-supply-class can provide
+ different information about the battery status. This framework
+ aggregates charger-related information from multiple sources and
+ shows combined information as a single power-supply-class.
+
+* Support for in suspend-to-RAM polling (with suspend_again callback)
+ While the battery is being charged and the system is in suspend-to-RAM,
+ we may need to monitor the battery health by looking at the ambient or
+ battery temperature. We can accomplish this by waking up the system
+ periodically. However, such a method wakes up devices unncessary for
+ monitoring the battery health and tasks, and user processes that are
+ supposed to be kept suspended. That, in turn, incurs unnecessary power
+ consumption and slow down charging process. Or even, such peak power
+ consumption can stop chargers in the middle of charging
+ (external power input < device power consumption), which not
+ only affects the charging time, but the lifespan of the battery.
+
+ Charger Manager provides a function "cm_suspend_again" that can be
+ used as suspend_again callback of platform_suspend_ops. If the platform
+ requires tasks other than cm_suspend_again, it may implement its own
+ suspend_again callback that calls cm_suspend_again in the middle.
+ Normally, the platform will need to resume and suspend some devices
+ that are used by Charger Manager.
+
+2. Global Charger-Manager Data related with suspend_again
+========================================================
+In order to setup Charger Manager with suspend-again feature
+(in-suspend monitoring), the user should provide charger_global_desc
+with setup_charger_manager(struct charger_global_desc *).
+This charger_global_desc data for in-suspend monitoring is global
+as the name suggests. Thus, the user needs to provide only once even
+if there are multiple batteries. If there are multiple batteries, the
+multiple instances of Charger Manager share the same charger_global_desc
+and it will manage in-suspend monitoring for all instances of Charger Manager.
+
+The user needs to provide all the two entries properly in order to activate
+in-suspend monitoring:
+
+struct charger_global_desc {
+
+char *rtc_name;
+ : The name of rtc (e.g., "rtc0") used to wakeup the system from
+ suspend for Charger Manager. The alarm interrupt (AIE) of the rtc
+ should be able to wake up the system from suspend. Charger Manager
+ saves and restores the alarm value and use the previously-defined
+ alarm if it is going to go off earlier than Charger Manager so that
+ Charger Manager does not interfere with previously-defined alarms.
+
+bool (*rtc_only_wakeup)(void);
+ : This callback should let CM know whether
+ the wakeup-from-suspend is caused only by the alarm of "rtc" in the
+ same struct. If there is any other wakeup source triggered the
+ wakeup, it should return false. If the "rtc" is the only wakeup
+ reason, it should return true.
+};
+
+3. How to setup suspend_again
+=============================
+Charger Manager provides a function "extern bool cm_suspend_again(void)".
+When cm_suspend_again is called, it monitors every battery. The suspend_ops
+callback of the system's platform_suspend_ops can call cm_suspend_again
+function to know whether Charger Manager wants to suspend again or not.
+If there are no other devices or tasks that want to use suspend_again
+feature, the platform_suspend_ops may directly refer to cm_suspend_again
+for its suspend_again callback.
+
+The cm_suspend_again() returns true (meaning "I want to suspend again")
+if the system was woken up by Charger Manager and the polling
+(in-suspend monitoring) results in "normal".
+
+4. Charger-Manager Data (struct charger_desc)
+=============================================
+For each battery charged independently from other batteries (if a series of
+batteries are charged by a single charger, they are counted as one independent
+battery), an instance of Charger Manager is attached to it.
+
+struct charger_desc {
+
+char *psy_name;
+ : The power-supply-class name of the battery. Default is
+ "battery" if psy_name is NULL. Users can access the psy entries
+ at "/sys/class/power_supply/[psy_name]/".
+
+enum polling_modes polling_mode;
+ : CM_POLL_DISABLE: do not poll this battery.
+ CM_POLL_ALWAYS: always poll this battery.
+ CM_POLL_EXTERNAL_POWER_ONLY: poll this battery if and only if
+ an external power source is attached.
+ CM_POLL_CHARGING_ONLY: poll this battery if and only if the
+ battery is being charged.
+
+unsigned int fullbatt_uV;
+ : If specified with a non-zero value, Charger Manager assumes
+ that the battery is full (capacity = 100) if the battery is not being
+ charged and the battery voltage is equal to or greater than
+ fullbatt_uV.
+
+unsigned int polling_interval_ms;
+ : Required polling interval in ms. Charger Manager will poll
+ this battery every polling_interval_ms or more frequently.
+
+enum data_source battery_present;
+ CM_FUEL_GAUGE: get battery presence information from fuel gauge.
+ CM_CHARGER_STAT: get battery presence from chargers.
+
+char **psy_charger_stat;
+ : An array ending with NULL that has power-supply-class names of
+ chargers. Each power-supply-class should provide "PRESENT" (if
+ battery_present is "CM_CHARGER_STAT"), "ONLINE" (shows whether an
+ external power source is attached or not), and "STATUS" (shows whether
+ the battery is {"FULL" or not FULL} or {"FULL", "Charging",
+ "Discharging", "NotCharging"}).
+
+int num_charger_regulators;
+struct regulator_bulk_data *charger_regulators;
+ : Regulators representing the chargers in the form for
+ regulator framework's bulk functions.
+
+char *psy_fuel_gauge;
+ : Power-supply-class name of the fuel gauge.
+
+int (*temperature_out_of_range)(int *mC);
+bool measure_battery_temp;
+ : This callback returns 0 if the temperature is safe for charging,
+ a positive number if it is too hot to charge, and a negative number
+ if it is too cold to charge. With the variable mC, the callback returns
+ the temperature in 1/1000 of centigrade.
+ The source of temperature can be battery or ambient one according to
+ the value of measure_battery_temp.
+};
+
+5. Other Considerations
+=======================
+
+At the charger/battery-related events such as battery-pulled-out,
+charger-pulled-out, charger-inserted, DCIN-over/under-voltage, charger-stopped,
+and others critical to chargers, the system should be configured to wake up.
+At least the following should wake up the system from a suspend:
+a) charger-on/off b) external-power-in/out c) battery-in/out (while charging)
+
+It is usually accomplished by configuring the PMIC as a wakeup source.
diff --git a/Documentation/security/00-INDEX b/Documentation/security/00-INDEX
index 19bc494..99b85d3 100644
--- a/Documentation/security/00-INDEX
+++ b/Documentation/security/00-INDEX
@@ -1,5 +1,7 @@
00-INDEX
- this file.
+LSM.txt
+ - description of the Linux Security Module framework.
SELinux.txt
- how to get started with the SELinux security enhancement.
Smack.txt
diff --git a/Documentation/security/LSM.txt b/Documentation/security/LSM.txt
new file mode 100644
index 0000000..c335a76
--- /dev/null
+++ b/Documentation/security/LSM.txt
@@ -0,0 +1,34 @@
+Linux Security Module framework
+-------------------------------
+
+The Linux Security Module (LSM) framework provides a mechanism for
+various security checks to be hooked by new kernel extensions. The name
+"module" is a bit of a misnomer since these extensions are not actually
+loadable kernel modules. Instead, they are selectable at build-time via
+CONFIG_DEFAULT_SECURITY and can be overridden at boot-time via the
+"security=..." kernel command line argument, in the case where multiple
+LSMs were built into a given kernel.
+
+The primary users of the LSM interface are Mandatory Access Control
+(MAC) extensions which provide a comprehensive security policy. Examples
+include SELinux, Smack, Tomoyo, and AppArmor. In addition to the larger
+MAC extensions, other extensions can be built using the LSM to provide
+specific changes to system operation when these tweaks are not available
+in the core functionality of Linux itself.
+
+Without a specific LSM built into the kernel, the default LSM will be the
+Linux capabilities system. Most LSMs choose to extend the capabilities
+system, building their checks on top of the defined capability hooks.
+For more details on capabilities, see capabilities(7) in the Linux
+man-pages project.
+
+Based on http://kerneltrap.org/Linux/Documenting_Security_Module_Intent,
+a new LSM is accepted into the kernel when its intent (a description of
+what it tries to protect against and in what cases one would expect to
+use it) has been appropriately documented in Documentation/security/.
+This allows an LSM's code to be easily compared to its goals, and so
+that end users and distros can make a more informed decision about which
+LSMs suit their requirements.
+
+For extensive documentation on the available LSM hook interfaces, please
+see include/linux/security.h.
diff --git a/Documentation/security/credentials.txt b/Documentation/security/credentials.txt
index fc0366c..8625705 100644
--- a/Documentation/security/credentials.txt
+++ b/Documentation/security/credentials.txt
@@ -221,10 +221,10 @@
(5) LSM
The Linux Security Module allows extra controls to be placed over the
- operations that a task may do. Currently Linux supports two main
- alternate LSM options: SELinux and Smack.
+ operations that a task may do. Currently Linux supports several LSM
+ options.
- Both work by labelling the objects in a system and then applying sets of
+ Some work by labelling the objects in a system and then applying sets of
rules (policies) that say what operations a task with one label may do to
an object with another label.
diff --git a/Documentation/sound/alsa/HD-Audio-Models.txt b/Documentation/sound/alsa/HD-Audio-Models.txt
index edad99a..c8c5454 100644
--- a/Documentation/sound/alsa/HD-Audio-Models.txt
+++ b/Documentation/sound/alsa/HD-Audio-Models.txt
@@ -42,19 +42,7 @@
ALC262
======
- fujitsu Fujitsu Laptop
- benq Benq ED8
- benq-t31 Benq T31
- hippo Hippo (ATI) with jack detection, Sony UX-90s
- hippo_1 Hippo (Benq) with jack detection
- toshiba-s06 Toshiba S06
- toshiba-rx1 Toshiba RX1
- tyan Tyan Thunder n6650W (S2915-E)
- ultra Samsung Q1 Ultra Vista model
- lenovo-3000 Lenovo 3000 y410
- nec NEC Versa S9100
- basic fixed pin assignment w/o SPDIF
- auto auto-config reading BIOS (default)
+ N/A
ALC267/268
==========
@@ -350,7 +338,6 @@
mic-ref Reference board with power management for ports
dell-s14 Dell laptop
dell-vostro-3500 Dell Vostro 3500 laptop
- hp HP laptops with (inverted) mute-LED
hp-dv7-4000 HP dv-7 4000
auto BIOS setup (default)
diff --git a/Documentation/sound/alsa/compress_offload.txt b/Documentation/sound/alsa/compress_offload.txt
new file mode 100644
index 0000000..c83a835
--- /dev/null
+++ b/Documentation/sound/alsa/compress_offload.txt
@@ -0,0 +1,188 @@
+ compress_offload.txt
+ =====================
+ Pierre-Louis.Bossart <pierre-louis.bossart@linux.intel.com>
+ Vinod Koul <vinod.koul@linux.intel.com>
+
+Overview
+
+Since its early days, the ALSA API was defined with PCM support or
+constant bitrates payloads such as IEC61937 in mind. Arguments and
+returned values in frames are the norm, making it a challenge to
+extend the existing API to compressed data streams.
+
+In recent years, audio digital signal processors (DSP) were integrated
+in system-on-chip designs, and DSPs are also integrated in audio
+codecs. Processing compressed data on such DSPs results in a dramatic
+reduction of power consumption compared to host-based
+processing. Support for such hardware has not been very good in Linux,
+mostly because of a lack of a generic API available in the mainline
+kernel.
+
+Rather than requiring a compability break with an API change of the
+ALSA PCM interface, a new 'Compressed Data' API is introduced to
+provide a control and data-streaming interface for audio DSPs.
+
+The design of this API was inspired by the 2-year experience with the
+Intel Moorestown SOC, with many corrections required to upstream the
+API in the mainline kernel instead of the staging tree and make it
+usable by others.
+
+Requirements
+
+The main requirements are:
+
+- separation between byte counts and time. Compressed formats may have
+ a header per file, per frame, or no header at all. The payload size
+ may vary from frame-to-frame. As a result, it is not possible to
+ estimate reliably the duration of audio buffers when handling
+ compressed data. Dedicated mechanisms are required to allow for
+ reliable audio-video synchronization, which requires precise
+ reporting of the number of samples rendered at any given time.
+
+- Handling of multiple formats. PCM data only requires a specification
+ of the sampling rate, number of channels and bits per sample. In
+ contrast, compressed data comes in a variety of formats. Audio DSPs
+ may also provide support for a limited number of audio encoders and
+ decoders embedded in firmware, or may support more choices through
+ dynamic download of libraries.
+
+- Focus on main formats. This API provides support for the most
+ popular formats used for audio and video capture and playback. It is
+ likely that as audio compression technology advances, new formats
+ will be added.
+
+- Handling of multiple configurations. Even for a given format like
+ AAC, some implementations may support AAC multichannel but HE-AAC
+ stereo. Likewise WMA10 level M3 may require too much memory and cpu
+ cycles. The new API needs to provide a generic way of listing these
+ formats.
+
+- Rendering/Grabbing only. This API does not provide any means of
+ hardware acceleration, where PCM samples are provided back to
+ user-space for additional processing. This API focuses instead on
+ streaming compressed data to a DSP, with the assumption that the
+ decoded samples are routed to a physical output or logical back-end.
+
+ - Complexity hiding. Existing user-space multimedia frameworks all
+ have existing enums/structures for each compressed format. This new
+ API assumes the existence of a platform-specific compatibility layer
+ to expose, translate and make use of the capabilities of the audio
+ DSP, eg. Android HAL or PulseAudio sinks. By construction, regular
+ applications are not supposed to make use of this API.
+
+
+Design
+
+The new API shares a number of concepts with with the PCM API for flow
+control. Start, pause, resume, drain and stop commands have the same
+semantics no matter what the content is.
+
+The concept of memory ring buffer divided in a set of fragments is
+borrowed from the ALSA PCM API. However, only sizes in bytes can be
+specified.
+
+Seeks/trick modes are assumed to be handled by the host.
+
+The notion of rewinds/forwards is not supported. Data committed to the
+ring buffer cannot be invalidated, except when dropping all buffers.
+
+The Compressed Data API does not make any assumptions on how the data
+is transmitted to the audio DSP. DMA transfers from main memory to an
+embedded audio cluster or to a SPI interface for external DSPs are
+possible. As in the ALSA PCM case, a core set of routines is exposed;
+each driver implementer will have to write support for a set of
+mandatory routines and possibly make use of optional ones.
+
+The main additions are
+
+- get_caps
+This routine returns the list of audio formats supported. Querying the
+codecs on a capture stream will return encoders, decoders will be
+listed for playback streams.
+
+- get_codec_caps For each codec, this routine returns a list of
+capabilities. The intent is to make sure all the capabilities
+correspond to valid settings, and to minimize the risks of
+configuration failures. For example, for a complex codec such as AAC,
+the number of channels supported may depend on a specific profile. If
+the capabilities were exposed with a single descriptor, it may happen
+that a specific combination of profiles/channels/formats may not be
+supported. Likewise, embedded DSPs have limited memory and cpu cycles,
+it is likely that some implementations make the list of capabilities
+dynamic and dependent on existing workloads. In addition to codec
+settings, this routine returns the minimum buffer size handled by the
+implementation. This information can be a function of the DMA buffer
+sizes, the number of bytes required to synchronize, etc, and can be
+used by userspace to define how much needs to be written in the ring
+buffer before playback can start.
+
+- set_params
+This routine sets the configuration chosen for a specific codec. The
+most important field in the parameters is the codec type; in most
+cases decoders will ignore other fields, while encoders will strictly
+comply to the settings
+
+- get_params
+This routines returns the actual settings used by the DSP. Changes to
+the settings should remain the exception.
+
+- get_timestamp
+The timestamp becomes a multiple field structure. It lists the number
+of bytes transferred, the number of samples processed and the number
+of samples rendered/grabbed. All these values can be used to determine
+the avarage bitrate, figure out if the ring buffer needs to be
+refilled or the delay due to decoding/encoding/io on the DSP.
+
+Note that the list of codecs/profiles/modes was derived from the
+OpenMAX AL specification instead of reinventing the wheel.
+Modifications include:
+- Addition of FLAC and IEC formats
+- Merge of encoder/decoder capabilities
+- Profiles/modes listed as bitmasks to make descriptors more compact
+- Addition of set_params for decoders (missing in OpenMAX AL)
+- Addition of AMR/AMR-WB encoding modes (missing in OpenMAX AL)
+- Addition of format information for WMA
+- Addition of encoding options when required (derived from OpenMAX IL)
+- Addition of rateControlSupported (missing in OpenMAX AL)
+
+Not supported:
+
+- Support for VoIP/circuit-switched calls is not the target of this
+ API. Support for dynamic bit-rate changes would require a tight
+ coupling between the DSP and the host stack, limiting power savings.
+
+- Packet-loss concealment is not supported. This would require an
+ additional interface to let the decoder synthesize data when frames
+ are lost during transmission. This may be added in the future.
+
+- Volume control/routing is not handled by this API. Devices exposing a
+ compressed data interface will be considered as regular ALSA devices;
+ volume changes and routing information will be provided with regular
+ ALSA kcontrols.
+
+- Embedded audio effects. Such effects should be enabled in the same
+ manner, no matter if the input was PCM or compressed.
+
+- multichannel IEC encoding. Unclear if this is required.
+
+- Encoding/decoding acceleration is not supported as mentioned
+ above. It is possible to route the output of a decoder to a capture
+ stream, or even implement transcoding capabilities. This routing
+ would be enabled with ALSA kcontrols.
+
+- Audio policy/resource management. This API does not provide any
+ hooks to query the utilization of the audio DSP, nor any premption
+ mechanisms.
+
+- No notion of underun/overrun. Since the bytes written are compressed
+ in nature and data written/read doesn't translate directly to
+ rendered output in time, this does not deal with underrun/overun and
+ maybe dealt in user-library
+
+Credits:
+- Mark Brown and Liam Girdwood for discussions on the need for this API
+- Harsha Priya for her work on intel_sst compressed API
+- Rakesh Ughreja for valuable feedback
+- Sing Nallasellan, Sikkandar Madar and Prasanna Samaga for
+ demonstrating and quantifying the benefits of audio offload on a
+ real platform.
diff --git a/Documentation/sysctl/kernel.txt b/Documentation/sysctl/kernel.txt
index 1f24636..6d8cd8b 100644
--- a/Documentation/sysctl/kernel.txt
+++ b/Documentation/sysctl/kernel.txt
@@ -49,6 +49,7 @@
- panic
- panic_on_oops
- panic_on_unrecovered_nmi
+- panic_on_stackoverflow
- pid_max
- powersave-nap [ PPC only ]
- printk
@@ -393,6 +394,19 @@
==============================================================
+panic_on_stackoverflow:
+
+Controls the kernel's behavior when detecting the overflows of
+kernel, IRQ and exception stacks except a user stack.
+This file shows up if CONFIG_DEBUG_STACKOVERFLOW is enabled.
+
+0: try to continue operation.
+
+1: panic immediately.
+
+==============================================================
+
+
pid_max:
PID allocation wrap value. When the kernel's next PID value
diff --git a/Documentation/vm/slub.txt b/Documentation/vm/slub.txt
index f464f47..2acdda9 100644
--- a/Documentation/vm/slub.txt
+++ b/Documentation/vm/slub.txt
@@ -117,7 +117,7 @@
slub_min_objects=x (default 4)
slub_min_order=x (default 0)
-slub_max_order=x (default 1)
+slub_max_order=x (default 3 (PAGE_ALLOC_COSTLY_ORDER))
slub_min_objects allows to specify how many objects must at least fit
into one slab in order for the allocation order to be acceptable.
diff --git a/MAINTAINERS b/MAINTAINERS
index 311b0c4..1094edf 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -537,6 +537,7 @@
F: sound/soc/codecs/adav*
F: sound/soc/codecs/ad1*
F: sound/soc/codecs/ssm*
+F: sound/soc/codecs/sigmadsp.*
ANALOG DEVICES INC ASOC DRIVERS
L: uclinux-dist-devel@blackfin.uclinux.org
diff --git a/arch/alpha/kernel/pci.c b/arch/alpha/kernel/pci.c
index f3cae27..8c723c1 100644
--- a/arch/alpha/kernel/pci.c
+++ b/arch/alpha/kernel/pci.c
@@ -281,27 +281,9 @@
void __devinit
pcibios_fixup_bus(struct pci_bus *bus)
{
- /* Propagate hose info into the subordinate devices. */
-
- struct pci_controller *hose = bus->sysdata;
struct pci_dev *dev = bus->self;
- if (!dev) {
- /* Root bus. */
- u32 pci_mem_end;
- u32 sg_base = hose->sg_pci ? hose->sg_pci->dma_base : ~0;
- unsigned long end;
-
- bus->resource[0] = hose->io_space;
- bus->resource[1] = hose->mem_space;
-
- /* Adjust hose mem_space limit to prevent PCI allocations
- in the iommu windows. */
- pci_mem_end = min((u32)__direct_map_base, sg_base) - 1;
- end = hose->mem_space->start + pci_mem_end;
- if (hose->mem_space->end > end)
- hose->mem_space->end = end;
- } else if (pci_probe_only &&
+ if (pci_probe_only && dev &&
(dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) {
pci_read_bridge_bases(bus);
pcibios_fixup_device_resources(dev, bus);
@@ -414,13 +396,31 @@
common_init_pci(void)
{
struct pci_controller *hose;
+ struct list_head resources;
struct pci_bus *bus;
int next_busno;
int need_domain_info = 0;
+ u32 pci_mem_end;
+ u32 sg_base;
+ unsigned long end;
/* Scan all of the recorded PCI controllers. */
for (next_busno = 0, hose = hose_head; hose; hose = hose->next) {
- bus = pci_scan_bus(next_busno, alpha_mv.pci_ops, hose);
+ sg_base = hose->sg_pci ? hose->sg_pci->dma_base : ~0;
+
+ /* Adjust hose mem_space limit to prevent PCI allocations
+ in the iommu windows. */
+ pci_mem_end = min((u32)__direct_map_base, sg_base) - 1;
+ end = hose->mem_space->start + pci_mem_end;
+ if (hose->mem_space->end > end)
+ hose->mem_space->end = end;
+
+ INIT_LIST_HEAD(&resources);
+ pci_add_resource(&resources, hose->io_space);
+ pci_add_resource(&resources, hose->mem_space);
+
+ bus = pci_scan_root_bus(NULL, next_busno, alpha_mv.pci_ops,
+ hose, &resources);
hose->bus = bus;
hose->need_domain_info = need_domain_info;
next_busno = bus->subordinate + 1;
diff --git a/arch/arm/common/it8152.c b/arch/arm/common/it8152.c
index b539ec8..d1bcd7b 100644
--- a/arch/arm/common/it8152.c
+++ b/arch/arm/common/it8152.c
@@ -299,8 +299,8 @@
goto err1;
}
- sys->resource[0] = &it8152_io;
- sys->resource[1] = &it8152_mem;
+ pci_add_resource(&sys->resources, &it8152_io);
+ pci_add_resource(&sys->resources, &it8152_mem);
if (platform_notify || platform_notify_remove) {
printk(KERN_ERR "PCI: Can't use platform_notify\n");
@@ -327,6 +327,9 @@
*/
unsigned int pcibios_max_latency = 255;
+/* ITE bridge requires setting latency timer to avoid early bus access
+ termination by PCI bus master devices
+*/
void pcibios_set_master(struct pci_dev *dev)
{
u8 lat;
@@ -352,7 +355,7 @@
struct pci_bus * __init it8152_pci_scan_bus(int nr, struct pci_sys_data *sys)
{
- return pci_scan_bus(nr, &it8152_ops, sys);
+ return pci_scan_root_bus(NULL, nr, &it8152_ops, sys, &sys->resources);
}
EXPORT_SYMBOL(dma_set_coherent_mask);
diff --git a/arch/arm/common/via82c505.c b/arch/arm/common/via82c505.c
index 8421d39..67dd2af 100644
--- a/arch/arm/common/via82c505.c
+++ b/arch/arm/common/via82c505.c
@@ -86,7 +86,8 @@
struct pci_bus * __init via82c505_scan_bus(int nr, struct pci_sys_data *sysdata)
{
if (nr == 0)
- return pci_scan_bus(0, &via82c505_ops, sysdata);
+ return pci_scan_root_bus(NULL, 0, &via82c505_ops, sysdata,
+ &sysdata->resources);
return NULL;
}
diff --git a/arch/arm/configs/bonito_defconfig b/arch/arm/configs/bonito_defconfig
new file mode 100644
index 0000000..5457108
--- /dev/null
+++ b/arch/arm/configs/bonito_defconfig
@@ -0,0 +1,72 @@
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=16
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+# CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_ARCH_SHMOBILE=y
+CONFIG_ARCH_R8A7740=y
+CONFIG_MACH_BONITO=y
+# CONFIG_SH_TIMER_TMU is not set
+CONFIG_AEABI=y
+# CONFIG_OABI_COMPAT is not set
+CONFIG_FORCE_MAX_ZONEORDER=12
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="console=ttySC5,115200 earlyprintk=sh-sci.5,115200 ignore_loglevel"
+CONFIG_KEXEC=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+# CONFIG_SUSPEND is not set
+CONFIG_PM_RUNTIME=y
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_FIRMWARE_IN_KERNEL is not set
+CONFIG_MTD=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_ARM_INTEGRATOR=y
+CONFIG_MTD_BLOCK2MTD=y
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+# CONFIG_SCSI_LOWLEVEL is not set
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_LEGACY_PTYS is not set
+CONFIG_SERIAL_SH_SCI=y
+CONFIG_SERIAL_SH_SCI_NR_UARTS=9
+CONFIG_SERIAL_SH_SCI_CONSOLE=y
+# CONFIG_HW_RANDOM is not set
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_SH_MOBILE=y
+CONFIG_GPIO_SYSFS=y
+# CONFIG_HWMON is not set
+# CONFIG_MFD_SUPPORT is not set
+# CONFIG_HID_SUPPORT is not set
+# CONFIG_USB_SUPPORT is not set
+CONFIG_UIO=y
+CONFIG_UIO_PDRV=y
+CONFIG_UIO_PDRV_GENIRQ=y
+# CONFIG_DNOTIFY is not set
+# CONFIG_INOTIFY_USER is not set
+CONFIG_TMPFS=y
+# CONFIG_MISC_FILESYSTEMS is not set
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+# CONFIG_ENABLE_MUST_CHECK is not set
+# CONFIG_ARM_UNWIND is not set
diff --git a/arch/arm/configs/kota2_defconfig b/arch/arm/configs/kota2_defconfig
new file mode 100644
index 0000000..b7735d6
--- /dev/null
+++ b/arch/arm/configs/kota2_defconfig
@@ -0,0 +1,122 @@
+# CONFIG_ARM_PATCH_PHYS_VIRT is not set
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=16
+CONFIG_CGROUPS=y
+CONFIG_CPUSETS=y
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+# CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_EMBEDDED=y
+CONFIG_SLAB=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_ARCH_SHMOBILE=y
+CONFIG_KEYBOARD_GPIO_POLLED=y
+CONFIG_ARCH_SH73A0=y
+CONFIG_MACH_KOTA2=y
+CONFIG_MEMORY_SIZE=0x1e0000000
+# CONFIG_SH_TIMER_TMU is not set
+# CONFIG_SWP_EMULATE is not set
+CONFIG_CPU_BPREDICT_DISABLE=y
+CONFIG_ARM_ERRATA_460075=y
+CONFIG_ARM_ERRATA_742230=y
+CONFIG_ARM_ERRATA_742231=y
+CONFIG_PL310_ERRATA_588369=y
+CONFIG_ARM_ERRATA_720789=y
+CONFIG_PL310_ERRATA_727915=y
+CONFIG_ARM_ERRATA_743622=y
+CONFIG_ARM_ERRATA_751472=y
+CONFIG_PL310_ERRATA_753970=y
+CONFIG_ARM_ERRATA_754322=y
+CONFIG_PL310_ERRATA_769419=y
+CONFIG_NO_HZ=y
+CONFIG_SMP=y
+CONFIG_AEABI=y
+# CONFIG_OABI_COMPAT is not set
+CONFIG_HIGHMEM=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="console=ttySC2,115200 earlyprintk=sh-sci.2,115200 ignore_loglevel"
+CONFIG_CMDLINE_FORCE=y
+CONFIG_KEXEC=y
+CONFIG_CPU_IDLE=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_PM_RUNTIME=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+# CONFIG_INET_DIAG is not set
+# CONFIG_IPV6 is not set
+CONFIG_CFG80211=y
+CONFIG_WIRELESS_EXT_SYSFS=y
+CONFIG_MAC80211=y
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_BLK_DEV is not set
+CONFIG_NETDEVICES=y
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_VENDOR_CHELSIO is not set
+# CONFIG_NET_VENDOR_FARADAY is not set
+# CONFIG_NET_VENDOR_INTEL is not set
+# CONFIG_NET_VENDOR_MARVELL is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+CONFIG_SMSC911X=y
+# CONFIG_NET_VENDOR_STMICRO is not set
+CONFIG_B43=y
+CONFIG_B43_PHY_N=y
+CONFIG_B43_DEBUG=y
+CONFIG_INPUT_SPARSEKMAP=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_KEYBOARD_ATKBD is not set
+CONFIG_KEYBOARD_GPIO=y
+CONFIG_KEYBOARD_SH_KEYSC=y
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_LEGACY_PTYS is not set
+CONFIG_SERIAL_SH_SCI=y
+CONFIG_SERIAL_SH_SCI_NR_UARTS=9
+CONFIG_SERIAL_SH_SCI_CONSOLE=y
+# CONFIG_HW_RANDOM is not set
+CONFIG_I2C_SH_MOBILE=y
+# CONFIG_HWMON is not set
+CONFIG_BCMA=y
+CONFIG_BCMA_DEBUG=y
+CONFIG_FB=y
+CONFIG_FB_SH_MOBILE_LCDC=y
+CONFIG_LCD_PLATFORM=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
+# CONFIG_HID_SUPPORT is not set
+# CONFIG_USB_SUPPORT is not set
+CONFIG_MMC=y
+CONFIG_MMC_SDHI=y
+CONFIG_MMC_SH_MMCIF=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_RENESAS_TPU=y
+CONFIG_LEDS_TRIGGERS=y
+# CONFIG_DNOTIFY is not set
+# CONFIG_INOTIFY_USER is not set
+CONFIG_TMPFS=y
+# CONFIG_MISC_FILESYSTEMS is not set
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_INFO_REDUCED=y
+# CONFIG_FTRACE is not set
+CONFIG_DEBUG_USER=y
diff --git a/arch/arm/configs/marzen_defconfig b/arch/arm/configs/marzen_defconfig
new file mode 100644
index 0000000..864f9a5
--- /dev/null
+++ b/arch/arm/configs/marzen_defconfig
@@ -0,0 +1,87 @@
+# CONFIG_ARM_PATCH_PHYS_VIRT is not set
+CONFIG_EXPERIMENTAL=y
+CONFIG_KERNEL_LZMA=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=16
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_EMBEDDED=y
+CONFIG_SLAB=y
+# CONFIG_BLOCK is not set
+CONFIG_ARCH_SHMOBILE=y
+CONFIG_ARCH_R8A7779=y
+CONFIG_MACH_MARZEN=y
+CONFIG_MEMORY_START=0x60000000
+CONFIG_MEMORY_SIZE=0x10000000
+CONFIG_SHMOBILE_TIMER_HZ=1024
+# CONFIG_SH_TIMER_CMT is not set
+# CONFIG_SWP_EMULATE is not set
+CONFIG_ARM_ERRATA_430973=y
+CONFIG_ARM_ERRATA_458693=y
+CONFIG_ARM_ERRATA_460075=y
+CONFIG_ARM_ERRATA_743622=y
+CONFIG_ARM_ERRATA_754322=y
+CONFIG_NO_HZ=y
+CONFIG_SMP=y
+# CONFIG_ARM_CPU_TOPOLOGY is not set
+CONFIG_AEABI=y
+# CONFIG_OABI_COMPAT is not set
+CONFIG_HIGHMEM=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="console=ttySC2,115200 earlyprintk=sh-sci.2,115200 ignore_loglevel"
+CONFIG_CMDLINE_FORCE=y
+CONFIG_KEXEC=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_PM_RUNTIME=y
+CONFIG_NET=y
+CONFIG_INET=y
+# CONFIG_IPV6 is not set
+# CONFIG_WIRELESS is not set
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+# CONFIG_STANDALONE is not set
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+# CONFIG_FW_LOADER is not set
+CONFIG_NETDEVICES=y
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_VENDOR_FARADAY is not set
+# CONFIG_NET_VENDOR_INTEL is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+CONFIG_SMC911X=y
+CONFIG_SMSC911X=y
+# CONFIG_NET_VENDOR_STMICRO is not set
+# CONFIG_WLAN is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+# CONFIG_VT is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_DEVKMEM is not set
+CONFIG_SERIAL_SH_SCI=y
+CONFIG_SERIAL_SH_SCI_NR_UARTS=6
+CONFIG_SERIAL_SH_SCI_CONSOLE=y
+# CONFIG_HW_RANDOM is not set
+CONFIG_GPIO_SYSFS=y
+# CONFIG_HWMON is not set
+CONFIG_SSB=y
+# CONFIG_HID_SUPPORT is not set
+# CONFIG_USB_SUPPORT is not set
+CONFIG_UIO=y
+CONFIG_UIO_PDRV_GENIRQ=y
+# CONFIG_IOMMU_SUPPORT is not set
+# CONFIG_FILE_LOCKING is not set
+# CONFIG_DNOTIFY is not set
+# CONFIG_INOTIFY_USER is not set
+CONFIG_TMPFS=y
+# CONFIG_MISC_FILESYSTEMS is not set
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_INFO_REDUCED=y
+# CONFIG_FTRACE is not set
+CONFIG_DEBUG_USER=y
+CONFIG_AVERAGE=y
diff --git a/arch/arm/include/asm/mach/pci.h b/arch/arm/include/asm/mach/pci.h
index 186efd4..d943b7d 100644
--- a/arch/arm/include/asm/mach/pci.h
+++ b/arch/arm/include/asm/mach/pci.h
@@ -40,7 +40,7 @@
u64 mem_offset; /* bus->cpu memory mapping offset */
unsigned long io_offset; /* bus->cpu IO mapping offset */
struct pci_bus *bus; /* PCI bus */
- struct resource *resource[3]; /* Primary PCI bus resources */
+ struct list_head resources; /* root bus resources (apertures) */
/* Bridge swizzling */
u8 (*swizzle)(struct pci_dev *, u8 *);
/* IRQ mapping */
diff --git a/arch/arm/include/asm/pci.h b/arch/arm/include/asm/pci.h
index 2b1f245..da337ba 100644
--- a/arch/arm/include/asm/pci.h
+++ b/arch/arm/include/asm/pci.h
@@ -31,18 +31,6 @@
}
#endif /* CONFIG_PCI_DOMAINS */
-#ifdef CONFIG_PCI_HOST_ITE8152
-/* ITE bridge requires setting latency timer to avoid early bus access
- termination by PIC bus mater devices
-*/
-extern void pcibios_set_master(struct pci_dev *dev);
-#else
-static inline void pcibios_set_master(struct pci_dev *dev)
-{
- /* No special bus mastering setup handling */
-}
-#endif
-
static inline void pcibios_penalize_isa_irq(int irq, int active)
{
/* We don't do dynamic PCI IRQ allocation */
diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c
index b530e91..f58ba35 100644
--- a/arch/arm/kernel/bios32.c
+++ b/arch/arm/kernel/bios32.c
@@ -316,21 +316,6 @@
}
}
-static void __devinit
-pbus_assign_bus_resources(struct pci_bus *bus, struct pci_sys_data *root)
-{
- struct pci_dev *dev = bus->self;
- int i;
-
- if (!dev) {
- /*
- * Assign root bus resources.
- */
- for (i = 0; i < 3; i++)
- bus->resource[i] = root->resource[i];
- }
-}
-
/*
* pcibios_fixup_bus - Called after each bus is probed,
* but before its children are examined.
@@ -341,8 +326,6 @@
struct pci_dev *dev;
u16 features = PCI_COMMAND_SERR | PCI_COMMAND_PARITY | PCI_COMMAND_FAST_BACK;
- pbus_assign_bus_resources(bus, root);
-
/*
* Walk the devices on this bus, working out what we can
* and can't support.
@@ -508,12 +491,18 @@
sys->busnr = busnr;
sys->swizzle = hw->swizzle;
sys->map_irq = hw->map_irq;
- sys->resource[0] = &ioport_resource;
- sys->resource[1] = &iomem_resource;
+ INIT_LIST_HEAD(&sys->resources);
ret = hw->setup(nr, sys);
if (ret > 0) {
+ if (list_empty(&sys->resources)) {
+ pci_add_resource(&sys->resources,
+ &ioport_resource);
+ pci_add_resource(&sys->resources,
+ &iomem_resource);
+ }
+
sys->bus = hw->scan(nr, sys);
if (!sys->bus)
@@ -571,6 +560,13 @@
}
}
+#ifndef CONFIG_PCI_HOST_ITE8152
+void pcibios_set_master(struct pci_dev *dev)
+{
+ /* No special bus mastering setup handling */
+}
+#endif
+
char * __init pcibios_setup(char *str)
{
if (!strcmp(str, "debug")) {
diff --git a/arch/arm/mach-cns3xxx/pcie.c b/arch/arm/mach-cns3xxx/pcie.c
index 0f8fca4..e159d69 100644
--- a/arch/arm/mach-cns3xxx/pcie.c
+++ b/arch/arm/mach-cns3xxx/pcie.c
@@ -151,13 +151,12 @@
struct cns3xxx_pcie *cnspci = sysdata_to_cnspci(sys);
struct resource *res_io = &cnspci->res_io;
struct resource *res_mem = &cnspci->res_mem;
- struct resource **sysres = sys->resource;
BUG_ON(request_resource(&iomem_resource, res_io) ||
request_resource(&iomem_resource, res_mem));
- sysres[0] = res_io;
- sysres[1] = res_mem;
+ pci_add_resource(&sys->resources, res_io);
+ pci_add_resource(&sys->resources, res_mem);
return 1;
}
@@ -169,7 +168,8 @@
static struct pci_bus *cns3xxx_pci_scan_bus(int nr, struct pci_sys_data *sys)
{
- return pci_scan_bus(sys->busnr, &cns3xxx_pcie_ops, sys);
+ return pci_scan_root_bus(NULL, sys->busnr, &cns3xxx_pcie_ops, sys,
+ &sys->resources);
}
static int cns3xxx_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
diff --git a/arch/arm/mach-dove/pcie.c b/arch/arm/mach-dove/pcie.c
index 6c11a4d..52e96d3 100644
--- a/arch/arm/mach-dove/pcie.c
+++ b/arch/arm/mach-dove/pcie.c
@@ -69,7 +69,7 @@
pp->res[0].flags = IORESOURCE_IO;
if (request_resource(&ioport_resource, &pp->res[0]))
panic("Request PCIe IO resource failed\n");
- sys->resource[0] = &pp->res[0];
+ pci_add_resource(&sys->resources, &pp->res[0]);
/*
* IORESOURCE_MEM
@@ -88,9 +88,7 @@
pp->res[1].flags = IORESOURCE_MEM;
if (request_resource(&iomem_resource, &pp->res[1]))
panic("Request PCIe Memory resource failed\n");
- sys->resource[1] = &pp->res[1];
-
- sys->resource[2] = NULL;
+ pci_add_resource(&sys->resources, &pp->res[1]);
return 1;
}
@@ -184,7 +182,8 @@
struct pci_bus *bus;
if (nr < num_pcie_ports) {
- bus = pci_scan_bus(sys->busnr, &pcie_ops, sys);
+ bus = pci_scan_root_bus(NULL, sys->busnr, &pcie_ops, sys,
+ &sys->resources);
} else {
bus = NULL;
BUG();
diff --git a/arch/arm/mach-exynos/include/mach/cpufreq.h b/arch/arm/mach-exynos/include/mach/cpufreq.h
new file mode 100644
index 0000000..3df27f2
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/cpufreq.h
@@ -0,0 +1,34 @@
+/* linux/arch/arm/mach-exynos/include/mach/cpufreq.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * EXYNOS - CPUFreq support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+enum cpufreq_level_index {
+ L0, L1, L2, L3, L4,
+ L5, L6, L7, L8, L9,
+ L10, L11, L12, L13, L14,
+ L15, L16, L17, L18, L19,
+ L20,
+};
+
+struct exynos_dvfs_info {
+ unsigned long mpll_freq_khz;
+ unsigned int pll_safe_idx;
+ unsigned int pm_lock_idx;
+ unsigned int max_support_idx;
+ unsigned int min_support_idx;
+ struct clk *cpu_clk;
+ unsigned int *volt_table;
+ struct cpufreq_frequency_table *freq_table;
+ void (*set_freq)(unsigned int, unsigned int);
+ bool (*need_apll_change)(unsigned int, unsigned int);
+};
+
+extern int exynos4210_cpufreq_init(struct exynos_dvfs_info *);
diff --git a/arch/arm/mach-footbridge/dc21285.c b/arch/arm/mach-footbridge/dc21285.c
index 18c32a5..f685650 100644
--- a/arch/arm/mach-footbridge/dc21285.c
+++ b/arch/arm/mach-footbridge/dc21285.c
@@ -275,9 +275,9 @@
allocate_resource(&iomem_resource, &res[0], 0x40000000,
0x80000000, 0xffffffff, 0x40000000, NULL, NULL);
- sys->resource[0] = &ioport_resource;
- sys->resource[1] = &res[0];
- sys->resource[2] = &res[1];
+ pci_add_resource(&sys->resources, &ioport_resource);
+ pci_add_resource(&sys->resources, &res[0]);
+ pci_add_resource(&sys->resources, &res[1]);
sys->mem_offset = DC21285_PCI_MEM;
return 1;
@@ -285,7 +285,7 @@
struct pci_bus * __init dc21285_scan_bus(int nr, struct pci_sys_data *sys)
{
- return pci_scan_bus(0, &dc21285_ops, sys);
+ return pci_scan_root_bus(NULL, 0, &dc21285_ops, sys, &sys->resources);
}
#define dc21285_request_irq(_a, _b, _c, _d, _e) \
diff --git a/arch/arm/mach-integrator/pci_v3.c b/arch/arm/mach-integrator/pci_v3.c
index b4d8f8b..3c82566 100644
--- a/arch/arm/mach-integrator/pci_v3.c
+++ b/arch/arm/mach-integrator/pci_v3.c
@@ -359,7 +359,7 @@
.flags = IORESOURCE_MEM | IORESOURCE_PREFETCH,
};
-static int __init pci_v3_setup_resources(struct resource **resource)
+static int __init pci_v3_setup_resources(struct pci_sys_data *sys)
{
if (request_resource(&iomem_resource, &non_mem)) {
printk(KERN_ERR "PCI: unable to allocate non-prefetchable "
@@ -374,13 +374,13 @@
}
/*
- * bus->resource[0] is the IO resource for this bus
- * bus->resource[1] is the mem resource for this bus
- * bus->resource[2] is the prefetch mem resource for this bus
+ * the IO resource for this bus
+ * the mem resource for this bus
+ * the prefetch mem resource for this bus
*/
- resource[0] = &ioport_resource;
- resource[1] = &non_mem;
- resource[2] = &pre_mem;
+ pci_add_resource(&sys->resources, &ioport_resource);
+ pci_add_resource(&sys->resources, &non_mem);
+ pci_add_resource(&sys->resources, &pre_mem);
return 1;
}
@@ -481,7 +481,7 @@
if (nr == 0) {
sys->mem_offset = PHYS_PCI_MEM_BASE;
- ret = pci_v3_setup_resources(sys->resource);
+ ret = pci_v3_setup_resources(sys);
}
return ret;
@@ -489,7 +489,8 @@
struct pci_bus * __init pci_v3_scan_bus(int nr, struct pci_sys_data *sys)
{
- return pci_scan_bus(sys->busnr, &pci_v3_ops, sys);
+ return pci_scan_root_bus(NULL, sys->busnr, &pci_v3_ops, sys,
+ &sys->resources);
}
/*
diff --git a/arch/arm/mach-iop13xx/pci.c b/arch/arm/mach-iop13xx/pci.c
index db012fa..b8f5a87 100644
--- a/arch/arm/mach-iop13xx/pci.c
+++ b/arch/arm/mach-iop13xx/pci.c
@@ -537,14 +537,14 @@
while(time_before(jiffies, atux_trhfa_timeout))
udelay(100);
- bus = pci_bus_atux = pci_scan_bus(sys->busnr,
- &iop13xx_atux_ops,
- sys);
+ bus = pci_bus_atux = pci_scan_root_bus(NULL, sys->busnr,
+ &iop13xx_atux_ops,
+ sys, &sys->resources);
break;
case IOP13XX_INIT_ATU_ATUE:
- bus = pci_bus_atue = pci_scan_bus(sys->busnr,
- &iop13xx_atue_ops,
- sys);
+ bus = pci_bus_atue = pci_scan_root_bus(NULL, sys->busnr,
+ &iop13xx_atue_ops,
+ sys, &sys->resources);
break;
}
@@ -1084,9 +1084,8 @@
request_resource(&ioport_resource, &res[0]);
request_resource(&iomem_resource, &res[1]);
- sys->resource[0] = &res[0];
- sys->resource[1] = &res[1];
- sys->resource[2] = NULL;
+ pci_add_resource(&sys->resources, &res[0]);
+ pci_add_resource(&sys->resources, &res[1]);
return 1;
}
diff --git a/arch/arm/mach-ixp2000/enp2611.c b/arch/arm/mach-ixp2000/enp2611.c
index ee52541..e872d23 100644
--- a/arch/arm/mach-ixp2000/enp2611.c
+++ b/arch/arm/mach-ixp2000/enp2611.c
@@ -145,7 +145,8 @@
static struct pci_bus * __init enp2611_pci_scan_bus(int nr,
struct pci_sys_data *sys)
{
- return pci_scan_bus(sys->busnr, &enp2611_pci_ops, sys);
+ return pci_scan_root_bus(NULL, sys->busnr, &enp2611_pci_ops, sys,
+ &sys->resources);
}
static int __init enp2611_pci_map_irq(const struct pci_dev *dev, u8 slot,
diff --git a/arch/arm/mach-ixp2000/pci.c b/arch/arm/mach-ixp2000/pci.c
index f5098b3..626fda4 100644
--- a/arch/arm/mach-ixp2000/pci.c
+++ b/arch/arm/mach-ixp2000/pci.c
@@ -132,7 +132,8 @@
struct pci_bus *ixp2000_pci_scan_bus(int nr, struct pci_sys_data *sysdata)
{
- return pci_scan_bus(sysdata->busnr, &ixp2000_pci_ops, sysdata);
+ return pci_scan_root_bus(NULL, sysdata->busnr, &ixp2000_pci_ops,
+ sysdata, &sysdata->resources);
}
@@ -242,9 +243,8 @@
if (nr >= 1)
return 0;
- sys->resource[0] = &ixp2000_pci_io_space;
- sys->resource[1] = &ixp2000_pci_mem_space;
- sys->resource[2] = NULL;
+ pci_add_resource(&sys->resources, &ixp2000_pci_io_space);
+ pci_add_resource(&sys->resources, &ixp2000_pci_mem_space);
return 1;
}
diff --git a/arch/arm/mach-ixp23xx/pci.c b/arch/arm/mach-ixp23xx/pci.c
index e6be571..25b5c46 100644
--- a/arch/arm/mach-ixp23xx/pci.c
+++ b/arch/arm/mach-ixp23xx/pci.c
@@ -143,7 +143,8 @@
struct pci_bus *ixp23xx_pci_scan_bus(int nr, struct pci_sys_data *sysdata)
{
- return pci_scan_bus(sysdata->busnr, &ixp23xx_pci_ops, sysdata);
+ return pci_scan_root_bus(NULL, sysdata->busnr, &ixp23xx_pci_ops,
+ sysdata, &sysdata->resources);
}
int ixp23xx_pci_abort_handler(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
@@ -280,9 +281,8 @@
if (nr >= 1)
return 0;
- sys->resource[0] = &ixp23xx_pci_io_space;
- sys->resource[1] = &ixp23xx_pci_mem_space;
- sys->resource[2] = NULL;
+ pci_add_resource(&sys->resources, &ixp23xx_pci_io_space);
+ pci_add_resource(&sys->resources, &ixp23xx_pci_mem_space);
return 1;
}
diff --git a/arch/arm/mach-ixp4xx/common-pci.c b/arch/arm/mach-ixp4xx/common-pci.c
index 8325058..5eff15f 100644
--- a/arch/arm/mach-ixp4xx/common-pci.c
+++ b/arch/arm/mach-ixp4xx/common-pci.c
@@ -472,9 +472,8 @@
request_resource(&ioport_resource, &res[0]);
request_resource(&iomem_resource, &res[1]);
- sys->resource[0] = &res[0];
- sys->resource[1] = &res[1];
- sys->resource[2] = NULL;
+ pci_add_resource(&sys->resources, &res[0]);
+ pci_add_resource(&sys->resources, &res[1]);
platform_notify = ixp4xx_pci_platform_notify;
platform_notify_remove = ixp4xx_pci_platform_notify_remove;
@@ -484,7 +483,8 @@
struct pci_bus * __devinit ixp4xx_scan_bus(int nr, struct pci_sys_data *sys)
{
- return pci_scan_bus(sys->busnr, &ixp4xx_ops, sys);
+ return pci_scan_root_bus(NULL, sys->busnr, &ixp4xx_ops, sys,
+ &sys->resources);
}
int dma_set_coherent_mask(struct device *dev, u64 mask)
diff --git a/arch/arm/mach-kirkwood/pcie.c b/arch/arm/mach-kirkwood/pcie.c
index fb451bf..a066a6d 100644
--- a/arch/arm/mach-kirkwood/pcie.c
+++ b/arch/arm/mach-kirkwood/pcie.c
@@ -198,9 +198,8 @@
if (request_resource(&iomem_resource, &pp->res[1]))
panic("Request PCIe%d Memory resource failed\n", index);
- sys->resource[0] = &pp->res[0];
- sys->resource[1] = &pp->res[1];
- sys->resource[2] = NULL;
+ pci_add_resource(&sys->resources, &pp->res[0]);
+ pci_add_resource(&sys->resources, &pp->res[1]);
sys->io_offset = 0;
/*
@@ -236,7 +235,8 @@
struct pci_bus *bus;
if (nr < num_pcie_ports) {
- bus = pci_scan_bus(sys->busnr, &pcie_ops, sys);
+ bus = pci_scan_root_bus(NULL, sys->busnr, &pcie_ops, sys,
+ &sys->resources);
} else {
bus = NULL;
BUG();
diff --git a/arch/arm/mach-ks8695/pci.c b/arch/arm/mach-ks8695/pci.c
index c7c9a18..b26f992 100644
--- a/arch/arm/mach-ks8695/pci.c
+++ b/arch/arm/mach-ks8695/pci.c
@@ -143,7 +143,8 @@
static struct pci_bus* __init ks8695_pci_scan_bus(int nr, struct pci_sys_data *sys)
{
- return pci_scan_bus(sys->busnr, &ks8695_pci_ops, sys);
+ return pci_scan_root_bus(NULL, sys->busnr, &ks8695_pci_ops, sys,
+ &sys->resources);
}
static struct resource pci_mem = {
@@ -168,9 +169,8 @@
request_resource(&iomem_resource, &pci_mem);
request_resource(&ioport_resource, &pci_io);
- sys->resource[0] = &pci_io;
- sys->resource[1] = &pci_mem;
- sys->resource[2] = NULL;
+ pci_add_resource(&sys->resources, &pci_io);
+ pci_add_resource(&sys->resources, &pci_mem);
/* Assign and enable processor bridge */
ks8695_local_writeconfig(PCI_BASE_ADDRESS_0, KS8695_PCIMEM_PA);
diff --git a/arch/arm/mach-mv78xx0/pcie.c b/arch/arm/mach-mv78xx0/pcie.c
index 12fcb10..8459f6d 100644
--- a/arch/arm/mach-mv78xx0/pcie.c
+++ b/arch/arm/mach-mv78xx0/pcie.c
@@ -155,9 +155,8 @@
orion_pcie_set_local_bus_nr(pp->base, sys->busnr);
orion_pcie_setup(pp->base);
- sys->resource[0] = &pp->res[0];
- sys->resource[1] = &pp->res[1];
- sys->resource[2] = NULL;
+ pci_add_resource(&sys->resources, &pp->res[0]);
+ pci_add_resource(&sys->resources, &pp->res[1]);
return 1;
}
@@ -251,7 +250,8 @@
struct pci_bus *bus;
if (nr < num_pcie_ports) {
- bus = pci_scan_bus(sys->busnr, &pcie_ops, sys);
+ bus = pci_scan_root_bus(NULL, sys->busnr, &pcie_ops, sys,
+ &sys->resources);
} else {
bus = NULL;
BUG();
diff --git a/arch/arm/mach-omap2/board-rx51-peripherals.c b/arch/arm/mach-omap2/board-rx51-peripherals.c
index d67bcdf..acb4e77 100644
--- a/arch/arm/mach-omap2/board-rx51-peripherals.c
+++ b/arch/arm/mach-omap2/board-rx51-peripherals.c
@@ -945,6 +945,9 @@
},
#endif
{
+ I2C_BOARD_INFO("bq27200", 0x55),
+ },
+ {
I2C_BOARD_INFO("tpa6130a2", 0x60),
.platform_data = &rx51_tpa6130a2_data,
}
diff --git a/arch/arm/mach-omap2/mcbsp.c b/arch/arm/mach-omap2/mcbsp.c
index 28fcb27..fb4bcf8 100644
--- a/arch/arm/mach-omap2/mcbsp.c
+++ b/arch/arm/mach-omap2/mcbsp.c
@@ -156,6 +156,9 @@
else
/* The FIFO has 128 locations */
pdata->buffer_size = 0x80;
+ } else if (oh->class->rev == MCBSP_CONFIG_TYPE4) {
+ /* The FIFO has 128 locations for all instances */
+ pdata->buffer_size = 0x80;
}
if (oh->class->rev >= MCBSP_CONFIG_TYPE3)
diff --git a/arch/arm/mach-orion5x/pci.c b/arch/arm/mach-orion5x/pci.c
index a494c47..09a045f 100644
--- a/arch/arm/mach-orion5x/pci.c
+++ b/arch/arm/mach-orion5x/pci.c
@@ -177,7 +177,7 @@
res[0].end = res[0].start + ORION5X_PCIE_IO_SIZE - 1;
if (request_resource(&ioport_resource, &res[0]))
panic("Request PCIe IO resource failed\n");
- sys->resource[0] = &res[0];
+ pci_add_resource(&sys->resources, &res[0]);
/*
* IORESOURCE_MEM
@@ -188,9 +188,8 @@
res[1].end = res[1].start + ORION5X_PCIE_MEM_SIZE - 1;
if (request_resource(&iomem_resource, &res[1]))
panic("Request PCIe Memory resource failed\n");
- sys->resource[1] = &res[1];
+ pci_add_resource(&sys->resources, &res[1]);
- sys->resource[2] = NULL;
sys->io_offset = 0;
return 1;
@@ -506,7 +505,7 @@
res[0].end = res[0].start + ORION5X_PCI_IO_SIZE - 1;
if (request_resource(&ioport_resource, &res[0]))
panic("Request PCI IO resource failed\n");
- sys->resource[0] = &res[0];
+ pci_add_resource(&sys->resources, &res[0]);
/*
* IORESOURCE_MEM
@@ -517,9 +516,8 @@
res[1].end = res[1].start + ORION5X_PCI_MEM_SIZE - 1;
if (request_resource(&iomem_resource, &res[1]))
panic("Request PCI Memory resource failed\n");
- sys->resource[1] = &res[1];
+ pci_add_resource(&sys->resources, &res[1]);
- sys->resource[2] = NULL;
sys->io_offset = 0;
return 1;
@@ -580,9 +578,11 @@
struct pci_bus *bus;
if (nr == 0) {
- bus = pci_scan_bus(sys->busnr, &pcie_ops, sys);
+ bus = pci_scan_root_bus(NULL, sys->busnr, &pcie_ops, sys,
+ &sys->resources);
} else if (nr == 1 && !orion5x_pci_disabled) {
- bus = pci_scan_bus(sys->busnr, &pci_ops, sys);
+ bus = pci_scan_root_bus(NULL, sys->busnr, &pci_ops, sys,
+ &sys->resources);
} else {
bus = NULL;
BUG();
diff --git a/arch/arm/mach-pxa/corgi.c b/arch/arm/mach-pxa/corgi.c
index 66600f0..11f1e73 100644
--- a/arch/arm/mach-pxa/corgi.c
+++ b/arch/arm/mach-pxa/corgi.c
@@ -436,6 +436,14 @@
};
/*
+ * Corgi Audio
+ */
+static struct platform_device corgi_audio_device = {
+ .name = "corgi-audio",
+ .id = -1,
+};
+
+/*
* MMC/SD Device
*
* The card detect interrupt isn't debounced so we delay it by 250ms
@@ -641,6 +649,7 @@
&corgifb_device,
&corgikbd_device,
&corgiled_device,
+ &corgi_audio_device,
&sharpsl_nand_device,
&sharpsl_rom_device,
};
diff --git a/arch/arm/mach-pxa/eseries.c b/arch/arm/mach-pxa/eseries.c
index f79a610..4cb2391 100644
--- a/arch/arm/mach-pxa/eseries.c
+++ b/arch/arm/mach-pxa/eseries.c
@@ -528,12 +528,18 @@
.resource = eseries_tmio_resources,
};
+static struct platform_device e740_audio_device = {
+ .name = "e740-audio",
+ .id = -1,
+};
+
/* ----------------------------------------------------------------------- */
static struct platform_device *e740_devices[] __initdata = {
&e740_fb_device,
&e740_t7l66xb_device,
&e7xx_gpio_vbus,
+ &e740_audio_device,
};
static void __init e740_init(void)
@@ -722,12 +728,18 @@
.resource = eseries_tmio_resources,
};
+static struct platform_device e750_audio_device = {
+ .name = "e750-audio",
+ .id = -1,
+};
+
/* ------------------------------------------------------------- */
static struct platform_device *e750_devices[] __initdata = {
&e750_fb_device,
&e750_tc6393xb_device,
&e7xx_gpio_vbus,
+ &e750_audio_device,
};
static void __init e750_init(void)
@@ -929,12 +941,18 @@
.resource = eseries_tmio_resources,
};
+static struct platform_device e800_audio_device = {
+ .name = "e800-audio",
+ .id = -1,
+};
+
/* ----------------------------------------------------------------------- */
static struct platform_device *e800_devices[] __initdata = {
&e800_fb_device,
&e800_tc6393xb_device,
&e800_gpio_vbus,
+ &e800_audio_device,
};
static void __init e800_init(void)
diff --git a/arch/arm/mach-pxa/poodle.c b/arch/arm/mach-pxa/poodle.c
index 69036e4..744baee 100644
--- a/arch/arm/mach-pxa/poodle.c
+++ b/arch/arm/mach-pxa/poodle.c
@@ -158,6 +158,11 @@
EXPORT_SYMBOL(poodle_scoop_device);
+static struct platform_device poodle_audio_device = {
+ .name = "poodle-audio",
+ .id = -1,
+};
+
/* LoCoMo device */
static struct resource locomo_resources[] = {
[0] = {
@@ -407,6 +412,7 @@
static struct platform_device *devices[] __initdata = {
&poodle_locomo_device,
&poodle_scoop_device,
+ &poodle_audio_device,
&sharpsl_nand_device,
&sharpsl_rom_device,
};
diff --git a/arch/arm/mach-pxa/stargate2.c b/arch/arm/mach-pxa/stargate2.c
index d8a2467..b0656e15 100644
--- a/arch/arm/mach-pxa/stargate2.c
+++ b/arch/arm/mach-pxa/stargate2.c
@@ -593,10 +593,16 @@
.udc_command = sg2_udc_command,
};
+static struct platform_device imote2_audio_device = {
+ .name = "imote2-audio",
+ .id = -1,
+};
+
static struct platform_device *imote2_devices[] = {
&stargate2_flash_device,
&imote2_leds,
&sht15,
+ &imote2_audio_device,
};
static void __init imote2_init(void)
diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c
index 7ce5c43..4d4eb60 100644
--- a/arch/arm/mach-pxa/tosa.c
+++ b/arch/arm/mach-pxa/tosa.c
@@ -889,6 +889,11 @@
.id = -1,
};
+static struct platform_device tosa_audio_device = {
+ .name = "tosa-audio",
+ .id = -1,
+};
+
static struct platform_device *devices[] __initdata = {
&tosascoop_device,
&tosascoop_jc_device,
@@ -901,6 +906,7 @@
&sharpsl_rom_device,
&wm9712_device,
&tosa_gpio_vbus,
+ &tosa_audio_device,
};
static void tosa_poweroff(void)
diff --git a/arch/arm/mach-s3c64xx/mach-crag6410.c b/arch/arm/mach-s3c64xx/mach-crag6410.c
index 680fd75..1cc91d7 100644
--- a/arch/arm/mach-s3c64xx/mach-crag6410.c
+++ b/arch/arm/mach-s3c64xx/mach-crag6410.c
@@ -286,8 +286,8 @@
.id = -1,
};
-static struct platform_device speyside_wm8962_device = {
- .name = "speyside-wm8962",
+static struct platform_device tobermory_device = {
+ .name = "tobermory",
.id = -1,
};
@@ -347,7 +347,7 @@
&crag6410_lcd_powerdev,
&crag6410_backlight_device,
&speyside_device,
- &speyside_wm8962_device,
+ &tobermory_device,
&littlemill_device,
&lowland_device,
&wallvdd_device,
diff --git a/arch/arm/mach-sa1100/pci-nanoengine.c b/arch/arm/mach-sa1100/pci-nanoengine.c
index dd39fee..0d01ca7 100644
--- a/arch/arm/mach-sa1100/pci-nanoengine.c
+++ b/arch/arm/mach-sa1100/pci-nanoengine.c
@@ -131,7 +131,8 @@
struct pci_bus * __init pci_nanoengine_scan_bus(int nr, struct pci_sys_data *sys)
{
- return pci_scan_bus(sys->busnr, &pci_nano_ops, sys);
+ return pci_scan_root_bus(NULL, sys->busnr, &pci_nano_ops, sys,
+ &sys->resources);
}
static struct resource pci_io_ports = {
@@ -226,7 +227,7 @@
.flags = IORESOURCE_MEM | IORESOURCE_PREFETCH,
};
-static int __init pci_nanoengine_setup_resources(struct resource **resource)
+static int __init pci_nanoengine_setup_resources(struct pci_sys_data *sys)
{
if (request_resource(&ioport_resource, &pci_io_ports)) {
printk(KERN_ERR "PCI: unable to allocate io port region\n");
@@ -243,9 +244,9 @@
printk(KERN_ERR "PCI: unable to allocate prefetchable\n");
return -EBUSY;
}
- resource[0] = &pci_io_ports;
- resource[1] = &pci_non_prefetchable_memory;
- resource[2] = &pci_prefetchable_memory;
+ pci_add_resource(&sys->resources, &pci_io_ports);
+ pci_add_resource(&sys->resources, &pci_non_prefetchable_memory);
+ pci_add_resource(&sys->resources, &pci_prefetchable_memory);
return 1;
}
@@ -260,7 +261,7 @@
if (nr == 0) {
sys->mem_offset = NANO_PCI_MEM_RW_PHYS;
sys->io_offset = 0x400;
- ret = pci_nanoengine_setup_resources(sys->resource);
+ ret = pci_nanoengine_setup_resources(sys);
/* Enable alternate memory bus master mode, see
* "Intel StrongARM SA1110 Developer's Manual",
* section 10.8, "Alternate Memory Bus Master Mode". */
diff --git a/arch/arm/mach-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig
index 0828fab..060e564 100644
--- a/arch/arm/mach-shmobile/Kconfig
+++ b/arch/arm/mach-shmobile/Kconfig
@@ -28,6 +28,19 @@
select ARM_GIC
select I2C
+config ARCH_R8A7740
+ bool "R-Mobile A1 (R8A77400)"
+ select CPU_V7
+ select SH_CLK_CPG
+ select ARCH_WANT_OPTIONAL_GPIOLIB
+
+config ARCH_R8A7779
+ bool "R-Car H1 (R8A77790)"
+ select CPU_V7
+ select SH_CLK_CPG
+ select ARM_GIC
+ select ARCH_WANT_OPTIONAL_GPIOLIB
+
comment "SH-Mobile Board Type"
config MACH_G3EVM
@@ -75,6 +88,16 @@
select ARCH_REQUIRE_GPIOLIB
depends on ARCH_SH73A0
+config MACH_BONITO
+ bool "bonito board"
+ select ARCH_REQUIRE_GPIOLIB
+ depends on ARCH_R8A7740
+
+config MACH_MARZEN
+ bool "MARZEN board"
+ depends on ARCH_R8A7779
+ select ARCH_REQUIRE_GPIOLIB
+
comment "SH-Mobile System Configuration"
menu "Memory configuration"
@@ -83,7 +106,7 @@
hex "Physical memory start address"
default "0x50000000" if MACH_G3EVM
default "0x40000000" if MACH_G4EVM || MACH_AP4EVB || MACH_AG5EVM || \
- MACH_MACKEREL
+ MACH_MACKEREL || MACH_BONITO
default "0x41000000" if MACH_KOTA2
default "0x00000000"
---help---
@@ -95,7 +118,7 @@
hex "Physical memory size"
default "0x08000000" if MACH_G3EVM
default "0x08000000" if MACH_G4EVM
- default "0x20000000" if MACH_AG5EVM
+ default "0x20000000" if MACH_AG5EVM || MACH_BONITO
default "0x1e000000" if MACH_KOTA2
default "0x10000000" if MACH_AP4EVB || MACH_MACKEREL
default "0x04000000"
diff --git a/arch/arm/mach-shmobile/Makefile b/arch/arm/mach-shmobile/Makefile
index 5ca1f9d..7ad6954 100644
--- a/arch/arm/mach-shmobile/Makefile
+++ b/arch/arm/mach-shmobile/Makefile
@@ -10,12 +10,15 @@
obj-$(CONFIG_ARCH_SH7377) += setup-sh7377.o clock-sh7377.o intc-sh7377.o
obj-$(CONFIG_ARCH_SH7372) += setup-sh7372.o clock-sh7372.o intc-sh7372.o
obj-$(CONFIG_ARCH_SH73A0) += setup-sh73a0.o clock-sh73a0.o intc-sh73a0.o
+obj-$(CONFIG_ARCH_R8A7740) += setup-r8a7740.o clock-r8a7740.o intc-r8a7740.o
+obj-$(CONFIG_ARCH_R8A7779) += setup-r8a7779.o clock-r8a7779.o intc-r8a7779.o
# SMP objects
smp-y := platsmp.o headsmp.o
smp-$(CONFIG_HOTPLUG_CPU) += hotplug.o
smp-$(CONFIG_LOCAL_TIMERS) += localtimer.o
smp-$(CONFIG_ARCH_SH73A0) += smp-sh73a0.o
+smp-$(CONFIG_ARCH_R8A7779) += smp-r8a7779.o
# Pinmux setup
pfc-y :=
@@ -23,16 +26,20 @@
pfc-$(CONFIG_ARCH_SH7377) += pfc-sh7377.o
pfc-$(CONFIG_ARCH_SH7372) += pfc-sh7372.o
pfc-$(CONFIG_ARCH_SH73A0) += pfc-sh73a0.o
+pfc-$(CONFIG_ARCH_R8A7740) += pfc-r8a7740.o
+pfc-$(CONFIG_ARCH_R8A7779) += pfc-r8a7779.o
# IRQ objects
obj-$(CONFIG_ARCH_SH7367) += entry-intc.o
obj-$(CONFIG_ARCH_SH7377) += entry-intc.o
obj-$(CONFIG_ARCH_SH7372) += entry-intc.o
+obj-$(CONFIG_ARCH_R8A7740) += entry-intc.o
# PM objects
obj-$(CONFIG_SUSPEND) += suspend.o
obj-$(CONFIG_CPU_IDLE) += cpuidle.o
obj-$(CONFIG_ARCH_SH7372) += pm-sh7372.o sleep-sh7372.o
+obj-$(CONFIG_ARCH_R8A7779) += pm-r8a7779.o
# Board objects
obj-$(CONFIG_MACH_G3EVM) += board-g3evm.o
@@ -41,6 +48,8 @@
obj-$(CONFIG_MACH_AG5EVM) += board-ag5evm.o
obj-$(CONFIG_MACH_MACKEREL) += board-mackerel.o
obj-$(CONFIG_MACH_KOTA2) += board-kota2.o
+obj-$(CONFIG_MACH_BONITO) += board-bonito.o
+obj-$(CONFIG_MACH_MARZEN) += board-marzen.o
# Framework support
obj-$(CONFIG_SMP) += $(smp-y)
diff --git a/arch/arm/mach-shmobile/board-ap4evb.c b/arch/arm/mach-shmobile/board-ap4evb.c
index 6a6f9f7..d2e7b73 100644
--- a/arch/arm/mach-shmobile/board-ap4evb.c
+++ b/arch/arm/mach-shmobile/board-ap4evb.c
@@ -762,9 +762,22 @@
},
};
-static struct platform_device fsi_ak4643_device = {
- .name = "sh_fsi2_a_ak4643",
+static struct fsi_ak4642_info fsi2_ak4643_info = {
+ .name = "AK4643",
+ .card = "FSI2A-AK4643",
+ .cpu_dai = "fsia-dai",
+ .codec = "ak4642-codec.0-0013",
+ .platform = "sh_fsi2",
+ .id = FSI_PORT_A,
};
+
+static struct platform_device fsi_ak4643_device = {
+ .name = "fsi-ak4642-audio",
+ .dev = {
+ .platform_data = &fsi_info,
+ },
+};
+
static struct sh_mobile_meram_cfg hdmi_meram_cfg = {
.icb[0] = {
.marker_icb = 30,
diff --git a/arch/arm/mach-shmobile/board-bonito.c b/arch/arm/mach-shmobile/board-bonito.c
new file mode 100644
index 0000000..4d22016
--- /dev/null
+++ b/arch/arm/mach-shmobile/board-bonito.c
@@ -0,0 +1,522 @@
+/*
+ * bonito board support
+ *
+ * Copyright (C) 2011 Renesas Solutions Corp.
+ * Copyright (C) 2011 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+ *
+ * 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; version 2 of the License.
+ *
+ * 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 <linux/kernel.h>
+#include <linux/i2c.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/smsc911x.h>
+#include <mach/common.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/time.h>
+#include <asm/hardware/cache-l2x0.h>
+#include <mach/r8a7740.h>
+#include <video/sh_mobile_lcdc.h>
+
+/*
+ * CS Address device note
+ *----------------------------------------------------------------
+ * 0 0x0000_0000 NOR Flash (64MB) SW12 : bit3 = OFF
+ * 2 0x0800_0000 ExtNOR (64MB) SW12 : bit3 = OFF
+ * 4 -
+ * 5A -
+ * 5B 0x1600_0000 SRAM (8MB)
+ * 6 0x1800_0000 FPGA (64K)
+ * 0x1801_0000 Ether (4KB)
+ * 0x1801_1000 USB (4KB)
+ */
+
+/*
+ * SW12
+ *
+ * bit1 bit2 bit3
+ *----------------------------------------------------------------------------
+ * ON NOR WriteProtect NAND WriteProtect CS0 ExtNOR / CS2 NOR
+ * OFF NOR Not WriteProtect NAND Not WriteProtect CS0 NOR / CS2 ExtNOR
+ */
+
+/*
+ * SCIFA5 (CN42)
+ *
+ * S38.3 = ON
+ * S39.6 = ON
+ * S43.1 = ON
+ */
+
+/*
+ * LCDC0 (CN3/CN4/CN7)
+ *
+ * S38.1 = OFF
+ * S38.2 = OFF
+ */
+
+/*
+ * FPGA
+ */
+#define IRQSR0 0x0020
+#define IRQSR1 0x0022
+#define IRQMR0 0x0030
+#define IRQMR1 0x0032
+#define BUSSWMR1 0x0070
+#define BUSSWMR2 0x0072
+#define BUSSWMR3 0x0074
+#define BUSSWMR4 0x0076
+
+#define LCDCR 0x10B4
+#define DEVRSTCR1 0x10D0
+#define DEVRSTCR2 0x10D2
+#define A1MDSR 0x10E0
+#define BVERR 0x1100
+
+/* FPGA IRQ */
+#define FPGA_IRQ_BASE (512)
+#define FPGA_IRQ0 (FPGA_IRQ_BASE)
+#define FPGA_IRQ1 (FPGA_IRQ_BASE + 16)
+#define FPGA_ETH_IRQ (FPGA_IRQ0 + 15)
+static u16 bonito_fpga_read(u32 offset)
+{
+ return __raw_readw(0xf0003000 + offset);
+}
+
+static void bonito_fpga_write(u32 offset, u16 val)
+{
+ __raw_writew(val, 0xf0003000 + offset);
+}
+
+static void bonito_fpga_irq_disable(struct irq_data *data)
+{
+ unsigned int irq = data->irq;
+ u32 addr = (irq < 1016) ? IRQMR0 : IRQMR1;
+ int shift = irq % 16;
+
+ bonito_fpga_write(addr, bonito_fpga_read(addr) | (1 << shift));
+}
+
+static void bonito_fpga_irq_enable(struct irq_data *data)
+{
+ unsigned int irq = data->irq;
+ u32 addr = (irq < 1016) ? IRQMR0 : IRQMR1;
+ int shift = irq % 16;
+
+ bonito_fpga_write(addr, bonito_fpga_read(addr) & ~(1 << shift));
+}
+
+static struct irq_chip bonito_fpga_irq_chip __read_mostly = {
+ .name = "bonito FPGA",
+ .irq_mask = bonito_fpga_irq_disable,
+ .irq_unmask = bonito_fpga_irq_enable,
+};
+
+static void bonito_fpga_irq_demux(unsigned int irq, struct irq_desc *desc)
+{
+ u32 val = bonito_fpga_read(IRQSR1) << 16 |
+ bonito_fpga_read(IRQSR0);
+ u32 mask = bonito_fpga_read(IRQMR1) << 16 |
+ bonito_fpga_read(IRQMR0);
+
+ int i;
+
+ val &= ~mask;
+
+ for (i = 0; i < 32; i++) {
+ if (!(val & (1 << i)))
+ continue;
+
+ generic_handle_irq(FPGA_IRQ_BASE + i);
+ }
+}
+
+static void bonito_fpga_init(void)
+{
+ int i;
+
+ bonito_fpga_write(IRQMR0, 0xffff); /* mask all */
+ bonito_fpga_write(IRQMR1, 0xffff); /* mask all */
+
+ /* Device reset */
+ bonito_fpga_write(DEVRSTCR1,
+ (1 << 2)); /* Eth */
+
+ /* FPGA irq require special handling */
+ for (i = FPGA_IRQ_BASE; i < FPGA_IRQ_BASE + 32; i++) {
+ irq_set_chip_and_handler_name(i, &bonito_fpga_irq_chip,
+ handle_level_irq, "level");
+ set_irq_flags(i, IRQF_VALID); /* yuck */
+ }
+
+ irq_set_chained_handler(evt2irq(0x0340), bonito_fpga_irq_demux);
+ irq_set_irq_type(evt2irq(0x0340), IRQ_TYPE_LEVEL_LOW);
+}
+
+/*
+* PMIC settings
+*
+* FIXME
+*
+* bonito board needs some settings by pmic which use i2c access.
+* pmic settings use device_initcall() here for use it.
+*/
+static __u8 *pmic_settings = NULL;
+static __u8 pmic_do_2A[] = {
+ 0x1C, 0x09,
+ 0x1A, 0x80,
+ 0xff, 0xff,
+};
+
+static int __init pmic_init(void)
+{
+ struct i2c_adapter *a = i2c_get_adapter(0);
+ struct i2c_msg msg;
+ __u8 buf[2];
+ int i, ret;
+
+ if (!pmic_settings)
+ return 0;
+ if (!a)
+ return 0;
+
+ msg.addr = 0x46;
+ msg.buf = buf;
+ msg.len = 2;
+ msg.flags = 0;
+
+ for (i = 0; ; i += 2) {
+ buf[0] = pmic_settings[i + 0];
+ buf[1] = pmic_settings[i + 1];
+
+ if ((0xff == buf[0]) && (0xff == buf[1]))
+ break;
+
+ ret = i2c_transfer(a, &msg, 1);
+ if (ret < 0) {
+ pr_err("i2c transfer fail\n");
+ break;
+ }
+ }
+
+ return 0;
+}
+device_initcall(pmic_init);
+
+/*
+ * LCDC0
+ */
+static const struct fb_videomode lcdc0_mode = {
+ .name = "WVGA Panel",
+ .xres = 800,
+ .yres = 480,
+ .left_margin = 88,
+ .right_margin = 40,
+ .hsync_len = 128,
+ .upper_margin = 20,
+ .lower_margin = 5,
+ .vsync_len = 5,
+ .sync = 0,
+};
+
+static struct sh_mobile_lcdc_info lcdc0_info = {
+ .clock_source = LCDC_CLK_BUS,
+ .ch[0] = {
+ .chan = LCDC_CHAN_MAINLCD,
+ .bpp = 16,
+ .interface_type = RGB24,
+ .clock_divider = 5,
+ .flags = 0,
+ .lcd_cfg = &lcdc0_mode,
+ .num_cfg = 1,
+ .lcd_size_cfg = {
+ .width = 152,
+ .height = 91,
+ },
+ },
+};
+
+static struct resource lcdc0_resources[] = {
+ [0] = {
+ .name = "LCDC0",
+ .start = 0xfe940000,
+ .end = 0xfe943fff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = intcs_evt2irq(0x0580),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device lcdc0_device = {
+ .name = "sh_mobile_lcdc_fb",
+ .id = 0,
+ .resource = lcdc0_resources,
+ .num_resources = ARRAY_SIZE(lcdc0_resources),
+ .dev = {
+ .platform_data = &lcdc0_info,
+ .coherent_dma_mask = ~0,
+ },
+};
+
+/*
+ * SMSC 9221
+ */
+static struct resource smsc_resources[] = {
+ [0] = {
+ .start = 0x18010000,
+ .end = 0x18011000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = FPGA_ETH_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct smsc911x_platform_config smsc_platdata = {
+ .flags = SMSC911X_USE_16BIT,
+ .phy_interface = PHY_INTERFACE_MODE_MII,
+ .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
+ .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL,
+};
+
+static struct platform_device smsc_device = {
+ .name = "smsc911x",
+ .dev = {
+ .platform_data = &smsc_platdata,
+ },
+ .resource = smsc_resources,
+ .num_resources = ARRAY_SIZE(smsc_resources),
+};
+
+/*
+ * core board devices
+ */
+static struct platform_device *bonito_core_devices[] __initdata = {
+};
+
+/*
+ * base board devices
+ */
+static struct platform_device *bonito_base_devices[] __initdata = {
+ &lcdc0_device,
+ &smsc_device,
+};
+
+/*
+ * map I/O
+ */
+static struct map_desc bonito_io_desc[] __initdata = {
+ /*
+ * for CPGA/INTC/PFC
+ * 0xe6000000-0xefffffff -> 0xe6000000-0xefffffff
+ */
+ {
+ .virtual = 0xe6000000,
+ .pfn = __phys_to_pfn(0xe6000000),
+ .length = 160 << 20,
+ .type = MT_DEVICE_NONSHARED
+ },
+#ifdef CONFIG_CACHE_L2X0
+ /*
+ * for l2x0_init()
+ * 0xf0100000-0xf0101000 -> 0xf0002000-0xf0003000
+ */
+ {
+ .virtual = 0xf0002000,
+ .pfn = __phys_to_pfn(0xf0100000),
+ .length = PAGE_SIZE,
+ .type = MT_DEVICE_NONSHARED
+ },
+#endif
+ /*
+ * for FPGA (0x1800000-0x19ffffff)
+ * 0x18000000-0x18002000 -> 0xf0003000-0xf0005000
+ */
+ {
+ .virtual = 0xf0003000,
+ .pfn = __phys_to_pfn(0x18000000),
+ .length = PAGE_SIZE * 2,
+ .type = MT_DEVICE_NONSHARED
+ }
+};
+
+static void __init bonito_map_io(void)
+{
+ iotable_init(bonito_io_desc, ARRAY_SIZE(bonito_io_desc));
+
+ /* setup early devices and console here as well */
+ r8a7740_add_early_devices();
+ shmobile_setup_console();
+}
+
+/*
+ * board init
+ */
+#define BIT_ON(sw, bit) (sw & (1 << bit))
+#define BIT_OFF(sw, bit) (!(sw & (1 << bit)))
+
+#define VCCQ1CR 0xE6058140
+#define VCCQ1LCDCR 0xE6058186
+
+static void __init bonito_init(void)
+{
+ u16 val;
+
+ r8a7740_pinmux_init();
+ bonito_fpga_init();
+
+ pmic_settings = pmic_do_2A;
+
+ /*
+ * core board settings
+ */
+
+#ifdef CONFIG_CACHE_L2X0
+ /* Early BRESP enable, Shared attribute override enable, 32K*8way */
+ l2x0_init(__io(0xf0002000), 0x40440000, 0x82000fff);
+#endif
+
+ r8a7740_add_standard_devices();
+
+ platform_add_devices(bonito_core_devices,
+ ARRAY_SIZE(bonito_core_devices));
+
+ /*
+ * base board settings
+ */
+ gpio_request(GPIO_PORT176, NULL);
+ gpio_direction_input(GPIO_PORT176);
+ if (!gpio_get_value(GPIO_PORT176)) {
+ u16 bsw2;
+ u16 bsw3;
+ u16 bsw4;
+
+ /*
+ * FPGA
+ */
+ gpio_request(GPIO_FN_CS5B, NULL);
+ gpio_request(GPIO_FN_CS6A, NULL);
+ gpio_request(GPIO_FN_CS5A_PORT105, NULL);
+ gpio_request(GPIO_FN_IRQ10, NULL);
+
+ val = bonito_fpga_read(BVERR);
+ pr_info("bonito version: cpu %02x, base %02x\n",
+ ((val >> 8) & 0xFF),
+ ((val >> 0) & 0xFF));
+
+ bsw2 = bonito_fpga_read(BUSSWMR2);
+ bsw3 = bonito_fpga_read(BUSSWMR3);
+ bsw4 = bonito_fpga_read(BUSSWMR4);
+
+ /*
+ * SCIFA5 (CN42)
+ */
+ if (BIT_OFF(bsw2, 1) && /* S38.3 = ON */
+ BIT_OFF(bsw3, 9) && /* S39.6 = ON */
+ BIT_OFF(bsw4, 4)) { /* S43.1 = ON */
+ gpio_request(GPIO_FN_SCIFA5_TXD_PORT91, NULL);
+ gpio_request(GPIO_FN_SCIFA5_RXD_PORT92, NULL);
+ }
+
+ /*
+ * LCDC0 (CN3)
+ */
+ if (BIT_ON(bsw2, 3) && /* S38.1 = OFF */
+ BIT_ON(bsw2, 2)) { /* S38.2 = OFF */
+ gpio_request(GPIO_FN_LCDC0_SELECT, NULL);
+ gpio_request(GPIO_FN_LCD0_D0, NULL);
+ gpio_request(GPIO_FN_LCD0_D1, NULL);
+ gpio_request(GPIO_FN_LCD0_D2, NULL);
+ gpio_request(GPIO_FN_LCD0_D3, NULL);
+ gpio_request(GPIO_FN_LCD0_D4, NULL);
+ gpio_request(GPIO_FN_LCD0_D5, NULL);
+ gpio_request(GPIO_FN_LCD0_D6, NULL);
+ gpio_request(GPIO_FN_LCD0_D7, NULL);
+ gpio_request(GPIO_FN_LCD0_D8, NULL);
+ gpio_request(GPIO_FN_LCD0_D9, NULL);
+ gpio_request(GPIO_FN_LCD0_D10, NULL);
+ gpio_request(GPIO_FN_LCD0_D11, NULL);
+ gpio_request(GPIO_FN_LCD0_D12, NULL);
+ gpio_request(GPIO_FN_LCD0_D13, NULL);
+ gpio_request(GPIO_FN_LCD0_D14, NULL);
+ gpio_request(GPIO_FN_LCD0_D15, NULL);
+ gpio_request(GPIO_FN_LCD0_D16, NULL);
+ gpio_request(GPIO_FN_LCD0_D17, NULL);
+ gpio_request(GPIO_FN_LCD0_D18_PORT163, NULL);
+ gpio_request(GPIO_FN_LCD0_D19_PORT162, NULL);
+ gpio_request(GPIO_FN_LCD0_D20_PORT161, NULL);
+ gpio_request(GPIO_FN_LCD0_D21_PORT158, NULL);
+ gpio_request(GPIO_FN_LCD0_D22_PORT160, NULL);
+ gpio_request(GPIO_FN_LCD0_D23_PORT159, NULL);
+ gpio_request(GPIO_FN_LCD0_DCK, NULL);
+ gpio_request(GPIO_FN_LCD0_VSYN, NULL);
+ gpio_request(GPIO_FN_LCD0_HSYN, NULL);
+ gpio_request(GPIO_FN_LCD0_DISP, NULL);
+ gpio_request(GPIO_FN_LCD0_LCLK_PORT165, NULL);
+
+ gpio_request(GPIO_PORT61, NULL); /* LCDDON */
+ gpio_direction_output(GPIO_PORT61, 1);
+
+ /* backlight on */
+ bonito_fpga_write(LCDCR, 1);
+
+ /* drivability Max */
+ __raw_writew(0x00FF , VCCQ1LCDCR);
+ __raw_writew(0xFFFF , VCCQ1CR);
+ }
+
+ platform_add_devices(bonito_base_devices,
+ ARRAY_SIZE(bonito_base_devices));
+ }
+}
+
+static void __init bonito_timer_init(void)
+{
+ u16 val;
+ u8 md_ck = 0;
+
+ /* read MD_CK value */
+ val = bonito_fpga_read(A1MDSR);
+ if (val & (1 << 10))
+ md_ck |= MD_CK2;
+ if (val & (1 << 9))
+ md_ck |= MD_CK1;
+ if (val & (1 << 8))
+ md_ck |= MD_CK0;
+
+ r8a7740_clock_init(md_ck);
+ shmobile_timer.init();
+}
+
+struct sys_timer bonito_timer = {
+ .init = bonito_timer_init,
+};
+
+MACHINE_START(BONITO, "bonito")
+ .map_io = bonito_map_io,
+ .init_irq = r8a7740_init_irq,
+ .handle_irq = shmobile_handle_irq_intc,
+ .init_machine = bonito_init,
+ .timer = &bonito_timer,
+MACHINE_END
diff --git a/arch/arm/mach-shmobile/board-mackerel.c b/arch/arm/mach-shmobile/board-mackerel.c
index ed52566..cbc5934 100644
--- a/arch/arm/mach-shmobile/board-mackerel.c
+++ b/arch/arm/mach-shmobile/board-mackerel.c
@@ -990,8 +990,20 @@
},
};
+static struct fsi_ak4642_info fsi2_ak4643_info = {
+ .name = "AK4643",
+ .card = "FSI2A-AK4643",
+ .cpu_dai = "fsia-dai",
+ .codec = "ak4642-codec.0-0013",
+ .platform = "sh_fsi2",
+ .id = FSI_PORT_A,
+};
+
static struct platform_device fsi_ak4643_device = {
- .name = "sh_fsi2_a_ak4643",
+ .name = "fsi-ak4642-audio",
+ .dev = {
+ .platform_data = &fsi2_ak4643_info,
+ },
};
/*
diff --git a/arch/arm/mach-shmobile/board-marzen.c b/arch/arm/mach-shmobile/board-marzen.c
new file mode 100644
index 0000000..f0e02c0
--- /dev/null
+++ b/arch/arm/mach-shmobile/board-marzen.c
@@ -0,0 +1,157 @@
+/*
+ * marzen board support
+ *
+ * Copyright (C) 2011 Renesas Solutions Corp.
+ * Copyright (C) 2011 Magnus Damm
+ *
+ * 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; version 2 of the License.
+ *
+ * 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 <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+#include <linux/dma-mapping.h>
+#include <linux/smsc911x.h>
+#include <mach/hardware.h>
+#include <mach/r8a7779.h>
+#include <mach/common.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/time.h>
+#include <asm/hardware/gic.h>
+#include <asm/traps.h>
+
+/* SMSC LAN89218 */
+static struct resource smsc911x_resources[] = {
+ [0] = {
+ .start = 0x18000000, /* ExCS0 */
+ .end = 0x180000ff, /* A1->A7 */
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = gic_spi(28), /* IRQ 1 */
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct smsc911x_platform_config smsc911x_platdata = {
+ .flags = SMSC911X_USE_32BIT, /* 32-bit SW on 16-bit HW bus */
+ .phy_interface = PHY_INTERFACE_MODE_MII,
+ .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
+ .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL,
+};
+
+static struct platform_device eth_device = {
+ .name = "smsc911x",
+ .id = 0,
+ .dev = {
+ .platform_data = &smsc911x_platdata,
+ },
+ .resource = smsc911x_resources,
+ .num_resources = ARRAY_SIZE(smsc911x_resources),
+};
+
+static struct platform_device *marzen_devices[] __initdata = {
+ ð_device,
+};
+
+static struct map_desc marzen_io_desc[] __initdata = {
+ /* 2M entity map for 0xf0000000 (MPCORE) */
+ {
+ .virtual = 0xf0000000,
+ .pfn = __phys_to_pfn(0xf0000000),
+ .length = SZ_2M,
+ .type = MT_DEVICE_NONSHARED
+ },
+ /* 16M entity map for 0xfexxxxxx (DMAC-S/HPBREG/INTC2/LRAM/DBSC) */
+ {
+ .virtual = 0xfe000000,
+ .pfn = __phys_to_pfn(0xfe000000),
+ .length = SZ_16M,
+ .type = MT_DEVICE_NONSHARED
+ },
+};
+
+static void __init marzen_map_io(void)
+{
+ iotable_init(marzen_io_desc, ARRAY_SIZE(marzen_io_desc));
+}
+
+static void __init marzen_init_early(void)
+{
+ r8a7779_add_early_devices();
+
+ /* Early serial console setup is not included here due to
+ * memory map collisions. The SCIF serial ports in r8a7779
+ * are difficult to entity map 1:1 due to collision with the
+ * virtual memory range used by the coherent DMA code on ARM.
+ *
+ * Anyone wanting to debug early can remove UPF_IOREMAP from
+ * the sh-sci serial console platform data, adjust mapbase
+ * to a static M:N virt:phys mapping that needs to be added to
+ * the mappings passed with iotable_init() above.
+ *
+ * Then add a call to shmobile_setup_console() from this function.
+ *
+ * As a final step pass earlyprint=sh-sci.2,115200 on the kernel
+ * command line.
+ */
+}
+
+static void __init marzen_init(void)
+{
+ r8a7779_pinmux_init();
+
+ /* SCIF2 (CN18: DEBUG0) */
+ gpio_request(GPIO_FN_TX2_C, NULL);
+ gpio_request(GPIO_FN_RX2_C, NULL);
+
+ /* SCIF4 (CN19: DEBUG1) */
+ gpio_request(GPIO_FN_TX4, NULL);
+ gpio_request(GPIO_FN_RX4, NULL);
+
+ /* LAN89218 */
+ gpio_request(GPIO_FN_EX_CS0, NULL); /* nCS */
+ gpio_request(GPIO_FN_IRQ1_B, NULL); /* IRQ + PME */
+
+ r8a7779_add_standard_devices();
+ platform_add_devices(marzen_devices, ARRAY_SIZE(marzen_devices));
+}
+
+static void __init marzen_timer_init(void)
+{
+ r8a7779_clock_init();
+ shmobile_timer.init();
+ return;
+}
+
+struct sys_timer marzen_timer = {
+ .init = marzen_timer_init,
+};
+
+MACHINE_START(MARZEN, "marzen")
+ .map_io = marzen_map_io,
+ .init_early = marzen_init_early,
+ .nr_irqs = NR_IRQS_LEGACY,
+ .init_irq = r8a7779_init_irq,
+ .handle_irq = gic_handle_irq,
+ .init_machine = marzen_init,
+ .timer = &marzen_timer,
+MACHINE_END
diff --git a/arch/arm/mach-shmobile/clock-r8a7740.c b/arch/arm/mach-shmobile/clock-r8a7740.c
new file mode 100644
index 0000000..3b35b9a
--- /dev/null
+++ b/arch/arm/mach-shmobile/clock-r8a7740.c
@@ -0,0 +1,382 @@
+/*
+ * R8A7740 processor support
+ *
+ * Copyright (C) 2011 Renesas Solutions Corp.
+ * Copyright (C) 2011 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+ *
+ * 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
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <linux/sh_clk.h>
+#include <linux/clkdev.h>
+#include <mach/common.h>
+#include <mach/r8a7740.h>
+
+/*
+ * | MDx | XTAL1/EXTAL1 | System | EXTALR |
+ * Clock |-------+-----------------+ clock | 32.768 | RCLK
+ * Mode | 2/1/0 | src MHz | source | KHz | source
+ * -------+-------+-----------------+-----------+--------+----------
+ * 0 | 0 0 0 | External 20~50 | XTAL1 | O | EXTALR
+ * 1 | 0 0 1 | Crystal 20~30 | XTAL1 | O | EXTALR
+ * 2 | 0 1 0 | External 40~50 | XTAL1 / 2 | O | EXTALR
+ * 3 | 0 1 1 | Crystal 40~50 | XTAL1 / 2 | O | EXTALR
+ * 4 | 1 0 0 | External 20~50 | XTAL1 | x | XTAL1 / 1024
+ * 5 | 1 0 1 | Crystal 20~30 | XTAL1 | x | XTAL1 / 1024
+ * 6 | 1 1 0 | External 40~50 | XTAL1 / 2 | x | XTAL1 / 2048
+ * 7 | 1 1 1 | Crystal 40~50 | XTAL1 / 2 | x | XTAL1 / 2048
+ */
+
+/* CPG registers */
+#define FRQCRA 0xe6150000
+#define FRQCRB 0xe6150004
+#define FRQCRC 0xe61500e0
+#define PLLC01CR 0xe6150028
+
+#define SUBCKCR 0xe6150080
+
+#define MSTPSR0 0xe6150030
+#define MSTPSR1 0xe6150038
+#define MSTPSR2 0xe6150040
+#define MSTPSR3 0xe6150048
+#define MSTPSR4 0xe615004c
+#define SMSTPCR0 0xe6150130
+#define SMSTPCR1 0xe6150134
+#define SMSTPCR2 0xe6150138
+#define SMSTPCR3 0xe615013c
+#define SMSTPCR4 0xe6150140
+
+/* Fixed 32 KHz root clock from EXTALR pin */
+static struct clk extalr_clk = {
+ .rate = 32768,
+};
+
+/*
+ * 25MHz default rate for the EXTAL1 root input clock.
+ * If needed, reset this with clk_set_rate() from the platform code.
+ */
+static struct clk extal1_clk = {
+ .rate = 25000000,
+};
+
+/*
+ * 48MHz default rate for the EXTAL2 root input clock.
+ * If needed, reset this with clk_set_rate() from the platform code.
+ */
+static struct clk extal2_clk = {
+ .rate = 48000000,
+};
+
+/*
+ * 27MHz default rate for the DV_CLKI root input clock.
+ * If needed, reset this with clk_set_rate() from the platform code.
+ */
+static struct clk dv_clk = {
+ .rate = 27000000,
+};
+
+static unsigned long div_recalc(struct clk *clk)
+{
+ return clk->parent->rate / (int)(clk->priv);
+}
+
+static struct clk_ops div_clk_ops = {
+ .recalc = div_recalc,
+};
+
+/* extal1 / 2 */
+static struct clk extal1_div2_clk = {
+ .ops = &div_clk_ops,
+ .priv = (void *)2,
+ .parent = &extal1_clk,
+};
+
+/* extal1 / 1024 */
+static struct clk extal1_div1024_clk = {
+ .ops = &div_clk_ops,
+ .priv = (void *)1024,
+ .parent = &extal1_clk,
+};
+
+/* extal1 / 2 / 1024 */
+static struct clk extal1_div2048_clk = {
+ .ops = &div_clk_ops,
+ .priv = (void *)1024,
+ .parent = &extal1_div2_clk,
+};
+
+/* extal2 / 2 */
+static struct clk extal2_div2_clk = {
+ .ops = &div_clk_ops,
+ .priv = (void *)2,
+ .parent = &extal2_clk,
+};
+
+static struct clk_ops followparent_clk_ops = {
+ .recalc = followparent_recalc,
+};
+
+/* Main clock */
+static struct clk system_clk = {
+ .ops = &followparent_clk_ops,
+};
+
+static struct clk system_div2_clk = {
+ .ops = &div_clk_ops,
+ .priv = (void *)2,
+ .parent = &system_clk,
+};
+
+/* r_clk */
+static struct clk r_clk = {
+ .ops = &followparent_clk_ops,
+};
+
+/* PLLC0/PLLC1 */
+static unsigned long pllc01_recalc(struct clk *clk)
+{
+ unsigned long mult = 1;
+
+ if (__raw_readl(PLLC01CR) & (1 << 14))
+ mult = ((__raw_readl(clk->enable_reg) >> 24) & 0x7f) + 1;
+
+ return clk->parent->rate * mult;
+}
+
+static struct clk_ops pllc01_clk_ops = {
+ .recalc = pllc01_recalc,
+};
+
+static struct clk pllc0_clk = {
+ .ops = &pllc01_clk_ops,
+ .flags = CLK_ENABLE_ON_INIT,
+ .parent = &system_clk,
+ .enable_reg = (void __iomem *)FRQCRC,
+};
+
+static struct clk pllc1_clk = {
+ .ops = &pllc01_clk_ops,
+ .flags = CLK_ENABLE_ON_INIT,
+ .parent = &system_div2_clk,
+ .enable_reg = (void __iomem *)FRQCRA,
+};
+
+/* PLLC1 / 2 */
+static struct clk pllc1_div2_clk = {
+ .ops = &div_clk_ops,
+ .priv = (void *)2,
+ .parent = &pllc1_clk,
+};
+
+struct clk *main_clks[] = {
+ &extalr_clk,
+ &extal1_clk,
+ &extal2_clk,
+ &extal1_div2_clk,
+ &extal1_div1024_clk,
+ &extal1_div2048_clk,
+ &extal2_div2_clk,
+ &dv_clk,
+ &system_clk,
+ &system_div2_clk,
+ &r_clk,
+ &pllc0_clk,
+ &pllc1_clk,
+ &pllc1_div2_clk,
+};
+
+static void div4_kick(struct clk *clk)
+{
+ unsigned long value;
+
+ /* set KICK bit in FRQCRB to update hardware setting */
+ value = __raw_readl(FRQCRB);
+ value |= (1 << 31);
+ __raw_writel(value, FRQCRB);
+}
+
+static int divisors[] = { 2, 3, 4, 6, 8, 12, 16, 18,
+ 24, 32, 36, 48, 0, 72, 96, 0 };
+
+static struct clk_div_mult_table div4_div_mult_table = {
+ .divisors = divisors,
+ .nr_divisors = ARRAY_SIZE(divisors),
+};
+
+static struct clk_div4_table div4_table = {
+ .div_mult_table = &div4_div_mult_table,
+ .kick = div4_kick,
+};
+
+enum {
+ DIV4_I, DIV4_ZG, DIV4_B, DIV4_M1, DIV4_HP,
+ DIV4_HPP, DIV4_S, DIV4_ZB, DIV4_M3, DIV4_CP,
+ DIV4_NR
+};
+
+struct clk div4_clks[DIV4_NR] = {
+ [DIV4_I] = SH_CLK_DIV4(&pllc1_clk, FRQCRA, 20, 0x6fff, CLK_ENABLE_ON_INIT),
+ [DIV4_ZG] = SH_CLK_DIV4(&pllc1_clk, FRQCRA, 16, 0x6fff, CLK_ENABLE_ON_INIT),
+ [DIV4_B] = SH_CLK_DIV4(&pllc1_clk, FRQCRA, 8, 0x6fff, CLK_ENABLE_ON_INIT),
+ [DIV4_M1] = SH_CLK_DIV4(&pllc1_clk, FRQCRA, 4, 0x6fff, CLK_ENABLE_ON_INIT),
+ [DIV4_HP] = SH_CLK_DIV4(&pllc1_clk, FRQCRB, 4, 0x6fff, 0),
+ [DIV4_HPP] = SH_CLK_DIV4(&pllc1_clk, FRQCRC, 20, 0x6fff, 0),
+ [DIV4_S] = SH_CLK_DIV4(&pllc1_clk, FRQCRC, 12, 0x6fff, 0),
+ [DIV4_ZB] = SH_CLK_DIV4(&pllc1_clk, FRQCRC, 8, 0x6fff, 0),
+ [DIV4_M3] = SH_CLK_DIV4(&pllc1_clk, FRQCRC, 4, 0x6fff, 0),
+ [DIV4_CP] = SH_CLK_DIV4(&pllc1_clk, FRQCRC, 0, 0x6fff, 0),
+};
+
+enum {
+ DIV6_SUB,
+ DIV6_NR
+};
+
+static struct clk div6_clks[DIV6_NR] = {
+ [DIV6_SUB] = SH_CLK_DIV6(&pllc1_div2_clk, SUBCKCR, 0),
+};
+
+enum {
+ MSTP125,
+ MSTP116, MSTP111, MSTP100, MSTP117,
+
+ MSTP230,
+ MSTP222,
+ MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200,
+
+ MSTP329, MSTP323,
+
+ MSTP_NR
+};
+
+static struct clk mstp_clks[MSTP_NR] = {
+ [MSTP125] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR1, 25, 0), /* TMU0 */
+ [MSTP117] = SH_CLK_MSTP32(&div4_clks[DIV4_B], SMSTPCR1, 17, 0), /* LCDC1 */
+ [MSTP116] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR1, 16, 0), /* IIC0 */
+ [MSTP111] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR1, 11, 0), /* TMU1 */
+ [MSTP100] = SH_CLK_MSTP32(&div4_clks[DIV4_B], SMSTPCR1, 0, 0), /* LCDC0 */
+
+ [MSTP230] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2, 30, 0), /* SCIFA6 */
+ [MSTP222] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2, 22, 0), /* SCIFA7 */
+ [MSTP207] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2, 7, 0), /* SCIFA5 */
+ [MSTP206] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2, 6, 0), /* SCIFB */
+ [MSTP204] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2, 4, 0), /* SCIFA0 */
+ [MSTP203] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2, 3, 0), /* SCIFA1 */
+ [MSTP202] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2, 2, 0), /* SCIFA2 */
+ [MSTP201] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2, 1, 0), /* SCIFA3 */
+ [MSTP200] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2, 0, 0), /* SCIFA4 */
+
+ [MSTP329] = SH_CLK_MSTP32(&r_clk, SMSTPCR3, 29, 0), /* CMT10 */
+ [MSTP323] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR3, 23, 0), /* IIC1 */
+};
+
+static struct clk_lookup lookups[] = {
+ /* main clocks */
+ CLKDEV_CON_ID("extalr", &extalr_clk),
+ CLKDEV_CON_ID("extal1", &extal1_clk),
+ CLKDEV_CON_ID("extal2", &extal2_clk),
+ CLKDEV_CON_ID("extal1_div2", &extal1_div2_clk),
+ CLKDEV_CON_ID("extal1_div1024", &extal1_div1024_clk),
+ CLKDEV_CON_ID("extal1_div2048", &extal1_div2048_clk),
+ CLKDEV_CON_ID("extal2_div2", &extal2_div2_clk),
+ CLKDEV_CON_ID("dv_clk", &dv_clk),
+ CLKDEV_CON_ID("system_clk", &system_clk),
+ CLKDEV_CON_ID("system_div2_clk", &system_div2_clk),
+ CLKDEV_CON_ID("r_clk", &r_clk),
+ CLKDEV_CON_ID("pllc0_clk", &pllc0_clk),
+ CLKDEV_CON_ID("pllc1_clk", &pllc1_clk),
+ CLKDEV_CON_ID("pllc1_div2_clk", &pllc1_div2_clk),
+
+ /* DIV4 clocks */
+ CLKDEV_CON_ID("i_clk", &div4_clks[DIV4_I]),
+ CLKDEV_CON_ID("zg_clk", &div4_clks[DIV4_ZG]),
+ CLKDEV_CON_ID("b_clk", &div4_clks[DIV4_B]),
+ CLKDEV_CON_ID("m1_clk", &div4_clks[DIV4_M1]),
+ CLKDEV_CON_ID("hp_clk", &div4_clks[DIV4_HP]),
+ CLKDEV_CON_ID("hpp_clk", &div4_clks[DIV4_HPP]),
+ CLKDEV_CON_ID("s_clk", &div4_clks[DIV4_S]),
+ CLKDEV_CON_ID("zb_clk", &div4_clks[DIV4_ZB]),
+ CLKDEV_CON_ID("m3_clk", &div4_clks[DIV4_M3]),
+ CLKDEV_CON_ID("cp_clk", &div4_clks[DIV4_CP]),
+
+ /* DIV6 clocks */
+ CLKDEV_CON_ID("sub_clk", &div6_clks[DIV6_SUB]),
+
+ /* MSTP32 clocks */
+ CLKDEV_DEV_ID("sh_mobile_lcdc_fb.0", &mstp_clks[MSTP100]),
+ CLKDEV_DEV_ID("sh_tmu.1", &mstp_clks[MSTP111]),
+ CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[MSTP116]),
+ CLKDEV_DEV_ID("sh_mobile_lcdc_fb.1", &mstp_clks[MSTP117]),
+ CLKDEV_DEV_ID("sh_tmu.0", &mstp_clks[MSTP125]),
+
+ CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP200]),
+ CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP201]),
+ CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP202]),
+ CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP203]),
+ CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]),
+ CLKDEV_DEV_ID("sh-sci.8", &mstp_clks[MSTP206]),
+ CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP207]),
+
+ CLKDEV_DEV_ID("sh-sci.7", &mstp_clks[MSTP222]),
+ CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP230]),
+
+ CLKDEV_DEV_ID("sh_cmt.10", &mstp_clks[MSTP329]),
+ CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]),
+};
+
+void __init r8a7740_clock_init(u8 md_ck)
+{
+ int k, ret = 0;
+
+ /* detect system clock parent */
+ if (md_ck & MD_CK1)
+ system_clk.parent = &extal1_div2_clk;
+ else
+ system_clk.parent = &extal1_clk;
+
+ /* detect RCLK parent */
+ switch (md_ck & (MD_CK2 | MD_CK1)) {
+ case MD_CK2 | MD_CK1:
+ r_clk.parent = &extal1_div2048_clk;
+ break;
+ case MD_CK2:
+ r_clk.parent = &extal1_div1024_clk;
+ break;
+ case MD_CK1:
+ default:
+ r_clk.parent = &extalr_clk;
+ break;
+ }
+
+ for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
+ ret = clk_register(main_clks[k]);
+
+ if (!ret)
+ ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table);
+
+ if (!ret)
+ ret = sh_clk_div6_register(div6_clks, DIV6_NR);
+
+ if (!ret)
+ ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR);
+
+ clkdev_add_table(lookups, ARRAY_SIZE(lookups));
+
+ if (!ret)
+ clk_init();
+ else
+ panic("failed to setup r8a7740 clocks\n");
+}
diff --git a/arch/arm/mach-shmobile/clock-r8a7779.c b/arch/arm/mach-shmobile/clock-r8a7779.c
new file mode 100644
index 0000000..b4b0e8c
--- /dev/null
+++ b/arch/arm/mach-shmobile/clock-r8a7779.c
@@ -0,0 +1,176 @@
+/*
+ * r8a7779 clock framework support
+ *
+ * Copyright (C) 2011 Renesas Solutions Corp.
+ * Copyright (C) 2011 Magnus Damm
+ *
+ * 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
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <linux/sh_clk.h>
+#include <linux/clkdev.h>
+#include <mach/common.h>
+
+#define FRQMR 0xffc80014
+#define MSTPCR0 0xffc80030
+#define MSTPCR1 0xffc80034
+#define MSTPCR3 0xffc8003c
+#define MSTPSR1 0xffc80044
+#define MSTPSR4 0xffc80048
+#define MSTPSR6 0xffc8004c
+#define MSTPCR4 0xffc80050
+#define MSTPCR5 0xffc80054
+#define MSTPCR6 0xffc80058
+#define MSTPCR7 0xffc80040
+
+/* ioremap() through clock mapping mandatory to avoid
+ * collision with ARM coherent DMA virtual memory range.
+ */
+
+static struct clk_mapping cpg_mapping = {
+ .phys = 0xffc80000,
+ .len = 0x80,
+};
+
+/*
+ * Default rate for the root input clock, reset this with clk_set_rate()
+ * from the platform code.
+ */
+static struct clk plla_clk = {
+ .rate = 1500000000,
+ .mapping = &cpg_mapping,
+};
+
+static struct clk *main_clks[] = {
+ &plla_clk,
+};
+
+static int divisors[] = { 0, 0, 0, 6, 8, 12, 16, 0, 24, 32, 36, 0, 0, 0, 0, 0 };
+
+static struct clk_div_mult_table div4_div_mult_table = {
+ .divisors = divisors,
+ .nr_divisors = ARRAY_SIZE(divisors),
+};
+
+static struct clk_div4_table div4_table = {
+ .div_mult_table = &div4_div_mult_table,
+};
+
+enum { DIV4_S, DIV4_OUT, DIV4_S4, DIV4_S3, DIV4_S1, DIV4_P, DIV4_NR };
+
+static struct clk div4_clks[DIV4_NR] = {
+ [DIV4_S] = SH_CLK_DIV4(&plla_clk, FRQMR, 20,
+ 0x0018, CLK_ENABLE_ON_INIT),
+ [DIV4_OUT] = SH_CLK_DIV4(&plla_clk, FRQMR, 16,
+ 0x0700, CLK_ENABLE_ON_INIT),
+ [DIV4_S4] = SH_CLK_DIV4(&plla_clk, FRQMR, 12,
+ 0x0040, CLK_ENABLE_ON_INIT),
+ [DIV4_S3] = SH_CLK_DIV4(&plla_clk, FRQMR, 8,
+ 0x0010, CLK_ENABLE_ON_INIT),
+ [DIV4_S1] = SH_CLK_DIV4(&plla_clk, FRQMR, 4,
+ 0x0060, CLK_ENABLE_ON_INIT),
+ [DIV4_P] = SH_CLK_DIV4(&plla_clk, FRQMR, 0,
+ 0x0300, CLK_ENABLE_ON_INIT),
+};
+
+enum { MSTP026, MSTP025, MSTP024, MSTP023, MSTP022, MSTP021,
+ MSTP016, MSTP015, MSTP014,
+ MSTP_NR };
+
+static struct clk mstp_clks[MSTP_NR] = {
+ [MSTP026] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 26, 0), /* SCIF0 */
+ [MSTP025] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 25, 0), /* SCIF1 */
+ [MSTP024] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 24, 0), /* SCIF2 */
+ [MSTP023] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 23, 0), /* SCIF3 */
+ [MSTP022] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 22, 0), /* SCIF4 */
+ [MSTP021] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 21, 0), /* SCIF5 */
+ [MSTP016] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 16, 0), /* TMU0 */
+ [MSTP015] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 15, 0), /* TMU1 */
+ [MSTP014] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 14, 0), /* TMU2 */
+};
+
+static unsigned long mul4_recalc(struct clk *clk)
+{
+ return clk->parent->rate * 4;
+}
+
+static struct clk_ops mul4_clk_ops = {
+ .recalc = mul4_recalc,
+};
+
+struct clk clkz_clk = {
+ .ops = &mul4_clk_ops,
+ .parent = &div4_clks[DIV4_S],
+};
+
+struct clk clkzs_clk = {
+ /* clks x 4 / 4 = clks */
+ .parent = &div4_clks[DIV4_S],
+};
+
+static struct clk *late_main_clks[] = {
+ &clkz_clk,
+ &clkzs_clk,
+};
+
+static struct clk_lookup lookups[] = {
+ /* main clocks */
+ CLKDEV_CON_ID("plla_clk", &plla_clk),
+ CLKDEV_CON_ID("clkz_clk", &clkz_clk),
+ CLKDEV_CON_ID("clkzs_clk", &clkzs_clk),
+
+ /* DIV4 clocks */
+ CLKDEV_CON_ID("shyway_clk", &div4_clks[DIV4_S]),
+ CLKDEV_CON_ID("bus_clk", &div4_clks[DIV4_OUT]),
+ CLKDEV_CON_ID("shyway4_clk", &div4_clks[DIV4_S4]),
+ CLKDEV_CON_ID("shyway3_clk", &div4_clks[DIV4_S3]),
+ CLKDEV_CON_ID("shyway1_clk", &div4_clks[DIV4_S1]),
+ CLKDEV_CON_ID("peripheral_clk", &div4_clks[DIV4_P]),
+
+ /* MSTP32 clocks */
+ CLKDEV_DEV_ID("sh_tmu.0", &mstp_clks[MSTP016]), /* TMU00 */
+ CLKDEV_DEV_ID("sh_tmu.1", &mstp_clks[MSTP016]), /* TMU01 */
+ CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP026]), /* SCIF0 */
+ CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP025]), /* SCIF1 */
+ CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP024]), /* SCIF2 */
+ CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP023]), /* SCIF3 */
+ CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP022]), /* SCIF4 */
+ CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP021]), /* SCIF6 */
+};
+
+void __init r8a7779_clock_init(void)
+{
+ int k, ret = 0;
+
+ for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
+ ret = clk_register(main_clks[k]);
+
+ if (!ret)
+ ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table);
+
+ if (!ret)
+ ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR);
+
+ for (k = 0; !ret && (k < ARRAY_SIZE(late_main_clks)); k++)
+ ret = clk_register(late_main_clks[k]);
+
+ clkdev_add_table(lookups, ARRAY_SIZE(lookups));
+
+ if (!ret)
+ clk_init();
+ else
+ panic("failed to setup r8a7779 clocks\n");
+}
diff --git a/arch/arm/mach-shmobile/clock-sh7372.c b/arch/arm/mach-shmobile/clock-sh7372.c
index 995a9c3..e349c22 100644
--- a/arch/arm/mach-shmobile/clock-sh7372.c
+++ b/arch/arm/mach-shmobile/clock-sh7372.c
@@ -411,11 +411,11 @@
};
static struct clk div6_reparent_clks[DIV6_REPARENT_NR] = {
- [DIV6_HDMI] = SH_CLK_DIV6_EXT(&pllc1_div2_clk, HDMICKCR, 0,
+ [DIV6_HDMI] = SH_CLK_DIV6_EXT(HDMICKCR, 0,
hdmi_parent, ARRAY_SIZE(hdmi_parent), 6, 2),
- [DIV6_FSIA] = SH_CLK_DIV6_EXT(&pllc1_div2_clk, FSIACKCR, 0,
+ [DIV6_FSIA] = SH_CLK_DIV6_EXT(FSIACKCR, 0,
fsiackcr_parent, ARRAY_SIZE(fsiackcr_parent), 6, 2),
- [DIV6_FSIB] = SH_CLK_DIV6_EXT(&pllc1_div2_clk, FSIBCKCR, 0,
+ [DIV6_FSIB] = SH_CLK_DIV6_EXT(FSIBCKCR, 0,
fsibckcr_parent, ARRAY_SIZE(fsibckcr_parent), 6, 2),
};
diff --git a/arch/arm/mach-shmobile/clock-sh73a0.c b/arch/arm/mach-shmobile/clock-sh73a0.c
index 1370a89..34944d0 100644
--- a/arch/arm/mach-shmobile/clock-sh73a0.c
+++ b/arch/arm/mach-shmobile/clock-sh73a0.c
@@ -92,6 +92,24 @@
.recalc = div2_recalc,
};
+static unsigned long div7_recalc(struct clk *clk)
+{
+ return clk->parent->rate / 7;
+}
+
+static struct clk_ops div7_clk_ops = {
+ .recalc = div7_recalc,
+};
+
+static unsigned long div13_recalc(struct clk *clk)
+{
+ return clk->parent->rate / 13;
+}
+
+static struct clk_ops div13_clk_ops = {
+ .recalc = div13_recalc,
+};
+
/* Divide extal1 by two */
static struct clk extal1_div2_clk = {
.ops = &div2_clk_ops,
@@ -174,12 +192,29 @@
.enable_bit = 3,
};
-/* Divide PLL1 by two */
+/* Divide PLL */
static struct clk pll1_div2_clk = {
.ops = &div2_clk_ops,
.parent = &pll1_clk,
};
+static struct clk pll1_div7_clk = {
+ .ops = &div7_clk_ops,
+ .parent = &pll1_clk,
+};
+
+static struct clk pll1_div13_clk = {
+ .ops = &div13_clk_ops,
+ .parent = &pll1_clk,
+};
+
+/* External input clock */
+struct clk sh73a0_extcki_clk = {
+};
+
+struct clk sh73a0_extalr_clk = {
+};
+
static struct clk *main_clks[] = {
&r_clk,
&sh73a0_extal1_clk,
@@ -193,6 +228,10 @@
&pll2_clk,
&pll3_clk,
&pll1_div2_clk,
+ &pll1_div7_clk,
+ &pll1_div13_clk,
+ &sh73a0_extcki_clk,
+ &sh73a0_extalr_clk,
};
static void div4_kick(struct clk *clk)
@@ -246,27 +285,84 @@
DIV6_DSIT, DIV6_DSI0P, DIV6_DSI1P,
DIV6_NR };
+static struct clk *vck_parent[8] = {
+ [0] = &pll1_div2_clk,
+ [1] = &pll2_clk,
+ [2] = &sh73a0_extcki_clk,
+ [3] = &sh73a0_extal2_clk,
+ [4] = &main_div2_clk,
+ [5] = &sh73a0_extalr_clk,
+ [6] = &main_clk,
+};
+
+static struct clk *pll_parent[4] = {
+ [0] = &pll1_div2_clk,
+ [1] = &pll2_clk,
+ [2] = &pll1_div13_clk,
+};
+
+static struct clk *hsi_parent[4] = {
+ [0] = &pll1_div2_clk,
+ [1] = &pll2_clk,
+ [2] = &pll1_div7_clk,
+};
+
+static struct clk *pll_extal2_parent[] = {
+ [0] = &pll1_div2_clk,
+ [1] = &pll2_clk,
+ [2] = &sh73a0_extal2_clk,
+ [3] = &sh73a0_extal2_clk,
+};
+
+static struct clk *dsi_parent[8] = {
+ [0] = &pll1_div2_clk,
+ [1] = &pll2_clk,
+ [2] = &main_clk,
+ [3] = &sh73a0_extal2_clk,
+ [4] = &sh73a0_extcki_clk,
+};
+
static struct clk div6_clks[DIV6_NR] = {
- [DIV6_VCK1] = SH_CLK_DIV6(&pll1_div2_clk, VCLKCR1, 0),
- [DIV6_VCK2] = SH_CLK_DIV6(&pll1_div2_clk, VCLKCR2, 0),
- [DIV6_VCK3] = SH_CLK_DIV6(&pll1_div2_clk, VCLKCR3, 0),
- [DIV6_ZB1] = SH_CLK_DIV6(&pll1_div2_clk, ZBCKCR, CLK_ENABLE_ON_INIT),
- [DIV6_FLCTL] = SH_CLK_DIV6(&pll1_div2_clk, FLCKCR, 0),
- [DIV6_SDHI0] = SH_CLK_DIV6(&pll1_div2_clk, SD0CKCR, 0),
- [DIV6_SDHI1] = SH_CLK_DIV6(&pll1_div2_clk, SD1CKCR, 0),
- [DIV6_SDHI2] = SH_CLK_DIV6(&pll1_div2_clk, SD2CKCR, 0),
- [DIV6_FSIA] = SH_CLK_DIV6(&pll1_div2_clk, FSIACKCR, 0),
- [DIV6_FSIB] = SH_CLK_DIV6(&pll1_div2_clk, FSIBCKCR, 0),
- [DIV6_SUB] = SH_CLK_DIV6(&sh73a0_extal2_clk, SUBCKCR, 0),
- [DIV6_SPUA] = SH_CLK_DIV6(&pll1_div2_clk, SPUACKCR, 0),
- [DIV6_SPUV] = SH_CLK_DIV6(&pll1_div2_clk, SPUVCKCR, 0),
- [DIV6_MSU] = SH_CLK_DIV6(&pll1_div2_clk, MSUCKCR, 0),
- [DIV6_HSI] = SH_CLK_DIV6(&pll1_div2_clk, HSICKCR, 0),
- [DIV6_MFG1] = SH_CLK_DIV6(&pll1_div2_clk, MFCK1CR, 0),
- [DIV6_MFG2] = SH_CLK_DIV6(&pll1_div2_clk, MFCK2CR, 0),
- [DIV6_DSIT] = SH_CLK_DIV6(&pll1_div2_clk, DSITCKCR, 0),
- [DIV6_DSI0P] = SH_CLK_DIV6(&pll1_div2_clk, DSI0PCKCR, 0),
- [DIV6_DSI1P] = SH_CLK_DIV6(&pll1_div2_clk, DSI1PCKCR, 0),
+ [DIV6_VCK1] = SH_CLK_DIV6_EXT(VCLKCR1, 0,
+ vck_parent, ARRAY_SIZE(vck_parent), 12, 3),
+ [DIV6_VCK2] = SH_CLK_DIV6_EXT(VCLKCR2, 0,
+ vck_parent, ARRAY_SIZE(vck_parent), 12, 3),
+ [DIV6_VCK3] = SH_CLK_DIV6_EXT(VCLKCR3, 0,
+ vck_parent, ARRAY_SIZE(vck_parent), 12, 3),
+ [DIV6_ZB1] = SH_CLK_DIV6_EXT(ZBCKCR, CLK_ENABLE_ON_INIT,
+ pll_parent, ARRAY_SIZE(pll_parent), 7, 1),
+ [DIV6_FLCTL] = SH_CLK_DIV6_EXT(FLCKCR, 0,
+ pll_parent, ARRAY_SIZE(pll_parent), 7, 1),
+ [DIV6_SDHI0] = SH_CLK_DIV6_EXT(SD0CKCR, 0,
+ pll_parent, ARRAY_SIZE(pll_parent), 6, 2),
+ [DIV6_SDHI1] = SH_CLK_DIV6_EXT(SD1CKCR, 0,
+ pll_parent, ARRAY_SIZE(pll_parent), 6, 2),
+ [DIV6_SDHI2] = SH_CLK_DIV6_EXT(SD2CKCR, 0,
+ pll_parent, ARRAY_SIZE(pll_parent), 6, 2),
+ [DIV6_FSIA] = SH_CLK_DIV6_EXT(FSIACKCR, 0,
+ pll_parent, ARRAY_SIZE(pll_parent), 6, 1),
+ [DIV6_FSIB] = SH_CLK_DIV6_EXT(FSIBCKCR, 0,
+ pll_parent, ARRAY_SIZE(pll_parent), 6, 1),
+ [DIV6_SUB] = SH_CLK_DIV6_EXT(SUBCKCR, 0,
+ pll_extal2_parent, ARRAY_SIZE(pll_extal2_parent), 6, 2),
+ [DIV6_SPUA] = SH_CLK_DIV6_EXT(SPUACKCR, 0,
+ pll_extal2_parent, ARRAY_SIZE(pll_extal2_parent), 6, 2),
+ [DIV6_SPUV] = SH_CLK_DIV6_EXT(SPUVCKCR, 0,
+ pll_extal2_parent, ARRAY_SIZE(pll_extal2_parent), 6, 2),
+ [DIV6_MSU] = SH_CLK_DIV6_EXT(MSUCKCR, 0,
+ pll_parent, ARRAY_SIZE(pll_parent), 7, 1),
+ [DIV6_HSI] = SH_CLK_DIV6_EXT(HSICKCR, 0,
+ hsi_parent, ARRAY_SIZE(hsi_parent), 6, 2),
+ [DIV6_MFG1] = SH_CLK_DIV6_EXT(MFCK1CR, 0,
+ pll_parent, ARRAY_SIZE(pll_parent), 7, 1),
+ [DIV6_MFG2] = SH_CLK_DIV6_EXT(MFCK2CR, 0,
+ pll_parent, ARRAY_SIZE(pll_parent), 7, 1),
+ [DIV6_DSIT] = SH_CLK_DIV6_EXT(DSITCKCR, 0,
+ pll_parent, ARRAY_SIZE(pll_parent), 7, 1),
+ [DIV6_DSI0P] = SH_CLK_DIV6_EXT(DSI0PCKCR, 0,
+ dsi_parent, ARRAY_SIZE(dsi_parent), 12, 3),
+ [DIV6_DSI1P] = SH_CLK_DIV6_EXT(DSI1PCKCR, 0,
+ dsi_parent, ARRAY_SIZE(dsi_parent), 12, 3),
};
enum { MSTP001,
@@ -403,7 +499,7 @@
ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table);
if (!ret)
- ret = sh_clk_div6_register(div6_clks, DIV6_NR);
+ ret = sh_clk_div6_reparent_register(div6_clks, DIV6_NR);
if (!ret)
ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR);
diff --git a/arch/arm/mach-shmobile/headsmp.S b/arch/arm/mach-shmobile/headsmp.S
index 26079d9..6ac015c 100644
--- a/arch/arm/mach-shmobile/headsmp.S
+++ b/arch/arm/mach-shmobile/headsmp.S
@@ -14,7 +14,7 @@
#include <linux/init.h>
#include <asm/memory.h>
- __INIT
+ __CPUINIT
/*
* Reset vector for secondary CPUs.
diff --git a/arch/arm/mach-shmobile/hotplug.c b/arch/arm/mach-shmobile/hotplug.c
index 238a0d9..828d22f 100644
--- a/arch/arm/mach-shmobile/hotplug.c
+++ b/arch/arm/mach-shmobile/hotplug.c
@@ -12,14 +12,43 @@
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/smp.h>
+#include <linux/cpumask.h>
+#include <linux/delay.h>
+#include <mach/common.h>
+#include <asm/cacheflush.h>
+
+static cpumask_t dead_cpus;
int platform_cpu_kill(unsigned int cpu)
{
- return 1;
+ int k;
+
+ /* this function is running on another CPU than the offline target,
+ * here we need wait for shutdown code in platform_cpu_die() to
+ * finish before asking SoC-specific code to power off the CPU core.
+ */
+ for (k = 0; k < 1000; k++) {
+ if (cpumask_test_cpu(cpu, &dead_cpus))
+ return shmobile_platform_cpu_kill(cpu);
+
+ mdelay(1);
+ }
+
+ return 0;
}
void platform_cpu_die(unsigned int cpu)
{
+ /* hardware shutdown code running on the CPU that is being offlined */
+ flush_cache_all();
+ dsb();
+
+ /* notify platform_cpu_kill() that hardware shutdown is finished */
+ cpumask_set_cpu(cpu, &dead_cpus);
+
+ /* wait for SoC code in platform_cpu_kill() to shut off CPU core
+ * power. CPU bring up starts from the reset vector.
+ */
while (1) {
/*
* here's the WFI
@@ -33,6 +62,7 @@
int platform_cpu_disable(unsigned int cpu)
{
+ cpumask_clear_cpu(cpu, &dead_cpus);
/*
* we don't allow CPU 0 to be shutdown (it is still too special
* e.g. clock tick interrupts)
diff --git a/arch/arm/mach-shmobile/include/mach/common.h b/arch/arm/mach-shmobile/include/mach/common.h
index be78a2c..e4b945e 100644
--- a/arch/arm/mach-shmobile/include/mach/common.h
+++ b/arch/arm/mach-shmobile/include/mach/common.h
@@ -4,6 +4,7 @@
extern struct sys_timer shmobile_timer;
extern void shmobile_setup_console(void);
extern void shmobile_secondary_vector(void);
+extern int shmobile_platform_cpu_kill(unsigned int cpu);
struct clk;
extern int clk_init(void);
extern void shmobile_handle_irq_intc(struct pt_regs *);
@@ -46,10 +47,31 @@
extern void sh73a0_pinmux_init(void);
extern struct clk sh73a0_extal1_clk;
extern struct clk sh73a0_extal2_clk;
+extern struct clk sh73a0_extcki_clk;
+extern struct clk sh73a0_extalr_clk;
extern unsigned int sh73a0_get_core_count(void);
extern void sh73a0_secondary_init(unsigned int cpu);
extern int sh73a0_boot_secondary(unsigned int cpu);
extern void sh73a0_smp_prepare_cpus(void);
+extern void r8a7740_init_irq(void);
+extern void r8a7740_add_early_devices(void);
+extern void r8a7740_add_standard_devices(void);
+extern void r8a7740_clock_init(u8 md_ck);
+extern void r8a7740_pinmux_init(void);
+
+extern void r8a7779_init_irq(void);
+extern void r8a7779_add_early_devices(void);
+extern void r8a7779_add_standard_devices(void);
+extern void r8a7779_clock_init(void);
+extern void r8a7779_pinmux_init(void);
+extern void r8a7779_pm_init(void);
+
+extern unsigned int r8a7779_get_core_count(void);
+extern int r8a7779_platform_cpu_kill(unsigned int cpu);
+extern void r8a7779_secondary_init(unsigned int cpu);
+extern int r8a7779_boot_secondary(unsigned int cpu);
+extern void r8a7779_smp_prepare_cpus(void);
+
#endif /* __ARCH_MACH_COMMON_H */
diff --git a/arch/arm/mach-shmobile/include/mach/r8a7740.h b/arch/arm/mach-shmobile/include/mach/r8a7740.h
new file mode 100644
index 0000000..9d447ab
--- /dev/null
+++ b/arch/arm/mach-shmobile/include/mach/r8a7740.h
@@ -0,0 +1,584 @@
+/*
+ * Copyright (C) 2011 Renesas Solutions Corp.
+ * Copyright (C) 2011 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+ *
+ * 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; version 2 of the License.
+ *
+ * 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
+ */
+
+#ifndef __ASM_R8A7740_H__
+#define __ASM_R8A7740_H__
+
+/*
+ * MD_CKx pin
+ */
+#define MD_CK2 (1 << 2)
+#define MD_CK1 (1 << 1)
+#define MD_CK0 (1 << 0)
+
+/*
+ * Pin Function Controller:
+ * GPIO_FN_xx - GPIO used to select pin function
+ * GPIO_PORTxx - GPIO mapped to real I/O pin on CPU
+ */
+enum {
+ /* PORT */
+ GPIO_PORT0, GPIO_PORT1, GPIO_PORT2, GPIO_PORT3, GPIO_PORT4,
+ GPIO_PORT5, GPIO_PORT6, GPIO_PORT7, GPIO_PORT8, GPIO_PORT9,
+
+ GPIO_PORT10, GPIO_PORT11, GPIO_PORT12, GPIO_PORT13, GPIO_PORT14,
+ GPIO_PORT15, GPIO_PORT16, GPIO_PORT17, GPIO_PORT18, GPIO_PORT19,
+
+ GPIO_PORT20, GPIO_PORT21, GPIO_PORT22, GPIO_PORT23, GPIO_PORT24,
+ GPIO_PORT25, GPIO_PORT26, GPIO_PORT27, GPIO_PORT28, GPIO_PORT29,
+
+ GPIO_PORT30, GPIO_PORT31, GPIO_PORT32, GPIO_PORT33, GPIO_PORT34,
+ GPIO_PORT35, GPIO_PORT36, GPIO_PORT37, GPIO_PORT38, GPIO_PORT39,
+
+ GPIO_PORT40, GPIO_PORT41, GPIO_PORT42, GPIO_PORT43, GPIO_PORT44,
+ GPIO_PORT45, GPIO_PORT46, GPIO_PORT47, GPIO_PORT48, GPIO_PORT49,
+
+ GPIO_PORT50, GPIO_PORT51, GPIO_PORT52, GPIO_PORT53, GPIO_PORT54,
+ GPIO_PORT55, GPIO_PORT56, GPIO_PORT57, GPIO_PORT58, GPIO_PORT59,
+
+ GPIO_PORT60, GPIO_PORT61, GPIO_PORT62, GPIO_PORT63, GPIO_PORT64,
+ GPIO_PORT65, GPIO_PORT66, GPIO_PORT67, GPIO_PORT68, GPIO_PORT69,
+
+ GPIO_PORT70, GPIO_PORT71, GPIO_PORT72, GPIO_PORT73, GPIO_PORT74,
+ GPIO_PORT75, GPIO_PORT76, GPIO_PORT77, GPIO_PORT78, GPIO_PORT79,
+
+ GPIO_PORT80, GPIO_PORT81, GPIO_PORT82, GPIO_PORT83, GPIO_PORT84,
+ GPIO_PORT85, GPIO_PORT86, GPIO_PORT87, GPIO_PORT88, GPIO_PORT89,
+
+ GPIO_PORT90, GPIO_PORT91, GPIO_PORT92, GPIO_PORT93, GPIO_PORT94,
+ GPIO_PORT95, GPIO_PORT96, GPIO_PORT97, GPIO_PORT98, GPIO_PORT99,
+
+ GPIO_PORT100, GPIO_PORT101, GPIO_PORT102, GPIO_PORT103, GPIO_PORT104,
+ GPIO_PORT105, GPIO_PORT106, GPIO_PORT107, GPIO_PORT108, GPIO_PORT109,
+
+ GPIO_PORT110, GPIO_PORT111, GPIO_PORT112, GPIO_PORT113, GPIO_PORT114,
+ GPIO_PORT115, GPIO_PORT116, GPIO_PORT117, GPIO_PORT118, GPIO_PORT119,
+
+ GPIO_PORT120, GPIO_PORT121, GPIO_PORT122, GPIO_PORT123, GPIO_PORT124,
+ GPIO_PORT125, GPIO_PORT126, GPIO_PORT127, GPIO_PORT128, GPIO_PORT129,
+
+ GPIO_PORT130, GPIO_PORT131, GPIO_PORT132, GPIO_PORT133, GPIO_PORT134,
+ GPIO_PORT135, GPIO_PORT136, GPIO_PORT137, GPIO_PORT138, GPIO_PORT139,
+
+ GPIO_PORT140, GPIO_PORT141, GPIO_PORT142, GPIO_PORT143, GPIO_PORT144,
+ GPIO_PORT145, GPIO_PORT146, GPIO_PORT147, GPIO_PORT148, GPIO_PORT149,
+
+ GPIO_PORT150, GPIO_PORT151, GPIO_PORT152, GPIO_PORT153, GPIO_PORT154,
+ GPIO_PORT155, GPIO_PORT156, GPIO_PORT157, GPIO_PORT158, GPIO_PORT159,
+
+ GPIO_PORT160, GPIO_PORT161, GPIO_PORT162, GPIO_PORT163, GPIO_PORT164,
+ GPIO_PORT165, GPIO_PORT166, GPIO_PORT167, GPIO_PORT168, GPIO_PORT169,
+
+ GPIO_PORT170, GPIO_PORT171, GPIO_PORT172, GPIO_PORT173, GPIO_PORT174,
+ GPIO_PORT175, GPIO_PORT176, GPIO_PORT177, GPIO_PORT178, GPIO_PORT179,
+
+ GPIO_PORT180, GPIO_PORT181, GPIO_PORT182, GPIO_PORT183, GPIO_PORT184,
+ GPIO_PORT185, GPIO_PORT186, GPIO_PORT187, GPIO_PORT188, GPIO_PORT189,
+
+ GPIO_PORT190, GPIO_PORT191, GPIO_PORT192, GPIO_PORT193, GPIO_PORT194,
+ GPIO_PORT195, GPIO_PORT196, GPIO_PORT197, GPIO_PORT198, GPIO_PORT199,
+
+ GPIO_PORT200, GPIO_PORT201, GPIO_PORT202, GPIO_PORT203, GPIO_PORT204,
+ GPIO_PORT205, GPIO_PORT206, GPIO_PORT207, GPIO_PORT208, GPIO_PORT209,
+
+ GPIO_PORT210, GPIO_PORT211,
+
+ /* IRQ */
+ GPIO_FN_IRQ0_PORT2, GPIO_FN_IRQ0_PORT13,
+ GPIO_FN_IRQ1,
+ GPIO_FN_IRQ2_PORT11, GPIO_FN_IRQ2_PORT12,
+ GPIO_FN_IRQ3_PORT10, GPIO_FN_IRQ3_PORT14,
+ GPIO_FN_IRQ4_PORT15, GPIO_FN_IRQ4_PORT172,
+ GPIO_FN_IRQ5_PORT0, GPIO_FN_IRQ5_PORT1,
+ GPIO_FN_IRQ6_PORT121, GPIO_FN_IRQ6_PORT173,
+ GPIO_FN_IRQ7_PORT120, GPIO_FN_IRQ7_PORT209,
+ GPIO_FN_IRQ8,
+ GPIO_FN_IRQ9_PORT118, GPIO_FN_IRQ9_PORT210,
+ GPIO_FN_IRQ10,
+ GPIO_FN_IRQ11,
+ GPIO_FN_IRQ12_PORT42, GPIO_FN_IRQ12_PORT97,
+ GPIO_FN_IRQ13_PORT64, GPIO_FN_IRQ13_PORT98,
+ GPIO_FN_IRQ14_PORT63, GPIO_FN_IRQ14_PORT99,
+ GPIO_FN_IRQ15_PORT62, GPIO_FN_IRQ15_PORT100,
+ GPIO_FN_IRQ16_PORT68, GPIO_FN_IRQ16_PORT211,
+ GPIO_FN_IRQ17,
+ GPIO_FN_IRQ18,
+ GPIO_FN_IRQ19,
+ GPIO_FN_IRQ20,
+ GPIO_FN_IRQ21,
+ GPIO_FN_IRQ22,
+ GPIO_FN_IRQ23,
+ GPIO_FN_IRQ24,
+ GPIO_FN_IRQ25,
+ GPIO_FN_IRQ26_PORT58, GPIO_FN_IRQ26_PORT81,
+ GPIO_FN_IRQ27_PORT57, GPIO_FN_IRQ27_PORT168,
+ GPIO_FN_IRQ28_PORT56, GPIO_FN_IRQ28_PORT169,
+ GPIO_FN_IRQ29_PORT50, GPIO_FN_IRQ29_PORT170,
+ GPIO_FN_IRQ30_PORT49, GPIO_FN_IRQ30_PORT171,
+ GPIO_FN_IRQ31_PORT41, GPIO_FN_IRQ31_PORT167,
+
+ /* Function */
+
+ /* DBGT */
+ GPIO_FN_DBGMDT2, GPIO_FN_DBGMDT1, GPIO_FN_DBGMDT0,
+ GPIO_FN_DBGMD10, GPIO_FN_DBGMD11, GPIO_FN_DBGMD20,
+ GPIO_FN_DBGMD21,
+
+ /* FSI */
+ GPIO_FN_FSIAISLD_PORT0, /* FSIAISLD Port 0/5 */
+ GPIO_FN_FSIAISLD_PORT5,
+ GPIO_FN_FSIASPDIF_PORT9, /* FSIASPDIF Port 9/18 */
+ GPIO_FN_FSIASPDIF_PORT18,
+ GPIO_FN_FSIAOSLD1, GPIO_FN_FSIAOSLD2,
+ GPIO_FN_FSIAOLR, GPIO_FN_FSIAOBT,
+ GPIO_FN_FSIAOSLD, GPIO_FN_FSIAOMC,
+ GPIO_FN_FSIACK, GPIO_FN_FSIAILR,
+ GPIO_FN_FSIAIBT,
+
+ /* FMSI */
+ GPIO_FN_FMSISLD_PORT1, /* FMSISLD Port 1/6 */
+ GPIO_FN_FMSISLD_PORT6,
+ GPIO_FN_FMSIILR, GPIO_FN_FMSIIBT,
+ GPIO_FN_FMSIOLR, GPIO_FN_FMSIOBT,
+ GPIO_FN_FMSICK, GPIO_FN_FMSOILR,
+ GPIO_FN_FMSOIBT, GPIO_FN_FMSOOLR,
+ GPIO_FN_FMSOOBT, GPIO_FN_FMSOSLD,
+ GPIO_FN_FMSOCK,
+
+ /* SCIFA0 */
+ GPIO_FN_SCIFA0_SCK, GPIO_FN_SCIFA0_CTS,
+ GPIO_FN_SCIFA0_RTS, GPIO_FN_SCIFA0_RXD,
+ GPIO_FN_SCIFA0_TXD,
+
+ /* SCIFA1 */
+ GPIO_FN_SCIFA1_CTS, GPIO_FN_SCIFA1_SCK,
+ GPIO_FN_SCIFA1_RXD, GPIO_FN_SCIFA1_TXD,
+ GPIO_FN_SCIFA1_RTS,
+
+ /* SCIFA2 */
+ GPIO_FN_SCIFA2_SCK_PORT22, /* SCIFA2_SCK Port 22/199 */
+ GPIO_FN_SCIFA2_SCK_PORT199,
+ GPIO_FN_SCIFA2_RXD, GPIO_FN_SCIFA2_TXD,
+ GPIO_FN_SCIFA2_CTS, GPIO_FN_SCIFA2_RTS,
+
+ /* SCIFA3 */
+ GPIO_FN_SCIFA3_RTS_PORT105, /* MSEL5CR_8_0 */
+ GPIO_FN_SCIFA3_SCK_PORT116,
+ GPIO_FN_SCIFA3_CTS_PORT117,
+ GPIO_FN_SCIFA3_RXD_PORT174,
+ GPIO_FN_SCIFA3_TXD_PORT175,
+
+ GPIO_FN_SCIFA3_RTS_PORT161, /* MSEL5CR_8_1 */
+ GPIO_FN_SCIFA3_SCK_PORT158,
+ GPIO_FN_SCIFA3_CTS_PORT162,
+ GPIO_FN_SCIFA3_RXD_PORT159,
+ GPIO_FN_SCIFA3_TXD_PORT160,
+
+ /* SCIFA4 */
+ GPIO_FN_SCIFA4_RXD_PORT12, /* MSEL5CR[12:11] = 00 */
+ GPIO_FN_SCIFA4_TXD_PORT13,
+
+ GPIO_FN_SCIFA4_RXD_PORT204, /* MSEL5CR[12:11] = 01 */
+ GPIO_FN_SCIFA4_TXD_PORT203,
+
+ GPIO_FN_SCIFA4_RXD_PORT94, /* MSEL5CR[12:11] = 10 */
+ GPIO_FN_SCIFA4_TXD_PORT93,
+
+ GPIO_FN_SCIFA4_SCK_PORT21, /* SCIFA4_SCK Port 21/205 */
+ GPIO_FN_SCIFA4_SCK_PORT205,
+
+ /* SCIFA5 */
+ GPIO_FN_SCIFA5_TXD_PORT20, /* MSEL5CR[15:14] = 00 */
+ GPIO_FN_SCIFA5_RXD_PORT10,
+
+ GPIO_FN_SCIFA5_RXD_PORT207, /* MSEL5CR[15:14] = 01 */
+ GPIO_FN_SCIFA5_TXD_PORT208,
+
+ GPIO_FN_SCIFA5_TXD_PORT91, /* MSEL5CR[15:14] = 10 */
+ GPIO_FN_SCIFA5_RXD_PORT92,
+
+ GPIO_FN_SCIFA5_SCK_PORT23, /* SCIFA5_SCK Port 23/206 */
+ GPIO_FN_SCIFA5_SCK_PORT206,
+
+ /* SCIFA6 */
+ GPIO_FN_SCIFA6_SCK, GPIO_FN_SCIFA6_RXD, GPIO_FN_SCIFA6_TXD,
+
+ /* SCIFA7 */
+ GPIO_FN_SCIFA7_TXD, GPIO_FN_SCIFA7_RXD,
+
+ /* SCIFAB */
+ GPIO_FN_SCIFB_SCK_PORT190, /* MSEL5CR_17_0 */
+ GPIO_FN_SCIFB_RXD_PORT191,
+ GPIO_FN_SCIFB_TXD_PORT192,
+ GPIO_FN_SCIFB_RTS_PORT186,
+ GPIO_FN_SCIFB_CTS_PORT187,
+
+ GPIO_FN_SCIFB_SCK_PORT2, /* MSEL5CR_17_1 */
+ GPIO_FN_SCIFB_RXD_PORT3,
+ GPIO_FN_SCIFB_TXD_PORT4,
+ GPIO_FN_SCIFB_RTS_PORT172,
+ GPIO_FN_SCIFB_CTS_PORT173,
+
+ /* LCD0 */
+ GPIO_FN_LCDC0_SELECT,
+ GPIO_FN_LCD0_D0, GPIO_FN_LCD0_D1, GPIO_FN_LCD0_D2,
+ GPIO_FN_LCD0_D3, GPIO_FN_LCD0_D4, GPIO_FN_LCD0_D5,
+ GPIO_FN_LCD0_D6, GPIO_FN_LCD0_D7, GPIO_FN_LCD0_D8,
+ GPIO_FN_LCD0_D9, GPIO_FN_LCD0_D10, GPIO_FN_LCD0_D11,
+ GPIO_FN_LCD0_D12, GPIO_FN_LCD0_D13, GPIO_FN_LCD0_D14,
+ GPIO_FN_LCD0_D15, GPIO_FN_LCD0_D16, GPIO_FN_LCD0_D17,
+ GPIO_FN_LCD0_DON, GPIO_FN_LCD0_VCPWC, GPIO_FN_LCD0_VEPWC,
+
+ GPIO_FN_LCD0_DCK, GPIO_FN_LCD0_VSYN, /* for RGB */
+ GPIO_FN_LCD0_HSYN, GPIO_FN_LCD0_DISP, /* for RGB */
+
+ GPIO_FN_LCD0_WR, GPIO_FN_LCD0_RD, /* for SYS */
+ GPIO_FN_LCD0_CS, GPIO_FN_LCD0_RS, /* for SYS */
+
+ GPIO_FN_LCD0_D18_PORT163, GPIO_FN_LCD0_D19_PORT162,
+ GPIO_FN_LCD0_D20_PORT161, GPIO_FN_LCD0_D21_PORT158,
+ GPIO_FN_LCD0_D22_PORT160, GPIO_FN_LCD0_D23_PORT159,
+ GPIO_FN_LCD0_LCLK_PORT165, /* MSEL5CR_6_1 */
+
+ GPIO_FN_LCD0_D18_PORT40, GPIO_FN_LCD0_D19_PORT4,
+ GPIO_FN_LCD0_D20_PORT3, GPIO_FN_LCD0_D21_PORT2,
+ GPIO_FN_LCD0_D22_PORT0, GPIO_FN_LCD0_D23_PORT1,
+ GPIO_FN_LCD0_LCLK_PORT102, /* MSEL5CR_6_0 */
+
+ /* LCD1 */
+ GPIO_FN_LCDC1_SELECT,
+ GPIO_FN_LCD1_D0, GPIO_FN_LCD1_D1, GPIO_FN_LCD1_D2,
+ GPIO_FN_LCD1_D3, GPIO_FN_LCD1_D4, GPIO_FN_LCD1_D5,
+ GPIO_FN_LCD1_D6, GPIO_FN_LCD1_D7, GPIO_FN_LCD1_D8,
+ GPIO_FN_LCD1_D9, GPIO_FN_LCD1_D10, GPIO_FN_LCD1_D11,
+ GPIO_FN_LCD1_D12, GPIO_FN_LCD1_D13, GPIO_FN_LCD1_D14,
+ GPIO_FN_LCD1_D15, GPIO_FN_LCD1_D16, GPIO_FN_LCD1_D17,
+ GPIO_FN_LCD1_D18, GPIO_FN_LCD1_D19, GPIO_FN_LCD1_D20,
+ GPIO_FN_LCD1_D21, GPIO_FN_LCD1_D22, GPIO_FN_LCD1_D23,
+ GPIO_FN_LCD1_DON, GPIO_FN_LCD1_VCPWC,
+ GPIO_FN_LCD1_LCLK, GPIO_FN_LCD1_VEPWC,
+
+ GPIO_FN_LCD1_DCK, GPIO_FN_LCD1_VSYN, /* for RGB */
+ GPIO_FN_LCD1_HSYN, GPIO_FN_LCD1_DISP, /* for RGB */
+
+ GPIO_FN_LCD1_WR, GPIO_FN_LCD1_RD, /* for SYS */
+ GPIO_FN_LCD1_CS, GPIO_FN_LCD1_RS, /* for SYS */
+
+ /* RSPI */
+ GPIO_FN_RSPI_SSL0_A, GPIO_FN_RSPI_SSL1_A,
+ GPIO_FN_RSPI_SSL2_A, GPIO_FN_RSPI_SSL3_A,
+ GPIO_FN_RSPI_MOSI_A, GPIO_FN_RSPI_MISO_A,
+ GPIO_FN_RSPI_CK_A,
+
+ /* VIO CKO */
+ GPIO_FN_VIO_CKO1,
+ GPIO_FN_VIO_CKO2,
+ GPIO_FN_VIO_CKO_1,
+ GPIO_FN_VIO_CKO,
+
+ /* VIO0 */
+ GPIO_FN_VIO0_D0, GPIO_FN_VIO0_D1, GPIO_FN_VIO0_D2,
+ GPIO_FN_VIO0_D3, GPIO_FN_VIO0_D4, GPIO_FN_VIO0_D5,
+ GPIO_FN_VIO0_D6, GPIO_FN_VIO0_D7, GPIO_FN_VIO0_D8,
+ GPIO_FN_VIO0_D9, GPIO_FN_VIO0_D10, GPIO_FN_VIO0_D11,
+ GPIO_FN_VIO0_D12, GPIO_FN_VIO0_VD, GPIO_FN_VIO0_HD,
+ GPIO_FN_VIO0_CLK, GPIO_FN_VIO0_FIELD,
+
+ GPIO_FN_VIO0_D13_PORT26, /* MSEL5CR_27_0 */
+ GPIO_FN_VIO0_D14_PORT25,
+ GPIO_FN_VIO0_D15_PORT24,
+
+ GPIO_FN_VIO0_D13_PORT22, /* MSEL5CR_27_1 */
+ GPIO_FN_VIO0_D14_PORT95,
+ GPIO_FN_VIO0_D15_PORT96,
+
+ /* VIO1 */
+ GPIO_FN_VIO1_D0, GPIO_FN_VIO1_D1, GPIO_FN_VIO1_D2,
+ GPIO_FN_VIO1_D3, GPIO_FN_VIO1_D4, GPIO_FN_VIO1_D5,
+ GPIO_FN_VIO1_D6, GPIO_FN_VIO1_D7, GPIO_FN_VIO1_VD,
+ GPIO_FN_VIO1_HD, GPIO_FN_VIO1_CLK, GPIO_FN_VIO1_FIELD,
+
+ /* TPU0 */
+ GPIO_FN_TPU0TO0, GPIO_FN_TPU0TO1,
+ GPIO_FN_TPU0TO3,
+ GPIO_FN_TPU0TO2_PORT66, /* TPU0TO2 Port 66/202 */
+ GPIO_FN_TPU0TO2_PORT202,
+
+ /* SSP1 0 */
+ GPIO_FN_STP0_IPD0, GPIO_FN_STP0_IPD1, GPIO_FN_STP0_IPD2,
+ GPIO_FN_STP0_IPD3, GPIO_FN_STP0_IPD4, GPIO_FN_STP0_IPD5,
+ GPIO_FN_STP0_IPD6, GPIO_FN_STP0_IPD7, GPIO_FN_STP0_IPEN,
+ GPIO_FN_STP0_IPCLK, GPIO_FN_STP0_IPSYNC,
+
+ /* SSP1 1 */
+ GPIO_FN_STP1_IPD1, GPIO_FN_STP1_IPD2, GPIO_FN_STP1_IPD3,
+ GPIO_FN_STP1_IPD4, GPIO_FN_STP1_IPD5, GPIO_FN_STP1_IPD6,
+ GPIO_FN_STP1_IPD7, GPIO_FN_STP1_IPCLK, GPIO_FN_STP1_IPSYNC,
+
+ GPIO_FN_STP1_IPD0_PORT186, /* MSEL5CR_23_0 */
+ GPIO_FN_STP1_IPEN_PORT187,
+
+ GPIO_FN_STP1_IPD0_PORT194, /* MSEL5CR_23_1 */
+ GPIO_FN_STP1_IPEN_PORT193,
+
+ /* SIM */
+ GPIO_FN_SIM_RST, GPIO_FN_SIM_CLK,
+ GPIO_FN_SIM_D_PORT22, /* SIM_D Port 22/199 */
+ GPIO_FN_SIM_D_PORT199,
+
+ /* SDHI0 */
+ GPIO_FN_SDHI0_D0, GPIO_FN_SDHI0_D1, GPIO_FN_SDHI0_D2,
+ GPIO_FN_SDHI0_D3, GPIO_FN_SDHI0_CD, GPIO_FN_SDHI0_WP,
+ GPIO_FN_SDHI0_CMD, GPIO_FN_SDHI0_CLK,
+
+ /* SDHI1 */
+ GPIO_FN_SDHI1_D0, GPIO_FN_SDHI1_D1, GPIO_FN_SDHI1_D2,
+ GPIO_FN_SDHI1_D3, GPIO_FN_SDHI1_CD, GPIO_FN_SDHI1_WP,
+ GPIO_FN_SDHI1_CMD, GPIO_FN_SDHI1_CLK,
+
+ /* SDHI2 */
+ GPIO_FN_SDHI2_D0, GPIO_FN_SDHI2_D1, GPIO_FN_SDHI2_D2,
+ GPIO_FN_SDHI2_D3, GPIO_FN_SDHI2_CLK, GPIO_FN_SDHI2_CMD,
+
+ GPIO_FN_SDHI2_CD_PORT24, /* MSEL5CR_19_0 */
+ GPIO_FN_SDHI2_WP_PORT25,
+
+ GPIO_FN_SDHI2_WP_PORT177, /* MSEL5CR_19_1 */
+ GPIO_FN_SDHI2_CD_PORT202,
+
+ /* MSIOF2 */
+ GPIO_FN_MSIOF2_TXD, GPIO_FN_MSIOF2_RXD, GPIO_FN_MSIOF2_TSCK,
+ GPIO_FN_MSIOF2_SS2, GPIO_FN_MSIOF2_TSYNC, GPIO_FN_MSIOF2_SS1,
+ GPIO_FN_MSIOF2_MCK1, GPIO_FN_MSIOF2_MCK0, GPIO_FN_MSIOF2_RSYNC,
+ GPIO_FN_MSIOF2_RSCK,
+
+ /* KEYSC */
+ GPIO_FN_KEYIN4, GPIO_FN_KEYIN5,
+ GPIO_FN_KEYIN6, GPIO_FN_KEYIN7,
+ GPIO_FN_KEYOUT0, GPIO_FN_KEYOUT1, GPIO_FN_KEYOUT2,
+ GPIO_FN_KEYOUT3, GPIO_FN_KEYOUT4, GPIO_FN_KEYOUT5,
+ GPIO_FN_KEYOUT6, GPIO_FN_KEYOUT7,
+
+ GPIO_FN_KEYIN0_PORT43, /* MSEL4CR_18_0 */
+ GPIO_FN_KEYIN1_PORT44,
+ GPIO_FN_KEYIN2_PORT45,
+ GPIO_FN_KEYIN3_PORT46,
+
+ GPIO_FN_KEYIN0_PORT58, /* MSEL4CR_18_1 */
+ GPIO_FN_KEYIN1_PORT57,
+ GPIO_FN_KEYIN2_PORT56,
+ GPIO_FN_KEYIN3_PORT55,
+
+ /* VOU */
+ GPIO_FN_DV_D0, GPIO_FN_DV_D1, GPIO_FN_DV_D2, GPIO_FN_DV_D3,
+ GPIO_FN_DV_D4, GPIO_FN_DV_D5, GPIO_FN_DV_D6, GPIO_FN_DV_D7,
+ GPIO_FN_DV_D8, GPIO_FN_DV_D9, GPIO_FN_DV_D10, GPIO_FN_DV_D11,
+ GPIO_FN_DV_D12, GPIO_FN_DV_D13, GPIO_FN_DV_D14, GPIO_FN_DV_D15,
+ GPIO_FN_DV_CLK,
+ GPIO_FN_DV_VSYNC,
+ GPIO_FN_DV_HSYNC,
+
+ /* MEMC */
+ GPIO_FN_MEMC_AD0, GPIO_FN_MEMC_AD1, GPIO_FN_MEMC_AD2,
+ GPIO_FN_MEMC_AD3, GPIO_FN_MEMC_AD4, GPIO_FN_MEMC_AD5,
+ GPIO_FN_MEMC_AD6, GPIO_FN_MEMC_AD7, GPIO_FN_MEMC_AD8,
+ GPIO_FN_MEMC_AD9, GPIO_FN_MEMC_AD10, GPIO_FN_MEMC_AD11,
+ GPIO_FN_MEMC_AD12, GPIO_FN_MEMC_AD13, GPIO_FN_MEMC_AD14,
+ GPIO_FN_MEMC_AD15, GPIO_FN_MEMC_CS0, GPIO_FN_MEMC_INT,
+ GPIO_FN_MEMC_NWE, GPIO_FN_MEMC_NOE,
+
+ GPIO_FN_MEMC_CS1, /* MSEL4CR_6_0 */
+ GPIO_FN_MEMC_ADV,
+ GPIO_FN_MEMC_WAIT,
+ GPIO_FN_MEMC_BUSCLK,
+
+ GPIO_FN_MEMC_A1, /* MSEL4CR_6_1 */
+ GPIO_FN_MEMC_DREQ0,
+ GPIO_FN_MEMC_DREQ1,
+ GPIO_FN_MEMC_A0,
+
+ /* MMC */
+ GPIO_FN_MMC0_D0_PORT68, GPIO_FN_MMC0_D1_PORT69,
+ GPIO_FN_MMC0_D2_PORT70, GPIO_FN_MMC0_D3_PORT71,
+ GPIO_FN_MMC0_D4_PORT72, GPIO_FN_MMC0_D5_PORT73,
+ GPIO_FN_MMC0_D6_PORT74, GPIO_FN_MMC0_D7_PORT75,
+ GPIO_FN_MMC0_CLK_PORT66,
+ GPIO_FN_MMC0_CMD_PORT67, /* MSEL4CR_15_0 */
+
+ GPIO_FN_MMC1_D0_PORT149, GPIO_FN_MMC1_D1_PORT148,
+ GPIO_FN_MMC1_D2_PORT147, GPIO_FN_MMC1_D3_PORT146,
+ GPIO_FN_MMC1_D4_PORT145, GPIO_FN_MMC1_D5_PORT144,
+ GPIO_FN_MMC1_D6_PORT143, GPIO_FN_MMC1_D7_PORT142,
+ GPIO_FN_MMC1_CLK_PORT103,
+ GPIO_FN_MMC1_CMD_PORT104, /* MSEL4CR_15_1 */
+
+ /* MSIOF0 */
+ GPIO_FN_MSIOF0_SS1, GPIO_FN_MSIOF0_SS2,
+ GPIO_FN_MSIOF0_RXD, GPIO_FN_MSIOF0_TXD,
+ GPIO_FN_MSIOF0_MCK0, GPIO_FN_MSIOF0_MCK1,
+ GPIO_FN_MSIOF0_RSYNC, GPIO_FN_MSIOF0_RSCK,
+ GPIO_FN_MSIOF0_TSCK, GPIO_FN_MSIOF0_TSYNC,
+
+ /* MSIOF1 */
+ GPIO_FN_MSIOF1_RSCK, GPIO_FN_MSIOF1_RSYNC,
+ GPIO_FN_MSIOF1_MCK0, GPIO_FN_MSIOF1_MCK1,
+
+ GPIO_FN_MSIOF1_SS2_PORT116, GPIO_FN_MSIOF1_SS1_PORT117,
+ GPIO_FN_MSIOF1_RXD_PORT118, GPIO_FN_MSIOF1_TXD_PORT119,
+ GPIO_FN_MSIOF1_TSYNC_PORT120,
+ GPIO_FN_MSIOF1_TSCK_PORT121, /* MSEL4CR_10_0 */
+
+ GPIO_FN_MSIOF1_SS1_PORT67, GPIO_FN_MSIOF1_TSCK_PORT72,
+ GPIO_FN_MSIOF1_TSYNC_PORT73, GPIO_FN_MSIOF1_TXD_PORT74,
+ GPIO_FN_MSIOF1_RXD_PORT75,
+ GPIO_FN_MSIOF1_SS2_PORT202, /* MSEL4CR_10_1 */
+
+ /* GPIO */
+ GPIO_FN_GPO0, GPIO_FN_GPI0,
+ GPIO_FN_GPO1, GPIO_FN_GPI1,
+
+ /* USB0 */
+ GPIO_FN_USB0_OCI, GPIO_FN_USB0_PPON, GPIO_FN_VBUS,
+
+ /* USB1 */
+ GPIO_FN_USB1_OCI, GPIO_FN_USB1_PPON,
+
+ /* BBIF1 */
+ GPIO_FN_BBIF1_RXD, GPIO_FN_BBIF1_TXD, GPIO_FN_BBIF1_TSYNC,
+ GPIO_FN_BBIF1_TSCK, GPIO_FN_BBIF1_RSCK, GPIO_FN_BBIF1_RSYNC,
+ GPIO_FN_BBIF1_FLOW, GPIO_FN_BBIF1_RX_FLOW_N,
+
+ /* BBIF2 */
+ GPIO_FN_BBIF2_TXD2_PORT5, /* MSEL5CR_0_0 */
+ GPIO_FN_BBIF2_RXD2_PORT60,
+ GPIO_FN_BBIF2_TSYNC2_PORT6,
+ GPIO_FN_BBIF2_TSCK2_PORT59,
+
+ GPIO_FN_BBIF2_RXD2_PORT90, /* MSEL5CR_0_1 */
+ GPIO_FN_BBIF2_TXD2_PORT183,
+ GPIO_FN_BBIF2_TSCK2_PORT89,
+ GPIO_FN_BBIF2_TSYNC2_PORT184,
+
+ /* BSC / FLCTL / PCMCIA */
+ GPIO_FN_CS0, GPIO_FN_CS2, GPIO_FN_CS4,
+ GPIO_FN_CS5B, GPIO_FN_CS6A,
+ GPIO_FN_CS5A_PORT105, /* CS5A PORT 19/105 */
+ GPIO_FN_CS5A_PORT19,
+ GPIO_FN_IOIS16, /* ? */
+
+ GPIO_FN_A0, GPIO_FN_A1, GPIO_FN_A2, GPIO_FN_A3,
+ GPIO_FN_A4_FOE, /* share with FLCTL */
+ GPIO_FN_A5_FCDE, /* share with FLCTL */
+ GPIO_FN_A6, GPIO_FN_A7, GPIO_FN_A8, GPIO_FN_A9,
+ GPIO_FN_A10, GPIO_FN_A11, GPIO_FN_A12, GPIO_FN_A13,
+ GPIO_FN_A14, GPIO_FN_A15, GPIO_FN_A16, GPIO_FN_A17,
+ GPIO_FN_A18, GPIO_FN_A19, GPIO_FN_A20, GPIO_FN_A21,
+ GPIO_FN_A22, GPIO_FN_A23, GPIO_FN_A24, GPIO_FN_A25,
+ GPIO_FN_A26,
+
+ GPIO_FN_D0_NAF0, GPIO_FN_D1_NAF1, /* share with FLCTL */
+ GPIO_FN_D2_NAF2, GPIO_FN_D3_NAF3, /* share with FLCTL */
+ GPIO_FN_D4_NAF4, GPIO_FN_D5_NAF5, /* share with FLCTL */
+ GPIO_FN_D6_NAF6, GPIO_FN_D7_NAF7, /* share with FLCTL */
+ GPIO_FN_D8_NAF8, GPIO_FN_D9_NAF9, /* share with FLCTL */
+ GPIO_FN_D10_NAF10, GPIO_FN_D11_NAF11, /* share with FLCTL */
+ GPIO_FN_D12_NAF12, GPIO_FN_D13_NAF13, /* share with FLCTL */
+ GPIO_FN_D14_NAF14, GPIO_FN_D15_NAF15, /* share with FLCTL */
+
+ GPIO_FN_D16, GPIO_FN_D17, GPIO_FN_D18, GPIO_FN_D19,
+ GPIO_FN_D20, GPIO_FN_D21, GPIO_FN_D22, GPIO_FN_D23,
+ GPIO_FN_D24, GPIO_FN_D25, GPIO_FN_D26, GPIO_FN_D27,
+ GPIO_FN_D28, GPIO_FN_D29, GPIO_FN_D30, GPIO_FN_D31,
+
+ GPIO_FN_WE0_FWE, /* share with FLCTL */
+ GPIO_FN_WE1,
+ GPIO_FN_WE2_ICIORD, /* share with PCMCIA */
+ GPIO_FN_WE3_ICIOWR, /* share with PCMCIA */
+ GPIO_FN_CKO, GPIO_FN_BS, GPIO_FN_RDWR,
+ GPIO_FN_RD_FSC, /* share with FLCTL */
+ GPIO_FN_WAIT_PORT177, /* WAIT Port 90/177 */
+ GPIO_FN_WAIT_PORT90,
+
+ GPIO_FN_FCE0, GPIO_FN_FCE1, GPIO_FN_FRB, /* FLCTL */
+
+ /* IRDA */
+ GPIO_FN_IRDA_FIRSEL, GPIO_FN_IRDA_IN, GPIO_FN_IRDA_OUT,
+
+ /* ATAPI */
+ GPIO_FN_IDE_D0, GPIO_FN_IDE_D1, GPIO_FN_IDE_D2,
+ GPIO_FN_IDE_D3, GPIO_FN_IDE_D4, GPIO_FN_IDE_D5,
+ GPIO_FN_IDE_D6, GPIO_FN_IDE_D7, GPIO_FN_IDE_D8,
+ GPIO_FN_IDE_D9, GPIO_FN_IDE_D10, GPIO_FN_IDE_D11,
+ GPIO_FN_IDE_D12, GPIO_FN_IDE_D13, GPIO_FN_IDE_D14,
+ GPIO_FN_IDE_D15, GPIO_FN_IDE_A0, GPIO_FN_IDE_A1,
+ GPIO_FN_IDE_A2, GPIO_FN_IDE_CS0, GPIO_FN_IDE_CS1,
+ GPIO_FN_IDE_IOWR, GPIO_FN_IDE_IORD, GPIO_FN_IDE_IORDY,
+ GPIO_FN_IDE_INT, GPIO_FN_IDE_RST, GPIO_FN_IDE_DIRECTION,
+ GPIO_FN_IDE_EXBUF_ENB, GPIO_FN_IDE_IODACK, GPIO_FN_IDE_IODREQ,
+
+ /* RMII */
+ GPIO_FN_RMII_CRS_DV, GPIO_FN_RMII_RX_ER, GPIO_FN_RMII_RXD0,
+ GPIO_FN_RMII_RXD1, GPIO_FN_RMII_TX_EN, GPIO_FN_RMII_TXD0,
+ GPIO_FN_RMII_MDC, GPIO_FN_RMII_TXD1, GPIO_FN_RMII_MDIO,
+ GPIO_FN_RMII_REF50CK, /* for RMII */
+ GPIO_FN_RMII_REF125CK, /* for GMII */
+
+ /* GEther */
+ GPIO_FN_ET_TX_CLK, GPIO_FN_ET_TX_EN, GPIO_FN_ET_ETXD0,
+ GPIO_FN_ET_ETXD1, GPIO_FN_ET_ETXD2, GPIO_FN_ET_ETXD3,
+ GPIO_FN_ET_ETXD4, GPIO_FN_ET_ETXD5, /* for GEther */
+ GPIO_FN_ET_ETXD6, GPIO_FN_ET_ETXD7, /* for GEther */
+ GPIO_FN_ET_COL, GPIO_FN_ET_TX_ER,
+ GPIO_FN_ET_RX_CLK, GPIO_FN_ET_RX_DV,
+ GPIO_FN_ET_ERXD0, GPIO_FN_ET_ERXD1,
+ GPIO_FN_ET_ERXD2, GPIO_FN_ET_ERXD3,
+ GPIO_FN_ET_ERXD4, GPIO_FN_ET_ERXD5, /* for GEther */
+ GPIO_FN_ET_ERXD6, GPIO_FN_ET_ERXD7, /* for GEther */
+ GPIO_FN_ET_RX_ER, GPIO_FN_ET_CRS,
+ GPIO_FN_ET_MDC, GPIO_FN_ET_MDIO,
+ GPIO_FN_ET_LINK, GPIO_FN_ET_PHY_INT,
+ GPIO_FN_ET_WOL, GPIO_FN_ET_GTX_CLK,
+
+ /* DMA0 */
+ GPIO_FN_DREQ0, GPIO_FN_DACK0,
+
+ /* DMA1 */
+ GPIO_FN_DREQ1, GPIO_FN_DACK1,
+
+ /* SYSC */
+ GPIO_FN_RESETOUTS,
+ GPIO_FN_RESETP_PULLUP,
+ GPIO_FN_RESETP_PLAIN,
+
+ /* SDENC */
+ GPIO_FN_SDENC_CPG,
+ GPIO_FN_SDENC_DV_CLKI,
+
+ /* IRREM */
+ GPIO_FN_IROUT,
+
+ /* DEBUG */
+ GPIO_FN_EDEBGREQ_PULLDOWN,
+ GPIO_FN_EDEBGREQ_PULLUP,
+
+ GPIO_FN_TRACEAUD_FROM_VIO,
+ GPIO_FN_TRACEAUD_FROM_LCDC0,
+ GPIO_FN_TRACEAUD_FROM_MEMC,
+};
+
+#endif /* __ASM_R8A7740_H__ */
diff --git a/arch/arm/mach-shmobile/include/mach/r8a7779.h b/arch/arm/mach-shmobile/include/mach/r8a7779.h
new file mode 100644
index 0000000..b07ad31
--- /dev/null
+++ b/arch/arm/mach-shmobile/include/mach/r8a7779.h
@@ -0,0 +1,363 @@
+#ifndef __ASM_R8A7779_H__
+#define __ASM_R8A7779_H__
+
+#include <linux/sh_clk.h>
+#include <linux/pm_domain.h>
+
+/* Pin Function Controller:
+ * GPIO_FN_xx - GPIO used to select pin function
+ * GPIO_GP_x_x - GPIO mapped to real I/O pin on CPU
+ */
+enum {
+ GPIO_GP_0_0, GPIO_GP_0_1, GPIO_GP_0_2, GPIO_GP_0_3,
+ GPIO_GP_0_4, GPIO_GP_0_5, GPIO_GP_0_6, GPIO_GP_0_7,
+ GPIO_GP_0_8, GPIO_GP_0_9, GPIO_GP_0_10, GPIO_GP_0_11,
+ GPIO_GP_0_12, GPIO_GP_0_13, GPIO_GP_0_14, GPIO_GP_0_15,
+ GPIO_GP_0_16, GPIO_GP_0_17, GPIO_GP_0_18, GPIO_GP_0_19,
+ GPIO_GP_0_20, GPIO_GP_0_21, GPIO_GP_0_22, GPIO_GP_0_23,
+ GPIO_GP_0_24, GPIO_GP_0_25, GPIO_GP_0_26, GPIO_GP_0_27,
+ GPIO_GP_0_28, GPIO_GP_0_29, GPIO_GP_0_30, GPIO_GP_0_31,
+
+ GPIO_GP_1_0, GPIO_GP_1_1, GPIO_GP_1_2, GPIO_GP_1_3,
+ GPIO_GP_1_4, GPIO_GP_1_5, GPIO_GP_1_6, GPIO_GP_1_7,
+ GPIO_GP_1_8, GPIO_GP_1_9, GPIO_GP_1_10, GPIO_GP_1_11,
+ GPIO_GP_1_12, GPIO_GP_1_13, GPIO_GP_1_14, GPIO_GP_1_15,
+ GPIO_GP_1_16, GPIO_GP_1_17, GPIO_GP_1_18, GPIO_GP_1_19,
+ GPIO_GP_1_20, GPIO_GP_1_21, GPIO_GP_1_22, GPIO_GP_1_23,
+ GPIO_GP_1_24, GPIO_GP_1_25, GPIO_GP_1_26, GPIO_GP_1_27,
+ GPIO_GP_1_28, GPIO_GP_1_29, GPIO_GP_1_30, GPIO_GP_1_31,
+
+ GPIO_GP_2_0, GPIO_GP_2_1, GPIO_GP_2_2, GPIO_GP_2_3,
+ GPIO_GP_2_4, GPIO_GP_2_5, GPIO_GP_2_6, GPIO_GP_2_7,
+ GPIO_GP_2_8, GPIO_GP_2_9, GPIO_GP_2_10, GPIO_GP_2_11,
+ GPIO_GP_2_12, GPIO_GP_2_13, GPIO_GP_2_14, GPIO_GP_2_15,
+ GPIO_GP_2_16, GPIO_GP_2_17, GPIO_GP_2_18, GPIO_GP_2_19,
+ GPIO_GP_2_20, GPIO_GP_2_21, GPIO_GP_2_22, GPIO_GP_2_23,
+ GPIO_GP_2_24, GPIO_GP_2_25, GPIO_GP_2_26, GPIO_GP_2_27,
+ GPIO_GP_2_28, GPIO_GP_2_29, GPIO_GP_2_30, GPIO_GP_2_31,
+
+ GPIO_GP_3_0, GPIO_GP_3_1, GPIO_GP_3_2, GPIO_GP_3_3,
+ GPIO_GP_3_4, GPIO_GP_3_5, GPIO_GP_3_6, GPIO_GP_3_7,
+ GPIO_GP_3_8, GPIO_GP_3_9, GPIO_GP_3_10, GPIO_GP_3_11,
+ GPIO_GP_3_12, GPIO_GP_3_13, GPIO_GP_3_14, GPIO_GP_3_15,
+ GPIO_GP_3_16, GPIO_GP_3_17, GPIO_GP_3_18, GPIO_GP_3_19,
+ GPIO_GP_3_20, GPIO_GP_3_21, GPIO_GP_3_22, GPIO_GP_3_23,
+ GPIO_GP_3_24, GPIO_GP_3_25, GPIO_GP_3_26, GPIO_GP_3_27,
+ GPIO_GP_3_28, GPIO_GP_3_29, GPIO_GP_3_30, GPIO_GP_3_31,
+
+ GPIO_GP_4_0, GPIO_GP_4_1, GPIO_GP_4_2, GPIO_GP_4_3,
+ GPIO_GP_4_4, GPIO_GP_4_5, GPIO_GP_4_6, GPIO_GP_4_7,
+ GPIO_GP_4_8, GPIO_GP_4_9, GPIO_GP_4_10, GPIO_GP_4_11,
+ GPIO_GP_4_12, GPIO_GP_4_13, GPIO_GP_4_14, GPIO_GP_4_15,
+ GPIO_GP_4_16, GPIO_GP_4_17, GPIO_GP_4_18, GPIO_GP_4_19,
+ GPIO_GP_4_20, GPIO_GP_4_21, GPIO_GP_4_22, GPIO_GP_4_23,
+ GPIO_GP_4_24, GPIO_GP_4_25, GPIO_GP_4_26, GPIO_GP_4_27,
+ GPIO_GP_4_28, GPIO_GP_4_29, GPIO_GP_4_30, GPIO_GP_4_31,
+
+ GPIO_GP_5_0, GPIO_GP_5_1, GPIO_GP_5_2, GPIO_GP_5_3,
+ GPIO_GP_5_4, GPIO_GP_5_5, GPIO_GP_5_6, GPIO_GP_5_7,
+ GPIO_GP_5_8, GPIO_GP_5_9, GPIO_GP_5_10, GPIO_GP_5_11,
+ GPIO_GP_5_12, GPIO_GP_5_13, GPIO_GP_5_14, GPIO_GP_5_15,
+ GPIO_GP_5_16, GPIO_GP_5_17, GPIO_GP_5_18, GPIO_GP_5_19,
+ GPIO_GP_5_20, GPIO_GP_5_21, GPIO_GP_5_22, GPIO_GP_5_23,
+ GPIO_GP_5_24, GPIO_GP_5_25, GPIO_GP_5_26, GPIO_GP_5_27,
+ GPIO_GP_5_28, GPIO_GP_5_29, GPIO_GP_5_30, GPIO_GP_5_31,
+
+ GPIO_GP_6_0, GPIO_GP_6_1, GPIO_GP_6_2, GPIO_GP_6_3,
+ GPIO_GP_6_4, GPIO_GP_6_5, GPIO_GP_6_6, GPIO_GP_6_7,
+ GPIO_GP_6_8,
+
+ GPIO_FN_AVS1, GPIO_FN_AVS2, GPIO_FN_A17, GPIO_FN_A18,
+ GPIO_FN_A19,
+
+ /* IPSR0 */
+ GPIO_FN_PENC2, GPIO_FN_SCK0, GPIO_FN_PWM1, GPIO_FN_PWMFSW0,
+ GPIO_FN_SCIF_CLK, GPIO_FN_TCLK0_C, GPIO_FN_BS, GPIO_FN_SD1_DAT2,
+ GPIO_FN_MMC0_D2, GPIO_FN_FD2, GPIO_FN_ATADIR0, GPIO_FN_SDSELF,
+ GPIO_FN_HCTS1, GPIO_FN_TX4_C, GPIO_FN_A0, GPIO_FN_SD1_DAT3,
+ GPIO_FN_MMC0_D3, GPIO_FN_FD3, GPIO_FN_A20, GPIO_FN_TX5_D,
+ GPIO_FN_HSPI_TX2_B, GPIO_FN_A21, GPIO_FN_SCK5_D, GPIO_FN_HSPI_CLK2_B,
+ GPIO_FN_A22, GPIO_FN_RX5_D, GPIO_FN_HSPI_RX2_B, GPIO_FN_VI1_R0,
+ GPIO_FN_A23, GPIO_FN_FCLE, GPIO_FN_HSPI_CLK2, GPIO_FN_VI1_R1,
+ GPIO_FN_A24, GPIO_FN_SD1_CD, GPIO_FN_MMC0_D4, GPIO_FN_FD4,
+ GPIO_FN_HSPI_CS2, GPIO_FN_VI1_R2, GPIO_FN_SSI_WS78_B, GPIO_FN_A25,
+ GPIO_FN_SD1_WP, GPIO_FN_MMC0_D5, GPIO_FN_FD5, GPIO_FN_HSPI_RX2,
+ GPIO_FN_VI1_R3, GPIO_FN_TX5_B, GPIO_FN_SSI_SDATA7_B, GPIO_FN_CTS0_B,
+ GPIO_FN_CLKOUT, GPIO_FN_TX3C_IRDA_TX_C, GPIO_FN_PWM0_B, GPIO_FN_CS0,
+ GPIO_FN_HSPI_CS2_B, GPIO_FN_CS1_A26, GPIO_FN_HSPI_TX2,
+ GPIO_FN_SDSELF_B, GPIO_FN_RD_WR, GPIO_FN_FWE, GPIO_FN_ATAG0,
+ GPIO_FN_VI1_R7, GPIO_FN_HRTS1, GPIO_FN_RX4_C,
+
+ /* IPSR1 */
+ GPIO_FN_EX_CS0, GPIO_FN_RX3_C_IRDA_RX_C, GPIO_FN_MMC0_D6,
+ GPIO_FN_FD6, GPIO_FN_EX_CS1, GPIO_FN_MMC0_D7, GPIO_FN_FD7,
+ GPIO_FN_EX_CS2, GPIO_FN_SD1_CLK, GPIO_FN_MMC0_CLK, GPIO_FN_FALE,
+ GPIO_FN_ATACS00, GPIO_FN_EX_CS3, GPIO_FN_SD1_CMD, GPIO_FN_MMC0_CMD,
+ GPIO_FN_FRE, GPIO_FN_ATACS10, GPIO_FN_VI1_R4, GPIO_FN_RX5_B,
+ GPIO_FN_HSCK1, GPIO_FN_SSI_SDATA8_B, GPIO_FN_RTS0_B_TANS_B,
+ GPIO_FN_SSI_SDATA9, GPIO_FN_EX_CS4, GPIO_FN_SD1_DAT0, GPIO_FN_MMC0_D0,
+ GPIO_FN_FD0, GPIO_FN_ATARD0, GPIO_FN_VI1_R5, GPIO_FN_SCK5_B,
+ GPIO_FN_HTX1, GPIO_FN_TX2_E, GPIO_FN_TX0_B, GPIO_FN_SSI_SCK9,
+ GPIO_FN_EX_CS5, GPIO_FN_SD1_DAT1, GPIO_FN_MMC0_D1, GPIO_FN_FD1,
+ GPIO_FN_ATAWR0, GPIO_FN_VI1_R6, GPIO_FN_HRX1, GPIO_FN_RX2_E,
+ GPIO_FN_RX0_B, GPIO_FN_SSI_WS9, GPIO_FN_MLB_CLK, GPIO_FN_PWM2,
+ GPIO_FN_SCK4, GPIO_FN_MLB_SIG, GPIO_FN_PWM3, GPIO_FN_TX4,
+ GPIO_FN_MLB_DAT, GPIO_FN_PWM4, GPIO_FN_RX4, GPIO_FN_HTX0,
+ GPIO_FN_TX1, GPIO_FN_SDATA, GPIO_FN_CTS0_C, GPIO_FN_SUB_TCK,
+ GPIO_FN_CC5_STATE2, GPIO_FN_CC5_STATE10, GPIO_FN_CC5_STATE18,
+ GPIO_FN_CC5_STATE26, GPIO_FN_CC5_STATE34,
+
+ /* IPSR2 */
+ GPIO_FN_HRX0, GPIO_FN_RX1, GPIO_FN_SCKZ, GPIO_FN_RTS0_C_TANS_C,
+ GPIO_FN_SUB_TDI, GPIO_FN_CC5_STATE3, GPIO_FN_CC5_STATE11,
+ GPIO_FN_CC5_STATE19, GPIO_FN_CC5_STATE27, GPIO_FN_CC5_STATE35,
+ GPIO_FN_HSCK0, GPIO_FN_SCK1, GPIO_FN_MTS, GPIO_FN_PWM5,
+ GPIO_FN_SCK0_C, GPIO_FN_SSI_SDATA9_B, GPIO_FN_SUB_TDO,
+ GPIO_FN_CC5_STATE0, GPIO_FN_CC5_STATE8, GPIO_FN_CC5_STATE16,
+ GPIO_FN_CC5_STATE24, GPIO_FN_CC5_STATE32, GPIO_FN_HCTS0, GPIO_FN_CTS1,
+ GPIO_FN_STM, GPIO_FN_PWM0_D, GPIO_FN_RX0_C, GPIO_FN_SCIF_CLK_C,
+ GPIO_FN_SUB_TRST, GPIO_FN_TCLK1_B, GPIO_FN_CC5_OSCOUT, GPIO_FN_HRTS0,
+ GPIO_FN_RTS1_TANS, GPIO_FN_MDATA, GPIO_FN_TX0_C, GPIO_FN_SUB_TMS,
+ GPIO_FN_CC5_STATE1, GPIO_FN_CC5_STATE9, GPIO_FN_CC5_STATE17,
+ GPIO_FN_CC5_STATE25, GPIO_FN_CC5_STATE33, GPIO_FN_DU0_DR0,
+ GPIO_FN_LCDOUT0, GPIO_FN_DREQ0, GPIO_FN_GPS_CLK_B, GPIO_FN_AUDATA0,
+ GPIO_FN_TX5_C, GPIO_FN_DU0_DR1, GPIO_FN_LCDOUT1, GPIO_FN_DACK0,
+ GPIO_FN_DRACK0, GPIO_FN_GPS_SIGN_B, GPIO_FN_AUDATA1, GPIO_FN_RX5_C,
+ GPIO_FN_DU0_DR2, GPIO_FN_LCDOUT2, GPIO_FN_DU0_DR3, GPIO_FN_LCDOUT3,
+ GPIO_FN_DU0_DR4, GPIO_FN_LCDOUT4, GPIO_FN_DU0_DR5, GPIO_FN_LCDOUT5,
+ GPIO_FN_DU0_DR6, GPIO_FN_LCDOUT6, GPIO_FN_DU0_DR7, GPIO_FN_LCDOUT7,
+ GPIO_FN_DU0_DG0, GPIO_FN_LCDOUT8, GPIO_FN_DREQ1, GPIO_FN_SCL2,
+ GPIO_FN_AUDATA2,
+
+ /* IPSR3 */
+ GPIO_FN_DU0_DG1, GPIO_FN_LCDOUT9, GPIO_FN_DACK1, GPIO_FN_SDA2,
+ GPIO_FN_AUDATA3, GPIO_FN_DU0_DG2, GPIO_FN_LCDOUT10, GPIO_FN_DU0_DG3,
+ GPIO_FN_LCDOUT11, GPIO_FN_DU0_DG4, GPIO_FN_LCDOUT12, GPIO_FN_DU0_DG5,
+ GPIO_FN_LCDOUT13, GPIO_FN_DU0_DG6, GPIO_FN_LCDOUT14, GPIO_FN_DU0_DG7,
+ GPIO_FN_LCDOUT15, GPIO_FN_DU0_DB0, GPIO_FN_LCDOUT16, GPIO_FN_EX_WAIT1,
+ GPIO_FN_SCL1, GPIO_FN_TCLK1, GPIO_FN_AUDATA4, GPIO_FN_DU0_DB1,
+ GPIO_FN_LCDOUT17, GPIO_FN_EX_WAIT2, GPIO_FN_SDA1, GPIO_FN_GPS_MAG_B,
+ GPIO_FN_AUDATA5, GPIO_FN_SCK5_C, GPIO_FN_DU0_DB2, GPIO_FN_LCDOUT18,
+ GPIO_FN_DU0_DB3, GPIO_FN_LCDOUT19, GPIO_FN_DU0_DB4, GPIO_FN_LCDOUT20,
+ GPIO_FN_DU0_DB5, GPIO_FN_LCDOUT21, GPIO_FN_DU0_DB6, GPIO_FN_LCDOUT22,
+ GPIO_FN_DU0_DB7, GPIO_FN_LCDOUT23, GPIO_FN_DU0_DOTCLKIN,
+ GPIO_FN_QSTVA_QVS, GPIO_FN_TX3_D_IRDA_TX_D, GPIO_FN_SCL3_B,
+ GPIO_FN_DU0_DOTCLKOUT0, GPIO_FN_QCLK, GPIO_FN_DU0_DOTCLKOUT1,
+ GPIO_FN_QSTVB_QVE, GPIO_FN_RX3_D_IRDA_RX_D, GPIO_FN_SDA3_B,
+ GPIO_FN_SDA2_C, GPIO_FN_DACK0_B, GPIO_FN_DRACK0_B,
+ GPIO_FN_DU0_EXHSYNC_DU0_HSYNC, GPIO_FN_QSTH_QHS,
+ GPIO_FN_DU0_EXVSYNC_DU0_VSYNC, GPIO_FN_QSTB_QHE,
+ GPIO_FN_DU0_EXODDF_DU0_ODDF_DISP_CDE, GPIO_FN_QCPV_QDE,
+ GPIO_FN_CAN1_TX, GPIO_FN_TX2_C, GPIO_FN_SCL2_C, GPIO_FN_REMOCON,
+
+ /* IPSR4 */
+ GPIO_FN_DU0_DISP, GPIO_FN_QPOLA, GPIO_FN_CAN_CLK_C, GPIO_FN_SCK2_C,
+ GPIO_FN_DU0_CDE, GPIO_FN_QPOLB, GPIO_FN_CAN1_RX, GPIO_FN_RX2_C,
+ GPIO_FN_DREQ0_B, GPIO_FN_SSI_SCK78_B, GPIO_FN_SCK0_B, GPIO_FN_DU1_DR0,
+ GPIO_FN_VI2_DATA0_VI2_B0, GPIO_FN_PWM6, GPIO_FN_SD3_CLK,
+ GPIO_FN_TX3_E_IRDA_TX_E, GPIO_FN_AUDCK, GPIO_FN_PWMFSW0_B,
+ GPIO_FN_DU1_DR1, GPIO_FN_VI2_DATA1_VI2_B1, GPIO_FN_PWM0,
+ GPIO_FN_SD3_CMD, GPIO_FN_RX3_E_IRDA_RX_E, GPIO_FN_AUDSYNC,
+ GPIO_FN_CTS0_D, GPIO_FN_DU1_DR2, GPIO_FN_VI2_G0, GPIO_FN_DU1_DR3,
+ GPIO_FN_VI2_G1, GPIO_FN_DU1_DR4, GPIO_FN_VI2_G2, GPIO_FN_DU1_DR5,
+ GPIO_FN_VI2_G3, GPIO_FN_DU1_DR6, GPIO_FN_VI2_G4, GPIO_FN_DU1_DR7,
+ GPIO_FN_VI2_G5, GPIO_FN_DU1_DG0, GPIO_FN_VI2_DATA2_VI2_B2,
+ GPIO_FN_SCL1_B, GPIO_FN_SD3_DAT2, GPIO_FN_SCK3_E, GPIO_FN_AUDATA6,
+ GPIO_FN_TX0_D, GPIO_FN_DU1_DG1, GPIO_FN_VI2_DATA3_VI2_B3,
+ GPIO_FN_SDA1_B, GPIO_FN_SD3_DAT3, GPIO_FN_SCK5, GPIO_FN_AUDATA7,
+ GPIO_FN_RX0_D, GPIO_FN_DU1_DG2, GPIO_FN_VI2_G6, GPIO_FN_DU1_DG3,
+ GPIO_FN_VI2_G7, GPIO_FN_DU1_DG4, GPIO_FN_VI2_R0, GPIO_FN_DU1_DG5,
+ GPIO_FN_VI2_R1, GPIO_FN_DU1_DG6, GPIO_FN_VI2_R2, GPIO_FN_DU1_DG7,
+ GPIO_FN_VI2_R3, GPIO_FN_DU1_DB0, GPIO_FN_VI2_DATA4_VI2_B4,
+ GPIO_FN_SCL2_B, GPIO_FN_SD3_DAT0, GPIO_FN_TX5, GPIO_FN_SCK0_D,
+
+ /* IPSR5 */
+ GPIO_FN_DU1_DB1, GPIO_FN_VI2_DATA5_VI2_B5, GPIO_FN_SDA2_B,
+ GPIO_FN_SD3_DAT1, GPIO_FN_RX5, GPIO_FN_RTS0_D_TANS_D,
+ GPIO_FN_DU1_DB2, GPIO_FN_VI2_R4, GPIO_FN_DU1_DB3, GPIO_FN_VI2_R5,
+ GPIO_FN_DU1_DB4, GPIO_FN_VI2_R6, GPIO_FN_DU1_DB5, GPIO_FN_VI2_R7,
+ GPIO_FN_DU1_DB6, GPIO_FN_SCL2_D, GPIO_FN_DU1_DB7, GPIO_FN_SDA2_D,
+ GPIO_FN_DU1_DOTCLKIN, GPIO_FN_VI2_CLKENB, GPIO_FN_HSPI_CS1,
+ GPIO_FN_SCL1_D, GPIO_FN_DU1_DOTCLKOUT, GPIO_FN_VI2_FIELD,
+ GPIO_FN_SDA1_D, GPIO_FN_DU1_EXHSYNC_DU1_HSYNC, GPIO_FN_VI2_HSYNC,
+ GPIO_FN_VI3_HSYNC, GPIO_FN_DU1_EXVSYNC_DU1_VSYNC, GPIO_FN_VI2_VSYNC,
+ GPIO_FN_VI3_VSYNC, GPIO_FN_DU1_EXODDF_DU1_ODDF_DISP_CDE,
+ GPIO_FN_VI2_CLK, GPIO_FN_TX3_B_IRDA_TX_B, GPIO_FN_SD3_CD,
+ GPIO_FN_HSPI_TX1, GPIO_FN_VI1_CLKENB, GPIO_FN_VI3_CLKENB,
+ GPIO_FN_AUDIO_CLKC, GPIO_FN_TX2_D, GPIO_FN_SPEEDIN,
+ GPIO_FN_GPS_SIGN_D, GPIO_FN_DU1_DISP, GPIO_FN_VI2_DATA6_VI2_B6,
+ GPIO_FN_TCLK0, GPIO_FN_QSTVA_B_QVS_B, GPIO_FN_HSPI_CLK1,
+ GPIO_FN_SCK2_D, GPIO_FN_AUDIO_CLKOUT_B, GPIO_FN_GPS_MAG_D,
+ GPIO_FN_DU1_CDE, GPIO_FN_VI2_DATA7_VI2_B7, GPIO_FN_RX3_B_IRDA_RX_B,
+ GPIO_FN_SD3_WP, GPIO_FN_HSPI_RX1, GPIO_FN_VI1_FIELD, GPIO_FN_VI3_FIELD,
+ GPIO_FN_AUDIO_CLKOUT, GPIO_FN_RX2_D, GPIO_FN_GPS_CLK_C,
+ GPIO_FN_GPS_CLK_D, GPIO_FN_AUDIO_CLKA, GPIO_FN_CAN_TXCLK,
+ GPIO_FN_AUDIO_CLKB, GPIO_FN_USB_OVC2, GPIO_FN_CAN_DEBUGOUT0,
+ GPIO_FN_MOUT0,
+
+ /* IPSR6 */
+ GPIO_FN_SSI_SCK0129, GPIO_FN_CAN_DEBUGOUT1, GPIO_FN_MOUT1,
+ GPIO_FN_SSI_WS0129, GPIO_FN_CAN_DEBUGOUT2, GPIO_FN_MOUT2,
+ GPIO_FN_SSI_SDATA0, GPIO_FN_CAN_DEBUGOUT3, GPIO_FN_MOUT5,
+ GPIO_FN_SSI_SDATA1, GPIO_FN_CAN_DEBUGOUT4, GPIO_FN_MOUT6,
+ GPIO_FN_SSI_SDATA2, GPIO_FN_CAN_DEBUGOUT5, GPIO_FN_SSI_SCK34,
+ GPIO_FN_CAN_DEBUGOUT6, GPIO_FN_CAN0_TX_B, GPIO_FN_IERX,
+ GPIO_FN_SSI_SCK9_C, GPIO_FN_SSI_WS34, GPIO_FN_CAN_DEBUGOUT7,
+ GPIO_FN_CAN0_RX_B, GPIO_FN_IETX, GPIO_FN_SSI_WS9_C,
+ GPIO_FN_SSI_SDATA3, GPIO_FN_PWM0_C, GPIO_FN_CAN_DEBUGOUT8,
+ GPIO_FN_CAN_CLK_B, GPIO_FN_IECLK, GPIO_FN_SCIF_CLK_B, GPIO_FN_TCLK0_B,
+ GPIO_FN_SSI_SDATA4, GPIO_FN_CAN_DEBUGOUT9, GPIO_FN_SSI_SDATA9_C,
+ GPIO_FN_SSI_SCK5, GPIO_FN_ADICLK, GPIO_FN_CAN_DEBUGOUT10,
+ GPIO_FN_SCK3, GPIO_FN_TCLK0_D, GPIO_FN_SSI_WS5, GPIO_FN_ADICS_SAMP,
+ GPIO_FN_CAN_DEBUGOUT11, GPIO_FN_TX3_IRDA_TX, GPIO_FN_SSI_SDATA5,
+ GPIO_FN_ADIDATA, GPIO_FN_CAN_DEBUGOUT12, GPIO_FN_RX3_IRDA_RX,
+ GPIO_FN_SSI_SCK6, GPIO_FN_ADICHS0, GPIO_FN_CAN0_TX, GPIO_FN_IERX_B,
+
+ /* IPSR7 */
+ GPIO_FN_SSI_WS6, GPIO_FN_ADICHS1, GPIO_FN_CAN0_RX, GPIO_FN_IETX_B,
+ GPIO_FN_SSI_SDATA6, GPIO_FN_ADICHS2, GPIO_FN_CAN_CLK, GPIO_FN_IECLK_B,
+ GPIO_FN_SSI_SCK78, GPIO_FN_CAN_DEBUGOUT13, GPIO_FN_IRQ0_B,
+ GPIO_FN_SSI_SCK9_B, GPIO_FN_HSPI_CLK1_C, GPIO_FN_SSI_WS78,
+ GPIO_FN_CAN_DEBUGOUT14, GPIO_FN_IRQ1_B, GPIO_FN_SSI_WS9_B,
+ GPIO_FN_HSPI_CS1_C, GPIO_FN_SSI_SDATA7, GPIO_FN_CAN_DEBUGOUT15,
+ GPIO_FN_IRQ2_B, GPIO_FN_TCLK1_C, GPIO_FN_HSPI_TX1_C,
+ GPIO_FN_SSI_SDATA8, GPIO_FN_VSP, GPIO_FN_IRQ3_B, GPIO_FN_HSPI_RX1_C,
+ GPIO_FN_SD0_CLK, GPIO_FN_ATACS01, GPIO_FN_SCK1_B, GPIO_FN_SD0_CMD,
+ GPIO_FN_ATACS11, GPIO_FN_TX1_B, GPIO_FN_CC5_TDO, GPIO_FN_SD0_DAT0,
+ GPIO_FN_ATADIR1, GPIO_FN_RX1_B, GPIO_FN_CC5_TRST, GPIO_FN_SD0_DAT1,
+ GPIO_FN_ATAG1, GPIO_FN_SCK2_B, GPIO_FN_CC5_TMS, GPIO_FN_SD0_DAT2,
+ GPIO_FN_ATARD1, GPIO_FN_TX2_B, GPIO_FN_CC5_TCK, GPIO_FN_SD0_DAT3,
+ GPIO_FN_ATAWR1, GPIO_FN_RX2_B, GPIO_FN_CC5_TDI, GPIO_FN_SD0_CD,
+ GPIO_FN_DREQ2, GPIO_FN_RTS1_B_TANS_B, GPIO_FN_SD0_WP, GPIO_FN_DACK2,
+ GPIO_FN_CTS1_B,
+
+ /* IPSR8 */
+ GPIO_FN_HSPI_CLK0, GPIO_FN_CTS0, GPIO_FN_USB_OVC0, GPIO_FN_AD_CLK,
+ GPIO_FN_CC5_STATE4, GPIO_FN_CC5_STATE12, GPIO_FN_CC5_STATE20,
+ GPIO_FN_CC5_STATE28, GPIO_FN_CC5_STATE36, GPIO_FN_HSPI_CS0,
+ GPIO_FN_RTS0_TANS, GPIO_FN_USB_OVC1, GPIO_FN_AD_DI,
+ GPIO_FN_CC5_STATE5, GPIO_FN_CC5_STATE13, GPIO_FN_CC5_STATE21,
+ GPIO_FN_CC5_STATE29, GPIO_FN_CC5_STATE37, GPIO_FN_HSPI_TX0,
+ GPIO_FN_TX0, GPIO_FN_CAN_DEBUG_HW_TRIGGER, GPIO_FN_AD_DO,
+ GPIO_FN_CC5_STATE6, GPIO_FN_CC5_STATE14, GPIO_FN_CC5_STATE22,
+ GPIO_FN_CC5_STATE30, GPIO_FN_CC5_STATE38, GPIO_FN_HSPI_RX0,
+ GPIO_FN_RX0, GPIO_FN_CAN_STEP0, GPIO_FN_AD_NCS, GPIO_FN_CC5_STATE7,
+ GPIO_FN_CC5_STATE15, GPIO_FN_CC5_STATE23, GPIO_FN_CC5_STATE31,
+ GPIO_FN_CC5_STATE39, GPIO_FN_FMCLK, GPIO_FN_RDS_CLK, GPIO_FN_PCMOE,
+ GPIO_FN_BPFCLK, GPIO_FN_PCMWE, GPIO_FN_FMIN, GPIO_FN_RDS_DATA,
+ GPIO_FN_VI0_CLK, GPIO_FN_MMC1_CLK, GPIO_FN_VI0_CLKENB, GPIO_FN_TX1_C,
+ GPIO_FN_HTX1_B, GPIO_FN_MT1_SYNC, GPIO_FN_VI0_FIELD, GPIO_FN_RX1_C,
+ GPIO_FN_HRX1_B, GPIO_FN_VI0_HSYNC, GPIO_FN_VI0_DATA0_B_VI0_B0_B,
+ GPIO_FN_CTS1_C, GPIO_FN_TX4_D, GPIO_FN_MMC1_CMD, GPIO_FN_HSCK1_B,
+ GPIO_FN_VI0_VSYNC, GPIO_FN_VI0_DATA1_B_VI0_B1_B,
+ GPIO_FN_RTS1_C_TANS_C, GPIO_FN_RX4_D, GPIO_FN_PWMFSW0_C,
+
+ /* IPSR9 */
+ GPIO_FN_VI0_DATA0_VI0_B0, GPIO_FN_HRTS1_B, GPIO_FN_MT1_VCXO,
+ GPIO_FN_VI0_DATA1_VI0_B1, GPIO_FN_HCTS1_B, GPIO_FN_MT1_PWM,
+ GPIO_FN_VI0_DATA2_VI0_B2, GPIO_FN_MMC1_D0, GPIO_FN_VI0_DATA3_VI0_B3,
+ GPIO_FN_MMC1_D1, GPIO_FN_VI0_DATA4_VI0_B4, GPIO_FN_MMC1_D2,
+ GPIO_FN_VI0_DATA5_VI0_B5, GPIO_FN_MMC1_D3, GPIO_FN_VI0_DATA6_VI0_B6,
+ GPIO_FN_MMC1_D4, GPIO_FN_ARM_TRACEDATA_0, GPIO_FN_VI0_DATA7_VI0_B7,
+ GPIO_FN_MMC1_D5, GPIO_FN_ARM_TRACEDATA_1, GPIO_FN_VI0_G0,
+ GPIO_FN_SSI_SCK78_C, GPIO_FN_IRQ0, GPIO_FN_ARM_TRACEDATA_2,
+ GPIO_FN_VI0_G1, GPIO_FN_SSI_WS78_C, GPIO_FN_IRQ1,
+ GPIO_FN_ARM_TRACEDATA_3, GPIO_FN_VI0_G2, GPIO_FN_ETH_TXD1,
+ GPIO_FN_MMC1_D6, GPIO_FN_ARM_TRACEDATA_4, GPIO_FN_TS_SPSYNC0,
+ GPIO_FN_VI0_G3, GPIO_FN_ETH_CRS_DV, GPIO_FN_MMC1_D7,
+ GPIO_FN_ARM_TRACEDATA_5, GPIO_FN_TS_SDAT0, GPIO_FN_VI0_G4,
+ GPIO_FN_ETH_TX_EN, GPIO_FN_SD2_DAT0_B, GPIO_FN_ARM_TRACEDATA_6,
+ GPIO_FN_VI0_G5, GPIO_FN_ETH_RX_ER, GPIO_FN_SD2_DAT1_B,
+ GPIO_FN_ARM_TRACEDATA_7, GPIO_FN_VI0_G6, GPIO_FN_ETH_RXD0,
+ GPIO_FN_SD2_DAT2_B, GPIO_FN_ARM_TRACEDATA_8, GPIO_FN_VI0_G7,
+ GPIO_FN_ETH_RXD1, GPIO_FN_SD2_DAT3_B, GPIO_FN_ARM_TRACEDATA_9,
+
+ /* IPSR10 */
+ GPIO_FN_VI0_R0, GPIO_FN_SSI_SDATA7_C, GPIO_FN_SCK1_C, GPIO_FN_DREQ1_B,
+ GPIO_FN_ARM_TRACEDATA_10, GPIO_FN_DREQ0_C, GPIO_FN_VI0_R1,
+ GPIO_FN_SSI_SDATA8_C, GPIO_FN_DACK1_B, GPIO_FN_ARM_TRACEDATA_11,
+ GPIO_FN_DACK0_C, GPIO_FN_DRACK0_C, GPIO_FN_VI0_R2, GPIO_FN_ETH_LINK,
+ GPIO_FN_SD2_CLK_B, GPIO_FN_IRQ2, GPIO_FN_ARM_TRACEDATA_12,
+ GPIO_FN_VI0_R3, GPIO_FN_ETH_MAGIC, GPIO_FN_SD2_CMD_B, GPIO_FN_IRQ3,
+ GPIO_FN_ARM_TRACEDATA_13, GPIO_FN_VI0_R4, GPIO_FN_ETH_REFCLK,
+ GPIO_FN_SD2_CD_B, GPIO_FN_HSPI_CLK1_B, GPIO_FN_ARM_TRACEDATA_14,
+ GPIO_FN_MT1_CLK, GPIO_FN_TS_SCK0, GPIO_FN_VI0_R5, GPIO_FN_ETH_TXD0,
+ GPIO_FN_SD2_WP_B, GPIO_FN_HSPI_CS1_B, GPIO_FN_ARM_TRACEDATA_15,
+ GPIO_FN_MT1_D, GPIO_FN_TS_SDEN0, GPIO_FN_VI0_R6, GPIO_FN_ETH_MDC,
+ GPIO_FN_DREQ2_C, GPIO_FN_HSPI_TX1_B, GPIO_FN_TRACECLK,
+ GPIO_FN_MT1_BEN, GPIO_FN_PWMFSW0_D, GPIO_FN_VI0_R7, GPIO_FN_ETH_MDIO,
+ GPIO_FN_DACK2_C, GPIO_FN_HSPI_RX1_B, GPIO_FN_SCIF_CLK_D,
+ GPIO_FN_TRACECTL, GPIO_FN_MT1_PEN, GPIO_FN_VI1_CLK, GPIO_FN_SIM_D,
+ GPIO_FN_SDA3, GPIO_FN_VI1_HSYNC, GPIO_FN_VI3_CLK, GPIO_FN_SSI_SCK4,
+ GPIO_FN_GPS_SIGN_C, GPIO_FN_PWMFSW0_E, GPIO_FN_VI1_VSYNC,
+ GPIO_FN_AUDIO_CLKOUT_C, GPIO_FN_SSI_WS4, GPIO_FN_SIM_CLK,
+ GPIO_FN_GPS_MAG_C, GPIO_FN_SPV_TRST, GPIO_FN_SCL3,
+
+ /* IPSR11 */
+ GPIO_FN_VI1_DATA0_VI1_B0, GPIO_FN_SD2_DAT0, GPIO_FN_SIM_RST,
+ GPIO_FN_SPV_TCK, GPIO_FN_ADICLK_B, GPIO_FN_VI1_DATA1_VI1_B1,
+ GPIO_FN_SD2_DAT1, GPIO_FN_MT0_CLK, GPIO_FN_SPV_TMS,
+ GPIO_FN_ADICS_B_SAMP_B, GPIO_FN_VI1_DATA2_VI1_B2, GPIO_FN_SD2_DAT2,
+ GPIO_FN_MT0_D, GPIO_FN_SPVTDI, GPIO_FN_ADIDATA_B,
+ GPIO_FN_VI1_DATA3_VI1_B3, GPIO_FN_SD2_DAT3, GPIO_FN_MT0_BEN,
+ GPIO_FN_SPV_TDO, GPIO_FN_ADICHS0_B, GPIO_FN_VI1_DATA4_VI1_B4,
+ GPIO_FN_SD2_CLK, GPIO_FN_MT0_PEN, GPIO_FN_SPA_TRST,
+ GPIO_FN_HSPI_CLK1_D, GPIO_FN_ADICHS1_B, GPIO_FN_VI1_DATA5_VI1_B5,
+ GPIO_FN_SD2_CMD, GPIO_FN_MT0_SYNC, GPIO_FN_SPA_TCK,
+ GPIO_FN_HSPI_CS1_D, GPIO_FN_ADICHS2_B, GPIO_FN_VI1_DATA6_VI1_B6,
+ GPIO_FN_SD2_CD, GPIO_FN_MT0_VCXO, GPIO_FN_SPA_TMS, GPIO_FN_HSPI_TX1_D,
+ GPIO_FN_VI1_DATA7_VI1_B7, GPIO_FN_SD2_WP, GPIO_FN_MT0_PWM,
+ GPIO_FN_SPA_TDI, GPIO_FN_HSPI_RX1_D, GPIO_FN_VI1_G0, GPIO_FN_VI3_DATA0,
+ GPIO_FN_DU1_DOTCLKOUT1, GPIO_FN_TS_SCK1, GPIO_FN_DREQ2_B, GPIO_FN_TX2,
+ GPIO_FN_SPA_TDO, GPIO_FN_HCTS0_B, GPIO_FN_VI1_G1, GPIO_FN_VI3_DATA1,
+ GPIO_FN_SSI_SCK1, GPIO_FN_TS_SDEN1, GPIO_FN_DACK2_B, GPIO_FN_RX2,
+ GPIO_FN_HRTS0_B,
+
+ /* IPSR12 */
+ GPIO_FN_VI1_G2, GPIO_FN_VI3_DATA2, GPIO_FN_SSI_WS1, GPIO_FN_TS_SPSYNC1,
+ GPIO_FN_SCK2, GPIO_FN_HSCK0_B, GPIO_FN_VI1_G3, GPIO_FN_VI3_DATA3,
+ GPIO_FN_SSI_SCK2, GPIO_FN_TS_SDAT1, GPIO_FN_SCL1_C, GPIO_FN_HTX0_B,
+ GPIO_FN_VI1_G4, GPIO_FN_VI3_DATA4, GPIO_FN_SSI_WS2, GPIO_FN_SDA1_C,
+ GPIO_FN_SIM_RST_B, GPIO_FN_HRX0_B, GPIO_FN_VI1_G5, GPIO_FN_VI3_DATA5,
+ GPIO_FN_GPS_CLK, GPIO_FN_FSE, GPIO_FN_TX4_B, GPIO_FN_SIM_D_B,
+ GPIO_FN_VI1_G6, GPIO_FN_VI3_DATA6, GPIO_FN_GPS_SIGN, GPIO_FN_FRB,
+ GPIO_FN_RX4_B, GPIO_FN_SIM_CLK_B, GPIO_FN_VI1_G7, GPIO_FN_VI3_DATA7,
+ GPIO_FN_GPS_MAG, GPIO_FN_FCE, GPIO_FN_SCK4_B,
+};
+
+struct platform_device;
+
+struct r8a7779_pm_ch {
+ unsigned long chan_offs;
+ unsigned int chan_bit;
+ unsigned int isr_bit;
+};
+
+struct r8a7779_pm_domain {
+ struct generic_pm_domain genpd;
+ struct r8a7779_pm_ch ch;
+};
+
+static inline struct r8a7779_pm_ch *to_r8a7779_ch(struct generic_pm_domain *d)
+{
+ return &container_of(d, struct r8a7779_pm_domain, genpd)->ch;
+}
+
+extern int r8a7779_sysc_power_down(struct r8a7779_pm_ch *r8a7779_ch);
+extern int r8a7779_sysc_power_up(struct r8a7779_pm_ch *r8a7779_ch);
+
+#ifdef CONFIG_PM
+extern struct r8a7779_pm_domain r8a7779_sh4a;
+extern struct r8a7779_pm_domain r8a7779_sgx;
+extern struct r8a7779_pm_domain r8a7779_vdp1;
+extern struct r8a7779_pm_domain r8a7779_impx3;
+
+extern void r8a7779_init_pm_domain(struct r8a7779_pm_domain *r8a7779_pd);
+extern void r8a7779_add_device_to_domain(struct r8a7779_pm_domain *r8a7779_pd,
+ struct platform_device *pdev);
+#else
+#define r8a7779_init_pm_domain(pd) do { } while (0)
+#define r8a7779_add_device_to_domain(pd, pdev) do { } while (0)
+#endif /* CONFIG_PM */
+
+#endif /* __ASM_R8A7779_H__ */
diff --git a/arch/arm/mach-shmobile/intc-r8a7740.c b/arch/arm/mach-shmobile/intc-r8a7740.c
new file mode 100644
index 0000000..272c84c
--- /dev/null
+++ b/arch/arm/mach-shmobile/intc-r8a7740.c
@@ -0,0 +1,631 @@
+/*
+ * R8A7740 processor support
+ *
+ * Copyright (C) 2011 Renesas Solutions Corp.
+ * Copyright (C) 2011 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+ *
+ * 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; version 2 of the License.
+ *
+ * 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 <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <linux/sh_intc.h>
+#include <mach/intc.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+/*
+ * INTCA
+ */
+enum {
+ UNUSED_INTCA = 0,
+
+ /* interrupt sources INTCA */
+ DIRC,
+ ATAPI,
+ IIC1_ALI, IIC1_TACKI, IIC1_WAITI, IIC1_DTEI,
+ AP_ARM_COMMTX, AP_ARM_COMMRX,
+ MFI, MFIS,
+ BBIF1, BBIF2,
+ USBHSDMAC,
+ USBF_OUL_SOF, USBF_IXL_INT,
+ SGX540,
+ CMT1_0, CMT1_1, CMT1_2, CMT1_3,
+ CMT2,
+ CMT3,
+ KEYSC,
+ SCIFA0, SCIFA1, SCIFA2, SCIFA3,
+ MSIOF2, MSIOF1,
+ SCIFA4, SCIFA5, SCIFB,
+ FLCTL_FLSTEI, FLCTL_FLTENDI, FLCTL_FLTREQ0I, FLCTL_FLTREQ1I,
+ SDHI0_0, SDHI0_1, SDHI0_2, SDHI0_3,
+ SDHI1_0, SDHI1_1, SDHI1_2, SDHI1_3,
+ AP_ARM_L2CINT,
+ IRDA,
+ TPU0,
+ SCIFA6, SCIFA7,
+ GbEther,
+ ICBS0,
+ DDM,
+ SDHI2_0, SDHI2_1, SDHI2_2, SDHI2_3,
+ RWDT0,
+ DMAC1_1_DEI0, DMAC1_1_DEI1, DMAC1_1_DEI2, DMAC1_1_DEI3,
+ DMAC1_2_DEI4, DMAC1_2_DEI5, DMAC1_2_DADERR,
+ DMAC2_1_DEI0, DMAC2_1_DEI1, DMAC2_1_DEI2, DMAC2_1_DEI3,
+ DMAC2_2_DEI4, DMAC2_2_DEI5, DMAC2_2_DADERR,
+ DMAC3_1_DEI0, DMAC3_1_DEI1, DMAC3_1_DEI2, DMAC3_1_DEI3,
+ DMAC3_2_DEI4, DMAC3_2_DEI5, DMAC3_2_DADERR,
+ SHWYSTAT_RT, SHWYSTAT_HS, SHWYSTAT_COM,
+ USBH_INT, USBH_OHCI, USBH_EHCI, USBH_PME, USBH_BIND,
+ RSPI_OVRF, RSPI_SPTEF, RSPI_SPRF,
+ SPU2_0, SPU2_1,
+ FSI, FMSI,
+ IPMMU,
+ AP_ARM_CTIIRQ, AP_ARM_PMURQ,
+ MFIS2,
+ CPORTR2S,
+ CMT14, CMT15,
+ MMCIF_0, MMCIF_1, MMCIF_2,
+ SIM_ERI, SIM_RXI, SIM_TXI, SIM_TEI,
+ STPRO_0, STPRO_1, STPRO_2, STPRO_3, STPRO_4,
+
+ /* interrupt groups INTCA */
+ DMAC1_1, DMAC1_2,
+ DMAC2_1, DMAC2_2,
+ DMAC3_1, DMAC3_2,
+ AP_ARM1, AP_ARM2,
+ SDHI0, SDHI1, SDHI2,
+ SHWYSTAT,
+ USBF, USBH1, USBH2,
+ RSPI, SPU2, FLCTL, IIC1,
+};
+
+static struct intc_vect intca_vectors[] __initdata = {
+ INTC_VECT(DIRC, 0x0560),
+ INTC_VECT(ATAPI, 0x05E0),
+ INTC_VECT(IIC1_ALI, 0x0780),
+ INTC_VECT(IIC1_TACKI, 0x07A0),
+ INTC_VECT(IIC1_WAITI, 0x07C0),
+ INTC_VECT(IIC1_DTEI, 0x07E0),
+ INTC_VECT(AP_ARM_COMMTX, 0x0840),
+ INTC_VECT(AP_ARM_COMMRX, 0x0860),
+ INTC_VECT(MFI, 0x0900),
+ INTC_VECT(MFIS, 0x0920),
+ INTC_VECT(BBIF1, 0x0940),
+ INTC_VECT(BBIF2, 0x0960),
+ INTC_VECT(USBHSDMAC, 0x0A00),
+ INTC_VECT(USBF_OUL_SOF, 0x0A20),
+ INTC_VECT(USBF_IXL_INT, 0x0A40),
+ INTC_VECT(SGX540, 0x0A60),
+ INTC_VECT(CMT1_0, 0x0B00),
+ INTC_VECT(CMT1_1, 0x0B20),
+ INTC_VECT(CMT1_2, 0x0B40),
+ INTC_VECT(CMT1_3, 0x0B60),
+ INTC_VECT(CMT2, 0x0B80),
+ INTC_VECT(CMT3, 0x0BA0),
+ INTC_VECT(KEYSC, 0x0BE0),
+ INTC_VECT(SCIFA0, 0x0C00),
+ INTC_VECT(SCIFA1, 0x0C20),
+ INTC_VECT(SCIFA2, 0x0C40),
+ INTC_VECT(SCIFA3, 0x0C60),
+ INTC_VECT(MSIOF2, 0x0C80),
+ INTC_VECT(MSIOF1, 0x0D00),
+ INTC_VECT(SCIFA4, 0x0D20),
+ INTC_VECT(SCIFA5, 0x0D40),
+ INTC_VECT(SCIFB, 0x0D60),
+ INTC_VECT(FLCTL_FLSTEI, 0x0D80),
+ INTC_VECT(FLCTL_FLTENDI, 0x0DA0),
+ INTC_VECT(FLCTL_FLTREQ0I, 0x0DC0),
+ INTC_VECT(FLCTL_FLTREQ1I, 0x0DE0),
+ INTC_VECT(SDHI0_0, 0x0E00),
+ INTC_VECT(SDHI0_1, 0x0E20),
+ INTC_VECT(SDHI0_2, 0x0E40),
+ INTC_VECT(SDHI0_3, 0x0E60),
+ INTC_VECT(SDHI1_0, 0x0E80),
+ INTC_VECT(SDHI1_1, 0x0EA0),
+ INTC_VECT(SDHI1_2, 0x0EC0),
+ INTC_VECT(SDHI1_3, 0x0EE0),
+ INTC_VECT(AP_ARM_L2CINT, 0x0FA0),
+ INTC_VECT(IRDA, 0x0480),
+ INTC_VECT(TPU0, 0x04A0),
+ INTC_VECT(SCIFA6, 0x04C0),
+ INTC_VECT(SCIFA7, 0x04E0),
+ INTC_VECT(GbEther, 0x0500),
+ INTC_VECT(ICBS0, 0x0540),
+ INTC_VECT(DDM, 0x1140),
+ INTC_VECT(SDHI2_0, 0x1200),
+ INTC_VECT(SDHI2_1, 0x1220),
+ INTC_VECT(SDHI2_2, 0x1240),
+ INTC_VECT(SDHI2_3, 0x1260),
+ INTC_VECT(RWDT0, 0x1280),
+ INTC_VECT(DMAC1_1_DEI0, 0x2000),
+ INTC_VECT(DMAC1_1_DEI1, 0x2020),
+ INTC_VECT(DMAC1_1_DEI2, 0x2040),
+ INTC_VECT(DMAC1_1_DEI3, 0x2060),
+ INTC_VECT(DMAC1_2_DEI4, 0x2080),
+ INTC_VECT(DMAC1_2_DEI5, 0x20A0),
+ INTC_VECT(DMAC1_2_DADERR, 0x20C0),
+ INTC_VECT(DMAC2_1_DEI0, 0x2100),
+ INTC_VECT(DMAC2_1_DEI1, 0x2120),
+ INTC_VECT(DMAC2_1_DEI2, 0x2140),
+ INTC_VECT(DMAC2_1_DEI3, 0x2160),
+ INTC_VECT(DMAC2_2_DEI4, 0x2180),
+ INTC_VECT(DMAC2_2_DEI5, 0x21A0),
+ INTC_VECT(DMAC2_2_DADERR, 0x21C0),
+ INTC_VECT(DMAC3_1_DEI0, 0x2200),
+ INTC_VECT(DMAC3_1_DEI1, 0x2220),
+ INTC_VECT(DMAC3_1_DEI2, 0x2240),
+ INTC_VECT(DMAC3_1_DEI3, 0x2260),
+ INTC_VECT(DMAC3_2_DEI4, 0x2280),
+ INTC_VECT(DMAC3_2_DEI5, 0x22A0),
+ INTC_VECT(DMAC3_2_DADERR, 0x22C0),
+ INTC_VECT(SHWYSTAT_RT, 0x1300),
+ INTC_VECT(SHWYSTAT_HS, 0x1320),
+ INTC_VECT(SHWYSTAT_COM, 0x1340),
+ INTC_VECT(USBH_INT, 0x1540),
+ INTC_VECT(USBH_OHCI, 0x1560),
+ INTC_VECT(USBH_EHCI, 0x1580),
+ INTC_VECT(USBH_PME, 0x15A0),
+ INTC_VECT(USBH_BIND, 0x15C0),
+ INTC_VECT(RSPI_OVRF, 0x1780),
+ INTC_VECT(RSPI_SPTEF, 0x17A0),
+ INTC_VECT(RSPI_SPRF, 0x17C0),
+ INTC_VECT(SPU2_0, 0x1800),
+ INTC_VECT(SPU2_1, 0x1820),
+ INTC_VECT(FSI, 0x1840),
+ INTC_VECT(FMSI, 0x1860),
+ INTC_VECT(IPMMU, 0x1920),
+ INTC_VECT(AP_ARM_CTIIRQ, 0x1980),
+ INTC_VECT(AP_ARM_PMURQ, 0x19A0),
+ INTC_VECT(MFIS2, 0x1A00),
+ INTC_VECT(CPORTR2S, 0x1A20),
+ INTC_VECT(CMT14, 0x1A40),
+ INTC_VECT(CMT15, 0x1A60),
+ INTC_VECT(MMCIF_0, 0x1AA0),
+ INTC_VECT(MMCIF_1, 0x1AC0),
+ INTC_VECT(MMCIF_2, 0x1AE0),
+ INTC_VECT(SIM_ERI, 0x1C00),
+ INTC_VECT(SIM_RXI, 0x1C20),
+ INTC_VECT(SIM_TXI, 0x1C40),
+ INTC_VECT(SIM_TEI, 0x1C60),
+ INTC_VECT(STPRO_0, 0x1C80),
+ INTC_VECT(STPRO_1, 0x1CA0),
+ INTC_VECT(STPRO_2, 0x1CC0),
+ INTC_VECT(STPRO_3, 0x1CE0),
+ INTC_VECT(STPRO_4, 0x1D00),
+};
+
+static struct intc_group intca_groups[] __initdata = {
+ INTC_GROUP(DMAC1_1,
+ DMAC1_1_DEI0, DMAC1_1_DEI1, DMAC1_1_DEI2, DMAC1_1_DEI3),
+ INTC_GROUP(DMAC1_2,
+ DMAC1_2_DEI4, DMAC1_2_DEI5, DMAC1_2_DADERR),
+ INTC_GROUP(DMAC2_1,
+ DMAC2_1_DEI0, DMAC2_1_DEI1, DMAC2_1_DEI2, DMAC2_1_DEI3),
+ INTC_GROUP(DMAC2_2,
+ DMAC2_2_DEI4, DMAC2_2_DEI5, DMAC2_2_DADERR),
+ INTC_GROUP(DMAC3_1,
+ DMAC3_1_DEI0, DMAC3_1_DEI1, DMAC3_1_DEI2, DMAC3_1_DEI3),
+ INTC_GROUP(DMAC3_2,
+ DMAC3_2_DEI4, DMAC3_2_DEI5, DMAC3_2_DADERR),
+ INTC_GROUP(AP_ARM1,
+ AP_ARM_COMMTX, AP_ARM_COMMRX),
+ INTC_GROUP(AP_ARM2,
+ AP_ARM_CTIIRQ, AP_ARM_PMURQ),
+ INTC_GROUP(USBF,
+ USBF_OUL_SOF, USBF_IXL_INT),
+ INTC_GROUP(SDHI0,
+ SDHI0_0, SDHI0_1, SDHI0_2, SDHI0_3),
+ INTC_GROUP(SDHI1,
+ SDHI1_0, SDHI1_1, SDHI1_2, SDHI1_3),
+ INTC_GROUP(SDHI2,
+ SDHI2_0, SDHI2_1, SDHI2_2, SDHI2_3),
+ INTC_GROUP(SHWYSTAT,
+ SHWYSTAT_RT, SHWYSTAT_HS, SHWYSTAT_COM),
+ INTC_GROUP(USBH1, /* FIXME */
+ USBH_INT, USBH_OHCI),
+ INTC_GROUP(USBH2, /* FIXME */
+ USBH_EHCI,
+ USBH_PME, USBH_BIND),
+ INTC_GROUP(RSPI,
+ RSPI_OVRF, RSPI_SPTEF, RSPI_SPRF),
+ INTC_GROUP(SPU2,
+ SPU2_0, SPU2_1),
+ INTC_GROUP(FLCTL,
+ FLCTL_FLSTEI, FLCTL_FLTENDI, FLCTL_FLTREQ0I, FLCTL_FLTREQ1I),
+ INTC_GROUP(IIC1,
+ IIC1_ALI, IIC1_TACKI, IIC1_WAITI, IIC1_DTEI),
+};
+
+static struct intc_mask_reg intca_mask_registers[] __initdata = {
+ { /* IMR0A / IMCR0A */ 0xe6940080, 0xe69400c0, 8,
+ { DMAC2_1_DEI3, DMAC2_1_DEI2, DMAC2_1_DEI1, DMAC2_1_DEI0,
+ 0, 0, AP_ARM_COMMTX, AP_ARM_COMMRX } },
+ { /* IMR1A / IMCR1A */ 0xe6940084, 0xe69400c4, 8,
+ { ATAPI, 0, DIRC, 0,
+ DMAC1_1_DEI3, DMAC1_1_DEI2, DMAC1_1_DEI1, DMAC1_1_DEI0 } },
+ { /* IMR2A / IMCR2A */ 0xe6940088, 0xe69400c8, 8,
+ { 0, 0, 0, 0,
+ BBIF1, BBIF2, MFIS, MFI } },
+ { /* IMR3A / IMCR3A */ 0xe694008c, 0xe69400cc, 8,
+ { DMAC3_1_DEI3, DMAC3_1_DEI2, DMAC3_1_DEI1, DMAC3_1_DEI0,
+ DMAC3_2_DADERR, DMAC3_2_DEI5, DMAC3_2_DEI4, IRDA } },
+ { /* IMR4A / IMCR4A */ 0xe6940090, 0xe69400d0, 8,
+ { DDM, 0, 0, 0,
+ 0, 0, 0, 0 } },
+ { /* IMR5A / IMCR5A */ 0xe6940094, 0xe69400d4, 8,
+ { KEYSC, DMAC1_2_DADERR, DMAC1_2_DEI5, DMAC1_2_DEI4,
+ SCIFA3, SCIFA2, SCIFA1, SCIFA0 } },
+ { /* IMR6A / IMCR6A */ 0xe6940098, 0xe69400d8, 8,
+ { SCIFB, SCIFA5, SCIFA4, MSIOF1,
+ 0, 0, MSIOF2, 0 } },
+ { /* IMR7A / IMCR7A */ 0xe694009c, 0xe69400dc, 8,
+ { SDHI0_3, SDHI0_2, SDHI0_1, SDHI0_0,
+ FLCTL_FLTREQ1I, FLCTL_FLTREQ0I, FLCTL_FLTENDI, FLCTL_FLSTEI } },
+ { /* IMR8A / IMCR8A */ 0xe69400a0, 0xe69400e0, 8,
+ { SDHI1_3, SDHI1_2, SDHI1_1, SDHI1_0,
+ 0, USBHSDMAC, 0, AP_ARM_L2CINT } },
+ { /* IMR9A / IMCR9A */ 0xe69400a4, 0xe69400e4, 8,
+ { CMT1_3, CMT1_2, CMT1_1, CMT1_0,
+ CMT2, USBF_IXL_INT, USBF_OUL_SOF, SGX540 } },
+ { /* IMR10A / IMCR10A */ 0xe69400a8, 0xe69400e8, 8,
+ { 0, DMAC2_2_DADERR, DMAC2_2_DEI5, DMAC2_2_DEI4,
+ 0, 0, 0, 0 } },
+ { /* IMR11A / IMCR11A */ 0xe69400ac, 0xe69400ec, 8,
+ { IIC1_DTEI, IIC1_WAITI, IIC1_TACKI, IIC1_ALI,
+ ICBS0, 0, 0, 0 } },
+ { /* IMR12A / IMCR12A */ 0xe69400b0, 0xe69400f0, 8,
+ { 0, 0, TPU0, SCIFA6,
+ SCIFA7, GbEther, 0, 0 } },
+ { /* IMR13A / IMCR13A */ 0xe69400b4, 0xe69400f4, 8,
+ { SDHI2_3, SDHI2_2, SDHI2_1, SDHI2_0,
+ 0, CMT3, 0, RWDT0 } },
+ { /* IMR0A3 / IMCR0A3 */ 0xe6950080, 0xe69500c0, 8,
+ { SHWYSTAT_RT, SHWYSTAT_HS, SHWYSTAT_COM, 0,
+ 0, 0, 0, 0 } },
+ /* IMR1A3 / IMCR1A3 */
+ { /* IMR2A3 / IMCR2A3 */ 0xe6950088, 0xe69500c8, 8,
+ { 0, 0, USBH_INT, USBH_OHCI,
+ USBH_EHCI, USBH_PME, USBH_BIND, 0 } },
+ /* IMR3A3 / IMCR3A3 */
+ { /* IMR4A3 / IMCR4A3 */ 0xe6950090, 0xe69500d0, 8,
+ { 0, 0, 0, 0,
+ RSPI_OVRF, RSPI_SPTEF, RSPI_SPRF, 0 } },
+ { /* IMR5A3 / IMCR5A3 */ 0xe6950094, 0xe69500d4, 8,
+ { SPU2_0, SPU2_1, FSI, FMSI,
+ 0, 0, 0, 0 } },
+ { /* IMR6A3 / IMCR6A3 */ 0xe6950098, 0xe69500d8, 8,
+ { 0, IPMMU, 0, 0,
+ AP_ARM_CTIIRQ, AP_ARM_PMURQ, 0, 0 } },
+ { /* IMR7A3 / IMCR7A3 */ 0xe695009c, 0xe69500dc, 8,
+ { MFIS2, CPORTR2S, CMT14, CMT15,
+ 0, MMCIF_0, MMCIF_1, MMCIF_2 } },
+ /* IMR8A3 / IMCR8A3 */
+ { /* IMR9A3 / IMCR9A3 */ 0xe69500a4, 0xe69500e4, 8,
+ { SIM_ERI, SIM_RXI, SIM_TXI, SIM_TEI,
+ STPRO_0, STPRO_1, STPRO_2, STPRO_3 } },
+ { /* IMR10A3 / IMCR10A3 */ 0xe69500a8, 0xe69500e8, 8,
+ { STPRO_4, 0, 0, 0,
+ 0, 0, 0, 0 } },
+};
+
+static struct intc_prio_reg intca_prio_registers[] __initdata = {
+ { 0xe6940000, 0, 16, 4, /* IPRAA */ { DMAC3_1, DMAC3_2, CMT2, ICBS0 } },
+ { 0xe6940004, 0, 16, 4, /* IPRBA */ { IRDA, 0, BBIF1, BBIF2 } },
+ { 0xe6940008, 0, 16, 4, /* IPRCA */ { ATAPI, 0, CMT1_1, AP_ARM1 } },
+ { 0xe694000c, 0, 16, 4, /* IPRDA */ { 0, 0, CMT1_2, 0 } },
+ { 0xe6940010, 0, 16, 4, /* IPREA */ { DMAC1_1, MFIS, MFI, USBF } },
+ { 0xe6940014, 0, 16, 4, /* IPRFA */ { KEYSC, DMAC1_2,
+ SGX540, CMT1_0 } },
+ { 0xe6940018, 0, 16, 4, /* IPRGA */ { SCIFA0, SCIFA1,
+ SCIFA2, SCIFA3 } },
+ { 0xe694001c, 0, 16, 4, /* IPRGH */ { MSIOF2, USBHSDMAC,
+ FLCTL, SDHI0 } },
+ { 0xe6940020, 0, 16, 4, /* IPRIA */ { MSIOF1, SCIFA4, 0, IIC1 } },
+ { 0xe6940024, 0, 16, 4, /* IPRJA */ { DMAC2_1, DMAC2_2,
+ AP_ARM_L2CINT, 0 } },
+ { 0xe6940028, 0, 16, 4, /* IPRKA */ { 0, CMT1_3, 0, SDHI1 } },
+ { 0xe694002c, 0, 16, 4, /* IPRLA */ { TPU0, SCIFA6,
+ SCIFA7, GbEther } },
+ { 0xe6940030, 0, 16, 4, /* IPRMA */ { 0, CMT3, 0, RWDT0 } },
+ { 0xe6940034, 0, 16, 4, /* IPRNA */ { SCIFB, SCIFA5, 0, DDM } },
+ { 0xe6940038, 0, 16, 4, /* IPROA */ { 0, 0, DIRC, SDHI2 } },
+ { 0xe6950000, 0, 16, 4, /* IPRAA3 */ { SHWYSTAT, 0, 0, 0 } },
+ /* IPRBA3 */
+ /* IPRCA3 */
+ /* IPRDA3 */
+ { 0xe6950010, 0, 16, 4, /* IPREA3 */ { USBH1, 0, 0, 0 } },
+ { 0xe6950014, 0, 16, 4, /* IPRFA3 */ { USBH2, 0, 0, 0 } },
+ /* IPRGA3 */
+ /* IPRHA3 */
+ /* IPRIA3 */
+ { 0xe6950024, 0, 16, 4, /* IPRJA3 */ { RSPI, 0, 0, 0 } },
+ { 0xe6950028, 0, 16, 4, /* IPRKA3 */ { SPU2, 0, FSI, FMSI } },
+ /* IPRLA3 */
+ { 0xe6950030, 0, 16, 4, /* IPRMA3 */ { IPMMU, 0, 0, 0 } },
+ { 0xe6950034, 0, 16, 4, /* IPRNA3 */ { AP_ARM2, 0, 0, 0 } },
+ { 0xe6950038, 0, 16, 4, /* IPROA3 */ { MFIS2, CPORTR2S,
+ CMT14, CMT15 } },
+ { 0xe695003c, 0, 16, 4, /* IPRPA3 */ { 0, MMCIF_0, MMCIF_1, MMCIF_2 } },
+ /* IPRQA3 */
+ /* IPRRA3 */
+ { 0xe6950048, 0, 16, 4, /* IPRSA3 */ { SIM_ERI, SIM_RXI,
+ SIM_TXI, SIM_TEI } },
+ { 0xe695004c, 0, 16, 4, /* IPRTA3 */ { STPRO_0, STPRO_1,
+ STPRO_2, STPRO_3 } },
+ { 0xe6950050, 0, 16, 4, /* IPRUA3 */ { STPRO_4, 0, 0, 0 } },
+};
+
+static DECLARE_INTC_DESC(intca_desc, "r8a7740-intca",
+ intca_vectors, intca_groups,
+ intca_mask_registers, intca_prio_registers,
+ NULL);
+
+INTC_IRQ_PINS_32(intca_irq_pins, 0xe6900000,
+ INTC_VECT, "r8a7740-intca-irq-pins");
+
+
+/*
+ * INTCS
+ */
+enum {
+ UNUSED_INTCS = 0,
+
+ INTCS,
+
+ /* interrupt sources INTCS */
+
+ /* HUDI */
+ /* STPRO */
+ /* RTDMAC(1) */
+ VPU5HA2,
+ _2DG_TRAP, _2DG_GPM_INT, _2DG_CER_INT,
+ /* MFI */
+ /* BBIF2 */
+ VPU5F,
+ _2DG_BRK_INT,
+ /* SGX540 */
+ /* 2DDMAC */
+ /* IPMMU */
+ /* RTDMAC 2 */
+ /* KEYSC */
+ /* MSIOF */
+ IIC0_ALI, IIC0_TACKI, IIC0_WAITI, IIC0_DTEI,
+ TMU0_0, TMU0_1, TMU0_2,
+ CMT0,
+ /* CMT2 */
+ LMB,
+ CTI,
+ VOU,
+ /* RWDT0 */
+ ICB,
+ VIO6C,
+ CEU20, CEU21,
+ JPU,
+ LCDC0,
+ LCRC,
+ /* RTDMAC2(1) */
+ /* RTDMAC2(2) */
+ LCDC1,
+ /* SPU2 */
+ /* FSI */
+ /* FMSI */
+ TMU1_0, TMU1_1, TMU1_2,
+ CMT4,
+ DISP,
+ DSRV,
+ /* MFIS2 */
+ CPORTS2R,
+
+ /* interrupt groups INTCS */
+ _2DG1,
+ IIC0, TMU1,
+};
+
+static struct intc_vect intcs_vectors[] = {
+ /* HUDI */
+ /* STPRO */
+ /* RTDMAC(1) */
+ INTCS_VECT(VPU5HA2, 0x0880),
+ INTCS_VECT(_2DG_TRAP, 0x08A0),
+ INTCS_VECT(_2DG_GPM_INT, 0x08C0),
+ INTCS_VECT(_2DG_CER_INT, 0x08E0),
+ /* MFI */
+ /* BBIF2 */
+ INTCS_VECT(VPU5F, 0x0980),
+ INTCS_VECT(_2DG_BRK_INT, 0x09A0),
+ /* SGX540 */
+ /* 2DDMAC */
+ /* IPMMU */
+ /* RTDMAC(2) */
+ /* KEYSC */
+ /* MSIOF */
+ INTCS_VECT(IIC0_ALI, 0x0E00),
+ INTCS_VECT(IIC0_TACKI, 0x0E20),
+ INTCS_VECT(IIC0_WAITI, 0x0E40),
+ INTCS_VECT(IIC0_DTEI, 0x0E60),
+ INTCS_VECT(TMU0_0, 0x0E80),
+ INTCS_VECT(TMU0_1, 0x0EA0),
+ INTCS_VECT(TMU0_2, 0x0EC0),
+ INTCS_VECT(CMT0, 0x0F00),
+ /* CMT2 */
+ INTCS_VECT(LMB, 0x0F60),
+ INTCS_VECT(CTI, 0x0400),
+ INTCS_VECT(VOU, 0x0420),
+ /* RWDT0 */
+ INTCS_VECT(ICB, 0x0480),
+ INTCS_VECT(VIO6C, 0x04E0),
+ INTCS_VECT(CEU20, 0x0500),
+ INTCS_VECT(CEU21, 0x0520),
+ INTCS_VECT(JPU, 0x0560),
+ INTCS_VECT(LCDC0, 0x0580),
+ INTCS_VECT(LCRC, 0x05A0),
+ /* RTDMAC2(1) */
+ /* RTDMAC2(2) */
+ INTCS_VECT(LCDC1, 0x1780),
+ /* SPU2 */
+ /* FSI */
+ /* FMSI */
+ INTCS_VECT(TMU1_0, 0x1900),
+ INTCS_VECT(TMU1_1, 0x1920),
+ INTCS_VECT(TMU1_2, 0x1940),
+ INTCS_VECT(CMT4, 0x1980),
+ INTCS_VECT(DISP, 0x19A0),
+ INTCS_VECT(DSRV, 0x19C0),
+ /* MFIS2 */
+ INTCS_VECT(CPORTS2R, 0x1A20),
+
+ INTC_VECT(INTCS, 0xf80),
+};
+
+static struct intc_group intcs_groups[] __initdata = {
+ INTC_GROUP(_2DG1, /*FIXME*/
+ _2DG_CER_INT, _2DG_GPM_INT, _2DG_TRAP),
+ INTC_GROUP(IIC0,
+ IIC0_DTEI, IIC0_WAITI, IIC0_TACKI, IIC0_ALI),
+ INTC_GROUP(TMU1,
+ TMU1_0, TMU1_1, TMU1_2),
+};
+
+static struct intc_mask_reg intcs_mask_registers[] = {
+ /* IMR0SA / IMCR0SA */ /* all 0 */
+ { /* IMR1SA / IMCR1SA */ 0xffd20184, 0xffd201c4, 8,
+ { _2DG_CER_INT, _2DG_GPM_INT, _2DG_TRAP, VPU5HA2,
+ 0, 0, 0, 0 /*STPRO*/ } },
+ { /* IMR2SA / IMCR2SA */ 0xffd20188, 0xffd201c8, 8,
+ { 0/*STPRO*/, 0, CEU21, VPU5F,
+ 0/*BBIF2*/, 0, 0, 0/*MFI*/ } },
+ { /* IMR3SA / IMCR3SA */ 0xffd2018c, 0xffd201cc, 8,
+ { 0, 0, 0, 0, /*2DDMAC*/
+ VIO6C, 0, 0, ICB } },
+ { /* IMR4SA / IMCR4SA */ 0xffd20190, 0xffd201d0, 8,
+ { 0, 0, VOU, CTI,
+ JPU, 0, LCRC, LCDC0 } },
+ /* IMR5SA / IMCR5SA */ /*KEYSC/RTDMAC2/RTDMAC1*/
+ /* IMR6SA / IMCR6SA */ /*MSIOF/SGX540*/
+ { /* IMR7SA / IMCR7SA */ 0xffd2019c, 0xffd201dc, 8,
+ { 0, TMU0_2, TMU0_1, TMU0_0,
+ 0, 0, 0, 0 } },
+ { /* IMR8SA / IMCR8SA */ 0xffd201a0, 0xffd201e0, 8,
+ { 0, 0, 0, 0,
+ CEU20, 0, 0, 0 } },
+ { /* IMR9SA / IMCR9SA */ 0xffd201a4, 0xffd201e4, 8,
+ { 0, 0/*RWDT0*/, 0/*CMT2*/, CMT0,
+ 0, 0, 0, 0 } },
+ /* IMR10SA / IMCR10SA */ /*IPMMU*/
+ { /* IMR11SA / IMCR11SA */ 0xffd201ac, 0xffd201ec, 8,
+ { IIC0_DTEI, IIC0_WAITI, IIC0_TACKI, IIC0_ALI,
+ 0, _2DG_BRK_INT, LMB, 0 } },
+ /* IMR12SA / IMCR12SA */
+ /* IMR13SA / IMCR13SA */
+ /* IMR0SA3 / IMCR0SA3 */ /*RTDMAC2(1)/RTDMAC2(2)*/
+ /* IMR1SA3 / IMCR1SA3 */
+ /* IMR2SA3 / IMCR2SA3 */
+ /* IMR3SA3 / IMCR3SA3 */
+ { /* IMR4SA3 / IMCR4SA3 */ 0xffd50190, 0xffd501d0, 8,
+ { 0, 0, 0, 0,
+ LCDC1, 0, 0, 0 } },
+ /* IMR5SA3 / IMCR5SA3 */ /* SPU2/FSI/FMSI */
+ { /* IMR6SA3 / IMCR6SA3 */ 0xffd50198, 0xffd501d8, 8,
+ { TMU1_0, TMU1_1, TMU1_2, 0,
+ CMT4, DISP, DSRV, 0 } },
+ { /* IMR7SA3 / IMCR7SA3 */ 0xffd5019c, 0xffd501dc, 8,
+ { 0/*MFIS2*/, CPORTS2R, 0, 0,
+ 0, 0, 0, 0 } },
+ { /* INTAMASK */ 0xffd20104, 0, 16,
+ { 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, INTCS } },
+};
+
+/* Priority is needed for INTCA to receive the INTCS interrupt */
+static struct intc_prio_reg intcs_prio_registers[] = {
+ { 0xffd20000, 0, 16, 4, /* IPRAS */ { CTI, VOU, 0/*2DDMAC*/, ICB } },
+ { 0xffd20004, 0, 16, 4, /* IPRBS */ { JPU, LCDC0, 0, LCRC } },
+ /* IPRCS */ /*BBIF2*/
+ /* IPRDS */
+ { 0xffd20010, 0, 16, 4, /* IPRES */ { 0/*RTDMAC(1)*/, VPU5HA2,
+ 0/*MFI*/, VPU5F } },
+ { 0xffd20014, 0, 16, 4, /* IPRFS */ { 0/*KEYSC*/, 0/*RTDMAC(2)*/,
+ 0/*CMT2*/, CMT0 } },
+ { 0xffd20018, 0, 16, 4, /* IPRGS */ { TMU0_0, TMU0_1,
+ TMU0_2, _2DG1 } },
+ { 0xffd2001c, 0, 16, 4, /* IPRHS */ { 0, 0/*STPRO*/, 0/*STPRO*/,
+ _2DG_BRK_INT/*FIXME*/ } },
+ { 0xffd20020, 0, 16, 4, /* IPRIS */ { 0, 0/*MSIOF*/, 0, IIC0 } },
+ { 0xffd20024, 0, 16, 4, /* IPRJS */ { CEU20, 0/*SGX540*/, 0, 0 } },
+ { 0xffd20028, 0, 16, 4, /* IPRKS */ { VIO6C, 0, LMB, 0 } },
+ { 0xffd2002c, 0, 16, 4, /* IPRLS */ { 0/*IPMMU*/, 0, CEU21, 0 } },
+ /* IPRMS */ /*RWDT0*/
+ /* IPRAS3 */ /*RTDMAC2(1)*/
+ /* IPRBS3 */ /*RTDMAC2(2)*/
+ /* IPRCS3 */
+ /* IPRDS3 */
+ /* IPRES3 */
+ /* IPRFS3 */
+ /* IPRGS3 */
+ /* IPRHS3 */
+ /* IPRIS3 */
+ { 0xffd50024, 0, 16, 4, /* IPRJS3 */ { LCDC1, 0, 0, 0 } },
+ /* IPRKS3 */ /*SPU2/FSI/FMSi*/
+ /* IPRLS3 */
+ { 0xffd50030, 0, 16, 4, /* IPRMS3 */ { TMU1, 0, 0, 0 } },
+ { 0xffd50034, 0, 16, 4, /* IPRNS3 */ { CMT4, DISP, DSRV, 0 } },
+ { 0xffd50038, 0, 16, 4, /* IPROS3 */ { 0/*MFIS2*/, CPORTS2R, 0, 0 } },
+ /* IPRPS3 */
+};
+
+static struct resource intcs_resources[] __initdata = {
+ [0] = {
+ .start = 0xffd20000,
+ .end = 0xffd201ff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 0xffd50000,
+ .end = 0xffd501ff,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static struct intc_desc intcs_desc __initdata = {
+ .name = "r8a7740-intcs",
+ .resource = intcs_resources,
+ .num_resources = ARRAY_SIZE(intcs_resources),
+ .hw = INTC_HW_DESC(intcs_vectors, intcs_groups, intcs_mask_registers,
+ intcs_prio_registers, NULL, NULL),
+};
+
+static void intcs_demux(unsigned int irq, struct irq_desc *desc)
+{
+ void __iomem *reg = (void *)irq_get_handler_data(irq);
+ unsigned int evtcodeas = ioread32(reg);
+
+ generic_handle_irq(intcs_evt2irq(evtcodeas));
+}
+
+void __init r8a7740_init_irq(void)
+{
+ void __iomem *intevtsa = ioremap_nocache(0xffd20100, PAGE_SIZE);
+
+ register_intc_controller(&intca_desc);
+ register_intc_controller(&intca_irq_pins_desc);
+ register_intc_controller(&intcs_desc);
+
+ /* demux using INTEVTSA */
+ irq_set_handler_data(evt2irq(0xf80), (void *)intevtsa);
+ irq_set_chained_handler(evt2irq(0xf80), intcs_demux);
+}
diff --git a/arch/arm/mach-shmobile/intc-r8a7779.c b/arch/arm/mach-shmobile/intc-r8a7779.c
new file mode 100644
index 0000000..5d92fcd
--- /dev/null
+++ b/arch/arm/mach-shmobile/intc-r8a7779.c
@@ -0,0 +1,58 @@
+/*
+ * r8a7779 processor support - INTC hardware block
+ *
+ * Copyright (C) 2011 Renesas Solutions Corp.
+ * Copyright (C) 2011 Magnus Damm
+ *
+ * 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; version 2 of the License.
+ *
+ * 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 <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <mach/common.h>
+#include <mach/intc.h>
+#include <mach/r8a7779.h>
+#include <asm/hardware/gic.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#define INT2SMSKCR0 0xfe7822a0
+#define INT2SMSKCR1 0xfe7822a4
+#define INT2SMSKCR2 0xfe7822a8
+#define INT2SMSKCR3 0xfe7822ac
+#define INT2SMSKCR4 0xfe7822b0
+
+static int r8a7779_set_wake(struct irq_data *data, unsigned int on)
+{
+ return 0; /* always allow wakeup */
+}
+
+void __init r8a7779_init_irq(void)
+{
+ void __iomem *gic_dist_base = __io(0xf0001000);
+ void __iomem *gic_cpu_base = __io(0xf0000100);
+
+ /* use GIC to handle interrupts */
+ gic_init(0, 29, gic_dist_base, gic_cpu_base);
+ gic_arch_extn.irq_set_wake = r8a7779_set_wake;
+
+ /* unmask all known interrupts in INTCS2 */
+ __raw_writel(0xfffffff0, INT2SMSKCR0);
+ __raw_writel(0xfff7ffff, INT2SMSKCR1);
+ __raw_writel(0xfffbffdf, INT2SMSKCR2);
+ __raw_writel(0xbffffffc, INT2SMSKCR3);
+ __raw_writel(0x003fee3f, INT2SMSKCR4);
+}
diff --git a/arch/arm/mach-shmobile/pfc-r8a7740.c b/arch/arm/mach-shmobile/pfc-r8a7740.c
new file mode 100644
index 0000000..a4fff69
--- /dev/null
+++ b/arch/arm/mach-shmobile/pfc-r8a7740.c
@@ -0,0 +1,2562 @@
+/*
+ * R8A7740 processor support
+ *
+ * Copyright (C) 2011 Renesas Solutions Corp.
+ * Copyright (C) 2011 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+ *
+ * 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; version 2 of the
+ * License.
+ *
+ * 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 <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/gpio.h>
+#include <mach/r8a7740.h>
+
+#define CPU_ALL_PORT(fn, pfx, sfx) \
+ PORT_10(fn, pfx, sfx), PORT_90(fn, pfx, sfx), \
+ PORT_10(fn, pfx##10, sfx), PORT_90(fn, pfx##1, sfx), \
+ PORT_10(fn, pfx##20, sfx), \
+ PORT_1(fn, pfx##210, sfx), PORT_1(fn, pfx##211, sfx)
+
+enum {
+ PINMUX_RESERVED = 0,
+
+ /* PORT0_DATA -> PORT211_DATA */
+ PINMUX_DATA_BEGIN,
+ PORT_ALL(DATA),
+ PINMUX_DATA_END,
+
+ /* PORT0_IN -> PORT211_IN */
+ PINMUX_INPUT_BEGIN,
+ PORT_ALL(IN),
+ PINMUX_INPUT_END,
+
+ /* PORT0_IN_PU -> PORT211_IN_PU */
+ PINMUX_INPUT_PULLUP_BEGIN,
+ PORT_ALL(IN_PU),
+ PINMUX_INPUT_PULLUP_END,
+
+ /* PORT0_IN_PD -> PORT211_IN_PD */
+ PINMUX_INPUT_PULLDOWN_BEGIN,
+ PORT_ALL(IN_PD),
+ PINMUX_INPUT_PULLDOWN_END,
+
+ /* PORT0_OUT -> PORT211_OUT */
+ PINMUX_OUTPUT_BEGIN,
+ PORT_ALL(OUT),
+ PINMUX_OUTPUT_END,
+
+ PINMUX_FUNCTION_BEGIN,
+ PORT_ALL(FN_IN), /* PORT0_FN_IN -> PORT211_FN_IN */
+ PORT_ALL(FN_OUT), /* PORT0_FN_OUT -> PORT211_FN_OUT */
+ PORT_ALL(FN0), /* PORT0_FN0 -> PORT211_FN0 */
+ PORT_ALL(FN1), /* PORT0_FN1 -> PORT211_FN1 */
+ PORT_ALL(FN2), /* PORT0_FN2 -> PORT211_FN2 */
+ PORT_ALL(FN3), /* PORT0_FN3 -> PORT211_FN3 */
+ PORT_ALL(FN4), /* PORT0_FN4 -> PORT211_FN4 */
+ PORT_ALL(FN5), /* PORT0_FN5 -> PORT211_FN5 */
+ PORT_ALL(FN6), /* PORT0_FN6 -> PORT211_FN6 */
+ PORT_ALL(FN7), /* PORT0_FN7 -> PORT211_FN7 */
+
+ MSEL1CR_31_0, MSEL1CR_31_1,
+ MSEL1CR_30_0, MSEL1CR_30_1,
+ MSEL1CR_29_0, MSEL1CR_29_1,
+ MSEL1CR_28_0, MSEL1CR_28_1,
+ MSEL1CR_27_0, MSEL1CR_27_1,
+ MSEL1CR_26_0, MSEL1CR_26_1,
+ MSEL1CR_16_0, MSEL1CR_16_1,
+ MSEL1CR_15_0, MSEL1CR_15_1,
+ MSEL1CR_14_0, MSEL1CR_14_1,
+ MSEL1CR_13_0, MSEL1CR_13_1,
+ MSEL1CR_12_0, MSEL1CR_12_1,
+ MSEL1CR_9_0, MSEL1CR_9_1,
+ MSEL1CR_7_0, MSEL1CR_7_1,
+ MSEL1CR_6_0, MSEL1CR_6_1,
+ MSEL1CR_5_0, MSEL1CR_5_1,
+ MSEL1CR_4_0, MSEL1CR_4_1,
+ MSEL1CR_3_0, MSEL1CR_3_1,
+ MSEL1CR_2_0, MSEL1CR_2_1,
+ MSEL1CR_0_0, MSEL1CR_0_1,
+
+ MSEL3CR_15_0, MSEL3CR_15_1, /* Trace / Debug ? */
+ MSEL3CR_6_0, MSEL3CR_6_1,
+
+ MSEL4CR_19_0, MSEL4CR_19_1,
+ MSEL4CR_18_0, MSEL4CR_18_1,
+ MSEL4CR_15_0, MSEL4CR_15_1,
+ MSEL4CR_10_0, MSEL4CR_10_1,
+ MSEL4CR_6_0, MSEL4CR_6_1,
+ MSEL4CR_4_0, MSEL4CR_4_1,
+ MSEL4CR_1_0, MSEL4CR_1_1,
+
+ MSEL5CR_31_0, MSEL5CR_31_1, /* irq/fiq output */
+ MSEL5CR_30_0, MSEL5CR_30_1,
+ MSEL5CR_29_0, MSEL5CR_29_1,
+ MSEL5CR_27_0, MSEL5CR_27_1,
+ MSEL5CR_25_0, MSEL5CR_25_1,
+ MSEL5CR_23_0, MSEL5CR_23_1,
+ MSEL5CR_21_0, MSEL5CR_21_1,
+ MSEL5CR_19_0, MSEL5CR_19_1,
+ MSEL5CR_17_0, MSEL5CR_17_1,
+ MSEL5CR_15_0, MSEL5CR_15_1,
+ MSEL5CR_14_0, MSEL5CR_14_1,
+ MSEL5CR_13_0, MSEL5CR_13_1,
+ MSEL5CR_12_0, MSEL5CR_12_1,
+ MSEL5CR_11_0, MSEL5CR_11_1,
+ MSEL5CR_10_0, MSEL5CR_10_1,
+ MSEL5CR_8_0, MSEL5CR_8_1,
+ MSEL5CR_7_0, MSEL5CR_7_1,
+ MSEL5CR_6_0, MSEL5CR_6_1,
+ MSEL5CR_5_0, MSEL5CR_5_1,
+ MSEL5CR_4_0, MSEL5CR_4_1,
+ MSEL5CR_3_0, MSEL5CR_3_1,
+ MSEL5CR_2_0, MSEL5CR_2_1,
+ MSEL5CR_0_0, MSEL5CR_0_1,
+ PINMUX_FUNCTION_END,
+
+ PINMUX_MARK_BEGIN,
+
+ /* IRQ */
+ IRQ0_PORT2_MARK, IRQ0_PORT13_MARK,
+ IRQ1_MARK,
+ IRQ2_PORT11_MARK, IRQ2_PORT12_MARK,
+ IRQ3_PORT10_MARK, IRQ3_PORT14_MARK,
+ IRQ4_PORT15_MARK, IRQ4_PORT172_MARK,
+ IRQ5_PORT0_MARK, IRQ5_PORT1_MARK,
+ IRQ6_PORT121_MARK, IRQ6_PORT173_MARK,
+ IRQ7_PORT120_MARK, IRQ7_PORT209_MARK,
+ IRQ8_MARK,
+ IRQ9_PORT118_MARK, IRQ9_PORT210_MARK,
+ IRQ10_MARK,
+ IRQ11_MARK,
+ IRQ12_PORT42_MARK, IRQ12_PORT97_MARK,
+ IRQ13_PORT64_MARK, IRQ13_PORT98_MARK,
+ IRQ14_PORT63_MARK, IRQ14_PORT99_MARK,
+ IRQ15_PORT62_MARK, IRQ15_PORT100_MARK,
+ IRQ16_PORT68_MARK, IRQ16_PORT211_MARK,
+ IRQ17_MARK,
+ IRQ18_MARK,
+ IRQ19_MARK,
+ IRQ20_MARK,
+ IRQ21_MARK,
+ IRQ22_MARK,
+ IRQ23_MARK,
+ IRQ24_MARK,
+ IRQ25_MARK,
+ IRQ26_PORT58_MARK, IRQ26_PORT81_MARK,
+ IRQ27_PORT57_MARK, IRQ27_PORT168_MARK,
+ IRQ28_PORT56_MARK, IRQ28_PORT169_MARK,
+ IRQ29_PORT50_MARK, IRQ29_PORT170_MARK,
+ IRQ30_PORT49_MARK, IRQ30_PORT171_MARK,
+ IRQ31_PORT41_MARK, IRQ31_PORT167_MARK,
+
+ /* Function */
+
+ /* DBGT */
+ DBGMDT2_MARK, DBGMDT1_MARK, DBGMDT0_MARK,
+ DBGMD10_MARK, DBGMD11_MARK, DBGMD20_MARK,
+ DBGMD21_MARK,
+
+ /* FSI */
+ FSIAISLD_PORT0_MARK, /* FSIAISLD Port 0/5 */
+ FSIAISLD_PORT5_MARK,
+ FSIASPDIF_PORT9_MARK, /* FSIASPDIF Port 9/18 */
+ FSIASPDIF_PORT18_MARK,
+ FSIAOSLD1_MARK, FSIAOSLD2_MARK, FSIAOLR_MARK,
+ FSIAOBT_MARK, FSIAOSLD_MARK, FSIAOMC_MARK,
+ FSIACK_MARK, FSIAILR_MARK, FSIAIBT_MARK,
+
+ /* FMSI */
+ FMSISLD_PORT1_MARK, /* FMSISLD Port 1/6 */
+ FMSISLD_PORT6_MARK,
+ FMSIILR_MARK, FMSIIBT_MARK, FMSIOLR_MARK, FMSIOBT_MARK,
+ FMSICK_MARK, FMSOILR_MARK, FMSOIBT_MARK, FMSOOLR_MARK,
+ FMSOOBT_MARK, FMSOSLD_MARK, FMSOCK_MARK,
+
+ /* SCIFA0 */
+ SCIFA0_SCK_MARK, SCIFA0_CTS_MARK, SCIFA0_RTS_MARK,
+ SCIFA0_RXD_MARK, SCIFA0_TXD_MARK,
+
+ /* SCIFA1 */
+ SCIFA1_CTS_MARK, SCIFA1_SCK_MARK, SCIFA1_RXD_MARK,
+ SCIFA1_TXD_MARK, SCIFA1_RTS_MARK,
+
+ /* SCIFA2 */
+ SCIFA2_SCK_PORT22_MARK, /* SCIFA2_SCK Port 22/199 */
+ SCIFA2_SCK_PORT199_MARK,
+ SCIFA2_RXD_MARK, SCIFA2_TXD_MARK,
+ SCIFA2_CTS_MARK, SCIFA2_RTS_MARK,
+
+ /* SCIFA3 */
+ SCIFA3_RTS_PORT105_MARK, /* MSEL5CR_8_0 */
+ SCIFA3_SCK_PORT116_MARK,
+ SCIFA3_CTS_PORT117_MARK,
+ SCIFA3_RXD_PORT174_MARK,
+ SCIFA3_TXD_PORT175_MARK,
+
+ SCIFA3_RTS_PORT161_MARK, /* MSEL5CR_8_1 */
+ SCIFA3_SCK_PORT158_MARK,
+ SCIFA3_CTS_PORT162_MARK,
+ SCIFA3_RXD_PORT159_MARK,
+ SCIFA3_TXD_PORT160_MARK,
+
+ /* SCIFA4 */
+ SCIFA4_RXD_PORT12_MARK, /* MSEL5CR[12:11] = 00 */
+ SCIFA4_TXD_PORT13_MARK,
+
+ SCIFA4_RXD_PORT204_MARK, /* MSEL5CR[12:11] = 01 */
+ SCIFA4_TXD_PORT203_MARK,
+
+ SCIFA4_RXD_PORT94_MARK, /* MSEL5CR[12:11] = 10 */
+ SCIFA4_TXD_PORT93_MARK,
+
+ SCIFA4_SCK_PORT21_MARK, /* SCIFA4_SCK Port 21/205 */
+ SCIFA4_SCK_PORT205_MARK,
+
+ /* SCIFA5 */
+ SCIFA5_TXD_PORT20_MARK, /* MSEL5CR[15:14] = 00 */
+ SCIFA5_RXD_PORT10_MARK,
+
+ SCIFA5_RXD_PORT207_MARK, /* MSEL5CR[15:14] = 01 */
+ SCIFA5_TXD_PORT208_MARK,
+
+ SCIFA5_TXD_PORT91_MARK, /* MSEL5CR[15:14] = 10 */
+ SCIFA5_RXD_PORT92_MARK,
+
+ SCIFA5_SCK_PORT23_MARK, /* SCIFA5_SCK Port 23/206 */
+ SCIFA5_SCK_PORT206_MARK,
+
+ /* SCIFA6 */
+ SCIFA6_SCK_MARK, SCIFA6_RXD_MARK, SCIFA6_TXD_MARK,
+
+ /* SCIFA7 */
+ SCIFA7_TXD_MARK, SCIFA7_RXD_MARK,
+
+ /* SCIFAB */
+ SCIFB_SCK_PORT190_MARK, /* MSEL5CR_17_0 */
+ SCIFB_RXD_PORT191_MARK,
+ SCIFB_TXD_PORT192_MARK,
+ SCIFB_RTS_PORT186_MARK,
+ SCIFB_CTS_PORT187_MARK,
+
+ SCIFB_SCK_PORT2_MARK, /* MSEL5CR_17_1 */
+ SCIFB_RXD_PORT3_MARK,
+ SCIFB_TXD_PORT4_MARK,
+ SCIFB_RTS_PORT172_MARK,
+ SCIFB_CTS_PORT173_MARK,
+
+ /* LCD0 */
+ LCDC0_SELECT_MARK,
+
+ LCD0_D0_MARK, LCD0_D1_MARK, LCD0_D2_MARK, LCD0_D3_MARK,
+ LCD0_D4_MARK, LCD0_D5_MARK, LCD0_D6_MARK, LCD0_D7_MARK,
+ LCD0_D8_MARK, LCD0_D9_MARK, LCD0_D10_MARK, LCD0_D11_MARK,
+ LCD0_D12_MARK, LCD0_D13_MARK, LCD0_D14_MARK, LCD0_D15_MARK,
+ LCD0_D16_MARK, LCD0_D17_MARK,
+ LCD0_DON_MARK, LCD0_VCPWC_MARK, LCD0_VEPWC_MARK,
+ LCD0_DCK_MARK, LCD0_VSYN_MARK, /* for RGB */
+ LCD0_HSYN_MARK, LCD0_DISP_MARK, /* for RGB */
+ LCD0_WR_MARK, LCD0_RD_MARK, /* for SYS */
+ LCD0_CS_MARK, LCD0_RS_MARK, /* for SYS */
+
+ LCD0_D21_PORT158_MARK, LCD0_D23_PORT159_MARK, /* MSEL5CR_6_1 */
+ LCD0_D22_PORT160_MARK, LCD0_D20_PORT161_MARK,
+ LCD0_D19_PORT162_MARK, LCD0_D18_PORT163_MARK,
+ LCD0_LCLK_PORT165_MARK,
+
+ LCD0_D18_PORT40_MARK, LCD0_D22_PORT0_MARK, /* MSEL5CR_6_0 */
+ LCD0_D23_PORT1_MARK, LCD0_D21_PORT2_MARK,
+ LCD0_D20_PORT3_MARK, LCD0_D19_PORT4_MARK,
+ LCD0_LCLK_PORT102_MARK,
+
+ /* LCD1 */
+ LCDC1_SELECT_MARK,
+
+ LCD1_D0_MARK, LCD1_D1_MARK, LCD1_D2_MARK, LCD1_D3_MARK,
+ LCD1_D4_MARK, LCD1_D5_MARK, LCD1_D6_MARK, LCD1_D7_MARK,
+ LCD1_D8_MARK, LCD1_D9_MARK, LCD1_D10_MARK, LCD1_D11_MARK,
+ LCD1_D12_MARK, LCD1_D13_MARK, LCD1_D14_MARK, LCD1_D15_MARK,
+ LCD1_D16_MARK, LCD1_D17_MARK, LCD1_D18_MARK, LCD1_D19_MARK,
+ LCD1_D20_MARK, LCD1_D21_MARK, LCD1_D22_MARK, LCD1_D23_MARK,
+ LCD1_DON_MARK, LCD1_VCPWC_MARK,
+ LCD1_LCLK_MARK, LCD1_VEPWC_MARK,
+
+ LCD1_DCK_MARK, LCD1_VSYN_MARK, /* for RGB */
+ LCD1_HSYN_MARK, LCD1_DISP_MARK, /* for RGB */
+ LCD1_RS_MARK, LCD1_CS_MARK, /* for SYS */
+ LCD1_RD_MARK, LCD1_WR_MARK, /* for SYS */
+
+ /* RSPI */
+ RSPI_SSL0_A_MARK, RSPI_SSL1_A_MARK, RSPI_SSL2_A_MARK,
+ RSPI_SSL3_A_MARK, RSPI_CK_A_MARK, RSPI_MOSI_A_MARK,
+ RSPI_MISO_A_MARK,
+
+ /* VIO CKO */
+ VIO_CKO1_MARK, /* needs fixup */
+ VIO_CKO2_MARK,
+ VIO_CKO_1_MARK,
+ VIO_CKO_MARK,
+
+ /* VIO0 */
+ VIO0_D0_MARK, VIO0_D1_MARK, VIO0_D2_MARK, VIO0_D3_MARK,
+ VIO0_D4_MARK, VIO0_D5_MARK, VIO0_D6_MARK, VIO0_D7_MARK,
+ VIO0_D8_MARK, VIO0_D9_MARK, VIO0_D10_MARK, VIO0_D11_MARK,
+ VIO0_D12_MARK, VIO0_VD_MARK, VIO0_HD_MARK, VIO0_CLK_MARK,
+ VIO0_FIELD_MARK,
+
+ VIO0_D13_PORT26_MARK, /* MSEL5CR_27_0 */
+ VIO0_D14_PORT25_MARK,
+ VIO0_D15_PORT24_MARK,
+
+ VIO0_D13_PORT22_MARK, /* MSEL5CR_27_1 */
+ VIO0_D14_PORT95_MARK,
+ VIO0_D15_PORT96_MARK,
+
+ /* VIO1 */
+ VIO1_D0_MARK, VIO1_D1_MARK, VIO1_D2_MARK, VIO1_D3_MARK,
+ VIO1_D4_MARK, VIO1_D5_MARK, VIO1_D6_MARK, VIO1_D7_MARK,
+ VIO1_VD_MARK, VIO1_HD_MARK, VIO1_CLK_MARK, VIO1_FIELD_MARK,
+
+ /* TPU0 */
+ TPU0TO0_MARK, TPU0TO1_MARK, TPU0TO3_MARK,
+ TPU0TO2_PORT66_MARK, /* TPU0TO2 Port 66/202 */
+ TPU0TO2_PORT202_MARK,
+
+ /* SSP1 0 */
+ STP0_IPD0_MARK, STP0_IPD1_MARK, STP0_IPD2_MARK, STP0_IPD3_MARK,
+ STP0_IPD4_MARK, STP0_IPD5_MARK, STP0_IPD6_MARK, STP0_IPD7_MARK,
+ STP0_IPEN_MARK, STP0_IPCLK_MARK, STP0_IPSYNC_MARK,
+
+ /* SSP1 1 */
+ STP1_IPD1_MARK, STP1_IPD2_MARK, STP1_IPD3_MARK, STP1_IPD4_MARK,
+ STP1_IPD5_MARK, STP1_IPD6_MARK, STP1_IPD7_MARK, STP1_IPCLK_MARK,
+ STP1_IPSYNC_MARK,
+
+ STP1_IPD0_PORT186_MARK, /* MSEL5CR_23_0 */
+ STP1_IPEN_PORT187_MARK,
+
+ STP1_IPD0_PORT194_MARK, /* MSEL5CR_23_1 */
+ STP1_IPEN_PORT193_MARK,
+
+ /* SIM */
+ SIM_RST_MARK, SIM_CLK_MARK,
+ SIM_D_PORT22_MARK, /* SIM_D Port 22/199 */
+ SIM_D_PORT199_MARK,
+
+ /* SDHI0 */
+ SDHI0_D0_MARK, SDHI0_D1_MARK, SDHI0_D2_MARK, SDHI0_D3_MARK,
+ SDHI0_CD_MARK, SDHI0_WP_MARK, SDHI0_CMD_MARK, SDHI0_CLK_MARK,
+
+ /* SDHI1 */
+ SDHI1_D0_MARK, SDHI1_D1_MARK, SDHI1_D2_MARK, SDHI1_D3_MARK,
+ SDHI1_CD_MARK, SDHI1_WP_MARK, SDHI1_CMD_MARK, SDHI1_CLK_MARK,
+
+ /* SDHI2 */
+ SDHI2_D0_MARK, SDHI2_D1_MARK, SDHI2_D2_MARK, SDHI2_D3_MARK,
+ SDHI2_CLK_MARK, SDHI2_CMD_MARK,
+
+ SDHI2_CD_PORT24_MARK, /* MSEL5CR_19_0 */
+ SDHI2_WP_PORT25_MARK,
+
+ SDHI2_WP_PORT177_MARK, /* MSEL5CR_19_1 */
+ SDHI2_CD_PORT202_MARK,
+
+ /* MSIOF2 */
+ MSIOF2_TXD_MARK, MSIOF2_RXD_MARK, MSIOF2_TSCK_MARK,
+ MSIOF2_SS2_MARK, MSIOF2_TSYNC_MARK, MSIOF2_SS1_MARK,
+ MSIOF2_MCK1_MARK, MSIOF2_MCK0_MARK, MSIOF2_RSYNC_MARK,
+ MSIOF2_RSCK_MARK,
+
+ /* KEYSC */
+ KEYIN4_MARK, KEYIN5_MARK, KEYIN6_MARK, KEYIN7_MARK,
+ KEYOUT0_MARK, KEYOUT1_MARK, KEYOUT2_MARK, KEYOUT3_MARK,
+ KEYOUT4_MARK, KEYOUT5_MARK, KEYOUT6_MARK, KEYOUT7_MARK,
+
+ KEYIN0_PORT43_MARK, /* MSEL4CR_18_0 */
+ KEYIN1_PORT44_MARK,
+ KEYIN2_PORT45_MARK,
+ KEYIN3_PORT46_MARK,
+
+ KEYIN0_PORT58_MARK, /* MSEL4CR_18_1 */
+ KEYIN1_PORT57_MARK,
+ KEYIN2_PORT56_MARK,
+ KEYIN3_PORT55_MARK,
+
+ /* VOU */
+ DV_D0_MARK, DV_D1_MARK, DV_D2_MARK, DV_D3_MARK,
+ DV_D4_MARK, DV_D5_MARK, DV_D6_MARK, DV_D7_MARK,
+ DV_D8_MARK, DV_D9_MARK, DV_D10_MARK, DV_D11_MARK,
+ DV_D12_MARK, DV_D13_MARK, DV_D14_MARK, DV_D15_MARK,
+ DV_CLK_MARK, DV_VSYNC_MARK, DV_HSYNC_MARK,
+
+ /* MEMC */
+ MEMC_AD0_MARK, MEMC_AD1_MARK, MEMC_AD2_MARK, MEMC_AD3_MARK,
+ MEMC_AD4_MARK, MEMC_AD5_MARK, MEMC_AD6_MARK, MEMC_AD7_MARK,
+ MEMC_AD8_MARK, MEMC_AD9_MARK, MEMC_AD10_MARK, MEMC_AD11_MARK,
+ MEMC_AD12_MARK, MEMC_AD13_MARK, MEMC_AD14_MARK, MEMC_AD15_MARK,
+ MEMC_CS0_MARK, MEMC_INT_MARK, MEMC_NWE_MARK, MEMC_NOE_MARK,
+
+ MEMC_CS1_MARK, /* MSEL4CR_6_0 */
+ MEMC_ADV_MARK,
+ MEMC_WAIT_MARK,
+ MEMC_BUSCLK_MARK,
+
+ MEMC_A1_MARK, /* MSEL4CR_6_1 */
+ MEMC_DREQ0_MARK,
+ MEMC_DREQ1_MARK,
+ MEMC_A0_MARK,
+
+ /* MMC */
+ MMC0_D0_PORT68_MARK, MMC0_D1_PORT69_MARK, MMC0_D2_PORT70_MARK,
+ MMC0_D3_PORT71_MARK, MMC0_D4_PORT72_MARK, MMC0_D5_PORT73_MARK,
+ MMC0_D6_PORT74_MARK, MMC0_D7_PORT75_MARK, MMC0_CLK_PORT66_MARK,
+ MMC0_CMD_PORT67_MARK, /* MSEL4CR_15_0 */
+
+ MMC1_D0_PORT149_MARK, MMC1_D1_PORT148_MARK, MMC1_D2_PORT147_MARK,
+ MMC1_D3_PORT146_MARK, MMC1_D4_PORT145_MARK, MMC1_D5_PORT144_MARK,
+ MMC1_D6_PORT143_MARK, MMC1_D7_PORT142_MARK, MMC1_CLK_PORT103_MARK,
+ MMC1_CMD_PORT104_MARK, /* MSEL4CR_15_1 */
+
+ /* MSIOF0 */
+ MSIOF0_SS1_MARK, MSIOF0_SS2_MARK, MSIOF0_RXD_MARK,
+ MSIOF0_TXD_MARK, MSIOF0_MCK0_MARK, MSIOF0_MCK1_MARK,
+ MSIOF0_RSYNC_MARK, MSIOF0_RSCK_MARK, MSIOF0_TSCK_MARK,
+ MSIOF0_TSYNC_MARK,
+
+ /* MSIOF1 */
+ MSIOF1_RSCK_MARK, MSIOF1_RSYNC_MARK,
+ MSIOF1_MCK0_MARK, MSIOF1_MCK1_MARK,
+
+ MSIOF1_SS2_PORT116_MARK, MSIOF1_SS1_PORT117_MARK,
+ MSIOF1_RXD_PORT118_MARK, MSIOF1_TXD_PORT119_MARK,
+ MSIOF1_TSYNC_PORT120_MARK,
+ MSIOF1_TSCK_PORT121_MARK, /* MSEL4CR_10_0 */
+
+ MSIOF1_SS1_PORT67_MARK, MSIOF1_TSCK_PORT72_MARK,
+ MSIOF1_TSYNC_PORT73_MARK, MSIOF1_TXD_PORT74_MARK,
+ MSIOF1_RXD_PORT75_MARK,
+ MSIOF1_SS2_PORT202_MARK, /* MSEL4CR_10_1 */
+
+ /* GPIO */
+ GPO0_MARK, GPI0_MARK, GPO1_MARK, GPI1_MARK,
+
+ /* USB0 */
+ USB0_OCI_MARK, USB0_PPON_MARK, VBUS_MARK,
+
+ /* USB1 */
+ USB1_OCI_MARK, USB1_PPON_MARK,
+
+ /* BBIF1 */
+ BBIF1_RXD_MARK, BBIF1_TXD_MARK, BBIF1_TSYNC_MARK,
+ BBIF1_TSCK_MARK, BBIF1_RSCK_MARK, BBIF1_RSYNC_MARK,
+ BBIF1_FLOW_MARK, BBIF1_RX_FLOW_N_MARK,
+
+ /* BBIF2 */
+ BBIF2_TXD2_PORT5_MARK, /* MSEL5CR_0_0 */
+ BBIF2_RXD2_PORT60_MARK,
+ BBIF2_TSYNC2_PORT6_MARK,
+ BBIF2_TSCK2_PORT59_MARK,
+
+ BBIF2_RXD2_PORT90_MARK, /* MSEL5CR_0_1 */
+ BBIF2_TXD2_PORT183_MARK,
+ BBIF2_TSCK2_PORT89_MARK,
+ BBIF2_TSYNC2_PORT184_MARK,
+
+ /* BSC / FLCTL / PCMCIA */
+ CS0_MARK, CS2_MARK, CS4_MARK,
+ CS5B_MARK, CS6A_MARK,
+ CS5A_PORT105_MARK, /* CS5A PORT 19/105 */
+ CS5A_PORT19_MARK,
+ IOIS16_MARK, /* ? */
+
+ A0_MARK, A1_MARK, A2_MARK, A3_MARK,
+ A4_FOE_MARK, /* share with FLCTL */
+ A5_FCDE_MARK, /* share with FLCTL */
+ A6_MARK, A7_MARK, A8_MARK, A9_MARK,
+ A10_MARK, A11_MARK, A12_MARK, A13_MARK,
+ A14_MARK, A15_MARK, A16_MARK, A17_MARK,
+ A18_MARK, A19_MARK, A20_MARK, A21_MARK,
+ A22_MARK, A23_MARK, A24_MARK, A25_MARK,
+ A26_MARK,
+
+ D0_NAF0_MARK, D1_NAF1_MARK, D2_NAF2_MARK, /* share with FLCTL */
+ D3_NAF3_MARK, D4_NAF4_MARK, D5_NAF5_MARK, /* share with FLCTL */
+ D6_NAF6_MARK, D7_NAF7_MARK, D8_NAF8_MARK, /* share with FLCTL */
+ D9_NAF9_MARK, D10_NAF10_MARK, D11_NAF11_MARK, /* share with FLCTL */
+ D12_NAF12_MARK, D13_NAF13_MARK, D14_NAF14_MARK, /* share with FLCTL */
+ D15_NAF15_MARK, /* share with FLCTL */
+ D16_MARK, D17_MARK, D18_MARK, D19_MARK,
+ D20_MARK, D21_MARK, D22_MARK, D23_MARK,
+ D24_MARK, D25_MARK, D26_MARK, D27_MARK,
+ D28_MARK, D29_MARK, D30_MARK, D31_MARK,
+
+ WE0_FWE_MARK, /* share with FLCTL */
+ WE1_MARK,
+ WE2_ICIORD_MARK, /* share with PCMCIA */
+ WE3_ICIOWR_MARK, /* share with PCMCIA */
+ CKO_MARK, BS_MARK, RDWR_MARK,
+ RD_FSC_MARK, /* share with FLCTL */
+ WAIT_PORT177_MARK, /* WAIT Port 90/177 */
+ WAIT_PORT90_MARK,
+
+ FCE0_MARK, FCE1_MARK, FRB_MARK, /* FLCTL */
+
+ /* IRDA */
+ IRDA_FIRSEL_MARK, IRDA_IN_MARK, IRDA_OUT_MARK,
+
+ /* ATAPI */
+ IDE_D0_MARK, IDE_D1_MARK, IDE_D2_MARK, IDE_D3_MARK,
+ IDE_D4_MARK, IDE_D5_MARK, IDE_D6_MARK, IDE_D7_MARK,
+ IDE_D8_MARK, IDE_D9_MARK, IDE_D10_MARK, IDE_D11_MARK,
+ IDE_D12_MARK, IDE_D13_MARK, IDE_D14_MARK, IDE_D15_MARK,
+ IDE_A0_MARK, IDE_A1_MARK, IDE_A2_MARK, IDE_CS0_MARK,
+ IDE_CS1_MARK, IDE_IOWR_MARK, IDE_IORD_MARK, IDE_IORDY_MARK,
+ IDE_INT_MARK, IDE_RST_MARK, IDE_DIRECTION_MARK,
+ IDE_EXBUF_ENB_MARK, IDE_IODACK_MARK, IDE_IODREQ_MARK,
+
+ /* RMII */
+ RMII_CRS_DV_MARK, RMII_RX_ER_MARK, RMII_RXD0_MARK,
+ RMII_RXD1_MARK, RMII_TX_EN_MARK, RMII_TXD0_MARK,
+ RMII_MDC_MARK, RMII_TXD1_MARK, RMII_MDIO_MARK,
+ RMII_REF50CK_MARK, /* for RMII */
+ RMII_REF125CK_MARK, /* for GMII */
+
+ /* GEther */
+ ET_TX_CLK_MARK, ET_TX_EN_MARK, ET_ETXD0_MARK, ET_ETXD1_MARK,
+ ET_ETXD2_MARK, ET_ETXD3_MARK,
+ ET_ETXD4_MARK, ET_ETXD5_MARK, /* for GEther */
+ ET_ETXD6_MARK, ET_ETXD7_MARK, /* for GEther */
+ ET_COL_MARK, ET_TX_ER_MARK, ET_RX_CLK_MARK, ET_RX_DV_MARK,
+ ET_ERXD0_MARK, ET_ERXD1_MARK, ET_ERXD2_MARK, ET_ERXD3_MARK,
+ ET_ERXD4_MARK, ET_ERXD5_MARK, /* for GEther */
+ ET_ERXD6_MARK, ET_ERXD7_MARK, /* for GEther */
+ ET_RX_ER_MARK, ET_CRS_MARK, ET_MDC_MARK, ET_MDIO_MARK,
+ ET_LINK_MARK, ET_PHY_INT_MARK, ET_WOL_MARK, ET_GTX_CLK_MARK,
+
+ /* DMA0 */
+ DREQ0_MARK, DACK0_MARK,
+
+ /* DMA1 */
+ DREQ1_MARK, DACK1_MARK,
+
+ /* SYSC */
+ RESETOUTS_MARK, RESETP_PULLUP_MARK, RESETP_PLAIN_MARK,
+
+ /* IRREM */
+ IROUT_MARK,
+
+ /* SDENC */
+ SDENC_CPG_MARK, SDENC_DV_CLKI_MARK,
+
+ /* DEBUG */
+ EDEBGREQ_PULLUP_MARK, /* for JTAG */
+ EDEBGREQ_PULLDOWN_MARK,
+
+ TRACEAUD_FROM_VIO_MARK, /* for TRACE/AUD */
+ TRACEAUD_FROM_LCDC0_MARK,
+ TRACEAUD_FROM_MEMC_MARK,
+
+ PINMUX_MARK_END,
+};
+
+static pinmux_enum_t pinmux_data[] = {
+ /* specify valid pin states for each pin in GPIO mode */
+
+ /* I/O and Pull U/D */
+ PORT_DATA_IO_PD(0), PORT_DATA_IO_PD(1),
+ PORT_DATA_IO_PD(2), PORT_DATA_IO_PD(3),
+ PORT_DATA_IO_PD(4), PORT_DATA_IO_PD(5),
+ PORT_DATA_IO_PD(6), PORT_DATA_IO(7),
+ PORT_DATA_IO(8), PORT_DATA_IO(9),
+
+ PORT_DATA_IO_PD(10), PORT_DATA_IO_PD(11),
+ PORT_DATA_IO_PD(12), PORT_DATA_IO_PU_PD(13),
+ PORT_DATA_IO_PD(14), PORT_DATA_IO_PD(15),
+ PORT_DATA_IO_PD(16), PORT_DATA_IO_PD(17),
+ PORT_DATA_IO(18), PORT_DATA_IO_PU(19),
+
+ PORT_DATA_IO_PU_PD(20), PORT_DATA_IO_PD(21),
+ PORT_DATA_IO_PU_PD(22), PORT_DATA_IO(23),
+ PORT_DATA_IO_PU(24), PORT_DATA_IO_PU(25),
+ PORT_DATA_IO_PU(26), PORT_DATA_IO_PU(27),
+ PORT_DATA_IO_PU(28), PORT_DATA_IO_PU(29),
+
+ PORT_DATA_IO_PU(30), PORT_DATA_IO_PD(31),
+ PORT_DATA_IO_PD(32), PORT_DATA_IO_PD(33),
+ PORT_DATA_IO_PD(34), PORT_DATA_IO_PU(35),
+ PORT_DATA_IO_PU(36), PORT_DATA_IO_PD(37),
+ PORT_DATA_IO_PU(38), PORT_DATA_IO_PD(39),
+
+ PORT_DATA_IO_PU_PD(40), PORT_DATA_IO_PD(41),
+ PORT_DATA_IO_PD(42), PORT_DATA_IO_PU_PD(43),
+ PORT_DATA_IO_PU_PD(44), PORT_DATA_IO_PU_PD(45),
+ PORT_DATA_IO_PU_PD(46), PORT_DATA_IO_PU_PD(47),
+ PORT_DATA_IO_PU_PD(48), PORT_DATA_IO_PU_PD(49),
+
+ PORT_DATA_IO_PU_PD(50), PORT_DATA_IO_PD(51),
+ PORT_DATA_IO_PD(52), PORT_DATA_IO_PD(53),
+ PORT_DATA_IO_PD(54), PORT_DATA_IO_PU_PD(55),
+ PORT_DATA_IO_PU_PD(56), PORT_DATA_IO_PU_PD(57),
+ PORT_DATA_IO_PU_PD(58), PORT_DATA_IO_PU_PD(59),
+
+ PORT_DATA_IO_PU_PD(60), PORT_DATA_IO_PD(61),
+ PORT_DATA_IO_PD(62), PORT_DATA_IO_PD(63),
+ PORT_DATA_IO_PD(64), PORT_DATA_IO_PD(65),
+ PORT_DATA_IO_PU_PD(66), PORT_DATA_IO_PU_PD(67),
+ PORT_DATA_IO_PU_PD(68), PORT_DATA_IO_PU_PD(69),
+
+ PORT_DATA_IO_PU_PD(70), PORT_DATA_IO_PU_PD(71),
+ PORT_DATA_IO_PU_PD(72), PORT_DATA_IO_PU_PD(73),
+ PORT_DATA_IO_PU_PD(74), PORT_DATA_IO_PU_PD(75),
+ PORT_DATA_IO_PU_PD(76), PORT_DATA_IO_PU_PD(77),
+ PORT_DATA_IO_PU_PD(78), PORT_DATA_IO_PU_PD(79),
+
+ PORT_DATA_IO_PU_PD(80), PORT_DATA_IO_PU_PD(81),
+ PORT_DATA_IO(82), PORT_DATA_IO_PU_PD(83),
+ PORT_DATA_IO(84), PORT_DATA_IO_PD(85),
+ PORT_DATA_IO_PD(86), PORT_DATA_IO_PD(87),
+ PORT_DATA_IO_PD(88), PORT_DATA_IO_PD(89),
+
+ PORT_DATA_IO_PD(90), PORT_DATA_IO_PU_PD(91),
+ PORT_DATA_IO_PU_PD(92), PORT_DATA_IO_PU_PD(93),
+ PORT_DATA_IO_PU_PD(94), PORT_DATA_IO_PU_PD(95),
+ PORT_DATA_IO_PU_PD(96), PORT_DATA_IO_PU_PD(97),
+ PORT_DATA_IO_PU_PD(98), PORT_DATA_IO_PU_PD(99),
+
+ PORT_DATA_IO_PU_PD(100), PORT_DATA_IO(101),
+ PORT_DATA_IO_PU(102), PORT_DATA_IO_PU_PD(103),
+ PORT_DATA_IO_PU(104), PORT_DATA_IO_PU(105),
+ PORT_DATA_IO_PU_PD(106), PORT_DATA_IO(107),
+ PORT_DATA_IO(108), PORT_DATA_IO(109),
+
+ PORT_DATA_IO(110), PORT_DATA_IO(111),
+ PORT_DATA_IO(112), PORT_DATA_IO(113),
+ PORT_DATA_IO_PU_PD(114), PORT_DATA_IO(115),
+ PORT_DATA_IO_PD(116), PORT_DATA_IO_PD(117),
+ PORT_DATA_IO_PD(118), PORT_DATA_IO_PD(119),
+
+ PORT_DATA_IO_PD(120), PORT_DATA_IO_PD(121),
+ PORT_DATA_IO_PD(122), PORT_DATA_IO_PD(123),
+ PORT_DATA_IO_PD(124), PORT_DATA_IO(125),
+ PORT_DATA_IO(126), PORT_DATA_IO(127),
+ PORT_DATA_IO(128), PORT_DATA_IO(129),
+
+ PORT_DATA_IO(130), PORT_DATA_IO(131),
+ PORT_DATA_IO(132), PORT_DATA_IO(133),
+ PORT_DATA_IO(134), PORT_DATA_IO(135),
+ PORT_DATA_IO(136), PORT_DATA_IO(137),
+ PORT_DATA_IO(138), PORT_DATA_IO(139),
+
+ PORT_DATA_IO(140), PORT_DATA_IO(141),
+ PORT_DATA_IO_PU(142), PORT_DATA_IO_PU(143),
+ PORT_DATA_IO_PU(144), PORT_DATA_IO_PU(145),
+ PORT_DATA_IO_PU(146), PORT_DATA_IO_PU(147),
+ PORT_DATA_IO_PU(148), PORT_DATA_IO_PU(149),
+
+ PORT_DATA_IO_PU(150), PORT_DATA_IO_PU(151),
+ PORT_DATA_IO_PU(152), PORT_DATA_IO_PU(153),
+ PORT_DATA_IO_PU(154), PORT_DATA_IO_PU(155),
+ PORT_DATA_IO_PU(156), PORT_DATA_IO_PU(157),
+ PORT_DATA_IO_PD(158), PORT_DATA_IO_PD(159),
+
+ PORT_DATA_IO_PU_PD(160), PORT_DATA_IO_PD(161),
+ PORT_DATA_IO_PD(162), PORT_DATA_IO_PD(163),
+ PORT_DATA_IO_PD(164), PORT_DATA_IO_PD(165),
+ PORT_DATA_IO_PU(166), PORT_DATA_IO_PU(167),
+ PORT_DATA_IO_PU(168), PORT_DATA_IO_PU(169),
+
+ PORT_DATA_IO_PU(170), PORT_DATA_IO_PU(171),
+ PORT_DATA_IO_PD(172), PORT_DATA_IO_PD(173),
+ PORT_DATA_IO_PD(174), PORT_DATA_IO_PD(175),
+ PORT_DATA_IO_PU(176), PORT_DATA_IO_PU_PD(177),
+ PORT_DATA_IO_PU(178), PORT_DATA_IO_PD(179),
+
+ PORT_DATA_IO_PD(180), PORT_DATA_IO_PU(181),
+ PORT_DATA_IO_PU(182), PORT_DATA_IO(183),
+ PORT_DATA_IO_PD(184), PORT_DATA_IO_PD(185),
+ PORT_DATA_IO_PD(186), PORT_DATA_IO_PD(187),
+ PORT_DATA_IO_PD(188), PORT_DATA_IO_PD(189),
+
+ PORT_DATA_IO_PD(190), PORT_DATA_IO_PD(191),
+ PORT_DATA_IO_PD(192), PORT_DATA_IO_PU_PD(193),
+ PORT_DATA_IO_PU_PD(194), PORT_DATA_IO_PD(195),
+ PORT_DATA_IO_PU_PD(196), PORT_DATA_IO_PD(197),
+ PORT_DATA_IO_PU_PD(198), PORT_DATA_IO_PU_PD(199),
+
+ PORT_DATA_IO_PU_PD(200), PORT_DATA_IO_PU(201),
+ PORT_DATA_IO_PU_PD(202), PORT_DATA_IO(203),
+ PORT_DATA_IO_PU_PD(204), PORT_DATA_IO_PU_PD(205),
+ PORT_DATA_IO_PU_PD(206), PORT_DATA_IO_PU_PD(207),
+ PORT_DATA_IO_PU_PD(208), PORT_DATA_IO_PD(209),
+
+ PORT_DATA_IO_PD(210), PORT_DATA_IO_PD(211),
+
+ /* Port0 */
+ PINMUX_DATA(DBGMDT2_MARK, PORT0_FN1),
+ PINMUX_DATA(FSIAISLD_PORT0_MARK, PORT0_FN2, MSEL5CR_3_0),
+ PINMUX_DATA(FSIAOSLD1_MARK, PORT0_FN3),
+ PINMUX_DATA(LCD0_D22_PORT0_MARK, PORT0_FN4, MSEL5CR_6_0),
+ PINMUX_DATA(SCIFA7_RXD_MARK, PORT0_FN6),
+ PINMUX_DATA(LCD1_D4_MARK, PORT0_FN7),
+ PINMUX_DATA(IRQ5_PORT0_MARK, PORT0_FN0, MSEL1CR_5_0),
+
+ /* Port1 */
+ PINMUX_DATA(DBGMDT1_MARK, PORT1_FN1),
+ PINMUX_DATA(FMSISLD_PORT1_MARK, PORT1_FN2, MSEL5CR_5_0),
+ PINMUX_DATA(FSIAOSLD2_MARK, PORT1_FN3),
+ PINMUX_DATA(LCD0_D23_PORT1_MARK, PORT1_FN4, MSEL5CR_6_0),
+ PINMUX_DATA(SCIFA7_TXD_MARK, PORT1_FN6),
+ PINMUX_DATA(LCD1_D3_MARK, PORT1_FN7),
+ PINMUX_DATA(IRQ5_PORT1_MARK, PORT1_FN0, MSEL1CR_5_1),
+
+ /* Port2 */
+ PINMUX_DATA(DBGMDT0_MARK, PORT2_FN1),
+ PINMUX_DATA(SCIFB_SCK_PORT2_MARK, PORT2_FN2, MSEL5CR_17_1),
+ PINMUX_DATA(LCD0_D21_PORT2_MARK, PORT2_FN4, MSEL5CR_6_0),
+ PINMUX_DATA(LCD1_D2_MARK, PORT2_FN7),
+ PINMUX_DATA(IRQ0_PORT2_MARK, PORT2_FN0, MSEL1CR_0_1),
+
+ /* Port3 */
+ PINMUX_DATA(DBGMD21_MARK, PORT3_FN1),
+ PINMUX_DATA(SCIFB_RXD_PORT3_MARK, PORT3_FN2, MSEL5CR_17_1),
+ PINMUX_DATA(LCD0_D20_PORT3_MARK, PORT3_FN4, MSEL5CR_6_0),
+ PINMUX_DATA(LCD1_D1_MARK, PORT3_FN7),
+
+ /* Port4 */
+ PINMUX_DATA(DBGMD20_MARK, PORT4_FN1),
+ PINMUX_DATA(SCIFB_TXD_PORT4_MARK, PORT4_FN2, MSEL5CR_17_1),
+ PINMUX_DATA(LCD0_D19_PORT4_MARK, PORT4_FN4, MSEL5CR_6_0),
+ PINMUX_DATA(LCD1_D0_MARK, PORT4_FN7),
+
+ /* Port5 */
+ PINMUX_DATA(DBGMD11_MARK, PORT5_FN1),
+ PINMUX_DATA(BBIF2_TXD2_PORT5_MARK, PORT5_FN2, MSEL5CR_0_0),
+ PINMUX_DATA(FSIAISLD_PORT5_MARK, PORT5_FN4, MSEL5CR_3_1),
+ PINMUX_DATA(RSPI_SSL0_A_MARK, PORT5_FN6),
+ PINMUX_DATA(LCD1_VCPWC_MARK, PORT5_FN7),
+
+ /* Port6 */
+ PINMUX_DATA(DBGMD10_MARK, PORT6_FN1),
+ PINMUX_DATA(BBIF2_TSYNC2_PORT6_MARK, PORT6_FN2, MSEL5CR_0_0),
+ PINMUX_DATA(FMSISLD_PORT6_MARK, PORT6_FN4, MSEL5CR_5_1),
+ PINMUX_DATA(RSPI_SSL1_A_MARK, PORT6_FN6),
+ PINMUX_DATA(LCD1_VEPWC_MARK, PORT6_FN7),
+
+ /* Port7 */
+ PINMUX_DATA(FSIAOLR_MARK, PORT7_FN1),
+
+ /* Port8 */
+ PINMUX_DATA(FSIAOBT_MARK, PORT8_FN1),
+
+ /* Port9 */
+ PINMUX_DATA(FSIAOSLD_MARK, PORT9_FN1),
+ PINMUX_DATA(FSIASPDIF_PORT9_MARK, PORT9_FN2, MSEL5CR_4_0),
+
+ /* Port10 */
+ PINMUX_DATA(FSIAOMC_MARK, PORT10_FN1),
+ PINMUX_DATA(SCIFA5_RXD_PORT10_MARK, PORT10_FN3, MSEL5CR_14_0, MSEL5CR_15_0),
+ PINMUX_DATA(IRQ3_PORT10_MARK, PORT10_FN0, MSEL1CR_3_0),
+
+ /* Port11 */
+ PINMUX_DATA(FSIACK_MARK, PORT11_FN1),
+ PINMUX_DATA(IRQ2_PORT11_MARK, PORT11_FN0, MSEL1CR_2_0),
+
+ /* Port12 */
+ PINMUX_DATA(FSIAILR_MARK, PORT12_FN1),
+ PINMUX_DATA(SCIFA4_RXD_PORT12_MARK, PORT12_FN2, MSEL5CR_12_0, MSEL5CR_11_0),
+ PINMUX_DATA(LCD1_RS_MARK, PORT12_FN6),
+ PINMUX_DATA(LCD1_DISP_MARK, PORT12_FN7),
+ PINMUX_DATA(IRQ2_PORT12_MARK, PORT12_FN0, MSEL1CR_2_1),
+
+ /* Port13 */
+ PINMUX_DATA(FSIAIBT_MARK, PORT13_FN1),
+ PINMUX_DATA(SCIFA4_TXD_PORT13_MARK, PORT13_FN2, MSEL5CR_12_0, MSEL5CR_11_0),
+ PINMUX_DATA(LCD1_RD_MARK, PORT13_FN7),
+ PINMUX_DATA(IRQ0_PORT13_MARK, PORT13_FN0, MSEL1CR_0_0),
+
+ /* Port14 */
+ PINMUX_DATA(FMSOILR_MARK, PORT14_FN1),
+ PINMUX_DATA(FMSIILR_MARK, PORT14_FN2),
+ PINMUX_DATA(VIO_CKO1_MARK, PORT14_FN3),
+ PINMUX_DATA(LCD1_D23_MARK, PORT14_FN7),
+ PINMUX_DATA(IRQ3_PORT14_MARK, PORT14_FN0, MSEL1CR_3_1),
+
+ /* Port15 */
+ PINMUX_DATA(FMSOIBT_MARK, PORT15_FN1),
+ PINMUX_DATA(FMSIIBT_MARK, PORT15_FN2),
+ PINMUX_DATA(VIO_CKO2_MARK, PORT15_FN3),
+ PINMUX_DATA(LCD1_D22_MARK, PORT15_FN7),
+ PINMUX_DATA(IRQ4_PORT15_MARK, PORT15_FN0, MSEL1CR_4_0),
+
+ /* Port16 */
+ PINMUX_DATA(FMSOOLR_MARK, PORT16_FN1),
+ PINMUX_DATA(FMSIOLR_MARK, PORT16_FN2),
+
+ /* Port17 */
+ PINMUX_DATA(FMSOOBT_MARK, PORT17_FN1),
+ PINMUX_DATA(FMSIOBT_MARK, PORT17_FN2),
+
+ /* Port18 */
+ PINMUX_DATA(FMSOSLD_MARK, PORT18_FN1),
+ PINMUX_DATA(FSIASPDIF_PORT18_MARK, PORT18_FN2, MSEL5CR_4_1),
+
+ /* Port19 */
+ PINMUX_DATA(FMSICK_MARK, PORT19_FN1),
+ PINMUX_DATA(CS5A_PORT19_MARK, PORT19_FN7, MSEL5CR_2_1),
+ PINMUX_DATA(IRQ10_MARK, PORT19_FN0),
+
+ /* Port20 */
+ PINMUX_DATA(FMSOCK_MARK, PORT20_FN1),
+ PINMUX_DATA(SCIFA5_TXD_PORT20_MARK, PORT20_FN3, MSEL5CR_15_0, MSEL5CR_14_0),
+ PINMUX_DATA(IRQ1_MARK, PORT20_FN0),
+
+ /* Port21 */
+ PINMUX_DATA(SCIFA1_CTS_MARK, PORT21_FN1),
+ PINMUX_DATA(SCIFA4_SCK_PORT21_MARK, PORT21_FN2, MSEL5CR_10_0),
+ PINMUX_DATA(TPU0TO1_MARK, PORT21_FN4),
+ PINMUX_DATA(VIO1_FIELD_MARK, PORT21_FN5),
+ PINMUX_DATA(STP0_IPD5_MARK, PORT21_FN6),
+ PINMUX_DATA(LCD1_D10_MARK, PORT21_FN7),
+
+ /* Port22 */
+ PINMUX_DATA(SCIFA2_SCK_PORT22_MARK, PORT22_FN1, MSEL5CR_7_0),
+ PINMUX_DATA(SIM_D_PORT22_MARK, PORT22_FN4, MSEL5CR_21_0),
+ PINMUX_DATA(VIO0_D13_PORT22_MARK, PORT22_FN7, MSEL5CR_27_1),
+
+ /* Port23 */
+ PINMUX_DATA(SCIFA1_RTS_MARK, PORT23_FN1),
+ PINMUX_DATA(SCIFA5_SCK_PORT23_MARK, PORT23_FN3, MSEL5CR_13_0),
+ PINMUX_DATA(TPU0TO0_MARK, PORT23_FN4),
+ PINMUX_DATA(VIO_CKO_1_MARK, PORT23_FN5),
+ PINMUX_DATA(STP0_IPD2_MARK, PORT23_FN6),
+ PINMUX_DATA(LCD1_D7_MARK, PORT23_FN7),
+
+ /* Port24 */
+ PINMUX_DATA(VIO0_D15_PORT24_MARK, PORT24_FN1, MSEL5CR_27_0),
+ PINMUX_DATA(VIO1_D7_MARK, PORT24_FN5),
+ PINMUX_DATA(SCIFA6_SCK_MARK, PORT24_FN6),
+ PINMUX_DATA(SDHI2_CD_PORT24_MARK, PORT24_FN7, MSEL5CR_19_0),
+
+ /* Port25 */
+ PINMUX_DATA(VIO0_D14_PORT25_MARK, PORT25_FN1, MSEL5CR_27_0),
+ PINMUX_DATA(VIO1_D6_MARK, PORT25_FN5),
+ PINMUX_DATA(SCIFA6_RXD_MARK, PORT25_FN6),
+ PINMUX_DATA(SDHI2_WP_PORT25_MARK, PORT25_FN7, MSEL5CR_19_0),
+
+ /* Port26 */
+ PINMUX_DATA(VIO0_D13_PORT26_MARK, PORT26_FN1, MSEL5CR_27_0),
+ PINMUX_DATA(VIO1_D5_MARK, PORT26_FN5),
+ PINMUX_DATA(SCIFA6_TXD_MARK, PORT26_FN6),
+
+ /* Port27 - Port39 Function */
+ PINMUX_DATA(VIO0_D7_MARK, PORT27_FN1),
+ PINMUX_DATA(VIO0_D6_MARK, PORT28_FN1),
+ PINMUX_DATA(VIO0_D5_MARK, PORT29_FN1),
+ PINMUX_DATA(VIO0_D4_MARK, PORT30_FN1),
+ PINMUX_DATA(VIO0_D3_MARK, PORT31_FN1),
+ PINMUX_DATA(VIO0_D2_MARK, PORT32_FN1),
+ PINMUX_DATA(VIO0_D1_MARK, PORT33_FN1),
+ PINMUX_DATA(VIO0_D0_MARK, PORT34_FN1),
+ PINMUX_DATA(VIO0_CLK_MARK, PORT35_FN1),
+ PINMUX_DATA(VIO_CKO_MARK, PORT36_FN1),
+ PINMUX_DATA(VIO0_HD_MARK, PORT37_FN1),
+ PINMUX_DATA(VIO0_FIELD_MARK, PORT38_FN1),
+ PINMUX_DATA(VIO0_VD_MARK, PORT39_FN1),
+
+ /* Port38 IRQ */
+ PINMUX_DATA(IRQ25_MARK, PORT38_FN0),
+
+ /* Port40 */
+ PINMUX_DATA(LCD0_D18_PORT40_MARK, PORT40_FN4, MSEL5CR_6_0),
+ PINMUX_DATA(RSPI_CK_A_MARK, PORT40_FN6),
+ PINMUX_DATA(LCD1_LCLK_MARK, PORT40_FN7),
+
+ /* Port41 */
+ PINMUX_DATA(LCD0_D17_MARK, PORT41_FN1),
+ PINMUX_DATA(MSIOF2_SS1_MARK, PORT41_FN2),
+ PINMUX_DATA(IRQ31_PORT41_MARK, PORT41_FN0, MSEL1CR_31_1),
+
+ /* Port42 */
+ PINMUX_DATA(LCD0_D16_MARK, PORT42_FN1),
+ PINMUX_DATA(MSIOF2_MCK1_MARK, PORT42_FN2),
+ PINMUX_DATA(IRQ12_PORT42_MARK, PORT42_FN0, MSEL1CR_12_1),
+
+ /* Port43 */
+ PINMUX_DATA(LCD0_D15_MARK, PORT43_FN1),
+ PINMUX_DATA(MSIOF2_MCK0_MARK, PORT43_FN2),
+ PINMUX_DATA(KEYIN0_PORT43_MARK, PORT43_FN3, MSEL4CR_18_0),
+ PINMUX_DATA(DV_D15_MARK, PORT43_FN6),
+
+ /* Port44 */
+ PINMUX_DATA(LCD0_D14_MARK, PORT44_FN1),
+ PINMUX_DATA(MSIOF2_RSYNC_MARK, PORT44_FN2),
+ PINMUX_DATA(KEYIN1_PORT44_MARK, PORT44_FN3, MSEL4CR_18_0),
+ PINMUX_DATA(DV_D14_MARK, PORT44_FN6),
+
+ /* Port45 */
+ PINMUX_DATA(LCD0_D13_MARK, PORT45_FN1),
+ PINMUX_DATA(MSIOF2_RSCK_MARK, PORT45_FN2),
+ PINMUX_DATA(KEYIN2_PORT45_MARK, PORT45_FN3, MSEL4CR_18_0),
+ PINMUX_DATA(DV_D13_MARK, PORT45_FN6),
+
+ /* Port46 */
+ PINMUX_DATA(LCD0_D12_MARK, PORT46_FN1),
+ PINMUX_DATA(KEYIN3_PORT46_MARK, PORT46_FN3, MSEL4CR_18_0),
+ PINMUX_DATA(DV_D12_MARK, PORT46_FN6),
+
+ /* Port47 */
+ PINMUX_DATA(LCD0_D11_MARK, PORT47_FN1),
+ PINMUX_DATA(KEYIN4_MARK, PORT47_FN3),
+ PINMUX_DATA(DV_D11_MARK, PORT47_FN6),
+
+ /* Port48 */
+ PINMUX_DATA(LCD0_D10_MARK, PORT48_FN1),
+ PINMUX_DATA(KEYIN5_MARK, PORT48_FN3),
+ PINMUX_DATA(DV_D10_MARK, PORT48_FN6),
+
+ /* Port49 */
+ PINMUX_DATA(LCD0_D9_MARK, PORT49_FN1),
+ PINMUX_DATA(KEYIN6_MARK, PORT49_FN3),
+ PINMUX_DATA(DV_D9_MARK, PORT49_FN6),
+ PINMUX_DATA(IRQ30_PORT49_MARK, PORT49_FN0, MSEL1CR_30_1),
+
+ /* Port50 */
+ PINMUX_DATA(LCD0_D8_MARK, PORT50_FN1),
+ PINMUX_DATA(KEYIN7_MARK, PORT50_FN3),
+ PINMUX_DATA(DV_D8_MARK, PORT50_FN6),
+ PINMUX_DATA(IRQ29_PORT50_MARK, PORT50_FN0, MSEL1CR_29_1),
+
+ /* Port51 */
+ PINMUX_DATA(LCD0_D7_MARK, PORT51_FN1),
+ PINMUX_DATA(KEYOUT0_MARK, PORT51_FN3),
+ PINMUX_DATA(DV_D7_MARK, PORT51_FN6),
+
+ /* Port52 */
+ PINMUX_DATA(LCD0_D6_MARK, PORT52_FN1),
+ PINMUX_DATA(KEYOUT1_MARK, PORT52_FN3),
+ PINMUX_DATA(DV_D6_MARK, PORT52_FN6),
+
+ /* Port53 */
+ PINMUX_DATA(LCD0_D5_MARK, PORT53_FN1),
+ PINMUX_DATA(KEYOUT2_MARK, PORT53_FN3),
+ PINMUX_DATA(DV_D5_MARK, PORT53_FN6),
+
+ /* Port54 */
+ PINMUX_DATA(LCD0_D4_MARK, PORT54_FN1),
+ PINMUX_DATA(KEYOUT3_MARK, PORT54_FN3),
+ PINMUX_DATA(DV_D4_MARK, PORT54_FN6),
+
+ /* Port55 */
+ PINMUX_DATA(LCD0_D3_MARK, PORT55_FN1),
+ PINMUX_DATA(KEYOUT4_MARK, PORT55_FN3),
+ PINMUX_DATA(KEYIN3_PORT55_MARK, PORT55_FN4, MSEL4CR_18_1),
+ PINMUX_DATA(DV_D3_MARK, PORT55_FN6),
+
+ /* Port56 */
+ PINMUX_DATA(LCD0_D2_MARK, PORT56_FN1),
+ PINMUX_DATA(KEYOUT5_MARK, PORT56_FN3),
+ PINMUX_DATA(KEYIN2_PORT56_MARK, PORT56_FN4, MSEL4CR_18_1),
+ PINMUX_DATA(DV_D2_MARK, PORT56_FN6),
+ PINMUX_DATA(IRQ28_PORT56_MARK, PORT56_FN0, MSEL1CR_28_1),
+
+ /* Port57 */
+ PINMUX_DATA(LCD0_D1_MARK, PORT57_FN1),
+ PINMUX_DATA(KEYOUT6_MARK, PORT57_FN3),
+ PINMUX_DATA(KEYIN1_PORT57_MARK, PORT57_FN4, MSEL4CR_18_1),
+ PINMUX_DATA(DV_D1_MARK, PORT57_FN6),
+ PINMUX_DATA(IRQ27_PORT57_MARK, PORT57_FN0, MSEL1CR_27_1),
+
+ /* Port58 */
+ PINMUX_DATA(LCD0_D0_MARK, PORT58_FN1),
+ PINMUX_DATA(KEYOUT7_MARK, PORT58_FN3),
+ PINMUX_DATA(KEYIN0_PORT58_MARK, PORT58_FN4, MSEL4CR_18_1),
+ PINMUX_DATA(DV_D0_MARK, PORT58_FN6),
+ PINMUX_DATA(IRQ26_PORT58_MARK, PORT58_FN0, MSEL1CR_26_1),
+
+ /* Port59 */
+ PINMUX_DATA(LCD0_VCPWC_MARK, PORT59_FN1),
+ PINMUX_DATA(BBIF2_TSCK2_PORT59_MARK, PORT59_FN2, MSEL5CR_0_0),
+ PINMUX_DATA(RSPI_MOSI_A_MARK, PORT59_FN6),
+
+ /* Port60 */
+ PINMUX_DATA(LCD0_VEPWC_MARK, PORT60_FN1),
+ PINMUX_DATA(BBIF2_RXD2_PORT60_MARK, PORT60_FN2, MSEL5CR_0_0),
+ PINMUX_DATA(RSPI_MISO_A_MARK, PORT60_FN6),
+
+ /* Port61 */
+ PINMUX_DATA(LCD0_DON_MARK, PORT61_FN1),
+ PINMUX_DATA(MSIOF2_TXD_MARK, PORT61_FN2),
+
+ /* Port62 */
+ PINMUX_DATA(LCD0_DCK_MARK, PORT62_FN1),
+ PINMUX_DATA(LCD0_WR_MARK, PORT62_FN4),
+ PINMUX_DATA(DV_CLK_MARK, PORT62_FN6),
+ PINMUX_DATA(IRQ15_PORT62_MARK, PORT62_FN0, MSEL1CR_15_1),
+
+ /* Port63 */
+ PINMUX_DATA(LCD0_VSYN_MARK, PORT63_FN1),
+ PINMUX_DATA(DV_VSYNC_MARK, PORT63_FN6),
+ PINMUX_DATA(IRQ14_PORT63_MARK, PORT63_FN0, MSEL1CR_14_1),
+
+ /* Port64 */
+ PINMUX_DATA(LCD0_HSYN_MARK, PORT64_FN1),
+ PINMUX_DATA(LCD0_CS_MARK, PORT64_FN4),
+ PINMUX_DATA(DV_HSYNC_MARK, PORT64_FN6),
+ PINMUX_DATA(IRQ13_PORT64_MARK, PORT64_FN0, MSEL1CR_13_1),
+
+ /* Port65 */
+ PINMUX_DATA(LCD0_DISP_MARK, PORT65_FN1),
+ PINMUX_DATA(MSIOF2_TSCK_MARK, PORT65_FN2),
+ PINMUX_DATA(LCD0_RS_MARK, PORT65_FN4),
+
+ /* Port66 */
+ PINMUX_DATA(MEMC_INT_MARK, PORT66_FN1),
+ PINMUX_DATA(TPU0TO2_PORT66_MARK, PORT66_FN3, MSEL5CR_25_0),
+ PINMUX_DATA(MMC0_CLK_PORT66_MARK, PORT66_FN4, MSEL4CR_15_0),
+ PINMUX_DATA(SDHI1_CLK_MARK, PORT66_FN6),
+
+ /* Port67 - Port73 Function1 */
+ PINMUX_DATA(MEMC_CS0_MARK, PORT67_FN1),
+ PINMUX_DATA(MEMC_AD8_MARK, PORT68_FN1),
+ PINMUX_DATA(MEMC_AD9_MARK, PORT69_FN1),
+ PINMUX_DATA(MEMC_AD10_MARK, PORT70_FN1),
+ PINMUX_DATA(MEMC_AD11_MARK, PORT71_FN1),
+ PINMUX_DATA(MEMC_AD12_MARK, PORT72_FN1),
+ PINMUX_DATA(MEMC_AD13_MARK, PORT73_FN1),
+
+ /* Port67 - Port73 Function2 */
+ PINMUX_DATA(MSIOF1_SS1_PORT67_MARK, PORT67_FN2, MSEL4CR_10_1),
+ PINMUX_DATA(MSIOF1_RSCK_MARK, PORT68_FN2),
+ PINMUX_DATA(MSIOF1_RSYNC_MARK, PORT69_FN2),
+ PINMUX_DATA(MSIOF1_MCK0_MARK, PORT70_FN2),
+ PINMUX_DATA(MSIOF1_MCK1_MARK, PORT71_FN2),
+ PINMUX_DATA(MSIOF1_TSCK_PORT72_MARK, PORT72_FN2, MSEL4CR_10_1),
+ PINMUX_DATA(MSIOF1_TSYNC_PORT73_MARK, PORT73_FN2, MSEL4CR_10_1),
+
+ /* Port67 - Port73 Function4 */
+ PINMUX_DATA(MMC0_CMD_PORT67_MARK, PORT67_FN4, MSEL4CR_15_0),
+ PINMUX_DATA(MMC0_D0_PORT68_MARK, PORT68_FN4, MSEL4CR_15_0),
+ PINMUX_DATA(MMC0_D1_PORT69_MARK, PORT69_FN4, MSEL4CR_15_0),
+ PINMUX_DATA(MMC0_D2_PORT70_MARK, PORT70_FN4, MSEL4CR_15_0),
+ PINMUX_DATA(MMC0_D3_PORT71_MARK, PORT71_FN4, MSEL4CR_15_0),
+ PINMUX_DATA(MMC0_D4_PORT72_MARK, PORT72_FN4, MSEL4CR_15_0),
+ PINMUX_DATA(MMC0_D5_PORT73_MARK, PORT73_FN4, MSEL4CR_15_0),
+
+ /* Port67 - Port73 Function6 */
+ PINMUX_DATA(SDHI1_CMD_MARK, PORT67_FN6),
+ PINMUX_DATA(SDHI1_D0_MARK, PORT68_FN6),
+ PINMUX_DATA(SDHI1_D1_MARK, PORT69_FN6),
+ PINMUX_DATA(SDHI1_D2_MARK, PORT70_FN6),
+ PINMUX_DATA(SDHI1_D3_MARK, PORT71_FN6),
+ PINMUX_DATA(SDHI1_CD_MARK, PORT72_FN6),
+ PINMUX_DATA(SDHI1_WP_MARK, PORT73_FN6),
+
+ /* Port67 - Port71 IRQ */
+ PINMUX_DATA(IRQ20_MARK, PORT67_FN0),
+ PINMUX_DATA(IRQ16_PORT68_MARK, PORT68_FN0, MSEL1CR_16_0),
+ PINMUX_DATA(IRQ17_MARK, PORT69_FN0),
+ PINMUX_DATA(IRQ18_MARK, PORT70_FN0),
+ PINMUX_DATA(IRQ19_MARK, PORT71_FN0),
+
+ /* Port74 */
+ PINMUX_DATA(MEMC_AD14_MARK, PORT74_FN1),
+ PINMUX_DATA(MSIOF1_TXD_PORT74_MARK, PORT74_FN2, MSEL4CR_10_1),
+ PINMUX_DATA(MMC0_D6_PORT74_MARK, PORT74_FN4, MSEL4CR_15_0),
+ PINMUX_DATA(STP1_IPD7_MARK, PORT74_FN6),
+ PINMUX_DATA(LCD1_D21_MARK, PORT74_FN7),
+
+ /* Port75 */
+ PINMUX_DATA(MEMC_AD15_MARK, PORT75_FN1),
+ PINMUX_DATA(MSIOF1_RXD_PORT75_MARK, PORT75_FN2, MSEL4CR_10_1),
+ PINMUX_DATA(MMC0_D7_PORT75_MARK, PORT75_FN4, MSEL4CR_15_0),
+ PINMUX_DATA(STP1_IPD6_MARK, PORT75_FN6),
+ PINMUX_DATA(LCD1_D20_MARK, PORT75_FN7),
+
+ /* Port76 - Port80 Function */
+ PINMUX_DATA(SDHI0_CMD_MARK, PORT76_FN1),
+ PINMUX_DATA(SDHI0_D0_MARK, PORT77_FN1),
+ PINMUX_DATA(SDHI0_D1_MARK, PORT78_FN1),
+ PINMUX_DATA(SDHI0_D2_MARK, PORT79_FN1),
+ PINMUX_DATA(SDHI0_D3_MARK, PORT80_FN1),
+
+ /* Port81 */
+ PINMUX_DATA(SDHI0_CD_MARK, PORT81_FN1),
+ PINMUX_DATA(IRQ26_PORT81_MARK, PORT81_FN0, MSEL1CR_26_0),
+
+ /* Port82 - Port88 Function */
+ PINMUX_DATA(SDHI0_CLK_MARK, PORT82_FN1),
+ PINMUX_DATA(SDHI0_WP_MARK, PORT83_FN1),
+ PINMUX_DATA(RESETOUTS_MARK, PORT84_FN1),
+ PINMUX_DATA(USB0_PPON_MARK, PORT85_FN1),
+ PINMUX_DATA(USB0_OCI_MARK, PORT86_FN1),
+ PINMUX_DATA(USB1_PPON_MARK, PORT87_FN1),
+ PINMUX_DATA(USB1_OCI_MARK, PORT88_FN1),
+
+ /* Port89 */
+ PINMUX_DATA(DREQ0_MARK, PORT89_FN1),
+ PINMUX_DATA(BBIF2_TSCK2_PORT89_MARK, PORT89_FN2, MSEL5CR_0_1),
+ PINMUX_DATA(RSPI_SSL3_A_MARK, PORT89_FN6),
+
+ /* Port90 */
+ PINMUX_DATA(DACK0_MARK, PORT90_FN1),
+ PINMUX_DATA(BBIF2_RXD2_PORT90_MARK, PORT90_FN2, MSEL5CR_0_1),
+ PINMUX_DATA(RSPI_SSL2_A_MARK, PORT90_FN6),
+ PINMUX_DATA(WAIT_PORT90_MARK, PORT90_FN7, MSEL5CR_2_1),
+
+ /* Port91 */
+ PINMUX_DATA(MEMC_AD0_MARK, PORT91_FN1),
+ PINMUX_DATA(BBIF1_RXD_MARK, PORT91_FN2),
+ PINMUX_DATA(SCIFA5_TXD_PORT91_MARK, PORT91_FN3, MSEL5CR_15_1, MSEL5CR_14_0),
+ PINMUX_DATA(LCD1_D5_MARK, PORT91_FN7),
+
+ /* Port92 */
+ PINMUX_DATA(MEMC_AD1_MARK, PORT92_FN1),
+ PINMUX_DATA(BBIF1_TSYNC_MARK, PORT92_FN2),
+ PINMUX_DATA(SCIFA5_RXD_PORT92_MARK, PORT92_FN3, MSEL5CR_15_1, MSEL5CR_14_0),
+ PINMUX_DATA(STP0_IPD1_MARK, PORT92_FN6),
+ PINMUX_DATA(LCD1_D6_MARK, PORT92_FN7),
+
+ /* Port93 */
+ PINMUX_DATA(MEMC_AD2_MARK, PORT93_FN1),
+ PINMUX_DATA(BBIF1_TSCK_MARK, PORT93_FN2),
+ PINMUX_DATA(SCIFA4_TXD_PORT93_MARK, PORT93_FN3, MSEL5CR_12_1, MSEL5CR_11_0),
+ PINMUX_DATA(STP0_IPD3_MARK, PORT93_FN6),
+ PINMUX_DATA(LCD1_D8_MARK, PORT93_FN7),
+
+ /* Port94 */
+ PINMUX_DATA(MEMC_AD3_MARK, PORT94_FN1),
+ PINMUX_DATA(BBIF1_TXD_MARK, PORT94_FN2),
+ PINMUX_DATA(SCIFA4_RXD_PORT94_MARK, PORT94_FN3, MSEL5CR_12_1, MSEL5CR_11_0),
+ PINMUX_DATA(STP0_IPD4_MARK, PORT94_FN6),
+ PINMUX_DATA(LCD1_D9_MARK, PORT94_FN7),
+
+ /* Port95 */
+ PINMUX_DATA(MEMC_CS1_MARK, PORT95_FN1, MSEL4CR_6_0),
+ PINMUX_DATA(MEMC_A1_MARK, PORT95_FN1, MSEL4CR_6_1),
+
+ PINMUX_DATA(SCIFA2_CTS_MARK, PORT95_FN2),
+ PINMUX_DATA(SIM_RST_MARK, PORT95_FN4),
+ PINMUX_DATA(VIO0_D14_PORT95_MARK, PORT95_FN7, MSEL5CR_27_1),
+ PINMUX_DATA(IRQ22_MARK, PORT95_FN0),
+
+ /* Port96 */
+ PINMUX_DATA(MEMC_ADV_MARK, PORT96_FN1, MSEL4CR_6_0),
+ PINMUX_DATA(MEMC_DREQ0_MARK, PORT96_FN1, MSEL4CR_6_1),
+
+ PINMUX_DATA(SCIFA2_RTS_MARK, PORT96_FN2),
+ PINMUX_DATA(SIM_CLK_MARK, PORT96_FN4),
+ PINMUX_DATA(VIO0_D15_PORT96_MARK, PORT96_FN7, MSEL5CR_27_1),
+ PINMUX_DATA(IRQ23_MARK, PORT96_FN0),
+
+ /* Port97 */
+ PINMUX_DATA(MEMC_AD4_MARK, PORT97_FN1),
+ PINMUX_DATA(BBIF1_RSCK_MARK, PORT97_FN2),
+ PINMUX_DATA(LCD1_CS_MARK, PORT97_FN6),
+ PINMUX_DATA(LCD1_HSYN_MARK, PORT97_FN7),
+ PINMUX_DATA(IRQ12_PORT97_MARK, PORT97_FN0, MSEL1CR_12_0),
+
+ /* Port98 */
+ PINMUX_DATA(MEMC_AD5_MARK, PORT98_FN1),
+ PINMUX_DATA(BBIF1_RSYNC_MARK, PORT98_FN2),
+ PINMUX_DATA(LCD1_VSYN_MARK, PORT98_FN7),
+ PINMUX_DATA(IRQ13_PORT98_MARK, PORT98_FN0, MSEL1CR_13_0),
+
+ /* Port99 */
+ PINMUX_DATA(MEMC_AD6_MARK, PORT99_FN1),
+ PINMUX_DATA(BBIF1_FLOW_MARK, PORT99_FN2),
+ PINMUX_DATA(LCD1_WR_MARK, PORT99_FN6),
+ PINMUX_DATA(LCD1_DCK_MARK, PORT99_FN7),
+ PINMUX_DATA(IRQ14_PORT99_MARK, PORT99_FN0, MSEL1CR_14_0),
+
+ /* Port100 */
+ PINMUX_DATA(MEMC_AD7_MARK, PORT100_FN1),
+ PINMUX_DATA(BBIF1_RX_FLOW_N_MARK, PORT100_FN2),
+ PINMUX_DATA(LCD1_DON_MARK, PORT100_FN7),
+ PINMUX_DATA(IRQ15_PORT100_MARK, PORT100_FN0, MSEL1CR_15_0),
+
+ /* Port101 */
+ PINMUX_DATA(FCE0_MARK, PORT101_FN1),
+
+ /* Port102 */
+ PINMUX_DATA(FRB_MARK, PORT102_FN1),
+ PINMUX_DATA(LCD0_LCLK_PORT102_MARK, PORT102_FN4, MSEL5CR_6_0),
+
+ /* Port103 */
+ PINMUX_DATA(CS5B_MARK, PORT103_FN1),
+ PINMUX_DATA(FCE1_MARK, PORT103_FN2),
+ PINMUX_DATA(MMC1_CLK_PORT103_MARK, PORT103_FN3, MSEL4CR_15_1),
+
+ /* Port104 */
+ PINMUX_DATA(CS6A_MARK, PORT104_FN1),
+ PINMUX_DATA(MMC1_CMD_PORT104_MARK, PORT104_FN3, MSEL4CR_15_1),
+ PINMUX_DATA(IRQ11_MARK, PORT104_FN0),
+
+ /* Port105 */
+ PINMUX_DATA(CS5A_PORT105_MARK, PORT105_FN1, MSEL5CR_2_0),
+ PINMUX_DATA(SCIFA3_RTS_PORT105_MARK, PORT105_FN4, MSEL5CR_8_0),
+
+ /* Port106 */
+ PINMUX_DATA(IOIS16_MARK, PORT106_FN1),
+ PINMUX_DATA(IDE_EXBUF_ENB_MARK, PORT106_FN6),
+
+ /* Port107 - Port115 Function */
+ PINMUX_DATA(WE3_ICIOWR_MARK, PORT107_FN1),
+ PINMUX_DATA(WE2_ICIORD_MARK, PORT108_FN1),
+ PINMUX_DATA(CS0_MARK, PORT109_FN1),
+ PINMUX_DATA(CS2_MARK, PORT110_FN1),
+ PINMUX_DATA(CS4_MARK, PORT111_FN1),
+ PINMUX_DATA(WE1_MARK, PORT112_FN1),
+ PINMUX_DATA(WE0_FWE_MARK, PORT113_FN1),
+ PINMUX_DATA(RDWR_MARK, PORT114_FN1),
+ PINMUX_DATA(RD_FSC_MARK, PORT115_FN1),
+
+ /* Port116 */
+ PINMUX_DATA(A25_MARK, PORT116_FN1),
+ PINMUX_DATA(MSIOF0_SS2_MARK, PORT116_FN2),
+ PINMUX_DATA(MSIOF1_SS2_PORT116_MARK, PORT116_FN3, MSEL4CR_10_0),
+ PINMUX_DATA(SCIFA3_SCK_PORT116_MARK, PORT116_FN4, MSEL5CR_8_0),
+ PINMUX_DATA(GPO1_MARK, PORT116_FN5),
+
+ /* Port117 */
+ PINMUX_DATA(A24_MARK, PORT117_FN1),
+ PINMUX_DATA(MSIOF0_SS1_MARK, PORT117_FN2),
+ PINMUX_DATA(MSIOF1_SS1_PORT117_MARK, PORT117_FN3, MSEL4CR_10_0),
+ PINMUX_DATA(SCIFA3_CTS_PORT117_MARK, PORT117_FN4, MSEL5CR_8_0),
+ PINMUX_DATA(GPO0_MARK, PORT117_FN5),
+
+ /* Port118 */
+ PINMUX_DATA(A23_MARK, PORT118_FN1),
+ PINMUX_DATA(MSIOF0_MCK1_MARK, PORT118_FN2),
+ PINMUX_DATA(MSIOF1_RXD_PORT118_MARK, PORT118_FN3, MSEL4CR_10_0),
+ PINMUX_DATA(GPI1_MARK, PORT118_FN5),
+ PINMUX_DATA(IRQ9_PORT118_MARK, PORT118_FN0, MSEL1CR_9_0),
+
+ /* Port119 */
+ PINMUX_DATA(A22_MARK, PORT119_FN1),
+ PINMUX_DATA(MSIOF0_MCK0_MARK, PORT119_FN2),
+ PINMUX_DATA(MSIOF1_TXD_PORT119_MARK, PORT119_FN3, MSEL4CR_10_0),
+ PINMUX_DATA(GPI0_MARK, PORT119_FN5),
+ PINMUX_DATA(IRQ8_MARK, PORT119_FN0),
+
+ /* Port120 */
+ PINMUX_DATA(A21_MARK, PORT120_FN1),
+ PINMUX_DATA(MSIOF0_RSYNC_MARK, PORT120_FN2),
+ PINMUX_DATA(MSIOF1_TSYNC_PORT120_MARK, PORT120_FN3, MSEL4CR_10_0),
+ PINMUX_DATA(IRQ7_PORT120_MARK, PORT120_FN0, MSEL1CR_7_0),
+
+ /* Port121 */
+ PINMUX_DATA(A20_MARK, PORT121_FN1),
+ PINMUX_DATA(MSIOF0_RSCK_MARK, PORT121_FN2),
+ PINMUX_DATA(MSIOF1_TSCK_PORT121_MARK, PORT121_FN3, MSEL4CR_10_0),
+ PINMUX_DATA(IRQ6_PORT121_MARK, PORT121_FN0, MSEL1CR_6_0),
+
+ /* Port122 */
+ PINMUX_DATA(A19_MARK, PORT122_FN1),
+ PINMUX_DATA(MSIOF0_RXD_MARK, PORT122_FN2),
+
+ /* Port123 */
+ PINMUX_DATA(A18_MARK, PORT123_FN1),
+ PINMUX_DATA(MSIOF0_TSCK_MARK, PORT123_FN2),
+
+ /* Port124 */
+ PINMUX_DATA(A17_MARK, PORT124_FN1),
+ PINMUX_DATA(MSIOF0_TSYNC_MARK, PORT124_FN2),
+
+ /* Port125 - Port141 Function */
+ PINMUX_DATA(A16_MARK, PORT125_FN1),
+ PINMUX_DATA(A15_MARK, PORT126_FN1),
+ PINMUX_DATA(A14_MARK, PORT127_FN1),
+ PINMUX_DATA(A13_MARK, PORT128_FN1),
+ PINMUX_DATA(A12_MARK, PORT129_FN1),
+ PINMUX_DATA(A11_MARK, PORT130_FN1),
+ PINMUX_DATA(A10_MARK, PORT131_FN1),
+ PINMUX_DATA(A9_MARK, PORT132_FN1),
+ PINMUX_DATA(A8_MARK, PORT133_FN1),
+ PINMUX_DATA(A7_MARK, PORT134_FN1),
+ PINMUX_DATA(A6_MARK, PORT135_FN1),
+ PINMUX_DATA(A5_FCDE_MARK, PORT136_FN1),
+ PINMUX_DATA(A4_FOE_MARK, PORT137_FN1),
+ PINMUX_DATA(A3_MARK, PORT138_FN1),
+ PINMUX_DATA(A2_MARK, PORT139_FN1),
+ PINMUX_DATA(A1_MARK, PORT140_FN1),
+ PINMUX_DATA(CKO_MARK, PORT141_FN1),
+
+ /* Port142 - Port157 Function1 */
+ PINMUX_DATA(D15_NAF15_MARK, PORT142_FN1),
+ PINMUX_DATA(D14_NAF14_MARK, PORT143_FN1),
+ PINMUX_DATA(D13_NAF13_MARK, PORT144_FN1),
+ PINMUX_DATA(D12_NAF12_MARK, PORT145_FN1),
+ PINMUX_DATA(D11_NAF11_MARK, PORT146_FN1),
+ PINMUX_DATA(D10_NAF10_MARK, PORT147_FN1),
+ PINMUX_DATA(D9_NAF9_MARK, PORT148_FN1),
+ PINMUX_DATA(D8_NAF8_MARK, PORT149_FN1),
+ PINMUX_DATA(D7_NAF7_MARK, PORT150_FN1),
+ PINMUX_DATA(D6_NAF6_MARK, PORT151_FN1),
+ PINMUX_DATA(D5_NAF5_MARK, PORT152_FN1),
+ PINMUX_DATA(D4_NAF4_MARK, PORT153_FN1),
+ PINMUX_DATA(D3_NAF3_MARK, PORT154_FN1),
+ PINMUX_DATA(D2_NAF2_MARK, PORT155_FN1),
+ PINMUX_DATA(D1_NAF1_MARK, PORT156_FN1),
+ PINMUX_DATA(D0_NAF0_MARK, PORT157_FN1),
+
+ /* Port142 - Port149 Function3 */
+ PINMUX_DATA(MMC1_D7_PORT142_MARK, PORT142_FN3, MSEL4CR_15_1),
+ PINMUX_DATA(MMC1_D6_PORT143_MARK, PORT143_FN3, MSEL4CR_15_1),
+ PINMUX_DATA(MMC1_D5_PORT144_MARK, PORT144_FN3, MSEL4CR_15_1),
+ PINMUX_DATA(MMC1_D4_PORT145_MARK, PORT145_FN3, MSEL4CR_15_1),
+ PINMUX_DATA(MMC1_D3_PORT146_MARK, PORT146_FN3, MSEL4CR_15_1),
+ PINMUX_DATA(MMC1_D2_PORT147_MARK, PORT147_FN3, MSEL4CR_15_1),
+ PINMUX_DATA(MMC1_D1_PORT148_MARK, PORT148_FN3, MSEL4CR_15_1),
+ PINMUX_DATA(MMC1_D0_PORT149_MARK, PORT149_FN3, MSEL4CR_15_1),
+
+ /* Port158 */
+ PINMUX_DATA(D31_MARK, PORT158_FN1),
+ PINMUX_DATA(SCIFA3_SCK_PORT158_MARK, PORT158_FN2, MSEL5CR_8_1),
+ PINMUX_DATA(RMII_REF125CK_MARK, PORT158_FN3),
+ PINMUX_DATA(LCD0_D21_PORT158_MARK, PORT158_FN4, MSEL5CR_6_1),
+ PINMUX_DATA(IRDA_FIRSEL_MARK, PORT158_FN5),
+ PINMUX_DATA(IDE_D15_MARK, PORT158_FN6),
+
+ /* Port159 */
+ PINMUX_DATA(D30_MARK, PORT159_FN1),
+ PINMUX_DATA(SCIFA3_RXD_PORT159_MARK, PORT159_FN2, MSEL5CR_8_1),
+ PINMUX_DATA(RMII_REF50CK_MARK, PORT159_FN3),
+ PINMUX_DATA(LCD0_D23_PORT159_MARK, PORT159_FN4, MSEL5CR_6_1),
+ PINMUX_DATA(IDE_D14_MARK, PORT159_FN6),
+
+ /* Port160 */
+ PINMUX_DATA(D29_MARK, PORT160_FN1),
+ PINMUX_DATA(SCIFA3_TXD_PORT160_MARK, PORT160_FN2, MSEL5CR_8_1),
+ PINMUX_DATA(LCD0_D22_PORT160_MARK, PORT160_FN4, MSEL5CR_6_1),
+ PINMUX_DATA(VIO1_HD_MARK, PORT160_FN5),
+ PINMUX_DATA(IDE_D13_MARK, PORT160_FN6),
+
+ /* Port161 */
+ PINMUX_DATA(D28_MARK, PORT161_FN1),
+ PINMUX_DATA(SCIFA3_RTS_PORT161_MARK, PORT161_FN2, MSEL5CR_8_1),
+ PINMUX_DATA(ET_RX_DV_MARK, PORT161_FN3),
+ PINMUX_DATA(LCD0_D20_PORT161_MARK, PORT161_FN4, MSEL5CR_6_1),
+ PINMUX_DATA(IRDA_IN_MARK, PORT161_FN5),
+ PINMUX_DATA(IDE_D12_MARK, PORT161_FN6),
+
+ /* Port162 */
+ PINMUX_DATA(D27_MARK, PORT162_FN1),
+ PINMUX_DATA(SCIFA3_CTS_PORT162_MARK, PORT162_FN2, MSEL5CR_8_1),
+ PINMUX_DATA(LCD0_D19_PORT162_MARK, PORT162_FN4, MSEL5CR_6_1),
+ PINMUX_DATA(IRDA_OUT_MARK, PORT162_FN5),
+ PINMUX_DATA(IDE_D11_MARK, PORT162_FN6),
+
+ /* Port163 */
+ PINMUX_DATA(D26_MARK, PORT163_FN1),
+ PINMUX_DATA(MSIOF2_SS2_MARK, PORT163_FN2),
+ PINMUX_DATA(ET_COL_MARK, PORT163_FN3),
+ PINMUX_DATA(LCD0_D18_PORT163_MARK, PORT163_FN4, MSEL5CR_6_1),
+ PINMUX_DATA(IROUT_MARK, PORT163_FN5),
+ PINMUX_DATA(IDE_D10_MARK, PORT163_FN6),
+
+ /* Port164 */
+ PINMUX_DATA(D25_MARK, PORT164_FN1),
+ PINMUX_DATA(MSIOF2_TSYNC_MARK, PORT164_FN2),
+ PINMUX_DATA(ET_PHY_INT_MARK, PORT164_FN3),
+ PINMUX_DATA(LCD0_RD_MARK, PORT164_FN4),
+ PINMUX_DATA(IDE_D9_MARK, PORT164_FN6),
+
+ /* Port165 */
+ PINMUX_DATA(D24_MARK, PORT165_FN1),
+ PINMUX_DATA(MSIOF2_RXD_MARK, PORT165_FN2),
+ PINMUX_DATA(LCD0_LCLK_PORT165_MARK, PORT165_FN4, MSEL5CR_6_1),
+ PINMUX_DATA(IDE_D8_MARK, PORT165_FN6),
+
+ /* Port166 - Port171 Function1 */
+ PINMUX_DATA(D21_MARK, PORT166_FN1),
+ PINMUX_DATA(D20_MARK, PORT167_FN1),
+ PINMUX_DATA(D19_MARK, PORT168_FN1),
+ PINMUX_DATA(D18_MARK, PORT169_FN1),
+ PINMUX_DATA(D17_MARK, PORT170_FN1),
+ PINMUX_DATA(D16_MARK, PORT171_FN1),
+
+ /* Port166 - Port171 Function3 */
+ PINMUX_DATA(ET_ETXD5_MARK, PORT166_FN3),
+ PINMUX_DATA(ET_ETXD4_MARK, PORT167_FN3),
+ PINMUX_DATA(ET_ETXD3_MARK, PORT168_FN3),
+ PINMUX_DATA(ET_ETXD2_MARK, PORT169_FN3),
+ PINMUX_DATA(ET_ETXD1_MARK, PORT170_FN3),
+ PINMUX_DATA(ET_ETXD0_MARK, PORT171_FN3),
+
+ /* Port166 - Port171 Function6 */
+ PINMUX_DATA(IDE_D5_MARK, PORT166_FN6),
+ PINMUX_DATA(IDE_D4_MARK, PORT167_FN6),
+ PINMUX_DATA(IDE_D3_MARK, PORT168_FN6),
+ PINMUX_DATA(IDE_D2_MARK, PORT169_FN6),
+ PINMUX_DATA(IDE_D1_MARK, PORT170_FN6),
+ PINMUX_DATA(IDE_D0_MARK, PORT171_FN6),
+
+ /* Port167 - Port171 IRQ */
+ PINMUX_DATA(IRQ31_PORT167_MARK, PORT167_FN0, MSEL1CR_31_0),
+ PINMUX_DATA(IRQ27_PORT168_MARK, PORT168_FN0, MSEL1CR_27_0),
+ PINMUX_DATA(IRQ28_PORT169_MARK, PORT169_FN0, MSEL1CR_28_0),
+ PINMUX_DATA(IRQ29_PORT170_MARK, PORT170_FN0, MSEL1CR_29_0),
+ PINMUX_DATA(IRQ30_PORT171_MARK, PORT171_FN0, MSEL1CR_30_0),
+
+ /* Port172 */
+ PINMUX_DATA(D23_MARK, PORT172_FN1),
+ PINMUX_DATA(SCIFB_RTS_PORT172_MARK, PORT172_FN2, MSEL5CR_17_1),
+ PINMUX_DATA(ET_ETXD7_MARK, PORT172_FN3),
+ PINMUX_DATA(IDE_D7_MARK, PORT172_FN6),
+ PINMUX_DATA(IRQ4_PORT172_MARK, PORT172_FN0, MSEL1CR_4_1),
+
+ /* Port173 */
+ PINMUX_DATA(D22_MARK, PORT173_FN1),
+ PINMUX_DATA(SCIFB_CTS_PORT173_MARK, PORT173_FN2, MSEL5CR_17_1),
+ PINMUX_DATA(ET_ETXD6_MARK, PORT173_FN3),
+ PINMUX_DATA(IDE_D6_MARK, PORT173_FN6),
+ PINMUX_DATA(IRQ6_PORT173_MARK, PORT173_FN0, MSEL1CR_6_1),
+
+ /* Port174 */
+ PINMUX_DATA(A26_MARK, PORT174_FN1),
+ PINMUX_DATA(MSIOF0_TXD_MARK, PORT174_FN2),
+ PINMUX_DATA(ET_RX_CLK_MARK, PORT174_FN3),
+ PINMUX_DATA(SCIFA3_RXD_PORT174_MARK, PORT174_FN4, MSEL5CR_8_0),
+
+ /* Port175 */
+ PINMUX_DATA(A0_MARK, PORT175_FN1),
+ PINMUX_DATA(BS_MARK, PORT175_FN2),
+ PINMUX_DATA(ET_WOL_MARK, PORT175_FN3),
+ PINMUX_DATA(SCIFA3_TXD_PORT175_MARK, PORT175_FN4, MSEL5CR_8_0),
+
+ /* Port176 */
+ PINMUX_DATA(ET_GTX_CLK_MARK, PORT176_FN3),
+
+ /* Port177 */
+ PINMUX_DATA(WAIT_PORT177_MARK, PORT177_FN1, MSEL5CR_2_0),
+ PINMUX_DATA(ET_LINK_MARK, PORT177_FN3),
+ PINMUX_DATA(IDE_IOWR_MARK, PORT177_FN6),
+ PINMUX_DATA(SDHI2_WP_PORT177_MARK, PORT177_FN7, MSEL5CR_19_1),
+
+ /* Port178 */
+ PINMUX_DATA(VIO0_D12_MARK, PORT178_FN1),
+ PINMUX_DATA(VIO1_D4_MARK, PORT178_FN5),
+ PINMUX_DATA(IDE_IORD_MARK, PORT178_FN6),
+
+ /* Port179 */
+ PINMUX_DATA(VIO0_D11_MARK, PORT179_FN1),
+ PINMUX_DATA(VIO1_D3_MARK, PORT179_FN5),
+ PINMUX_DATA(IDE_IORDY_MARK, PORT179_FN6),
+
+ /* Port180 */
+ PINMUX_DATA(VIO0_D10_MARK, PORT180_FN1),
+ PINMUX_DATA(TPU0TO3_MARK, PORT180_FN4),
+ PINMUX_DATA(VIO1_D2_MARK, PORT180_FN5),
+ PINMUX_DATA(IDE_INT_MARK, PORT180_FN6),
+ PINMUX_DATA(IRQ24_MARK, PORT180_FN0),
+
+ /* Port181 */
+ PINMUX_DATA(VIO0_D9_MARK, PORT181_FN1),
+ PINMUX_DATA(VIO1_D1_MARK, PORT181_FN5),
+ PINMUX_DATA(IDE_RST_MARK, PORT181_FN6),
+
+ /* Port182 */
+ PINMUX_DATA(VIO0_D8_MARK, PORT182_FN1),
+ PINMUX_DATA(VIO1_D0_MARK, PORT182_FN5),
+ PINMUX_DATA(IDE_DIRECTION_MARK, PORT182_FN6),
+
+ /* Port183 */
+ PINMUX_DATA(DREQ1_MARK, PORT183_FN1),
+ PINMUX_DATA(BBIF2_TXD2_PORT183_MARK, PORT183_FN2, MSEL5CR_0_1),
+ PINMUX_DATA(ET_TX_EN_MARK, PORT183_FN3),
+
+ /* Port184 */
+ PINMUX_DATA(DACK1_MARK, PORT184_FN1),
+ PINMUX_DATA(BBIF2_TSYNC2_PORT184_MARK, PORT184_FN2, MSEL5CR_0_1),
+ PINMUX_DATA(ET_TX_CLK_MARK, PORT184_FN3),
+
+ /* Port185 - Port192 Function1 */
+ PINMUX_DATA(SCIFA1_SCK_MARK, PORT185_FN1),
+ PINMUX_DATA(SCIFB_RTS_PORT186_MARK, PORT186_FN1, MSEL5CR_17_0),
+ PINMUX_DATA(SCIFB_CTS_PORT187_MARK, PORT187_FN1, MSEL5CR_17_0),
+ PINMUX_DATA(SCIFA0_SCK_MARK, PORT188_FN1),
+ PINMUX_DATA(SCIFB_SCK_PORT190_MARK, PORT190_FN1, MSEL5CR_17_0),
+ PINMUX_DATA(SCIFB_RXD_PORT191_MARK, PORT191_FN1, MSEL5CR_17_0),
+ PINMUX_DATA(SCIFB_TXD_PORT192_MARK, PORT192_FN1, MSEL5CR_17_0),
+
+ /* Port185 - Port192 Function3 */
+ PINMUX_DATA(ET_ERXD0_MARK, PORT185_FN3),
+ PINMUX_DATA(ET_ERXD1_MARK, PORT186_FN3),
+ PINMUX_DATA(ET_ERXD2_MARK, PORT187_FN3),
+ PINMUX_DATA(ET_ERXD3_MARK, PORT188_FN3),
+ PINMUX_DATA(ET_ERXD4_MARK, PORT189_FN3),
+ PINMUX_DATA(ET_ERXD5_MARK, PORT190_FN3),
+ PINMUX_DATA(ET_ERXD6_MARK, PORT191_FN3),
+ PINMUX_DATA(ET_ERXD7_MARK, PORT192_FN3),
+
+ /* Port185 - Port192 Function6 */
+ PINMUX_DATA(STP1_IPCLK_MARK, PORT185_FN6),
+ PINMUX_DATA(STP1_IPD0_PORT186_MARK, PORT186_FN6, MSEL5CR_23_0),
+ PINMUX_DATA(STP1_IPEN_PORT187_MARK, PORT187_FN6, MSEL5CR_23_0),
+ PINMUX_DATA(STP1_IPSYNC_MARK, PORT188_FN6),
+ PINMUX_DATA(STP0_IPCLK_MARK, PORT189_FN6),
+ PINMUX_DATA(STP0_IPD0_MARK, PORT190_FN6),
+ PINMUX_DATA(STP0_IPEN_MARK, PORT191_FN6),
+ PINMUX_DATA(STP0_IPSYNC_MARK, PORT192_FN6),
+
+ /* Port193 */
+ PINMUX_DATA(SCIFA0_CTS_MARK, PORT193_FN1),
+ PINMUX_DATA(RMII_CRS_DV_MARK, PORT193_FN3),
+ PINMUX_DATA(STP1_IPEN_PORT193_MARK, PORT193_FN6, MSEL5CR_23_1), /* ? */
+ PINMUX_DATA(LCD1_D17_MARK, PORT193_FN7),
+
+ /* Port194 */
+ PINMUX_DATA(SCIFA0_RTS_MARK, PORT194_FN1),
+ PINMUX_DATA(RMII_RX_ER_MARK, PORT194_FN3),
+ PINMUX_DATA(STP1_IPD0_PORT194_MARK, PORT194_FN6, MSEL5CR_23_1), /* ? */
+ PINMUX_DATA(LCD1_D16_MARK, PORT194_FN7),
+
+ /* Port195 */
+ PINMUX_DATA(SCIFA1_RXD_MARK, PORT195_FN1),
+ PINMUX_DATA(RMII_RXD0_MARK, PORT195_FN3),
+ PINMUX_DATA(STP1_IPD3_MARK, PORT195_FN6),
+ PINMUX_DATA(LCD1_D15_MARK, PORT195_FN7),
+
+ /* Port196 */
+ PINMUX_DATA(SCIFA1_TXD_MARK, PORT196_FN1),
+ PINMUX_DATA(RMII_RXD1_MARK, PORT196_FN3),
+ PINMUX_DATA(STP1_IPD2_MARK, PORT196_FN6),
+ PINMUX_DATA(LCD1_D14_MARK, PORT196_FN7),
+
+ /* Port197 */
+ PINMUX_DATA(SCIFA0_RXD_MARK, PORT197_FN1),
+ PINMUX_DATA(VIO1_CLK_MARK, PORT197_FN5),
+ PINMUX_DATA(STP1_IPD5_MARK, PORT197_FN6),
+ PINMUX_DATA(LCD1_D19_MARK, PORT197_FN7),
+
+ /* Port198 */
+ PINMUX_DATA(SCIFA0_TXD_MARK, PORT198_FN1),
+ PINMUX_DATA(VIO1_VD_MARK, PORT198_FN5),
+ PINMUX_DATA(STP1_IPD4_MARK, PORT198_FN6),
+ PINMUX_DATA(LCD1_D18_MARK, PORT198_FN7),
+
+ /* Port199 */
+ PINMUX_DATA(MEMC_NWE_MARK, PORT199_FN1),
+ PINMUX_DATA(SCIFA2_SCK_PORT199_MARK, PORT199_FN2, MSEL5CR_7_1),
+ PINMUX_DATA(RMII_TX_EN_MARK, PORT199_FN3),
+ PINMUX_DATA(SIM_D_PORT199_MARK, PORT199_FN4, MSEL5CR_21_1),
+ PINMUX_DATA(STP1_IPD1_MARK, PORT199_FN6),
+ PINMUX_DATA(LCD1_D13_MARK, PORT199_FN7),
+
+ /* Port200 */
+ PINMUX_DATA(MEMC_NOE_MARK, PORT200_FN1),
+ PINMUX_DATA(SCIFA2_RXD_MARK, PORT200_FN2),
+ PINMUX_DATA(RMII_TXD0_MARK, PORT200_FN3),
+ PINMUX_DATA(STP0_IPD7_MARK, PORT200_FN6),
+ PINMUX_DATA(LCD1_D12_MARK, PORT200_FN7),
+
+ /* Port201 */
+ PINMUX_DATA(MEMC_WAIT_MARK, PORT201_FN1, MSEL4CR_6_0),
+ PINMUX_DATA(MEMC_DREQ1_MARK, PORT201_FN1, MSEL4CR_6_1),
+
+ PINMUX_DATA(SCIFA2_TXD_MARK, PORT201_FN2),
+ PINMUX_DATA(RMII_TXD1_MARK, PORT201_FN3),
+ PINMUX_DATA(STP0_IPD6_MARK, PORT201_FN6),
+ PINMUX_DATA(LCD1_D11_MARK, PORT201_FN7),
+
+ /* Port202 */
+ PINMUX_DATA(MEMC_BUSCLK_MARK, PORT202_FN1, MSEL4CR_6_0),
+ PINMUX_DATA(MEMC_A0_MARK, PORT202_FN1, MSEL4CR_6_1),
+
+ PINMUX_DATA(MSIOF1_SS2_PORT202_MARK, PORT202_FN2, MSEL4CR_10_1),
+ PINMUX_DATA(RMII_MDC_MARK, PORT202_FN3),
+ PINMUX_DATA(TPU0TO2_PORT202_MARK, PORT202_FN4, MSEL5CR_25_1),
+ PINMUX_DATA(IDE_CS0_MARK, PORT202_FN6),
+ PINMUX_DATA(SDHI2_CD_PORT202_MARK, PORT202_FN7, MSEL5CR_19_1),
+ PINMUX_DATA(IRQ21_MARK, PORT202_FN0),
+
+ /* Port203 - Port208 Function1 */
+ PINMUX_DATA(SDHI2_CLK_MARK, PORT203_FN1),
+ PINMUX_DATA(SDHI2_CMD_MARK, PORT204_FN1),
+ PINMUX_DATA(SDHI2_D0_MARK, PORT205_FN1),
+ PINMUX_DATA(SDHI2_D1_MARK, PORT206_FN1),
+ PINMUX_DATA(SDHI2_D2_MARK, PORT207_FN1),
+ PINMUX_DATA(SDHI2_D3_MARK, PORT208_FN1),
+
+ /* Port203 - Port208 Function3 */
+ PINMUX_DATA(ET_TX_ER_MARK, PORT203_FN3),
+ PINMUX_DATA(ET_RX_ER_MARK, PORT204_FN3),
+ PINMUX_DATA(ET_CRS_MARK, PORT205_FN3),
+ PINMUX_DATA(ET_MDC_MARK, PORT206_FN3),
+ PINMUX_DATA(ET_MDIO_MARK, PORT207_FN3),
+ PINMUX_DATA(RMII_MDIO_MARK, PORT208_FN3),
+
+ /* Port203 - Port208 Function6 */
+ PINMUX_DATA(IDE_A2_MARK, PORT203_FN6),
+ PINMUX_DATA(IDE_A1_MARK, PORT204_FN6),
+ PINMUX_DATA(IDE_A0_MARK, PORT205_FN6),
+ PINMUX_DATA(IDE_IODACK_MARK, PORT206_FN6),
+ PINMUX_DATA(IDE_IODREQ_MARK, PORT207_FN6),
+ PINMUX_DATA(IDE_CS1_MARK, PORT208_FN6),
+
+ /* Port203 - Port208 Function7 */
+ PINMUX_DATA(SCIFA4_TXD_PORT203_MARK, PORT203_FN7, MSEL5CR_12_0, MSEL5CR_11_1),
+ PINMUX_DATA(SCIFA4_RXD_PORT204_MARK, PORT204_FN7, MSEL5CR_12_0, MSEL5CR_11_1),
+ PINMUX_DATA(SCIFA4_SCK_PORT205_MARK, PORT205_FN7, MSEL5CR_10_1),
+ PINMUX_DATA(SCIFA5_SCK_PORT206_MARK, PORT206_FN7, MSEL5CR_13_1),
+ PINMUX_DATA(SCIFA5_RXD_PORT207_MARK, PORT207_FN7, MSEL5CR_15_0, MSEL5CR_14_1),
+ PINMUX_DATA(SCIFA5_TXD_PORT208_MARK, PORT208_FN7, MSEL5CR_15_0, MSEL5CR_14_1),
+
+ /* Port209 */
+ PINMUX_DATA(VBUS_MARK, PORT209_FN1),
+ PINMUX_DATA(IRQ7_PORT209_MARK, PORT209_FN0, MSEL1CR_7_1),
+
+ /* Port210 */
+ PINMUX_DATA(IRQ9_PORT210_MARK, PORT210_FN0, MSEL1CR_9_1),
+
+ /* Port211 */
+ PINMUX_DATA(IRQ16_PORT211_MARK, PORT211_FN0, MSEL1CR_16_1),
+
+ /* LCDC select */
+ PINMUX_DATA(LCDC0_SELECT_MARK, MSEL3CR_6_0),
+ PINMUX_DATA(LCDC1_SELECT_MARK, MSEL3CR_6_1),
+
+ /* SDENC */
+ PINMUX_DATA(SDENC_CPG_MARK, MSEL4CR_19_0),
+ PINMUX_DATA(SDENC_DV_CLKI_MARK, MSEL4CR_19_1),
+
+ /* SYSC */
+ PINMUX_DATA(RESETP_PULLUP_MARK, MSEL4CR_4_0),
+ PINMUX_DATA(RESETP_PLAIN_MARK, MSEL4CR_4_1),
+
+ /* DEBUG */
+ PINMUX_DATA(EDEBGREQ_PULLDOWN_MARK, MSEL4CR_1_0),
+ PINMUX_DATA(EDEBGREQ_PULLUP_MARK, MSEL4CR_1_1),
+
+ PINMUX_DATA(TRACEAUD_FROM_VIO_MARK, MSEL5CR_30_0, MSEL5CR_29_0),
+ PINMUX_DATA(TRACEAUD_FROM_LCDC0_MARK, MSEL5CR_30_0, MSEL5CR_29_1),
+ PINMUX_DATA(TRACEAUD_FROM_MEMC_MARK, MSEL5CR_30_1, MSEL5CR_29_0),
+};
+
+static struct pinmux_gpio pinmux_gpios[] = {
+
+ /* PORT */
+ GPIO_PORT_ALL(),
+
+ /* IRQ */
+ GPIO_FN(IRQ0_PORT2), GPIO_FN(IRQ0_PORT13),
+ GPIO_FN(IRQ1),
+ GPIO_FN(IRQ2_PORT11), GPIO_FN(IRQ2_PORT12),
+ GPIO_FN(IRQ3_PORT10), GPIO_FN(IRQ3_PORT14),
+ GPIO_FN(IRQ4_PORT15), GPIO_FN(IRQ4_PORT172),
+ GPIO_FN(IRQ5_PORT0), GPIO_FN(IRQ5_PORT1),
+ GPIO_FN(IRQ6_PORT121), GPIO_FN(IRQ6_PORT173),
+ GPIO_FN(IRQ7_PORT120), GPIO_FN(IRQ7_PORT209),
+ GPIO_FN(IRQ8),
+ GPIO_FN(IRQ9_PORT118), GPIO_FN(IRQ9_PORT210),
+ GPIO_FN(IRQ10),
+ GPIO_FN(IRQ11),
+ GPIO_FN(IRQ12_PORT42), GPIO_FN(IRQ12_PORT97),
+ GPIO_FN(IRQ13_PORT64), GPIO_FN(IRQ13_PORT98),
+ GPIO_FN(IRQ14_PORT63), GPIO_FN(IRQ14_PORT99),
+ GPIO_FN(IRQ15_PORT62), GPIO_FN(IRQ15_PORT100),
+ GPIO_FN(IRQ16_PORT68), GPIO_FN(IRQ16_PORT211),
+ GPIO_FN(IRQ17),
+ GPIO_FN(IRQ18),
+ GPIO_FN(IRQ19),
+ GPIO_FN(IRQ20),
+ GPIO_FN(IRQ21),
+ GPIO_FN(IRQ22),
+ GPIO_FN(IRQ23),
+ GPIO_FN(IRQ24),
+ GPIO_FN(IRQ25),
+ GPIO_FN(IRQ26_PORT58), GPIO_FN(IRQ26_PORT81),
+ GPIO_FN(IRQ27_PORT57), GPIO_FN(IRQ27_PORT168),
+ GPIO_FN(IRQ28_PORT56), GPIO_FN(IRQ28_PORT169),
+ GPIO_FN(IRQ29_PORT50), GPIO_FN(IRQ29_PORT170),
+ GPIO_FN(IRQ30_PORT49), GPIO_FN(IRQ30_PORT171),
+ GPIO_FN(IRQ31_PORT41), GPIO_FN(IRQ31_PORT167),
+
+ /* Function */
+
+ /* DBGT */
+ GPIO_FN(DBGMDT2), GPIO_FN(DBGMDT1), GPIO_FN(DBGMDT0),
+ GPIO_FN(DBGMD10), GPIO_FN(DBGMD11), GPIO_FN(DBGMD20),
+ GPIO_FN(DBGMD21),
+
+ /* FSI */
+ GPIO_FN(FSIAISLD_PORT0), /* FSIAISLD Port 0/5 */
+ GPIO_FN(FSIAISLD_PORT5),
+ GPIO_FN(FSIASPDIF_PORT9), /* FSIASPDIF Port 9/18 */
+ GPIO_FN(FSIASPDIF_PORT18),
+ GPIO_FN(FSIAOSLD1), GPIO_FN(FSIAOSLD2), GPIO_FN(FSIAOLR),
+ GPIO_FN(FSIAOBT), GPIO_FN(FSIAOSLD), GPIO_FN(FSIAOMC),
+ GPIO_FN(FSIACK), GPIO_FN(FSIAILR), GPIO_FN(FSIAIBT),
+
+ /* FMSI */
+ GPIO_FN(FMSISLD_PORT1), /* FMSISLD Port 1/6 */
+ GPIO_FN(FMSISLD_PORT6),
+ GPIO_FN(FMSIILR), GPIO_FN(FMSIIBT), GPIO_FN(FMSIOLR),
+ GPIO_FN(FMSIOBT), GPIO_FN(FMSICK), GPIO_FN(FMSOILR),
+ GPIO_FN(FMSOIBT), GPIO_FN(FMSOOLR), GPIO_FN(FMSOOBT),
+ GPIO_FN(FMSOSLD), GPIO_FN(FMSOCK),
+
+ /* SCIFA0 */
+ GPIO_FN(SCIFA0_SCK), GPIO_FN(SCIFA0_CTS), GPIO_FN(SCIFA0_RTS),
+ GPIO_FN(SCIFA0_RXD), GPIO_FN(SCIFA0_TXD),
+
+ /* SCIFA1 */
+ GPIO_FN(SCIFA1_CTS), GPIO_FN(SCIFA1_SCK),
+ GPIO_FN(SCIFA1_RXD), GPIO_FN(SCIFA1_TXD), GPIO_FN(SCIFA1_RTS),
+
+ /* SCIFA2 */
+ GPIO_FN(SCIFA2_SCK_PORT22), /* SCIFA2_SCK Port 22/199 */
+ GPIO_FN(SCIFA2_SCK_PORT199),
+ GPIO_FN(SCIFA2_RXD), GPIO_FN(SCIFA2_TXD),
+ GPIO_FN(SCIFA2_CTS), GPIO_FN(SCIFA2_RTS),
+
+ /* SCIFA3 */
+ GPIO_FN(SCIFA3_RTS_PORT105), /* MSEL5CR_8_0 */
+ GPIO_FN(SCIFA3_SCK_PORT116),
+ GPIO_FN(SCIFA3_CTS_PORT117),
+ GPIO_FN(SCIFA3_RXD_PORT174),
+ GPIO_FN(SCIFA3_TXD_PORT175),
+
+ GPIO_FN(SCIFA3_RTS_PORT161), /* MSEL5CR_8_1 */
+ GPIO_FN(SCIFA3_SCK_PORT158),
+ GPIO_FN(SCIFA3_CTS_PORT162),
+ GPIO_FN(SCIFA3_RXD_PORT159),
+ GPIO_FN(SCIFA3_TXD_PORT160),
+
+ /* SCIFA4 */
+ GPIO_FN(SCIFA4_RXD_PORT12), /* MSEL5CR[12:11] = 00 */
+ GPIO_FN(SCIFA4_TXD_PORT13),
+
+ GPIO_FN(SCIFA4_RXD_PORT204), /* MSEL5CR[12:11] = 01 */
+ GPIO_FN(SCIFA4_TXD_PORT203),
+
+ GPIO_FN(SCIFA4_RXD_PORT94), /* MSEL5CR[12:11] = 10 */
+ GPIO_FN(SCIFA4_TXD_PORT93),
+
+ GPIO_FN(SCIFA4_SCK_PORT21), /* SCIFA4_SCK Port 21/205 */
+ GPIO_FN(SCIFA4_SCK_PORT205),
+
+ /* SCIFA5 */
+ GPIO_FN(SCIFA5_TXD_PORT20), /* MSEL5CR[15:14] = 00 */
+ GPIO_FN(SCIFA5_RXD_PORT10),
+
+ GPIO_FN(SCIFA5_RXD_PORT207), /* MSEL5CR[15:14] = 01 */
+ GPIO_FN(SCIFA5_TXD_PORT208),
+
+ GPIO_FN(SCIFA5_TXD_PORT91), /* MSEL5CR[15:14] = 10 */
+ GPIO_FN(SCIFA5_RXD_PORT92),
+
+ GPIO_FN(SCIFA5_SCK_PORT23), /* SCIFA5_SCK Port 23/206 */
+ GPIO_FN(SCIFA5_SCK_PORT206),
+
+ /* SCIFA6 */
+ GPIO_FN(SCIFA6_SCK), GPIO_FN(SCIFA6_RXD), GPIO_FN(SCIFA6_TXD),
+
+ /* SCIFA7 */
+ GPIO_FN(SCIFA7_TXD), GPIO_FN(SCIFA7_RXD),
+
+ /* SCIFAB */
+ GPIO_FN(SCIFB_SCK_PORT190), /* MSEL5CR_17_0 */
+ GPIO_FN(SCIFB_RXD_PORT191),
+ GPIO_FN(SCIFB_TXD_PORT192),
+ GPIO_FN(SCIFB_RTS_PORT186),
+ GPIO_FN(SCIFB_CTS_PORT187),
+
+ GPIO_FN(SCIFB_SCK_PORT2), /* MSEL5CR_17_1 */
+ GPIO_FN(SCIFB_RXD_PORT3),
+ GPIO_FN(SCIFB_TXD_PORT4),
+ GPIO_FN(SCIFB_RTS_PORT172),
+ GPIO_FN(SCIFB_CTS_PORT173),
+
+ /* LCD0 */
+ GPIO_FN(LCD0_D0), GPIO_FN(LCD0_D1), GPIO_FN(LCD0_D2),
+ GPIO_FN(LCD0_D3), GPIO_FN(LCD0_D4), GPIO_FN(LCD0_D5),
+ GPIO_FN(LCD0_D6), GPIO_FN(LCD0_D7), GPIO_FN(LCD0_D8),
+ GPIO_FN(LCD0_D9), GPIO_FN(LCD0_D10), GPIO_FN(LCD0_D11),
+ GPIO_FN(LCD0_D12), GPIO_FN(LCD0_D13), GPIO_FN(LCD0_D14),
+ GPIO_FN(LCD0_D15), GPIO_FN(LCD0_D16), GPIO_FN(LCD0_D17),
+ GPIO_FN(LCD0_DON), GPIO_FN(LCD0_VCPWC), GPIO_FN(LCD0_VEPWC),
+ GPIO_FN(LCD0_DCK), GPIO_FN(LCD0_VSYN),
+ GPIO_FN(LCD0_HSYN), GPIO_FN(LCD0_DISP),
+ GPIO_FN(LCD0_WR), GPIO_FN(LCD0_RD),
+ GPIO_FN(LCD0_CS), GPIO_FN(LCD0_RS),
+
+ GPIO_FN(LCD0_D18_PORT163), GPIO_FN(LCD0_D19_PORT162),
+ GPIO_FN(LCD0_D20_PORT161), GPIO_FN(LCD0_D21_PORT158),
+ GPIO_FN(LCD0_D22_PORT160), GPIO_FN(LCD0_D23_PORT159),
+ GPIO_FN(LCD0_LCLK_PORT165), /* MSEL5CR_6_1 */
+
+ GPIO_FN(LCD0_D18_PORT40), GPIO_FN(LCD0_D19_PORT4),
+ GPIO_FN(LCD0_D20_PORT3), GPIO_FN(LCD0_D21_PORT2),
+ GPIO_FN(LCD0_D22_PORT0), GPIO_FN(LCD0_D23_PORT1),
+ GPIO_FN(LCD0_LCLK_PORT102), /* MSEL5CR_6_0 */
+
+ /* LCD1 */
+ GPIO_FN(LCD1_D0), GPIO_FN(LCD1_D1), GPIO_FN(LCD1_D2),
+ GPIO_FN(LCD1_D3), GPIO_FN(LCD1_D4), GPIO_FN(LCD1_D5),
+ GPIO_FN(LCD1_D6), GPIO_FN(LCD1_D7), GPIO_FN(LCD1_D8),
+ GPIO_FN(LCD1_D9), GPIO_FN(LCD1_D10), GPIO_FN(LCD1_D11),
+ GPIO_FN(LCD1_D12), GPIO_FN(LCD1_D13), GPIO_FN(LCD1_D14),
+ GPIO_FN(LCD1_D15), GPIO_FN(LCD1_D16), GPIO_FN(LCD1_D17),
+ GPIO_FN(LCD1_D18), GPIO_FN(LCD1_D19), GPIO_FN(LCD1_D20),
+ GPIO_FN(LCD1_D21), GPIO_FN(LCD1_D22), GPIO_FN(LCD1_D23),
+ GPIO_FN(LCD1_RS), GPIO_FN(LCD1_RD), GPIO_FN(LCD1_CS),
+ GPIO_FN(LCD1_WR), GPIO_FN(LCD1_DCK), GPIO_FN(LCD1_DON),
+ GPIO_FN(LCD1_VCPWC), GPIO_FN(LCD1_LCLK), GPIO_FN(LCD1_HSYN),
+ GPIO_FN(LCD1_VSYN), GPIO_FN(LCD1_VEPWC), GPIO_FN(LCD1_DISP),
+
+ /* RSPI */
+ GPIO_FN(RSPI_SSL0_A), GPIO_FN(RSPI_SSL1_A), GPIO_FN(RSPI_SSL2_A),
+ GPIO_FN(RSPI_SSL3_A), GPIO_FN(RSPI_CK_A), GPIO_FN(RSPI_MOSI_A),
+ GPIO_FN(RSPI_MISO_A),
+
+ /* VIO CKO */
+ GPIO_FN(VIO_CKO1),
+ GPIO_FN(VIO_CKO2),
+ GPIO_FN(VIO_CKO_1),
+ GPIO_FN(VIO_CKO),
+
+ /* VIO0 */
+ GPIO_FN(VIO0_D0), GPIO_FN(VIO0_D1), GPIO_FN(VIO0_D2),
+ GPIO_FN(VIO0_D3), GPIO_FN(VIO0_D4), GPIO_FN(VIO0_D5),
+ GPIO_FN(VIO0_D6), GPIO_FN(VIO0_D7), GPIO_FN(VIO0_D8),
+ GPIO_FN(VIO0_D9), GPIO_FN(VIO0_D10), GPIO_FN(VIO0_D11),
+ GPIO_FN(VIO0_D12), GPIO_FN(VIO0_VD), GPIO_FN(VIO0_HD),
+ GPIO_FN(VIO0_CLK), GPIO_FN(VIO0_FIELD),
+
+ GPIO_FN(VIO0_D13_PORT26), /* MSEL5CR_27_0 */
+ GPIO_FN(VIO0_D14_PORT25),
+ GPIO_FN(VIO0_D15_PORT24),
+
+ GPIO_FN(VIO0_D13_PORT22), /* MSEL5CR_27_1 */
+ GPIO_FN(VIO0_D14_PORT95),
+ GPIO_FN(VIO0_D15_PORT96),
+
+ /* VIO1 */
+ GPIO_FN(VIO1_D0), GPIO_FN(VIO1_D1), GPIO_FN(VIO1_D2),
+ GPIO_FN(VIO1_D3), GPIO_FN(VIO1_D4), GPIO_FN(VIO1_D5),
+ GPIO_FN(VIO1_D6), GPIO_FN(VIO1_D7), GPIO_FN(VIO1_VD),
+ GPIO_FN(VIO1_HD), GPIO_FN(VIO1_CLK), GPIO_FN(VIO1_FIELD),
+
+ /* TPU0 */
+ GPIO_FN(TPU0TO0), GPIO_FN(TPU0TO1), GPIO_FN(TPU0TO3),
+ GPIO_FN(TPU0TO2_PORT66), /* TPU0TO2 Port 66/202 */
+ GPIO_FN(TPU0TO2_PORT202),
+
+ /* SSP1 0 */
+ GPIO_FN(STP0_IPD0), GPIO_FN(STP0_IPD1), GPIO_FN(STP0_IPD2),
+ GPIO_FN(STP0_IPD3), GPIO_FN(STP0_IPD4), GPIO_FN(STP0_IPD5),
+ GPIO_FN(STP0_IPD6), GPIO_FN(STP0_IPD7), GPIO_FN(STP0_IPEN),
+ GPIO_FN(STP0_IPCLK), GPIO_FN(STP0_IPSYNC),
+
+ /* SSP1 1 */
+ GPIO_FN(STP1_IPD1), GPIO_FN(STP1_IPD2), GPIO_FN(STP1_IPD3),
+ GPIO_FN(STP1_IPD4), GPIO_FN(STP1_IPD5), GPIO_FN(STP1_IPD6),
+ GPIO_FN(STP1_IPD7), GPIO_FN(STP1_IPCLK), GPIO_FN(STP1_IPSYNC),
+
+ GPIO_FN(STP1_IPD0_PORT186), /* MSEL5CR_23_0 */
+ GPIO_FN(STP1_IPEN_PORT187),
+
+ GPIO_FN(STP1_IPD0_PORT194), /* MSEL5CR_23_1 */
+ GPIO_FN(STP1_IPEN_PORT193),
+
+ /* SIM */
+ GPIO_FN(SIM_RST), GPIO_FN(SIM_CLK),
+ GPIO_FN(SIM_D_PORT22), /* SIM_D Port 22/199 */
+ GPIO_FN(SIM_D_PORT199),
+
+ /* SDHI0 */
+ GPIO_FN(SDHI0_D0), GPIO_FN(SDHI0_D1), GPIO_FN(SDHI0_D2),
+ GPIO_FN(SDHI0_D3), GPIO_FN(SDHI0_CD), GPIO_FN(SDHI0_WP),
+ GPIO_FN(SDHI0_CMD), GPIO_FN(SDHI0_CLK),
+
+ /* SDHI1 */
+ GPIO_FN(SDHI1_D0), GPIO_FN(SDHI1_D1), GPIO_FN(SDHI1_D2),
+ GPIO_FN(SDHI1_D3), GPIO_FN(SDHI1_CD), GPIO_FN(SDHI1_WP),
+ GPIO_FN(SDHI1_CMD), GPIO_FN(SDHI1_CLK),
+
+ /* SDHI2 */
+ GPIO_FN(SDHI2_D0), GPIO_FN(SDHI2_D1), GPIO_FN(SDHI2_D2),
+ GPIO_FN(SDHI2_D3), GPIO_FN(SDHI2_CLK), GPIO_FN(SDHI2_CMD),
+
+ GPIO_FN(SDHI2_CD_PORT24), /* MSEL5CR_19_0 */
+ GPIO_FN(SDHI2_WP_PORT25),
+
+ GPIO_FN(SDHI2_WP_PORT177), /* MSEL5CR_19_1 */
+ GPIO_FN(SDHI2_CD_PORT202),
+
+ /* MSIOF2 */
+ GPIO_FN(MSIOF2_TXD), GPIO_FN(MSIOF2_RXD), GPIO_FN(MSIOF2_TSCK),
+ GPIO_FN(MSIOF2_SS2), GPIO_FN(MSIOF2_TSYNC), GPIO_FN(MSIOF2_SS1),
+ GPIO_FN(MSIOF2_MCK1), GPIO_FN(MSIOF2_MCK0), GPIO_FN(MSIOF2_RSYNC),
+ GPIO_FN(MSIOF2_RSCK),
+
+ /* KEYSC */
+ GPIO_FN(KEYIN4), GPIO_FN(KEYIN5),
+ GPIO_FN(KEYIN6), GPIO_FN(KEYIN7),
+ GPIO_FN(KEYOUT0), GPIO_FN(KEYOUT1), GPIO_FN(KEYOUT2),
+ GPIO_FN(KEYOUT3), GPIO_FN(KEYOUT4), GPIO_FN(KEYOUT5),
+ GPIO_FN(KEYOUT6), GPIO_FN(KEYOUT7),
+
+ GPIO_FN(KEYIN0_PORT43), /* MSEL4CR_18_0 */
+ GPIO_FN(KEYIN1_PORT44),
+ GPIO_FN(KEYIN2_PORT45),
+ GPIO_FN(KEYIN3_PORT46),
+
+ GPIO_FN(KEYIN0_PORT58), /* MSEL4CR_18_1 */
+ GPIO_FN(KEYIN1_PORT57),
+ GPIO_FN(KEYIN2_PORT56),
+ GPIO_FN(KEYIN3_PORT55),
+
+ /* VOU */
+ GPIO_FN(DV_D0), GPIO_FN(DV_D1), GPIO_FN(DV_D2),
+ GPIO_FN(DV_D3), GPIO_FN(DV_D4), GPIO_FN(DV_D5),
+ GPIO_FN(DV_D6), GPIO_FN(DV_D7), GPIO_FN(DV_D8),
+ GPIO_FN(DV_D9), GPIO_FN(DV_D10), GPIO_FN(DV_D11),
+ GPIO_FN(DV_D12), GPIO_FN(DV_D13), GPIO_FN(DV_D14),
+ GPIO_FN(DV_D15), GPIO_FN(DV_CLK),
+ GPIO_FN(DV_VSYNC), GPIO_FN(DV_HSYNC),
+
+ /* MEMC */
+ GPIO_FN(MEMC_AD0), GPIO_FN(MEMC_AD1), GPIO_FN(MEMC_AD2),
+ GPIO_FN(MEMC_AD3), GPIO_FN(MEMC_AD4), GPIO_FN(MEMC_AD5),
+ GPIO_FN(MEMC_AD6), GPIO_FN(MEMC_AD7), GPIO_FN(MEMC_AD8),
+ GPIO_FN(MEMC_AD9), GPIO_FN(MEMC_AD10), GPIO_FN(MEMC_AD11),
+ GPIO_FN(MEMC_AD12), GPIO_FN(MEMC_AD13), GPIO_FN(MEMC_AD14),
+ GPIO_FN(MEMC_AD15), GPIO_FN(MEMC_CS0), GPIO_FN(MEMC_INT),
+ GPIO_FN(MEMC_NWE), GPIO_FN(MEMC_NOE), GPIO_FN(MEMC_CS1),
+ GPIO_FN(MEMC_A1), GPIO_FN(MEMC_ADV), GPIO_FN(MEMC_DREQ0),
+ GPIO_FN(MEMC_WAIT), GPIO_FN(MEMC_DREQ1), GPIO_FN(MEMC_BUSCLK),
+ GPIO_FN(MEMC_A0),
+
+ /* MMC */
+ GPIO_FN(MMC0_D0_PORT68), GPIO_FN(MMC0_D1_PORT69),
+ GPIO_FN(MMC0_D2_PORT70), GPIO_FN(MMC0_D3_PORT71),
+ GPIO_FN(MMC0_D4_PORT72), GPIO_FN(MMC0_D5_PORT73),
+ GPIO_FN(MMC0_D6_PORT74), GPIO_FN(MMC0_D7_PORT75),
+ GPIO_FN(MMC0_CLK_PORT66),
+ GPIO_FN(MMC0_CMD_PORT67), /* MSEL4CR_15_0 */
+
+ GPIO_FN(MMC1_D0_PORT149), GPIO_FN(MMC1_D1_PORT148),
+ GPIO_FN(MMC1_D2_PORT147), GPIO_FN(MMC1_D3_PORT146),
+ GPIO_FN(MMC1_D4_PORT145), GPIO_FN(MMC1_D5_PORT144),
+ GPIO_FN(MMC1_D6_PORT143), GPIO_FN(MMC1_D7_PORT142),
+ GPIO_FN(MMC1_CLK_PORT103),
+ GPIO_FN(MMC1_CMD_PORT104), /* MSEL4CR_15_1 */
+
+ /* MSIOF0 */
+ GPIO_FN(MSIOF0_SS1), GPIO_FN(MSIOF0_SS2), GPIO_FN(MSIOF0_RXD),
+ GPIO_FN(MSIOF0_TXD), GPIO_FN(MSIOF0_MCK0), GPIO_FN(MSIOF0_MCK1),
+ GPIO_FN(MSIOF0_RSYNC), GPIO_FN(MSIOF0_RSCK), GPIO_FN(MSIOF0_TSCK),
+ GPIO_FN(MSIOF0_TSYNC),
+
+ /* MSIOF1 */
+ GPIO_FN(MSIOF1_RSCK), GPIO_FN(MSIOF1_RSYNC),
+ GPIO_FN(MSIOF1_MCK0), GPIO_FN(MSIOF1_MCK1),
+
+ GPIO_FN(MSIOF1_SS2_PORT116), GPIO_FN(MSIOF1_SS1_PORT117),
+ GPIO_FN(MSIOF1_RXD_PORT118), GPIO_FN(MSIOF1_TXD_PORT119),
+ GPIO_FN(MSIOF1_TSYNC_PORT120),
+ GPIO_FN(MSIOF1_TSCK_PORT121), /* MSEL4CR_10_0 */
+
+ GPIO_FN(MSIOF1_SS1_PORT67), GPIO_FN(MSIOF1_TSCK_PORT72),
+ GPIO_FN(MSIOF1_TSYNC_PORT73), GPIO_FN(MSIOF1_TXD_PORT74),
+ GPIO_FN(MSIOF1_RXD_PORT75),
+ GPIO_FN(MSIOF1_SS2_PORT202), /* MSEL4CR_10_1 */
+
+ /* GPIO */
+ GPIO_FN(GPO0), GPIO_FN(GPI0),
+ GPIO_FN(GPO1), GPIO_FN(GPI1),
+
+ /* USB0 */
+ GPIO_FN(USB0_OCI), GPIO_FN(USB0_PPON), GPIO_FN(VBUS),
+
+ /* USB1 */
+ GPIO_FN(USB1_OCI), GPIO_FN(USB1_PPON),
+
+ /* BBIF1 */
+ GPIO_FN(BBIF1_RXD), GPIO_FN(BBIF1_TXD), GPIO_FN(BBIF1_TSYNC),
+ GPIO_FN(BBIF1_TSCK), GPIO_FN(BBIF1_RSCK), GPIO_FN(BBIF1_RSYNC),
+ GPIO_FN(BBIF1_FLOW), GPIO_FN(BBIF1_RX_FLOW_N),
+
+ /* BBIF2 */
+ GPIO_FN(BBIF2_TXD2_PORT5), /* MSEL5CR_0_0 */
+ GPIO_FN(BBIF2_RXD2_PORT60),
+ GPIO_FN(BBIF2_TSYNC2_PORT6),
+ GPIO_FN(BBIF2_TSCK2_PORT59),
+
+ GPIO_FN(BBIF2_RXD2_PORT90), /* MSEL5CR_0_1 */
+ GPIO_FN(BBIF2_TXD2_PORT183),
+ GPIO_FN(BBIF2_TSCK2_PORT89),
+ GPIO_FN(BBIF2_TSYNC2_PORT184),
+
+ /* BSC / FLCTL / PCMCIA */
+ GPIO_FN(CS0), GPIO_FN(CS2), GPIO_FN(CS4),
+ GPIO_FN(CS5B), GPIO_FN(CS6A),
+ GPIO_FN(CS5A_PORT105), /* CS5A PORT 19/105 */
+ GPIO_FN(CS5A_PORT19),
+ GPIO_FN(IOIS16), /* ? */
+
+ GPIO_FN(A0), GPIO_FN(A1), GPIO_FN(A2), GPIO_FN(A3),
+ GPIO_FN(A4_FOE), GPIO_FN(A5_FCDE), /* share with FLCTL */
+ GPIO_FN(A6), GPIO_FN(A7), GPIO_FN(A8), GPIO_FN(A9),
+ GPIO_FN(A10), GPIO_FN(A11), GPIO_FN(A12), GPIO_FN(A13),
+ GPIO_FN(A14), GPIO_FN(A15), GPIO_FN(A16), GPIO_FN(A17),
+ GPIO_FN(A18), GPIO_FN(A19), GPIO_FN(A20), GPIO_FN(A21),
+ GPIO_FN(A22), GPIO_FN(A23), GPIO_FN(A24), GPIO_FN(A25),
+ GPIO_FN(A26),
+
+ GPIO_FN(D0_NAF0), GPIO_FN(D1_NAF1), /* share with FLCTL */
+ GPIO_FN(D2_NAF2), GPIO_FN(D3_NAF3), /* share with FLCTL */
+ GPIO_FN(D4_NAF4), GPIO_FN(D5_NAF5), /* share with FLCTL */
+ GPIO_FN(D6_NAF6), GPIO_FN(D7_NAF7), /* share with FLCTL */
+ GPIO_FN(D8_NAF8), GPIO_FN(D9_NAF9), /* share with FLCTL */
+ GPIO_FN(D10_NAF10), GPIO_FN(D11_NAF11), /* share with FLCTL */
+ GPIO_FN(D12_NAF12), GPIO_FN(D13_NAF13), /* share with FLCTL */
+ GPIO_FN(D14_NAF14), GPIO_FN(D15_NAF15), /* share with FLCTL */
+ GPIO_FN(D16), GPIO_FN(D17), GPIO_FN(D18), GPIO_FN(D19),
+ GPIO_FN(D20), GPIO_FN(D21), GPIO_FN(D22), GPIO_FN(D23),
+ GPIO_FN(D24), GPIO_FN(D25), GPIO_FN(D26), GPIO_FN(D27),
+ GPIO_FN(D28), GPIO_FN(D29), GPIO_FN(D30), GPIO_FN(D31),
+
+ GPIO_FN(WE0_FWE), /* share with FLCTL */
+ GPIO_FN(WE1),
+ GPIO_FN(WE2_ICIORD), /* share with PCMCIA */
+ GPIO_FN(WE3_ICIOWR), /* share with PCMCIA */
+ GPIO_FN(CKO), GPIO_FN(BS), GPIO_FN(RDWR),
+ GPIO_FN(RD_FSC), /* share with FLCTL */
+ GPIO_FN(WAIT_PORT177), /* WAIT Port 90/177 */
+ GPIO_FN(WAIT_PORT90),
+
+ GPIO_FN(FCE0), GPIO_FN(FCE1), GPIO_FN(FRB), /* FLCTL */
+
+ /* IRDA */
+ GPIO_FN(IRDA_FIRSEL), GPIO_FN(IRDA_IN), GPIO_FN(IRDA_OUT),
+
+ /* ATAPI */
+ GPIO_FN(IDE_D0), GPIO_FN(IDE_D1), GPIO_FN(IDE_D2),
+ GPIO_FN(IDE_D3), GPIO_FN(IDE_D4), GPIO_FN(IDE_D5),
+ GPIO_FN(IDE_D6), GPIO_FN(IDE_D7), GPIO_FN(IDE_D8),
+ GPIO_FN(IDE_D9), GPIO_FN(IDE_D10), GPIO_FN(IDE_D11),
+ GPIO_FN(IDE_D12), GPIO_FN(IDE_D13), GPIO_FN(IDE_D14),
+ GPIO_FN(IDE_D15), GPIO_FN(IDE_A0), GPIO_FN(IDE_A1),
+ GPIO_FN(IDE_A2), GPIO_FN(IDE_CS0), GPIO_FN(IDE_CS1),
+ GPIO_FN(IDE_IOWR), GPIO_FN(IDE_IORD), GPIO_FN(IDE_IORDY),
+ GPIO_FN(IDE_INT), GPIO_FN(IDE_RST), GPIO_FN(IDE_DIRECTION),
+ GPIO_FN(IDE_EXBUF_ENB), GPIO_FN(IDE_IODACK), GPIO_FN(IDE_IODREQ),
+
+ /* RMII */
+ GPIO_FN(RMII_CRS_DV), GPIO_FN(RMII_RX_ER), GPIO_FN(RMII_RXD0),
+ GPIO_FN(RMII_RXD1), GPIO_FN(RMII_TX_EN), GPIO_FN(RMII_TXD0),
+ GPIO_FN(RMII_MDC), GPIO_FN(RMII_TXD1), GPIO_FN(RMII_MDIO),
+ GPIO_FN(RMII_REF50CK), GPIO_FN(RMII_REF125CK), /* for GMII */
+
+ /* GEther */
+ GPIO_FN(ET_TX_CLK), GPIO_FN(ET_TX_EN), GPIO_FN(ET_ETXD0),
+ GPIO_FN(ET_ETXD1), GPIO_FN(ET_ETXD2), GPIO_FN(ET_ETXD3),
+ GPIO_FN(ET_ETXD4), GPIO_FN(ET_ETXD5), /* for GEther */
+ GPIO_FN(ET_ETXD6), GPIO_FN(ET_ETXD7), /* for GEther */
+ GPIO_FN(ET_COL), GPIO_FN(ET_TX_ER), GPIO_FN(ET_RX_CLK),
+ GPIO_FN(ET_RX_DV), GPIO_FN(ET_ERXD0), GPIO_FN(ET_ERXD1),
+ GPIO_FN(ET_ERXD2), GPIO_FN(ET_ERXD3),
+ GPIO_FN(ET_ERXD4), GPIO_FN(ET_ERXD5), /* for GEther */
+ GPIO_FN(ET_ERXD6), GPIO_FN(ET_ERXD7), /* for GEther */
+ GPIO_FN(ET_RX_ER), GPIO_FN(ET_CRS), GPIO_FN(ET_MDC),
+ GPIO_FN(ET_MDIO), GPIO_FN(ET_LINK), GPIO_FN(ET_PHY_INT),
+ GPIO_FN(ET_WOL), GPIO_FN(ET_GTX_CLK),
+
+ /* DMA0 */
+ GPIO_FN(DREQ0), GPIO_FN(DACK0),
+
+ /* DMA1 */
+ GPIO_FN(DREQ1), GPIO_FN(DACK1),
+
+ /* SYSC */
+ GPIO_FN(RESETOUTS),
+
+ /* IRREM */
+ GPIO_FN(IROUT),
+
+ /* LCDC */
+ GPIO_FN(LCDC0_SELECT),
+ GPIO_FN(LCDC1_SELECT),
+
+ /* SDENC */
+ GPIO_FN(SDENC_CPG),
+ GPIO_FN(SDENC_DV_CLKI),
+
+ /* SYSC */
+ GPIO_FN(RESETP_PULLUP),
+ GPIO_FN(RESETP_PLAIN),
+
+ /* DEBUG */
+ GPIO_FN(EDEBGREQ_PULLDOWN),
+ GPIO_FN(EDEBGREQ_PULLUP),
+
+ GPIO_FN(TRACEAUD_FROM_VIO),
+ GPIO_FN(TRACEAUD_FROM_LCDC0),
+ GPIO_FN(TRACEAUD_FROM_MEMC),
+};
+
+static struct pinmux_cfg_reg pinmux_config_regs[] = {
+ PORTCR(0, 0xe6050000), /* PORT0CR */
+ PORTCR(1, 0xe6050001), /* PORT1CR */
+ PORTCR(2, 0xe6050002), /* PORT2CR */
+ PORTCR(3, 0xe6050003), /* PORT3CR */
+ PORTCR(4, 0xe6050004), /* PORT4CR */
+ PORTCR(5, 0xe6050005), /* PORT5CR */
+ PORTCR(6, 0xe6050006), /* PORT6CR */
+ PORTCR(7, 0xe6050007), /* PORT7CR */
+ PORTCR(8, 0xe6050008), /* PORT8CR */
+ PORTCR(9, 0xe6050009), /* PORT9CR */
+ PORTCR(10, 0xe605000a), /* PORT10CR */
+ PORTCR(11, 0xe605000b), /* PORT11CR */
+ PORTCR(12, 0xe605000c), /* PORT12CR */
+ PORTCR(13, 0xe605000d), /* PORT13CR */
+ PORTCR(14, 0xe605000e), /* PORT14CR */
+ PORTCR(15, 0xe605000f), /* PORT15CR */
+ PORTCR(16, 0xe6050010), /* PORT16CR */
+ PORTCR(17, 0xe6050011), /* PORT17CR */
+ PORTCR(18, 0xe6050012), /* PORT18CR */
+ PORTCR(19, 0xe6050013), /* PORT19CR */
+ PORTCR(20, 0xe6050014), /* PORT20CR */
+ PORTCR(21, 0xe6050015), /* PORT21CR */
+ PORTCR(22, 0xe6050016), /* PORT22CR */
+ PORTCR(23, 0xe6050017), /* PORT23CR */
+ PORTCR(24, 0xe6050018), /* PORT24CR */
+ PORTCR(25, 0xe6050019), /* PORT25CR */
+ PORTCR(26, 0xe605001a), /* PORT26CR */
+ PORTCR(27, 0xe605001b), /* PORT27CR */
+ PORTCR(28, 0xe605001c), /* PORT28CR */
+ PORTCR(29, 0xe605001d), /* PORT29CR */
+ PORTCR(30, 0xe605001e), /* PORT30CR */
+ PORTCR(31, 0xe605001f), /* PORT31CR */
+ PORTCR(32, 0xe6050020), /* PORT32CR */
+ PORTCR(33, 0xe6050021), /* PORT33CR */
+ PORTCR(34, 0xe6050022), /* PORT34CR */
+ PORTCR(35, 0xe6050023), /* PORT35CR */
+ PORTCR(36, 0xe6050024), /* PORT36CR */
+ PORTCR(37, 0xe6050025), /* PORT37CR */
+ PORTCR(38, 0xe6050026), /* PORT38CR */
+ PORTCR(39, 0xe6050027), /* PORT39CR */
+ PORTCR(40, 0xe6050028), /* PORT40CR */
+ PORTCR(41, 0xe6050029), /* PORT41CR */
+ PORTCR(42, 0xe605002a), /* PORT42CR */
+ PORTCR(43, 0xe605002b), /* PORT43CR */
+ PORTCR(44, 0xe605002c), /* PORT44CR */
+ PORTCR(45, 0xe605002d), /* PORT45CR */
+ PORTCR(46, 0xe605002e), /* PORT46CR */
+ PORTCR(47, 0xe605002f), /* PORT47CR */
+ PORTCR(48, 0xe6050030), /* PORT48CR */
+ PORTCR(49, 0xe6050031), /* PORT49CR */
+ PORTCR(50, 0xe6050032), /* PORT50CR */
+ PORTCR(51, 0xe6050033), /* PORT51CR */
+ PORTCR(52, 0xe6050034), /* PORT52CR */
+ PORTCR(53, 0xe6050035), /* PORT53CR */
+ PORTCR(54, 0xe6050036), /* PORT54CR */
+ PORTCR(55, 0xe6050037), /* PORT55CR */
+ PORTCR(56, 0xe6050038), /* PORT56CR */
+ PORTCR(57, 0xe6050039), /* PORT57CR */
+ PORTCR(58, 0xe605003a), /* PORT58CR */
+ PORTCR(59, 0xe605003b), /* PORT59CR */
+ PORTCR(60, 0xe605003c), /* PORT60CR */
+ PORTCR(61, 0xe605003d), /* PORT61CR */
+ PORTCR(62, 0xe605003e), /* PORT62CR */
+ PORTCR(63, 0xe605003f), /* PORT63CR */
+ PORTCR(64, 0xe6050040), /* PORT64CR */
+ PORTCR(65, 0xe6050041), /* PORT65CR */
+ PORTCR(66, 0xe6050042), /* PORT66CR */
+ PORTCR(67, 0xe6050043), /* PORT67CR */
+ PORTCR(68, 0xe6050044), /* PORT68CR */
+ PORTCR(69, 0xe6050045), /* PORT69CR */
+ PORTCR(70, 0xe6050046), /* PORT70CR */
+ PORTCR(71, 0xe6050047), /* PORT71CR */
+ PORTCR(72, 0xe6050048), /* PORT72CR */
+ PORTCR(73, 0xe6050049), /* PORT73CR */
+ PORTCR(74, 0xe605004a), /* PORT74CR */
+ PORTCR(75, 0xe605004b), /* PORT75CR */
+ PORTCR(76, 0xe605004c), /* PORT76CR */
+ PORTCR(77, 0xe605004d), /* PORT77CR */
+ PORTCR(78, 0xe605004e), /* PORT78CR */
+ PORTCR(79, 0xe605004f), /* PORT79CR */
+ PORTCR(80, 0xe6050050), /* PORT80CR */
+ PORTCR(81, 0xe6050051), /* PORT81CR */
+ PORTCR(82, 0xe6050052), /* PORT82CR */
+ PORTCR(83, 0xe6050053), /* PORT83CR */
+
+ PORTCR(84, 0xe6051054), /* PORT84CR */
+ PORTCR(85, 0xe6051055), /* PORT85CR */
+ PORTCR(86, 0xe6051056), /* PORT86CR */
+ PORTCR(87, 0xe6051057), /* PORT87CR */
+ PORTCR(88, 0xe6051058), /* PORT88CR */
+ PORTCR(89, 0xe6051059), /* PORT89CR */
+ PORTCR(90, 0xe605105a), /* PORT90CR */
+ PORTCR(91, 0xe605105b), /* PORT91CR */
+ PORTCR(92, 0xe605105c), /* PORT92CR */
+ PORTCR(93, 0xe605105d), /* PORT93CR */
+ PORTCR(94, 0xe605105e), /* PORT94CR */
+ PORTCR(95, 0xe605105f), /* PORT95CR */
+ PORTCR(96, 0xe6051060), /* PORT96CR */
+ PORTCR(97, 0xe6051061), /* PORT97CR */
+ PORTCR(98, 0xe6051062), /* PORT98CR */
+ PORTCR(99, 0xe6051063), /* PORT99CR */
+ PORTCR(100, 0xe6051064), /* PORT100CR */
+ PORTCR(101, 0xe6051065), /* PORT101CR */
+ PORTCR(102, 0xe6051066), /* PORT102CR */
+ PORTCR(103, 0xe6051067), /* PORT103CR */
+ PORTCR(104, 0xe6051068), /* PORT104CR */
+ PORTCR(105, 0xe6051069), /* PORT105CR */
+ PORTCR(106, 0xe605106a), /* PORT106CR */
+ PORTCR(107, 0xe605106b), /* PORT107CR */
+ PORTCR(108, 0xe605106c), /* PORT108CR */
+ PORTCR(109, 0xe605106d), /* PORT109CR */
+ PORTCR(110, 0xe605106e), /* PORT110CR */
+ PORTCR(111, 0xe605106f), /* PORT111CR */
+ PORTCR(112, 0xe6051070), /* PORT112CR */
+ PORTCR(113, 0xe6051071), /* PORT113CR */
+ PORTCR(114, 0xe6051072), /* PORT114CR */
+
+ PORTCR(115, 0xe6052073), /* PORT115CR */
+ PORTCR(116, 0xe6052074), /* PORT116CR */
+ PORTCR(117, 0xe6052075), /* PORT117CR */
+ PORTCR(118, 0xe6052076), /* PORT118CR */
+ PORTCR(119, 0xe6052077), /* PORT119CR */
+ PORTCR(120, 0xe6052078), /* PORT120CR */
+ PORTCR(121, 0xe6052079), /* PORT121CR */
+ PORTCR(122, 0xe605207a), /* PORT122CR */
+ PORTCR(123, 0xe605207b), /* PORT123CR */
+ PORTCR(124, 0xe605207c), /* PORT124CR */
+ PORTCR(125, 0xe605207d), /* PORT125CR */
+ PORTCR(126, 0xe605207e), /* PORT126CR */
+ PORTCR(127, 0xe605207f), /* PORT127CR */
+ PORTCR(128, 0xe6052080), /* PORT128CR */
+ PORTCR(129, 0xe6052081), /* PORT129CR */
+ PORTCR(130, 0xe6052082), /* PORT130CR */
+ PORTCR(131, 0xe6052083), /* PORT131CR */
+ PORTCR(132, 0xe6052084), /* PORT132CR */
+ PORTCR(133, 0xe6052085), /* PORT133CR */
+ PORTCR(134, 0xe6052086), /* PORT134CR */
+ PORTCR(135, 0xe6052087), /* PORT135CR */
+ PORTCR(136, 0xe6052088), /* PORT136CR */
+ PORTCR(137, 0xe6052089), /* PORT137CR */
+ PORTCR(138, 0xe605208a), /* PORT138CR */
+ PORTCR(139, 0xe605208b), /* PORT139CR */
+ PORTCR(140, 0xe605208c), /* PORT140CR */
+ PORTCR(141, 0xe605208d), /* PORT141CR */
+ PORTCR(142, 0xe605208e), /* PORT142CR */
+ PORTCR(143, 0xe605208f), /* PORT143CR */
+ PORTCR(144, 0xe6052090), /* PORT144CR */
+ PORTCR(145, 0xe6052091), /* PORT145CR */
+ PORTCR(146, 0xe6052092), /* PORT146CR */
+ PORTCR(147, 0xe6052093), /* PORT147CR */
+ PORTCR(148, 0xe6052094), /* PORT148CR */
+ PORTCR(149, 0xe6052095), /* PORT149CR */
+ PORTCR(150, 0xe6052096), /* PORT150CR */
+ PORTCR(151, 0xe6052097), /* PORT151CR */
+ PORTCR(152, 0xe6052098), /* PORT152CR */
+ PORTCR(153, 0xe6052099), /* PORT153CR */
+ PORTCR(154, 0xe605209a), /* PORT154CR */
+ PORTCR(155, 0xe605209b), /* PORT155CR */
+ PORTCR(156, 0xe605209c), /* PORT156CR */
+ PORTCR(157, 0xe605209d), /* PORT157CR */
+ PORTCR(158, 0xe605209e), /* PORT158CR */
+ PORTCR(159, 0xe605209f), /* PORT159CR */
+ PORTCR(160, 0xe60520a0), /* PORT160CR */
+ PORTCR(161, 0xe60520a1), /* PORT161CR */
+ PORTCR(162, 0xe60520a2), /* PORT162CR */
+ PORTCR(163, 0xe60520a3), /* PORT163CR */
+ PORTCR(164, 0xe60520a4), /* PORT164CR */
+ PORTCR(165, 0xe60520a5), /* PORT165CR */
+ PORTCR(166, 0xe60520a6), /* PORT166CR */
+ PORTCR(167, 0xe60520a7), /* PORT167CR */
+ PORTCR(168, 0xe60520a8), /* PORT168CR */
+ PORTCR(169, 0xe60520a9), /* PORT169CR */
+ PORTCR(170, 0xe60520aa), /* PORT170CR */
+ PORTCR(171, 0xe60520ab), /* PORT171CR */
+ PORTCR(172, 0xe60520ac), /* PORT172CR */
+ PORTCR(173, 0xe60520ad), /* PORT173CR */
+ PORTCR(174, 0xe60520ae), /* PORT174CR */
+ PORTCR(175, 0xe60520af), /* PORT175CR */
+ PORTCR(176, 0xe60520b0), /* PORT176CR */
+ PORTCR(177, 0xe60520b1), /* PORT177CR */
+ PORTCR(178, 0xe60520b2), /* PORT178CR */
+ PORTCR(179, 0xe60520b3), /* PORT179CR */
+ PORTCR(180, 0xe60520b4), /* PORT180CR */
+ PORTCR(181, 0xe60520b5), /* PORT181CR */
+ PORTCR(182, 0xe60520b6), /* PORT182CR */
+ PORTCR(183, 0xe60520b7), /* PORT183CR */
+ PORTCR(184, 0xe60520b8), /* PORT184CR */
+ PORTCR(185, 0xe60520b9), /* PORT185CR */
+ PORTCR(186, 0xe60520ba), /* PORT186CR */
+ PORTCR(187, 0xe60520bb), /* PORT187CR */
+ PORTCR(188, 0xe60520bc), /* PORT188CR */
+ PORTCR(189, 0xe60520bd), /* PORT189CR */
+ PORTCR(190, 0xe60520be), /* PORT190CR */
+ PORTCR(191, 0xe60520bf), /* PORT191CR */
+ PORTCR(192, 0xe60520c0), /* PORT192CR */
+ PORTCR(193, 0xe60520c1), /* PORT193CR */
+ PORTCR(194, 0xe60520c2), /* PORT194CR */
+ PORTCR(195, 0xe60520c3), /* PORT195CR */
+ PORTCR(196, 0xe60520c4), /* PORT196CR */
+ PORTCR(197, 0xe60520c5), /* PORT197CR */
+ PORTCR(198, 0xe60520c6), /* PORT198CR */
+ PORTCR(199, 0xe60520c7), /* PORT199CR */
+ PORTCR(200, 0xe60520c8), /* PORT200CR */
+ PORTCR(201, 0xe60520c9), /* PORT201CR */
+ PORTCR(202, 0xe60520ca), /* PORT202CR */
+ PORTCR(203, 0xe60520cb), /* PORT203CR */
+ PORTCR(204, 0xe60520cc), /* PORT204CR */
+ PORTCR(205, 0xe60520cd), /* PORT205CR */
+ PORTCR(206, 0xe60520ce), /* PORT206CR */
+ PORTCR(207, 0xe60520cf), /* PORT207CR */
+ PORTCR(208, 0xe60520d0), /* PORT208CR */
+ PORTCR(209, 0xe60520d1), /* PORT209CR */
+
+ PORTCR(210, 0xe60530d2), /* PORT210CR */
+ PORTCR(211, 0xe60530d3), /* PORT211CR */
+
+ { PINMUX_CFG_REG("MSEL1CR", 0xe605800c, 32, 1) {
+ MSEL1CR_31_0, MSEL1CR_31_1,
+ MSEL1CR_30_0, MSEL1CR_30_1,
+ MSEL1CR_29_0, MSEL1CR_29_1,
+ MSEL1CR_28_0, MSEL1CR_28_1,
+ MSEL1CR_27_0, MSEL1CR_27_1,
+ MSEL1CR_26_0, MSEL1CR_26_1,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ MSEL1CR_16_0, MSEL1CR_16_1,
+ MSEL1CR_15_0, MSEL1CR_15_1,
+ MSEL1CR_14_0, MSEL1CR_14_1,
+ MSEL1CR_13_0, MSEL1CR_13_1,
+ MSEL1CR_12_0, MSEL1CR_12_1,
+ 0, 0, 0, 0,
+ MSEL1CR_9_0, MSEL1CR_9_1,
+ 0, 0,
+ MSEL1CR_7_0, MSEL1CR_7_1,
+ MSEL1CR_6_0, MSEL1CR_6_1,
+ MSEL1CR_5_0, MSEL1CR_5_1,
+ MSEL1CR_4_0, MSEL1CR_4_1,
+ MSEL1CR_3_0, MSEL1CR_3_1,
+ MSEL1CR_2_0, MSEL1CR_2_1,
+ 0, 0,
+ MSEL1CR_0_0, MSEL1CR_0_1,
+ }
+ },
+ { PINMUX_CFG_REG("MSEL3CR", 0xE6058020, 32, 1) {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ MSEL3CR_15_0, MSEL3CR_15_1,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ MSEL3CR_6_0, MSEL3CR_6_1,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ }
+ },
+ { PINMUX_CFG_REG("MSEL4CR", 0xE6058024, 32, 1) {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ MSEL4CR_19_0, MSEL4CR_19_1,
+ MSEL4CR_18_0, MSEL4CR_18_1,
+ 0, 0, 0, 0,
+ MSEL4CR_15_0, MSEL4CR_15_1,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ MSEL4CR_10_0, MSEL4CR_10_1,
+ 0, 0, 0, 0, 0, 0,
+ MSEL4CR_6_0, MSEL4CR_6_1,
+ 0, 0,
+ MSEL4CR_4_0, MSEL4CR_4_1,
+ 0, 0, 0, 0,
+ MSEL4CR_1_0, MSEL4CR_1_1,
+ 0, 0,
+ }
+ },
+ { PINMUX_CFG_REG("MSEL5CR", 0xE6058028, 32, 1) {
+ MSEL5CR_31_0, MSEL5CR_31_1,
+ MSEL5CR_30_0, MSEL5CR_30_1,
+ MSEL5CR_29_0, MSEL5CR_29_1,
+ 0, 0,
+ MSEL5CR_27_0, MSEL5CR_27_1,
+ 0, 0,
+ MSEL5CR_25_0, MSEL5CR_25_1,
+ 0, 0,
+ MSEL5CR_23_0, MSEL5CR_23_1,
+ 0, 0,
+ MSEL5CR_21_0, MSEL5CR_21_1,
+ 0, 0,
+ MSEL5CR_19_0, MSEL5CR_19_1,
+ 0, 0,
+ MSEL5CR_17_0, MSEL5CR_17_1,
+ 0, 0,
+ MSEL5CR_15_0, MSEL5CR_15_1,
+ MSEL5CR_14_0, MSEL5CR_14_1,
+ MSEL5CR_13_0, MSEL5CR_13_1,
+ MSEL5CR_12_0, MSEL5CR_12_1,
+ MSEL5CR_11_0, MSEL5CR_11_1,
+ MSEL5CR_10_0, MSEL5CR_10_1,
+ 0, 0,
+ MSEL5CR_8_0, MSEL5CR_8_1,
+ MSEL5CR_7_0, MSEL5CR_7_1,
+ MSEL5CR_6_0, MSEL5CR_6_1,
+ MSEL5CR_5_0, MSEL5CR_5_1,
+ MSEL5CR_4_0, MSEL5CR_4_1,
+ MSEL5CR_3_0, MSEL5CR_3_1,
+ MSEL5CR_2_0, MSEL5CR_2_1,
+ 0, 0,
+ MSEL5CR_0_0, MSEL5CR_0_1,
+ }
+ },
+ { },
+};
+
+static struct pinmux_data_reg pinmux_data_regs[] = {
+ { PINMUX_DATA_REG("PORTL031_000DR", 0xe6054800, 32) {
+ PORT31_DATA, PORT30_DATA, PORT29_DATA, PORT28_DATA,
+ PORT27_DATA, PORT26_DATA, PORT25_DATA, PORT24_DATA,
+ PORT23_DATA, PORT22_DATA, PORT21_DATA, PORT20_DATA,
+ PORT19_DATA, PORT18_DATA, PORT17_DATA, PORT16_DATA,
+ PORT15_DATA, PORT14_DATA, PORT13_DATA, PORT12_DATA,
+ PORT11_DATA, PORT10_DATA, PORT9_DATA, PORT8_DATA,
+ PORT7_DATA, PORT6_DATA, PORT5_DATA, PORT4_DATA,
+ PORT3_DATA, PORT2_DATA, PORT1_DATA, PORT0_DATA }
+ },
+ { PINMUX_DATA_REG("PORTL063_032DR", 0xe6054804, 32) {
+ PORT63_DATA, PORT62_DATA, PORT61_DATA, PORT60_DATA,
+ PORT59_DATA, PORT58_DATA, PORT57_DATA, PORT56_DATA,
+ PORT55_DATA, PORT54_DATA, PORT53_DATA, PORT52_DATA,
+ PORT51_DATA, PORT50_DATA, PORT49_DATA, PORT48_DATA,
+ PORT47_DATA, PORT46_DATA, PORT45_DATA, PORT44_DATA,
+ PORT43_DATA, PORT42_DATA, PORT41_DATA, PORT40_DATA,
+ PORT39_DATA, PORT38_DATA, PORT37_DATA, PORT36_DATA,
+ PORT35_DATA, PORT34_DATA, PORT33_DATA, PORT32_DATA }
+ },
+ { PINMUX_DATA_REG("PORTL095_064DR", 0xe6054808, 32) {
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ PORT83_DATA, PORT82_DATA, PORT81_DATA, PORT80_DATA,
+ PORT79_DATA, PORT78_DATA, PORT77_DATA, PORT76_DATA,
+ PORT75_DATA, PORT74_DATA, PORT73_DATA, PORT72_DATA,
+ PORT71_DATA, PORT70_DATA, PORT69_DATA, PORT68_DATA,
+ PORT67_DATA, PORT66_DATA, PORT65_DATA, PORT64_DATA }
+ },
+ { PINMUX_DATA_REG("PORTD095_064DR", 0xe6055808, 32) {
+ PORT95_DATA, PORT94_DATA, PORT93_DATA, PORT92_DATA,
+ PORT91_DATA, PORT90_DATA, PORT89_DATA, PORT88_DATA,
+ PORT87_DATA, PORT86_DATA, PORT85_DATA, PORT84_DATA,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0 }
+ },
+ { PINMUX_DATA_REG("PORTD127_096DR", 0xe605580c, 32) {
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, PORT114_DATA, PORT113_DATA, PORT112_DATA,
+ PORT111_DATA, PORT110_DATA, PORT109_DATA, PORT108_DATA,
+ PORT107_DATA, PORT106_DATA, PORT105_DATA, PORT104_DATA,
+ PORT103_DATA, PORT102_DATA, PORT101_DATA, PORT100_DATA,
+ PORT99_DATA, PORT98_DATA, PORT97_DATA, PORT96_DATA }
+ },
+ { PINMUX_DATA_REG("PORTR127_096DR", 0xe605680C, 32) {
+ PORT127_DATA, PORT126_DATA, PORT125_DATA, PORT124_DATA,
+ PORT123_DATA, PORT122_DATA, PORT121_DATA, PORT120_DATA,
+ PORT119_DATA, PORT118_DATA, PORT117_DATA, PORT116_DATA,
+ PORT115_DATA, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0 }
+ },
+ { PINMUX_DATA_REG("PORTR159_128DR", 0xe6056810, 32) {
+ PORT159_DATA, PORT158_DATA, PORT157_DATA, PORT156_DATA,
+ PORT155_DATA, PORT154_DATA, PORT153_DATA, PORT152_DATA,
+ PORT151_DATA, PORT150_DATA, PORT149_DATA, PORT148_DATA,
+ PORT147_DATA, PORT146_DATA, PORT145_DATA, PORT144_DATA,
+ PORT143_DATA, PORT142_DATA, PORT141_DATA, PORT140_DATA,
+ PORT139_DATA, PORT138_DATA, PORT137_DATA, PORT136_DATA,
+ PORT135_DATA, PORT134_DATA, PORT133_DATA, PORT132_DATA,
+ PORT131_DATA, PORT130_DATA, PORT129_DATA, PORT128_DATA }
+ },
+ { PINMUX_DATA_REG("PORTR191_160DR", 0xe6056814, 32) {
+ PORT191_DATA, PORT190_DATA, PORT189_DATA, PORT188_DATA,
+ PORT187_DATA, PORT186_DATA, PORT185_DATA, PORT184_DATA,
+ PORT183_DATA, PORT182_DATA, PORT181_DATA, PORT180_DATA,
+ PORT179_DATA, PORT178_DATA, PORT177_DATA, PORT176_DATA,
+ PORT175_DATA, PORT174_DATA, PORT173_DATA, PORT172_DATA,
+ PORT171_DATA, PORT170_DATA, PORT169_DATA, PORT168_DATA,
+ PORT167_DATA, PORT166_DATA, PORT165_DATA, PORT164_DATA,
+ PORT163_DATA, PORT162_DATA, PORT161_DATA, PORT160_DATA }
+ },
+ { PINMUX_DATA_REG("PORTR223_192DR", 0xe6056818, 32) {
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, PORT209_DATA, PORT208_DATA,
+ PORT207_DATA, PORT206_DATA, PORT205_DATA, PORT204_DATA,
+ PORT203_DATA, PORT202_DATA, PORT201_DATA, PORT200_DATA,
+ PORT199_DATA, PORT198_DATA, PORT197_DATA, PORT196_DATA,
+ PORT195_DATA, PORT194_DATA, PORT193_DATA, PORT192_DATA }
+ },
+ { PINMUX_DATA_REG("PORTU223_192DR", 0xe6057818, 32) {
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ PORT211_DATA, PORT210_DATA, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0 }
+ },
+ { },
+};
+
+static struct pinmux_info r8a7740_pinmux_info = {
+ .name = "r8a7740_pfc",
+ .reserved_id = PINMUX_RESERVED,
+ .data = { PINMUX_DATA_BEGIN,
+ PINMUX_DATA_END },
+ .input = { PINMUX_INPUT_BEGIN,
+ PINMUX_INPUT_END },
+ .input_pu = { PINMUX_INPUT_PULLUP_BEGIN,
+ PINMUX_INPUT_PULLUP_END },
+ .input_pd = { PINMUX_INPUT_PULLDOWN_BEGIN,
+ PINMUX_INPUT_PULLDOWN_END },
+ .output = { PINMUX_OUTPUT_BEGIN,
+ PINMUX_OUTPUT_END },
+ .mark = { PINMUX_MARK_BEGIN,
+ PINMUX_MARK_END },
+ .function = { PINMUX_FUNCTION_BEGIN,
+ PINMUX_FUNCTION_END },
+
+ .first_gpio = GPIO_PORT0,
+ .last_gpio = GPIO_FN_TRACEAUD_FROM_MEMC,
+
+ .gpios = pinmux_gpios,
+ .cfg_regs = pinmux_config_regs,
+ .data_regs = pinmux_data_regs,
+
+ .gpio_data = pinmux_data,
+ .gpio_data_size = ARRAY_SIZE(pinmux_data),
+};
+
+void r8a7740_pinmux_init(void)
+{
+ register_pinmux(&r8a7740_pinmux_info);
+}
diff --git a/arch/arm/mach-shmobile/pfc-r8a7779.c b/arch/arm/mach-shmobile/pfc-r8a7779.c
new file mode 100644
index 0000000..963532f
--- /dev/null
+++ b/arch/arm/mach-shmobile/pfc-r8a7779.c
@@ -0,0 +1,2645 @@
+/*
+ * r8a7779 processor support - PFC hardware block
+ *
+ * Copyright (C) 2011 Renesas Solutions Corp.
+ * Copyright (C) 2011 Magnus Damm
+ *
+ * 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; version 2 of the License.
+ *
+ * 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 <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/gpio.h>
+#include <linux/ioport.h>
+#include <mach/r8a7779.h>
+
+#define CPU_32_PORT(fn, pfx, sfx) \
+ PORT_10(fn, pfx, sfx), PORT_10(fn, pfx##1, sfx), \
+ PORT_10(fn, pfx##2, sfx), PORT_1(fn, pfx##30, sfx), \
+ PORT_1(fn, pfx##31, sfx)
+
+#define CPU_32_PORT6(fn, pfx, sfx) \
+ PORT_1(fn, pfx##0, sfx), PORT_1(fn, pfx##1, sfx), \
+ PORT_1(fn, pfx##2, sfx), PORT_1(fn, pfx##3, sfx), \
+ PORT_1(fn, pfx##4, sfx), PORT_1(fn, pfx##5, sfx), \
+ PORT_1(fn, pfx##6, sfx), PORT_1(fn, pfx##7, sfx), \
+ PORT_1(fn, pfx##8, sfx)
+
+#define CPU_ALL_PORT(fn, pfx, sfx) \
+ CPU_32_PORT(fn, pfx##_0_, sfx), \
+ CPU_32_PORT(fn, pfx##_1_, sfx), \
+ CPU_32_PORT(fn, pfx##_2_, sfx), \
+ CPU_32_PORT(fn, pfx##_3_, sfx), \
+ CPU_32_PORT(fn, pfx##_4_, sfx), \
+ CPU_32_PORT(fn, pfx##_5_, sfx), \
+ CPU_32_PORT6(fn, pfx##_6_, sfx)
+
+#define _GP_GPIO(pfx, sfx) PINMUX_GPIO(GPIO_GP##pfx, GP##pfx##_DATA)
+#define _GP_DATA(pfx, sfx) PINMUX_DATA(GP##pfx##_DATA, GP##pfx##_FN, \
+ GP##pfx##_IN, GP##pfx##_OUT)
+
+#define _GP_INOUTSEL(pfx, sfx) GP##pfx##_IN, GP##pfx##_OUT
+#define _GP_INDT(pfx, sfx) GP##pfx##_DATA
+
+#define GP_ALL(str) CPU_ALL_PORT(_PORT_ALL, GP, str)
+#define PINMUX_GPIO_GP_ALL() CPU_ALL_PORT(_GP_GPIO, , unused)
+#define PINMUX_DATA_GP_ALL() CPU_ALL_PORT(_GP_DATA, , unused)
+
+
+#define PORT_10_REV(fn, pfx, sfx) \
+ PORT_1(fn, pfx##9, sfx), PORT_1(fn, pfx##8, sfx), \
+ PORT_1(fn, pfx##7, sfx), PORT_1(fn, pfx##6, sfx), \
+ PORT_1(fn, pfx##5, sfx), PORT_1(fn, pfx##4, sfx), \
+ PORT_1(fn, pfx##3, sfx), PORT_1(fn, pfx##2, sfx), \
+ PORT_1(fn, pfx##1, sfx), PORT_1(fn, pfx##0, sfx)
+
+#define CPU_32_PORT_REV(fn, pfx, sfx) \
+ PORT_1(fn, pfx##31, sfx), PORT_1(fn, pfx##30, sfx), \
+ PORT_10_REV(fn, pfx##2, sfx), PORT_10_REV(fn, pfx##1, sfx), \
+ PORT_10_REV(fn, pfx, sfx)
+
+#define GP_INOUTSEL(bank) CPU_32_PORT_REV(_GP_INOUTSEL, _##bank##_, unused)
+#define GP_INDT(bank) CPU_32_PORT_REV(_GP_INDT, _##bank##_, unused)
+
+#define PINMUX_IPSR_DATA(ipsr, fn) PINMUX_DATA(fn##_MARK, FN_##ipsr, FN_##fn)
+#define PINMUX_IPSR_MODSEL_DATA(ipsr, fn, ms) PINMUX_DATA(fn##_MARK, FN_##ms, \
+ FN_##ipsr, FN_##fn)
+
+enum {
+ PINMUX_RESERVED = 0,
+
+ PINMUX_DATA_BEGIN,
+ GP_ALL(DATA), /* GP_0_0_DATA -> GP_6_8_DATA */
+ PINMUX_DATA_END,
+
+ PINMUX_INPUT_BEGIN,
+ GP_ALL(IN), /* GP_0_0_IN -> GP_6_8_IN */
+ PINMUX_INPUT_END,
+
+ PINMUX_OUTPUT_BEGIN,
+ GP_ALL(OUT), /* GP_0_0_OUT -> GP_6_8_OUT */
+ PINMUX_OUTPUT_END,
+
+ PINMUX_FUNCTION_BEGIN,
+ GP_ALL(FN), /* GP_0_0_FN -> GP_6_8_FN */
+
+ /* GPSR0 */
+ FN_AVS1, FN_AVS2, FN_IP0_7_6, FN_A17,
+ FN_A18, FN_A19, FN_IP0_9_8, FN_IP0_11_10,
+ FN_IP0_13_12, FN_IP0_15_14, FN_IP0_18_16, FN_IP0_22_19,
+ FN_IP0_24_23, FN_IP0_25, FN_IP0_27_26, FN_IP1_1_0,
+ FN_IP1_3_2, FN_IP1_6_4, FN_IP1_10_7, FN_IP1_14_11,
+ FN_IP1_18_15, FN_IP0_5_3, FN_IP0_30_28, FN_IP2_18_16,
+ FN_IP2_21_19, FN_IP2_30_28, FN_IP3_2_0, FN_IP3_11_9,
+ FN_IP3_14_12, FN_IP3_22_21, FN_IP3_26_24, FN_IP3_31_29,
+
+ /* GPSR1 */
+ FN_IP4_1_0, FN_IP4_4_2, FN_IP4_7_5, FN_IP4_10_8,
+ FN_IP4_11, FN_IP4_12, FN_IP4_13, FN_IP4_14,
+ FN_IP4_15, FN_IP4_16, FN_IP4_19_17, FN_IP4_22_20,
+ FN_IP4_23, FN_IP4_24, FN_IP4_25, FN_IP4_26,
+ FN_IP4_27, FN_IP4_28, FN_IP4_31_29, FN_IP5_2_0,
+ FN_IP5_3, FN_IP5_4, FN_IP5_5, FN_IP5_6,
+ FN_IP5_7, FN_IP5_8, FN_IP5_10_9, FN_IP5_12_11,
+ FN_IP5_14_13, FN_IP5_16_15, FN_IP5_20_17, FN_IP5_23_21,
+
+ /* GPSR2 */
+ FN_IP5_27_24, FN_IP8_20, FN_IP8_22_21, FN_IP8_24_23,
+ FN_IP8_27_25, FN_IP8_30_28, FN_IP9_1_0, FN_IP9_3_2,
+ FN_IP9_4, FN_IP9_5, FN_IP9_6, FN_IP9_7,
+ FN_IP9_9_8, FN_IP9_11_10, FN_IP9_13_12, FN_IP9_15_14,
+ FN_IP9_18_16, FN_IP9_21_19, FN_IP9_23_22, FN_IP9_25_24,
+ FN_IP9_27_26, FN_IP9_29_28, FN_IP10_2_0, FN_IP10_5_3,
+ FN_IP10_8_6, FN_IP10_11_9, FN_IP10_14_12, FN_IP10_17_15,
+ FN_IP10_20_18, FN_IP10_23_21, FN_IP10_25_24, FN_IP10_28_26,
+
+ /* GPSR3 */
+ FN_IP10_31_29, FN_IP11_2_0, FN_IP11_5_3, FN_IP11_8_6,
+ FN_IP11_11_9, FN_IP11_14_12, FN_IP11_17_15, FN_IP11_20_18,
+ FN_IP11_23_21, FN_IP11_26_24, FN_IP11_29_27, FN_IP12_2_0,
+ FN_IP12_5_3, FN_IP12_8_6, FN_IP12_11_9, FN_IP12_14_12,
+ FN_IP12_17_15, FN_IP7_16_15, FN_IP7_18_17, FN_IP7_28_27,
+ FN_IP7_30_29, FN_IP7_20_19, FN_IP7_22_21, FN_IP7_24_23,
+ FN_IP7_26_25, FN_IP1_20_19, FN_IP1_22_21, FN_IP1_24_23,
+ FN_IP5_28, FN_IP5_30_29, FN_IP6_1_0, FN_IP6_3_2,
+
+ /* GPSR4 */
+ FN_IP6_5_4, FN_IP6_7_6, FN_IP6_8, FN_IP6_11_9,
+ FN_IP6_14_12, FN_IP6_17_15, FN_IP6_19_18, FN_IP6_22_20,
+ FN_IP6_24_23, FN_IP6_26_25, FN_IP6_30_29, FN_IP7_1_0,
+ FN_IP7_3_2, FN_IP7_6_4, FN_IP7_9_7, FN_IP7_12_10,
+ FN_IP7_14_13, FN_IP2_7_4, FN_IP2_11_8, FN_IP2_15_12,
+ FN_IP1_28_25, FN_IP2_3_0, FN_IP8_3_0, FN_IP8_7_4,
+ FN_IP8_11_8, FN_IP8_15_12, FN_PENC0, FN_PENC1,
+ FN_IP0_2_0, FN_IP8_17_16, FN_IP8_18, FN_IP8_19,
+
+ /* GPSR5 */
+ FN_A1, FN_A2, FN_A3, FN_A4,
+ FN_A5, FN_A6, FN_A7, FN_A8,
+ FN_A9, FN_A10, FN_A11, FN_A12,
+ FN_A13, FN_A14, FN_A15, FN_A16,
+ FN_RD, FN_WE0, FN_WE1, FN_EX_WAIT0,
+ FN_IP3_23, FN_IP3_27, FN_IP3_28, FN_IP2_22,
+ FN_IP2_23, FN_IP2_24, FN_IP2_25, FN_IP2_26,
+ FN_IP2_27, FN_IP3_3, FN_IP3_4, FN_IP3_5,
+
+ /* GPSR6 */
+ FN_IP3_6, FN_IP3_7, FN_IP3_8, FN_IP3_15,
+ FN_IP3_16, FN_IP3_17, FN_IP3_18, FN_IP3_19,
+ FN_IP3_20,
+
+ /* IPSR0 */
+ FN_RD_WR, FN_FWE, FN_ATAG0, FN_VI1_R7,
+ FN_HRTS1, FN_RX4_C,
+ FN_CS1_A26, FN_HSPI_TX2, FN_SDSELF_B,
+ FN_CS0, FN_HSPI_CS2_B,
+ FN_CLKOUT, FN_TX3C_IRDA_TX_C, FN_PWM0_B,
+ FN_A25, FN_SD1_WP, FN_MMC0_D5, FN_FD5,
+ FN_HSPI_RX2, FN_VI1_R3, FN_TX5_B, FN_SSI_SDATA7_B,
+ FN_CTS0_B,
+ FN_A24, FN_SD1_CD, FN_MMC0_D4, FN_FD4,
+ FN_HSPI_CS2, FN_VI1_R2, FN_SSI_WS78_B,
+ FN_A23, FN_FCLE, FN_HSPI_CLK2, FN_VI1_R1,
+ FN_A22, FN_RX5_D, FN_HSPI_RX2_B, FN_VI1_R0,
+ FN_A21, FN_SCK5_D, FN_HSPI_CLK2_B,
+ FN_A20, FN_TX5_D, FN_HSPI_TX2_B,
+ FN_A0, FN_SD1_DAT3, FN_MMC0_D3, FN_FD3,
+ FN_BS, FN_SD1_DAT2, FN_MMC0_D2, FN_FD2,
+ FN_ATADIR0, FN_SDSELF, FN_HCTS1, FN_TX4_C,
+ FN_PENC2, FN_SCK0, FN_PWM1, FN_PWMFSW0,
+ FN_SCIF_CLK, FN_TCLK0_C,
+
+ /* IPSR1 */
+ FN_EX_CS0, FN_RX3_C_IRDA_RX_C, FN_MMC0_D6,
+ FN_FD6, FN_EX_CS1, FN_MMC0_D7, FN_FD7,
+ FN_EX_CS2, FN_SD1_CLK, FN_MMC0_CLK, FN_FALE,
+ FN_ATACS00, FN_EX_CS3, FN_SD1_CMD, FN_MMC0_CMD,
+ FN_FRE, FN_ATACS10, FN_VI1_R4, FN_RX5_B,
+ FN_HSCK1, FN_SSI_SDATA8_B, FN_RTS0_B_TANS_B, FN_SSI_SDATA9,
+ FN_EX_CS4, FN_SD1_DAT0, FN_MMC0_D0, FN_FD0,
+ FN_ATARD0, FN_VI1_R5, FN_SCK5_B, FN_HTX1,
+ FN_TX2_E, FN_TX0_B, FN_SSI_SCK9, FN_EX_CS5,
+ FN_SD1_DAT1, FN_MMC0_D1, FN_FD1, FN_ATAWR0,
+ FN_VI1_R6, FN_HRX1, FN_RX2_E, FN_RX0_B,
+ FN_SSI_WS9, FN_MLB_CLK, FN_PWM2, FN_SCK4,
+ FN_MLB_SIG, FN_PWM3, FN_TX4, FN_MLB_DAT,
+ FN_PWM4, FN_RX4, FN_HTX0, FN_TX1,
+ FN_SDATA, FN_CTS0_C, FN_SUB_TCK, FN_CC5_STATE2,
+ FN_CC5_STATE10, FN_CC5_STATE18, FN_CC5_STATE26, FN_CC5_STATE34,
+
+ /* IPSR2 */
+ FN_HRX0, FN_RX1, FN_SCKZ, FN_RTS0_C_TANS_C,
+ FN_SUB_TDI, FN_CC5_STATE3, FN_CC5_STATE11, FN_CC5_STATE19,
+ FN_CC5_STATE27, FN_CC5_STATE35, FN_HSCK0, FN_SCK1,
+ FN_MTS, FN_PWM5, FN_SCK0_C, FN_SSI_SDATA9_B,
+ FN_SUB_TDO, FN_CC5_STATE0, FN_CC5_STATE8, FN_CC5_STATE16,
+ FN_CC5_STATE24, FN_CC5_STATE32, FN_HCTS0, FN_CTS1,
+ FN_STM, FN_PWM0_D, FN_RX0_C, FN_SCIF_CLK_C,
+ FN_SUB_TRST, FN_TCLK1_B, FN_CC5_OSCOUT, FN_HRTS0,
+ FN_RTS1_TANS, FN_MDATA, FN_TX0_C, FN_SUB_TMS,
+ FN_CC5_STATE1, FN_CC5_STATE9, FN_CC5_STATE17, FN_CC5_STATE25,
+ FN_CC5_STATE33, FN_DU0_DR0, FN_LCDOUT0, FN_DREQ0,
+ FN_GPS_CLK_B, FN_AUDATA0, FN_TX5_C, FN_DU0_DR1,
+ FN_LCDOUT1, FN_DACK0, FN_DRACK0, FN_GPS_SIGN_B,
+ FN_AUDATA1, FN_RX5_C, FN_DU0_DR2, FN_LCDOUT2,
+ FN_DU0_DR3, FN_LCDOUT3, FN_DU0_DR4, FN_LCDOUT4,
+ FN_DU0_DR5, FN_LCDOUT5, FN_DU0_DR6, FN_LCDOUT6,
+ FN_DU0_DR7, FN_LCDOUT7, FN_DU0_DG0, FN_LCDOUT8,
+ FN_DREQ1, FN_SCL2, FN_AUDATA2,
+
+ /* IPSR3 */
+ FN_DU0_DG1, FN_LCDOUT9, FN_DACK1, FN_SDA2,
+ FN_AUDATA3, FN_DU0_DG2, FN_LCDOUT10, FN_DU0_DG3,
+ FN_LCDOUT11, FN_DU0_DG4, FN_LCDOUT12, FN_DU0_DG5,
+ FN_LCDOUT13, FN_DU0_DG6, FN_LCDOUT14, FN_DU0_DG7,
+ FN_LCDOUT15, FN_DU0_DB0, FN_LCDOUT16, FN_EX_WAIT1,
+ FN_SCL1, FN_TCLK1, FN_AUDATA4, FN_DU0_DB1,
+ FN_LCDOUT17, FN_EX_WAIT2, FN_SDA1, FN_GPS_MAG_B,
+ FN_AUDATA5, FN_SCK5_C, FN_DU0_DB2, FN_LCDOUT18,
+ FN_DU0_DB3, FN_LCDOUT19, FN_DU0_DB4, FN_LCDOUT20,
+ FN_DU0_DB5, FN_LCDOUT21, FN_DU0_DB6, FN_LCDOUT22,
+ FN_DU0_DB7, FN_LCDOUT23, FN_DU0_DOTCLKIN, FN_QSTVA_QVS,
+ FN_TX3_D_IRDA_TX_D, FN_SCL3_B, FN_DU0_DOTCLKOUT0, FN_QCLK,
+ FN_DU0_DOTCLKOUT1, FN_QSTVB_QVE, FN_RX3_D_IRDA_RX_D, FN_SDA3_B,
+ FN_SDA2_C, FN_DACK0_B, FN_DRACK0_B, FN_DU0_EXHSYNC_DU0_HSYNC,
+ FN_QSTH_QHS, FN_DU0_EXVSYNC_DU0_VSYNC, FN_QSTB_QHE,
+ FN_DU0_EXODDF_DU0_ODDF_DISP_CDE, FN_QCPV_QDE, FN_CAN1_TX,
+ FN_TX2_C, FN_SCL2_C, FN_REMOCON,
+
+ /* IPSR4 */
+ FN_DU0_DISP, FN_QPOLA, FN_CAN_CLK_C, FN_SCK2_C,
+ FN_DU0_CDE, FN_QPOLB, FN_CAN1_RX, FN_RX2_C,
+ FN_DREQ0_B, FN_SSI_SCK78_B, FN_SCK0_B, FN_DU1_DR0,
+ FN_VI2_DATA0_VI2_B0, FN_PWM6, FN_SD3_CLK, FN_TX3_E_IRDA_TX_E,
+ FN_AUDCK, FN_PWMFSW0_B, FN_DU1_DR1, FN_VI2_DATA1_VI2_B1,
+ FN_PWM0, FN_SD3_CMD, FN_RX3_E_IRDA_RX_E, FN_AUDSYNC,
+ FN_CTS0_D, FN_DU1_DR2, FN_VI2_G0, FN_DU1_DR3,
+ FN_VI2_G1, FN_DU1_DR4, FN_VI2_G2, FN_DU1_DR5,
+ FN_VI2_G3, FN_DU1_DR6, FN_VI2_G4, FN_DU1_DR7,
+ FN_VI2_G5, FN_DU1_DG0, FN_VI2_DATA2_VI2_B2, FN_SCL1_B,
+ FN_SD3_DAT2, FN_SCK3_E, FN_AUDATA6, FN_TX0_D,
+ FN_DU1_DG1, FN_VI2_DATA3_VI2_B3, FN_SDA1_B, FN_SD3_DAT3,
+ FN_SCK5, FN_AUDATA7, FN_RX0_D, FN_DU1_DG2,
+ FN_VI2_G6, FN_DU1_DG3, FN_VI2_G7, FN_DU1_DG4,
+ FN_VI2_R0, FN_DU1_DG5, FN_VI2_R1, FN_DU1_DG6,
+ FN_VI2_R2, FN_DU1_DG7, FN_VI2_R3, FN_DU1_DB0,
+ FN_VI2_DATA4_VI2_B4, FN_SCL2_B, FN_SD3_DAT0, FN_TX5,
+ FN_SCK0_D,
+
+ /* IPSR5 */
+ FN_DU1_DB1, FN_VI2_DATA5_VI2_B5, FN_SDA2_B, FN_SD3_DAT1,
+ FN_RX5, FN_RTS0_D_TANS_D, FN_DU1_DB2, FN_VI2_R4,
+ FN_DU1_DB3, FN_VI2_R5, FN_DU1_DB4, FN_VI2_R6,
+ FN_DU1_DB5, FN_VI2_R7, FN_DU1_DB6, FN_SCL2_D,
+ FN_DU1_DB7, FN_SDA2_D, FN_DU1_DOTCLKIN, FN_VI2_CLKENB,
+ FN_HSPI_CS1, FN_SCL1_D, FN_DU1_DOTCLKOUT, FN_VI2_FIELD,
+ FN_SDA1_D, FN_DU1_EXHSYNC_DU1_HSYNC, FN_VI2_HSYNC,
+ FN_VI3_HSYNC, FN_DU1_EXVSYNC_DU1_VSYNC, FN_VI2_VSYNC, FN_VI3_VSYNC,
+ FN_DU1_EXODDF_DU1_ODDF_DISP_CDE, FN_VI2_CLK, FN_TX3_B_IRDA_TX_B,
+ FN_SD3_CD, FN_HSPI_TX1, FN_VI1_CLKENB, FN_VI3_CLKENB,
+ FN_AUDIO_CLKC, FN_TX2_D, FN_SPEEDIN, FN_GPS_SIGN_D,
+ FN_DU1_DISP, FN_VI2_DATA6_VI2_B6, FN_TCLK0, FN_QSTVA_B_QVS_B,
+ FN_HSPI_CLK1, FN_SCK2_D, FN_AUDIO_CLKOUT_B, FN_GPS_MAG_D,
+ FN_DU1_CDE, FN_VI2_DATA7_VI2_B7, FN_RX3_B_IRDA_RX_B,
+ FN_SD3_WP, FN_HSPI_RX1, FN_VI1_FIELD, FN_VI3_FIELD,
+ FN_AUDIO_CLKOUT, FN_RX2_D, FN_GPS_CLK_C, FN_GPS_CLK_D,
+ FN_AUDIO_CLKA, FN_CAN_TXCLK, FN_AUDIO_CLKB, FN_USB_OVC2,
+ FN_CAN_DEBUGOUT0, FN_MOUT0,
+
+ /* IPSR6 */
+ FN_SSI_SCK0129, FN_CAN_DEBUGOUT1, FN_MOUT1, FN_SSI_WS0129,
+ FN_CAN_DEBUGOUT2, FN_MOUT2, FN_SSI_SDATA0, FN_CAN_DEBUGOUT3,
+ FN_MOUT5, FN_SSI_SDATA1, FN_CAN_DEBUGOUT4, FN_MOUT6,
+ FN_SSI_SDATA2, FN_CAN_DEBUGOUT5, FN_SSI_SCK34, FN_CAN_DEBUGOUT6,
+ FN_CAN0_TX_B, FN_IERX, FN_SSI_SCK9_C, FN_SSI_WS34,
+ FN_CAN_DEBUGOUT7, FN_CAN0_RX_B, FN_IETX, FN_SSI_WS9_C,
+ FN_SSI_SDATA3, FN_PWM0_C, FN_CAN_DEBUGOUT8, FN_CAN_CLK_B,
+ FN_IECLK, FN_SCIF_CLK_B, FN_TCLK0_B, FN_SSI_SDATA4,
+ FN_CAN_DEBUGOUT9, FN_SSI_SDATA9_C, FN_SSI_SCK5, FN_ADICLK,
+ FN_CAN_DEBUGOUT10, FN_SCK3, FN_TCLK0_D, FN_SSI_WS5,
+ FN_ADICS_SAMP, FN_CAN_DEBUGOUT11, FN_TX3_IRDA_TX, FN_SSI_SDATA5,
+ FN_ADIDATA, FN_CAN_DEBUGOUT12, FN_RX3_IRDA_RX, FN_SSI_SCK6,
+ FN_ADICHS0, FN_CAN0_TX, FN_IERX_B,
+
+ /* IPSR7 */
+ FN_SSI_WS6, FN_ADICHS1, FN_CAN0_RX, FN_IETX_B,
+ FN_SSI_SDATA6, FN_ADICHS2, FN_CAN_CLK, FN_IECLK_B,
+ FN_SSI_SCK78, FN_CAN_DEBUGOUT13, FN_IRQ0_B, FN_SSI_SCK9_B,
+ FN_HSPI_CLK1_C, FN_SSI_WS78, FN_CAN_DEBUGOUT14, FN_IRQ1_B,
+ FN_SSI_WS9_B, FN_HSPI_CS1_C, FN_SSI_SDATA7, FN_CAN_DEBUGOUT15,
+ FN_IRQ2_B, FN_TCLK1_C, FN_HSPI_TX1_C, FN_SSI_SDATA8,
+ FN_VSP, FN_IRQ3_B, FN_HSPI_RX1_C, FN_SD0_CLK,
+ FN_ATACS01, FN_SCK1_B, FN_SD0_CMD, FN_ATACS11,
+ FN_TX1_B, FN_CC5_TDO, FN_SD0_DAT0, FN_ATADIR1,
+ FN_RX1_B, FN_CC5_TRST, FN_SD0_DAT1, FN_ATAG1,
+ FN_SCK2_B, FN_CC5_TMS, FN_SD0_DAT2, FN_ATARD1,
+ FN_TX2_B, FN_CC5_TCK, FN_SD0_DAT3, FN_ATAWR1,
+ FN_RX2_B, FN_CC5_TDI, FN_SD0_CD, FN_DREQ2,
+ FN_RTS1_B_TANS_B, FN_SD0_WP, FN_DACK2, FN_CTS1_B,
+
+ /* IPSR8 */
+ FN_HSPI_CLK0, FN_CTS0, FN_USB_OVC0, FN_AD_CLK,
+ FN_CC5_STATE4, FN_CC5_STATE12, FN_CC5_STATE20, FN_CC5_STATE28,
+ FN_CC5_STATE36, FN_HSPI_CS0, FN_RTS0_TANS, FN_USB_OVC1,
+ FN_AD_DI, FN_CC5_STATE5, FN_CC5_STATE13, FN_CC5_STATE21,
+ FN_CC5_STATE29, FN_CC5_STATE37, FN_HSPI_TX0, FN_TX0,
+ FN_CAN_DEBUG_HW_TRIGGER, FN_AD_DO, FN_CC5_STATE6, FN_CC5_STATE14,
+ FN_CC5_STATE22, FN_CC5_STATE30, FN_CC5_STATE38, FN_HSPI_RX0,
+ FN_RX0, FN_CAN_STEP0, FN_AD_NCS, FN_CC5_STATE7,
+ FN_CC5_STATE15, FN_CC5_STATE23, FN_CC5_STATE31, FN_CC5_STATE39,
+ FN_FMCLK, FN_RDS_CLK, FN_PCMOE, FN_BPFCLK,
+ FN_PCMWE, FN_FMIN, FN_RDS_DATA, FN_VI0_CLK,
+ FN_MMC1_CLK, FN_VI0_CLKENB, FN_TX1_C, FN_HTX1_B,
+ FN_MT1_SYNC, FN_VI0_FIELD, FN_RX1_C, FN_HRX1_B,
+ FN_VI0_HSYNC, FN_VI0_DATA0_B_VI0_B0_B, FN_CTS1_C, FN_TX4_D,
+ FN_MMC1_CMD, FN_HSCK1_B, FN_VI0_VSYNC, FN_VI0_DATA1_B_VI0_B1_B,
+ FN_RTS1_C_TANS_C, FN_RX4_D, FN_PWMFSW0_C,
+
+ /* IPSR9 */
+ FN_VI0_DATA0_VI0_B0, FN_HRTS1_B, FN_MT1_VCXO, FN_VI0_DATA1_VI0_B1,
+ FN_HCTS1_B, FN_MT1_PWM, FN_VI0_DATA2_VI0_B2, FN_MMC1_D0,
+ FN_VI0_DATA3_VI0_B3, FN_MMC1_D1, FN_VI0_DATA4_VI0_B4, FN_MMC1_D2,
+ FN_VI0_DATA5_VI0_B5, FN_MMC1_D3, FN_VI0_DATA6_VI0_B6, FN_MMC1_D4,
+ FN_ARM_TRACEDATA_0, FN_VI0_DATA7_VI0_B7, FN_MMC1_D5,
+ FN_ARM_TRACEDATA_1, FN_VI0_G0, FN_SSI_SCK78_C, FN_IRQ0,
+ FN_ARM_TRACEDATA_2, FN_VI0_G1, FN_SSI_WS78_C, FN_IRQ1,
+ FN_ARM_TRACEDATA_3, FN_VI0_G2, FN_ETH_TXD1, FN_MMC1_D6,
+ FN_ARM_TRACEDATA_4, FN_TS_SPSYNC0, FN_VI0_G3, FN_ETH_CRS_DV,
+ FN_MMC1_D7, FN_ARM_TRACEDATA_5, FN_TS_SDAT0, FN_VI0_G4,
+ FN_ETH_TX_EN, FN_SD2_DAT0_B, FN_ARM_TRACEDATA_6, FN_VI0_G5,
+ FN_ETH_RX_ER, FN_SD2_DAT1_B, FN_ARM_TRACEDATA_7, FN_VI0_G6,
+ FN_ETH_RXD0, FN_SD2_DAT2_B, FN_ARM_TRACEDATA_8, FN_VI0_G7,
+ FN_ETH_RXD1, FN_SD2_DAT3_B, FN_ARM_TRACEDATA_9,
+
+ /* IPSR10 */
+ FN_VI0_R0, FN_SSI_SDATA7_C, FN_SCK1_C, FN_DREQ1_B,
+ FN_ARM_TRACEDATA_10, FN_DREQ0_C, FN_VI0_R1, FN_SSI_SDATA8_C,
+ FN_DACK1_B, FN_ARM_TRACEDATA_11, FN_DACK0_C, FN_DRACK0_C,
+ FN_VI0_R2, FN_ETH_LINK, FN_SD2_CLK_B, FN_IRQ2,
+ FN_ARM_TRACEDATA_12, FN_VI0_R3, FN_ETH_MAGIC, FN_SD2_CMD_B,
+ FN_IRQ3, FN_ARM_TRACEDATA_13, FN_VI0_R4, FN_ETH_REFCLK,
+ FN_SD2_CD_B, FN_HSPI_CLK1_B, FN_ARM_TRACEDATA_14, FN_MT1_CLK,
+ FN_TS_SCK0, FN_VI0_R5, FN_ETH_TXD0, FN_SD2_WP_B, FN_HSPI_CS1_B,
+ FN_ARM_TRACEDATA_15, FN_MT1_D, FN_TS_SDEN0, FN_VI0_R6,
+ FN_ETH_MDC, FN_DREQ2_C, FN_HSPI_TX1_B, FN_TRACECLK,
+ FN_MT1_BEN, FN_PWMFSW0_D, FN_VI0_R7, FN_ETH_MDIO,
+ FN_DACK2_C, FN_HSPI_RX1_B, FN_SCIF_CLK_D, FN_TRACECTL,
+ FN_MT1_PEN, FN_VI1_CLK, FN_SIM_D, FN_SDA3,
+ FN_VI1_HSYNC, FN_VI3_CLK, FN_SSI_SCK4, FN_GPS_SIGN_C,
+ FN_PWMFSW0_E, FN_VI1_VSYNC, FN_AUDIO_CLKOUT_C, FN_SSI_WS4,
+ FN_SIM_CLK, FN_GPS_MAG_C, FN_SPV_TRST, FN_SCL3,
+
+ /* IPSR11 */
+ FN_VI1_DATA0_VI1_B0, FN_SD2_DAT0, FN_SIM_RST, FN_SPV_TCK,
+ FN_ADICLK_B, FN_VI1_DATA1_VI1_B1, FN_SD2_DAT1, FN_MT0_CLK,
+ FN_SPV_TMS, FN_ADICS_B_SAMP_B, FN_VI1_DATA2_VI1_B2, FN_SD2_DAT2,
+ FN_MT0_D, FN_SPVTDI, FN_ADIDATA_B, FN_VI1_DATA3_VI1_B3,
+ FN_SD2_DAT3, FN_MT0_BEN, FN_SPV_TDO, FN_ADICHS0_B,
+ FN_VI1_DATA4_VI1_B4, FN_SD2_CLK, FN_MT0_PEN, FN_SPA_TRST,
+ FN_HSPI_CLK1_D, FN_ADICHS1_B, FN_VI1_DATA5_VI1_B5, FN_SD2_CMD,
+ FN_MT0_SYNC, FN_SPA_TCK, FN_HSPI_CS1_D, FN_ADICHS2_B,
+ FN_VI1_DATA6_VI1_B6, FN_SD2_CD, FN_MT0_VCXO, FN_SPA_TMS,
+ FN_HSPI_TX1_D, FN_VI1_DATA7_VI1_B7, FN_SD2_WP, FN_MT0_PWM,
+ FN_SPA_TDI, FN_HSPI_RX1_D, FN_VI1_G0, FN_VI3_DATA0,
+ FN_DU1_DOTCLKOUT1, FN_TS_SCK1, FN_DREQ2_B, FN_TX2,
+ FN_SPA_TDO, FN_HCTS0_B, FN_VI1_G1, FN_VI3_DATA1,
+ FN_SSI_SCK1, FN_TS_SDEN1, FN_DACK2_B, FN_RX2, FN_HRTS0_B,
+
+ /* IPSR12 */
+ FN_VI1_G2, FN_VI3_DATA2, FN_SSI_WS1, FN_TS_SPSYNC1,
+ FN_SCK2, FN_HSCK0_B, FN_VI1_G3, FN_VI3_DATA3,
+ FN_SSI_SCK2, FN_TS_SDAT1, FN_SCL1_C, FN_HTX0_B,
+ FN_VI1_G4, FN_VI3_DATA4, FN_SSI_WS2, FN_SDA1_C,
+ FN_SIM_RST_B, FN_HRX0_B, FN_VI1_G5, FN_VI3_DATA5,
+ FN_GPS_CLK, FN_FSE, FN_TX4_B, FN_SIM_D_B,
+ FN_VI1_G6, FN_VI3_DATA6, FN_GPS_SIGN, FN_FRB,
+ FN_RX4_B, FN_SIM_CLK_B, FN_VI1_G7, FN_VI3_DATA7,
+ FN_GPS_MAG, FN_FCE, FN_SCK4_B,
+
+ FN_SEL_SCIF5_0, FN_SEL_SCIF5_1, FN_SEL_SCIF5_2, FN_SEL_SCIF5_3,
+ FN_SEL_SCIF4_0, FN_SEL_SCIF4_1, FN_SEL_SCIF4_2, FN_SEL_SCIF4_3,
+ FN_SEL_SCIF3_0, FN_SEL_SCIF3_1, FN_SEL_SCIF3_2,
+ FN_SEL_SCIF3_3, FN_SEL_SCIF3_4,
+ FN_SEL_SCIF2_0, FN_SEL_SCIF2_1, FN_SEL_SCIF2_2,
+ FN_SEL_SCIF2_3, FN_SEL_SCIF2_4,
+ FN_SEL_SCIF1_0, FN_SEL_SCIF1_1, FN_SEL_SCIF1_2,
+ FN_SEL_SCIF0_0, FN_SEL_SCIF0_1, FN_SEL_SCIF0_2, FN_SEL_SCIF0_3,
+ FN_SEL_SSI9_0, FN_SEL_SSI9_1, FN_SEL_SSI9_2,
+ FN_SEL_SSI8_0, FN_SEL_SSI8_1, FN_SEL_SSI8_2,
+ FN_SEL_SSI7_0, FN_SEL_SSI7_1, FN_SEL_SSI7_2,
+ FN_SEL_VI0_0, FN_SEL_VI0_1,
+ FN_SEL_SD2_0, FN_SEL_SD2_1,
+ FN_SEL_INT3_0, FN_SEL_INT3_1,
+ FN_SEL_INT2_0, FN_SEL_INT2_1,
+ FN_SEL_INT1_0, FN_SEL_INT1_1,
+ FN_SEL_INT0_0, FN_SEL_INT0_1,
+ FN_SEL_IE_0, FN_SEL_IE_1,
+ FN_SEL_EXBUS2_0, FN_SEL_EXBUS2_1, FN_SEL_EXBUS2_2,
+ FN_SEL_EXBUS1_0, FN_SEL_EXBUS1_1,
+ FN_SEL_EXBUS0_0, FN_SEL_EXBUS0_1, FN_SEL_EXBUS0_2,
+
+ FN_SEL_TMU1_0, FN_SEL_TMU1_1, FN_SEL_TMU1_2,
+ FN_SEL_TMU0_0, FN_SEL_TMU0_1, FN_SEL_TMU0_2, FN_SEL_TMU0_3,
+ FN_SEL_SCIF_0, FN_SEL_SCIF_1, FN_SEL_SCIF_2, FN_SEL_SCIF_3,
+ FN_SEL_CANCLK_0, FN_SEL_CANCLK_1, FN_SEL_CANCLK_2,
+ FN_SEL_CAN0_0, FN_SEL_CAN0_1,
+ FN_SEL_HSCIF1_0, FN_SEL_HSCIF1_1,
+ FN_SEL_HSCIF0_0, FN_SEL_HSCIF0_1,
+ FN_SEL_PWMFSW_0, FN_SEL_PWMFSW_1, FN_SEL_PWMFSW_2,
+ FN_SEL_PWMFSW_3, FN_SEL_PWMFSW_4,
+ FN_SEL_ADI_0, FN_SEL_ADI_1,
+ FN_SEL_GPS_0, FN_SEL_GPS_1, FN_SEL_GPS_2, FN_SEL_GPS_3,
+ FN_SEL_SIM_0, FN_SEL_SIM_1,
+ FN_SEL_HSPI2_0, FN_SEL_HSPI2_1,
+ FN_SEL_HSPI1_0, FN_SEL_HSPI1_1, FN_SEL_HSPI1_2, FN_SEL_HSPI1_3,
+ FN_SEL_I2C3_0, FN_SEL_I2C3_1,
+ FN_SEL_I2C2_0, FN_SEL_I2C2_1, FN_SEL_I2C2_2, FN_SEL_I2C2_3,
+ FN_SEL_I2C1_0, FN_SEL_I2C1_1, FN_SEL_I2C1_2, FN_SEL_I2C1_3,
+ PINMUX_FUNCTION_END,
+
+ PINMUX_MARK_BEGIN,
+ AVS1_MARK, AVS2_MARK, A17_MARK, A18_MARK,
+ A19_MARK,
+
+ RD_WR_MARK, FWE_MARK, ATAG0_MARK, VI1_R7_MARK,
+ HRTS1_MARK, RX4_C_MARK,
+ CS1_A26_MARK, HSPI_TX2_MARK, SDSELF_B_MARK,
+ CS0_MARK, HSPI_CS2_B_MARK,
+ CLKOUT_MARK, TX3C_IRDA_TX_C_MARK, PWM0_B_MARK,
+ A25_MARK, SD1_WP_MARK, MMC0_D5_MARK, FD5_MARK,
+ HSPI_RX2_MARK, VI1_R3_MARK, TX5_B_MARK, SSI_SDATA7_B_MARK, CTS0_B_MARK,
+ A24_MARK, SD1_CD_MARK, MMC0_D4_MARK, FD4_MARK,
+ HSPI_CS2_MARK, VI1_R2_MARK, SSI_WS78_B_MARK,
+ A23_MARK, FCLE_MARK, HSPI_CLK2_MARK, VI1_R1_MARK,
+ A22_MARK, RX5_D_MARK, HSPI_RX2_B_MARK, VI1_R0_MARK,
+ A21_MARK, SCK5_D_MARK, HSPI_CLK2_B_MARK,
+ A20_MARK, TX5_D_MARK, HSPI_TX2_B_MARK,
+ A0_MARK, SD1_DAT3_MARK, MMC0_D3_MARK, FD3_MARK,
+ BS_MARK, SD1_DAT2_MARK, MMC0_D2_MARK, FD2_MARK,
+ ATADIR0_MARK, SDSELF_MARK, HCTS1_MARK, TX4_C_MARK,
+ PENC2_MARK, SCK0_MARK, PWM1_MARK, PWMFSW0_MARK,
+ SCIF_CLK_MARK, TCLK0_C_MARK,
+
+ EX_CS0_MARK, RX3_C_IRDA_RX_C_MARK, MMC0_D6_MARK,
+ FD6_MARK, EX_CS1_MARK, MMC0_D7_MARK, FD7_MARK,
+ EX_CS2_MARK, SD1_CLK_MARK, MMC0_CLK_MARK, FALE_MARK,
+ ATACS00_MARK, EX_CS3_MARK, SD1_CMD_MARK, MMC0_CMD_MARK,
+ FRE_MARK, ATACS10_MARK, VI1_R4_MARK, RX5_B_MARK,
+ HSCK1_MARK, SSI_SDATA8_B_MARK, RTS0_B_TANS_B_MARK, SSI_SDATA9_MARK,
+ EX_CS4_MARK, SD1_DAT0_MARK, MMC0_D0_MARK, FD0_MARK,
+ ATARD0_MARK, VI1_R5_MARK, SCK5_B_MARK, HTX1_MARK,
+ TX2_E_MARK, TX0_B_MARK, SSI_SCK9_MARK, EX_CS5_MARK,
+ SD1_DAT1_MARK, MMC0_D1_MARK, FD1_MARK, ATAWR0_MARK,
+ VI1_R6_MARK, HRX1_MARK, RX2_E_MARK, RX0_B_MARK,
+ SSI_WS9_MARK, MLB_CLK_MARK, PWM2_MARK, SCK4_MARK,
+ MLB_SIG_MARK, PWM3_MARK, TX4_MARK, MLB_DAT_MARK,
+ PWM4_MARK, RX4_MARK, HTX0_MARK, TX1_MARK,
+ SDATA_MARK, CTS0_C_MARK, SUB_TCK_MARK, CC5_STATE2_MARK,
+ CC5_STATE10_MARK, CC5_STATE18_MARK, CC5_STATE26_MARK, CC5_STATE34_MARK,
+
+ HRX0_MARK, RX1_MARK, SCKZ_MARK, RTS0_C_TANS_C_MARK,
+ SUB_TDI_MARK, CC5_STATE3_MARK, CC5_STATE11_MARK, CC5_STATE19_MARK,
+ CC5_STATE27_MARK, CC5_STATE35_MARK, HSCK0_MARK, SCK1_MARK,
+ MTS_MARK, PWM5_MARK, SCK0_C_MARK, SSI_SDATA9_B_MARK,
+ SUB_TDO_MARK, CC5_STATE0_MARK, CC5_STATE8_MARK, CC5_STATE16_MARK,
+ CC5_STATE24_MARK, CC5_STATE32_MARK, HCTS0_MARK, CTS1_MARK,
+ STM_MARK, PWM0_D_MARK, RX0_C_MARK, SCIF_CLK_C_MARK,
+ SUB_TRST_MARK, TCLK1_B_MARK, CC5_OSCOUT_MARK, HRTS0_MARK,
+ RTS1_TANS_MARK, MDATA_MARK, TX0_C_MARK, SUB_TMS_MARK,
+ CC5_STATE1_MARK, CC5_STATE9_MARK, CC5_STATE17_MARK, CC5_STATE25_MARK,
+ CC5_STATE33_MARK, DU0_DR0_MARK, LCDOUT0_MARK, DREQ0_MARK,
+ GPS_CLK_B_MARK, AUDATA0_MARK, TX5_C_MARK, DU0_DR1_MARK,
+ LCDOUT1_MARK, DACK0_MARK, DRACK0_MARK, GPS_SIGN_B_MARK,
+ AUDATA1_MARK, RX5_C_MARK, DU0_DR2_MARK, LCDOUT2_MARK,
+ DU0_DR3_MARK, LCDOUT3_MARK, DU0_DR4_MARK, LCDOUT4_MARK,
+ DU0_DR5_MARK, LCDOUT5_MARK, DU0_DR6_MARK, LCDOUT6_MARK,
+ DU0_DR7_MARK, LCDOUT7_MARK, DU0_DG0_MARK, LCDOUT8_MARK,
+ DREQ1_MARK, SCL2_MARK, AUDATA2_MARK,
+
+ DU0_DG1_MARK, LCDOUT9_MARK, DACK1_MARK, SDA2_MARK,
+ AUDATA3_MARK, DU0_DG2_MARK, LCDOUT10_MARK, DU0_DG3_MARK,
+ LCDOUT11_MARK, DU0_DG4_MARK, LCDOUT12_MARK, DU0_DG5_MARK,
+ LCDOUT13_MARK, DU0_DG6_MARK, LCDOUT14_MARK, DU0_DG7_MARK,
+ LCDOUT15_MARK, DU0_DB0_MARK, LCDOUT16_MARK, EX_WAIT1_MARK,
+ SCL1_MARK, TCLK1_MARK, AUDATA4_MARK, DU0_DB1_MARK,
+ LCDOUT17_MARK, EX_WAIT2_MARK, SDA1_MARK, GPS_MAG_B_MARK,
+ AUDATA5_MARK, SCK5_C_MARK, DU0_DB2_MARK, LCDOUT18_MARK,
+ DU0_DB3_MARK, LCDOUT19_MARK, DU0_DB4_MARK, LCDOUT20_MARK,
+ DU0_DB5_MARK, LCDOUT21_MARK, DU0_DB6_MARK, LCDOUT22_MARK,
+ DU0_DB7_MARK, LCDOUT23_MARK, DU0_DOTCLKIN_MARK, QSTVA_QVS_MARK,
+ TX3_D_IRDA_TX_D_MARK, SCL3_B_MARK, DU0_DOTCLKOUT0_MARK, QCLK_MARK,
+ DU0_DOTCLKOUT1_MARK, QSTVB_QVE_MARK, RX3_D_IRDA_RX_D_MARK, SDA3_B_MARK,
+ SDA2_C_MARK, DACK0_B_MARK, DRACK0_B_MARK, DU0_EXHSYNC_DU0_HSYNC_MARK,
+ QSTH_QHS_MARK, DU0_EXVSYNC_DU0_VSYNC_MARK, QSTB_QHE_MARK,
+ DU0_EXODDF_DU0_ODDF_DISP_CDE_MARK, QCPV_QDE_MARK, CAN1_TX_MARK,
+ TX2_C_MARK, SCL2_C_MARK, REMOCON_MARK,
+
+ DU0_DISP_MARK, QPOLA_MARK, CAN_CLK_C_MARK, SCK2_C_MARK,
+ DU0_CDE_MARK, QPOLB_MARK, CAN1_RX_MARK, RX2_C_MARK,
+ DREQ0_B_MARK, SSI_SCK78_B_MARK, SCK0_B_MARK, DU1_DR0_MARK,
+ VI2_DATA0_VI2_B0_MARK, PWM6_MARK, SD3_CLK_MARK, TX3_E_IRDA_TX_E_MARK,
+ AUDCK_MARK, PWMFSW0_B_MARK, DU1_DR1_MARK, VI2_DATA1_VI2_B1_MARK,
+ PWM0_MARK, SD3_CMD_MARK, RX3_E_IRDA_RX_E_MARK, AUDSYNC_MARK,
+ CTS0_D_MARK, DU1_DR2_MARK, VI2_G0_MARK, DU1_DR3_MARK,
+ VI2_G1_MARK, DU1_DR4_MARK, VI2_G2_MARK, DU1_DR5_MARK,
+ VI2_G3_MARK, DU1_DR6_MARK, VI2_G4_MARK, DU1_DR7_MARK,
+ VI2_G5_MARK, DU1_DG0_MARK, VI2_DATA2_VI2_B2_MARK, SCL1_B_MARK,
+ SD3_DAT2_MARK, SCK3_E_MARK, AUDATA6_MARK, TX0_D_MARK,
+ DU1_DG1_MARK, VI2_DATA3_VI2_B3_MARK, SDA1_B_MARK, SD3_DAT3_MARK,
+ SCK5_MARK, AUDATA7_MARK, RX0_D_MARK, DU1_DG2_MARK,
+ VI2_G6_MARK, DU1_DG3_MARK, VI2_G7_MARK, DU1_DG4_MARK,
+ VI2_R0_MARK, DU1_DG5_MARK, VI2_R1_MARK, DU1_DG6_MARK,
+ VI2_R2_MARK, DU1_DG7_MARK, VI2_R3_MARK, DU1_DB0_MARK,
+ VI2_DATA4_VI2_B4_MARK, SCL2_B_MARK, SD3_DAT0_MARK, TX5_MARK,
+ SCK0_D_MARK,
+
+ DU1_DB1_MARK, VI2_DATA5_VI2_B5_MARK, SDA2_B_MARK, SD3_DAT1_MARK,
+ RX5_MARK, RTS0_D_TANS_D_MARK, DU1_DB2_MARK, VI2_R4_MARK,
+ DU1_DB3_MARK, VI2_R5_MARK, DU1_DB4_MARK, VI2_R6_MARK,
+ DU1_DB5_MARK, VI2_R7_MARK, DU1_DB6_MARK, SCL2_D_MARK,
+ DU1_DB7_MARK, SDA2_D_MARK, DU1_DOTCLKIN_MARK, VI2_CLKENB_MARK,
+ HSPI_CS1_MARK, SCL1_D_MARK, DU1_DOTCLKOUT_MARK, VI2_FIELD_MARK,
+ SDA1_D_MARK, DU1_EXHSYNC_DU1_HSYNC_MARK, VI2_HSYNC_MARK,
+ VI3_HSYNC_MARK, DU1_EXVSYNC_DU1_VSYNC_MARK, VI2_VSYNC_MARK,
+ VI3_VSYNC_MARK, DU1_EXODDF_DU1_ODDF_DISP_CDE_MARK, VI2_CLK_MARK,
+ TX3_B_IRDA_TX_B_MARK, SD3_CD_MARK, HSPI_TX1_MARK, VI1_CLKENB_MARK,
+ VI3_CLKENB_MARK, AUDIO_CLKC_MARK, TX2_D_MARK, SPEEDIN_MARK,
+ GPS_SIGN_D_MARK, DU1_DISP_MARK, VI2_DATA6_VI2_B6_MARK, TCLK0_MARK,
+ QSTVA_B_QVS_B_MARK, HSPI_CLK1_MARK, SCK2_D_MARK, AUDIO_CLKOUT_B_MARK,
+ GPS_MAG_D_MARK, DU1_CDE_MARK, VI2_DATA7_VI2_B7_MARK,
+ RX3_B_IRDA_RX_B_MARK, SD3_WP_MARK, HSPI_RX1_MARK, VI1_FIELD_MARK,
+ VI3_FIELD_MARK, AUDIO_CLKOUT_MARK, RX2_D_MARK, GPS_CLK_C_MARK,
+ GPS_CLK_D_MARK, AUDIO_CLKA_MARK, CAN_TXCLK_MARK, AUDIO_CLKB_MARK,
+ USB_OVC2_MARK, CAN_DEBUGOUT0_MARK, MOUT0_MARK,
+
+ SSI_SCK0129_MARK, CAN_DEBUGOUT1_MARK, MOUT1_MARK, SSI_WS0129_MARK,
+ CAN_DEBUGOUT2_MARK, MOUT2_MARK, SSI_SDATA0_MARK, CAN_DEBUGOUT3_MARK,
+ MOUT5_MARK, SSI_SDATA1_MARK, CAN_DEBUGOUT4_MARK, MOUT6_MARK,
+ SSI_SDATA2_MARK, CAN_DEBUGOUT5_MARK, SSI_SCK34_MARK,
+ CAN_DEBUGOUT6_MARK, CAN0_TX_B_MARK, IERX_MARK, SSI_SCK9_C_MARK,
+ SSI_WS34_MARK, CAN_DEBUGOUT7_MARK, CAN0_RX_B_MARK, IETX_MARK,
+ SSI_WS9_C_MARK, SSI_SDATA3_MARK, PWM0_C_MARK, CAN_DEBUGOUT8_MARK,
+ CAN_CLK_B_MARK, IECLK_MARK, SCIF_CLK_B_MARK, TCLK0_B_MARK,
+ SSI_SDATA4_MARK, CAN_DEBUGOUT9_MARK, SSI_SDATA9_C_MARK, SSI_SCK5_MARK,
+ ADICLK_MARK, CAN_DEBUGOUT10_MARK, SCK3_MARK, TCLK0_D_MARK,
+ SSI_WS5_MARK, ADICS_SAMP_MARK, CAN_DEBUGOUT11_MARK, TX3_IRDA_TX_MARK,
+ SSI_SDATA5_MARK, ADIDATA_MARK, CAN_DEBUGOUT12_MARK, RX3_IRDA_RX_MARK,
+ SSI_SCK6_MARK, ADICHS0_MARK, CAN0_TX_MARK, IERX_B_MARK,
+
+ SSI_WS6_MARK, ADICHS1_MARK, CAN0_RX_MARK, IETX_B_MARK,
+ SSI_SDATA6_MARK, ADICHS2_MARK, CAN_CLK_MARK, IECLK_B_MARK,
+ SSI_SCK78_MARK, CAN_DEBUGOUT13_MARK, IRQ0_B_MARK, SSI_SCK9_B_MARK,
+ HSPI_CLK1_C_MARK, SSI_WS78_MARK, CAN_DEBUGOUT14_MARK, IRQ1_B_MARK,
+ SSI_WS9_B_MARK, HSPI_CS1_C_MARK, SSI_SDATA7_MARK, CAN_DEBUGOUT15_MARK,
+ IRQ2_B_MARK, TCLK1_C_MARK, HSPI_TX1_C_MARK, SSI_SDATA8_MARK,
+ VSP_MARK, IRQ3_B_MARK, HSPI_RX1_C_MARK, SD0_CLK_MARK,
+ ATACS01_MARK, SCK1_B_MARK, SD0_CMD_MARK, ATACS11_MARK,
+ TX1_B_MARK, CC5_TDO_MARK, SD0_DAT0_MARK, ATADIR1_MARK,
+ RX1_B_MARK, CC5_TRST_MARK, SD0_DAT1_MARK, ATAG1_MARK,
+ SCK2_B_MARK, CC5_TMS_MARK, SD0_DAT2_MARK, ATARD1_MARK,
+ TX2_B_MARK, CC5_TCK_MARK, SD0_DAT3_MARK, ATAWR1_MARK,
+ RX2_B_MARK, CC5_TDI_MARK, SD0_CD_MARK, DREQ2_MARK,
+ RTS1_B_TANS_B_MARK, SD0_WP_MARK, DACK2_MARK, CTS1_B_MARK,
+
+ HSPI_CLK0_MARK, CTS0_MARK, USB_OVC0_MARK, AD_CLK_MARK,
+ CC5_STATE4_MARK, CC5_STATE12_MARK, CC5_STATE20_MARK, CC5_STATE28_MARK,
+ CC5_STATE36_MARK, HSPI_CS0_MARK, RTS0_TANS_MARK, USB_OVC1_MARK,
+ AD_DI_MARK, CC5_STATE5_MARK, CC5_STATE13_MARK, CC5_STATE21_MARK,
+ CC5_STATE29_MARK, CC5_STATE37_MARK, HSPI_TX0_MARK, TX0_MARK,
+ CAN_DEBUG_HW_TRIGGER_MARK, AD_DO_MARK, CC5_STATE6_MARK,
+ CC5_STATE14_MARK, CC5_STATE22_MARK, CC5_STATE30_MARK,
+ CC5_STATE38_MARK, HSPI_RX0_MARK, RX0_MARK, CAN_STEP0_MARK,
+ AD_NCS_MARK, CC5_STATE7_MARK, CC5_STATE15_MARK, CC5_STATE23_MARK,
+ CC5_STATE31_MARK, CC5_STATE39_MARK, FMCLK_MARK, RDS_CLK_MARK,
+ PCMOE_MARK, BPFCLK_MARK, PCMWE_MARK, FMIN_MARK, RDS_DATA_MARK,
+ VI0_CLK_MARK, MMC1_CLK_MARK, VI0_CLKENB_MARK, TX1_C_MARK, HTX1_B_MARK,
+ MT1_SYNC_MARK, VI0_FIELD_MARK, RX1_C_MARK, HRX1_B_MARK,
+ VI0_HSYNC_MARK, VI0_DATA0_B_VI0_B0_B_MARK, CTS1_C_MARK, TX4_D_MARK,
+ MMC1_CMD_MARK, HSCK1_B_MARK, VI0_VSYNC_MARK, VI0_DATA1_B_VI0_B1_B_MARK,
+ RTS1_C_TANS_C_MARK, RX4_D_MARK, PWMFSW0_C_MARK,
+
+ VI0_DATA0_VI0_B0_MARK, HRTS1_B_MARK, MT1_VCXO_MARK,
+ VI0_DATA1_VI0_B1_MARK, HCTS1_B_MARK, MT1_PWM_MARK,
+ VI0_DATA2_VI0_B2_MARK, MMC1_D0_MARK, VI0_DATA3_VI0_B3_MARK,
+ MMC1_D1_MARK, VI0_DATA4_VI0_B4_MARK, MMC1_D2_MARK,
+ VI0_DATA5_VI0_B5_MARK, MMC1_D3_MARK, VI0_DATA6_VI0_B6_MARK,
+ MMC1_D4_MARK, ARM_TRACEDATA_0_MARK, VI0_DATA7_VI0_B7_MARK,
+ MMC1_D5_MARK, ARM_TRACEDATA_1_MARK, VI0_G0_MARK, SSI_SCK78_C_MARK,
+ IRQ0_MARK, ARM_TRACEDATA_2_MARK, VI0_G1_MARK, SSI_WS78_C_MARK,
+ IRQ1_MARK, ARM_TRACEDATA_3_MARK, VI0_G2_MARK, ETH_TXD1_MARK,
+ MMC1_D6_MARK, ARM_TRACEDATA_4_MARK, TS_SPSYNC0_MARK, VI0_G3_MARK,
+ ETH_CRS_DV_MARK, MMC1_D7_MARK, ARM_TRACEDATA_5_MARK, TS_SDAT0_MARK,
+ VI0_G4_MARK, ETH_TX_EN_MARK, SD2_DAT0_B_MARK, ARM_TRACEDATA_6_MARK,
+ VI0_G5_MARK, ETH_RX_ER_MARK, SD2_DAT1_B_MARK, ARM_TRACEDATA_7_MARK,
+ VI0_G6_MARK, ETH_RXD0_MARK, SD2_DAT2_B_MARK, ARM_TRACEDATA_8_MARK,
+ VI0_G7_MARK, ETH_RXD1_MARK, SD2_DAT3_B_MARK, ARM_TRACEDATA_9_MARK,
+
+ VI0_R0_MARK, SSI_SDATA7_C_MARK, SCK1_C_MARK, DREQ1_B_MARK,
+ ARM_TRACEDATA_10_MARK, DREQ0_C_MARK, VI0_R1_MARK, SSI_SDATA8_C_MARK,
+ DACK1_B_MARK, ARM_TRACEDATA_11_MARK, DACK0_C_MARK, DRACK0_C_MARK,
+ VI0_R2_MARK, ETH_LINK_MARK, SD2_CLK_B_MARK, IRQ2_MARK,
+ ARM_TRACEDATA_12_MARK, VI0_R3_MARK, ETH_MAGIC_MARK, SD2_CMD_B_MARK,
+ IRQ3_MARK, ARM_TRACEDATA_13_MARK, VI0_R4_MARK, ETH_REFCLK_MARK,
+ SD2_CD_B_MARK, HSPI_CLK1_B_MARK, ARM_TRACEDATA_14_MARK, MT1_CLK_MARK,
+ TS_SCK0_MARK, VI0_R5_MARK, ETH_TXD0_MARK, SD2_WP_B_MARK,
+ HSPI_CS1_B_MARK, ARM_TRACEDATA_15_MARK, MT1_D_MARK, TS_SDEN0_MARK,
+ VI0_R6_MARK, ETH_MDC_MARK, DREQ2_C_MARK, HSPI_TX1_B_MARK,
+ TRACECLK_MARK, MT1_BEN_MARK, PWMFSW0_D_MARK, VI0_R7_MARK,
+ ETH_MDIO_MARK, DACK2_C_MARK, HSPI_RX1_B_MARK, SCIF_CLK_D_MARK,
+ TRACECTL_MARK, MT1_PEN_MARK, VI1_CLK_MARK, SIM_D_MARK, SDA3_MARK,
+ VI1_HSYNC_MARK, VI3_CLK_MARK, SSI_SCK4_MARK, GPS_SIGN_C_MARK,
+ PWMFSW0_E_MARK, VI1_VSYNC_MARK, AUDIO_CLKOUT_C_MARK, SSI_WS4_MARK,
+ SIM_CLK_MARK, GPS_MAG_C_MARK, SPV_TRST_MARK, SCL3_MARK,
+
+ VI1_DATA0_VI1_B0_MARK, SD2_DAT0_MARK, SIM_RST_MARK, SPV_TCK_MARK,
+ ADICLK_B_MARK, VI1_DATA1_VI1_B1_MARK, SD2_DAT1_MARK, MT0_CLK_MARK,
+ SPV_TMS_MARK, ADICS_B_SAMP_B_MARK, VI1_DATA2_VI1_B2_MARK,
+ SD2_DAT2_MARK, MT0_D_MARK, SPVTDI_MARK, ADIDATA_B_MARK,
+ VI1_DATA3_VI1_B3_MARK, SD2_DAT3_MARK, MT0_BEN_MARK, SPV_TDO_MARK,
+ ADICHS0_B_MARK, VI1_DATA4_VI1_B4_MARK, SD2_CLK_MARK, MT0_PEN_MARK,
+ SPA_TRST_MARK, HSPI_CLK1_D_MARK, ADICHS1_B_MARK,
+ VI1_DATA5_VI1_B5_MARK, SD2_CMD_MARK, MT0_SYNC_MARK, SPA_TCK_MARK,
+ HSPI_CS1_D_MARK, ADICHS2_B_MARK, VI1_DATA6_VI1_B6_MARK, SD2_CD_MARK,
+ MT0_VCXO_MARK, SPA_TMS_MARK, HSPI_TX1_D_MARK, VI1_DATA7_VI1_B7_MARK,
+ SD2_WP_MARK, MT0_PWM_MARK, SPA_TDI_MARK, HSPI_RX1_D_MARK,
+ VI1_G0_MARK, VI3_DATA0_MARK, DU1_DOTCLKOUT1_MARK, TS_SCK1_MARK,
+ DREQ2_B_MARK, TX2_MARK, SPA_TDO_MARK, HCTS0_B_MARK,
+ VI1_G1_MARK, VI3_DATA1_MARK, SSI_SCK1_MARK, TS_SDEN1_MARK,
+ DACK2_B_MARK, RX2_MARK, HRTS0_B_MARK,
+
+ VI1_G2_MARK, VI3_DATA2_MARK, SSI_WS1_MARK, TS_SPSYNC1_MARK,
+ SCK2_MARK, HSCK0_B_MARK, VI1_G3_MARK, VI3_DATA3_MARK,
+ SSI_SCK2_MARK, TS_SDAT1_MARK, SCL1_C_MARK, HTX0_B_MARK,
+ VI1_G4_MARK, VI3_DATA4_MARK, SSI_WS2_MARK, SDA1_C_MARK,
+ SIM_RST_B_MARK, HRX0_B_MARK, VI1_G5_MARK, VI3_DATA5_MARK,
+ GPS_CLK_MARK, FSE_MARK, TX4_B_MARK, SIM_D_B_MARK,
+ VI1_G6_MARK, VI3_DATA6_MARK, GPS_SIGN_MARK, FRB_MARK,
+ RX4_B_MARK, SIM_CLK_B_MARK, VI1_G7_MARK, VI3_DATA7_MARK,
+ GPS_MAG_MARK, FCE_MARK, SCK4_B_MARK,
+ PINMUX_MARK_END,
+};
+
+static pinmux_enum_t pinmux_data[] = {
+ PINMUX_DATA_GP_ALL(), /* PINMUX_DATA(GP_M_N_DATA, GP_M_N_FN...), */
+
+ PINMUX_DATA(AVS1_MARK, FN_AVS1),
+ PINMUX_DATA(AVS1_MARK, FN_AVS1),
+ PINMUX_DATA(A17_MARK, FN_A17),
+ PINMUX_DATA(A18_MARK, FN_A18),
+ PINMUX_DATA(A19_MARK, FN_A19),
+
+ PINMUX_IPSR_DATA(IP0_2_0, PENC2),
+ PINMUX_IPSR_MODSEL_DATA(IP0_2_0, SCK0, SEL_SCIF0_0),
+ PINMUX_IPSR_DATA(IP0_2_0, PWM1),
+ PINMUX_IPSR_MODSEL_DATA(IP0_2_0, PWMFSW0, SEL_PWMFSW_0),
+ PINMUX_IPSR_MODSEL_DATA(IP0_2_0, SCIF_CLK, SEL_SCIF_0),
+ PINMUX_IPSR_MODSEL_DATA(IP0_2_0, TCLK0_C, SEL_TMU0_2),
+ PINMUX_IPSR_DATA(IP0_5_3, BS),
+ PINMUX_IPSR_DATA(IP0_5_3, SD1_DAT2),
+ PINMUX_IPSR_DATA(IP0_5_3, MMC0_D2),
+ PINMUX_IPSR_DATA(IP0_5_3, FD2),
+ PINMUX_IPSR_DATA(IP0_5_3, ATADIR0),
+ PINMUX_IPSR_DATA(IP0_5_3, SDSELF),
+ PINMUX_IPSR_MODSEL_DATA(IP0_5_3, HCTS1, SEL_HSCIF1_0),
+ PINMUX_IPSR_DATA(IP0_5_3, TX4_C),
+ PINMUX_IPSR_DATA(IP0_7_6, A0),
+ PINMUX_IPSR_DATA(IP0_7_6, SD1_DAT3),
+ PINMUX_IPSR_DATA(IP0_7_6, MMC0_D3),
+ PINMUX_IPSR_DATA(IP0_7_6, FD3),
+ PINMUX_IPSR_DATA(IP0_9_8, A20),
+ PINMUX_IPSR_DATA(IP0_9_8, TX5_D),
+ PINMUX_IPSR_DATA(IP0_9_8, HSPI_TX2_B),
+ PINMUX_IPSR_DATA(IP0_11_10, A21),
+ PINMUX_IPSR_MODSEL_DATA(IP0_11_10, SCK5_D, SEL_SCIF5_3),
+ PINMUX_IPSR_MODSEL_DATA(IP0_11_10, HSPI_CLK2_B, SEL_HSPI2_1),
+ PINMUX_IPSR_DATA(IP0_13_12, A22),
+ PINMUX_IPSR_MODSEL_DATA(IP0_13_12, RX5_D, SEL_SCIF5_3),
+ PINMUX_IPSR_MODSEL_DATA(IP0_13_12, HSPI_RX2_B, SEL_HSPI2_1),
+ PINMUX_IPSR_DATA(IP0_13_12, VI1_R0),
+ PINMUX_IPSR_DATA(IP0_15_14, A23),
+ PINMUX_IPSR_DATA(IP0_15_14, FCLE),
+ PINMUX_IPSR_MODSEL_DATA(IP0_15_14, HSPI_CLK2, SEL_HSPI2_0),
+ PINMUX_IPSR_DATA(IP0_15_14, VI1_R1),
+ PINMUX_IPSR_DATA(IP0_18_16, A24),
+ PINMUX_IPSR_DATA(IP0_18_16, SD1_CD),
+ PINMUX_IPSR_DATA(IP0_18_16, MMC0_D4),
+ PINMUX_IPSR_DATA(IP0_18_16, FD4),
+ PINMUX_IPSR_MODSEL_DATA(IP0_18_16, HSPI_CS2, SEL_HSPI2_0),
+ PINMUX_IPSR_DATA(IP0_18_16, VI1_R2),
+ PINMUX_IPSR_MODSEL_DATA(IP0_18_16, SSI_WS78_B, SEL_SSI7_1),
+ PINMUX_IPSR_DATA(IP0_22_19, A25),
+ PINMUX_IPSR_DATA(IP0_22_19, SD1_WP),
+ PINMUX_IPSR_DATA(IP0_22_19, MMC0_D5),
+ PINMUX_IPSR_DATA(IP0_22_19, FD5),
+ PINMUX_IPSR_MODSEL_DATA(IP0_22_19, HSPI_RX2, SEL_HSPI2_0),
+ PINMUX_IPSR_DATA(IP0_22_19, VI1_R3),
+ PINMUX_IPSR_DATA(IP0_22_19, TX5_B),
+ PINMUX_IPSR_MODSEL_DATA(IP0_22_19, SSI_SDATA7_B, SEL_SSI7_1),
+ PINMUX_IPSR_MODSEL_DATA(IP0_22_19, CTS0_B, SEL_SCIF0_1),
+ PINMUX_IPSR_DATA(IP0_24_23, CLKOUT),
+ PINMUX_IPSR_DATA(IP0_24_23, TX3C_IRDA_TX_C),
+ PINMUX_IPSR_DATA(IP0_24_23, PWM0_B),
+ PINMUX_IPSR_DATA(IP0_25, CS0),
+ PINMUX_IPSR_MODSEL_DATA(IP0_25, HSPI_CS2_B, SEL_HSPI2_1),
+ PINMUX_IPSR_DATA(IP0_27_26, CS1_A26),
+ PINMUX_IPSR_DATA(IP0_27_26, HSPI_TX2),
+ PINMUX_IPSR_DATA(IP0_27_26, SDSELF_B),
+ PINMUX_IPSR_DATA(IP0_30_28, RD_WR),
+ PINMUX_IPSR_DATA(IP0_30_28, FWE),
+ PINMUX_IPSR_DATA(IP0_30_28, ATAG0),
+ PINMUX_IPSR_DATA(IP0_30_28, VI1_R7),
+ PINMUX_IPSR_MODSEL_DATA(IP0_30_28, HRTS1, SEL_HSCIF1_0),
+ PINMUX_IPSR_MODSEL_DATA(IP0_30_28, RX4_C, SEL_SCIF4_2),
+
+ PINMUX_IPSR_DATA(IP1_1_0, EX_CS0),
+ PINMUX_IPSR_MODSEL_DATA(IP1_1_0, RX3_C_IRDA_RX_C, SEL_SCIF3_2),
+ PINMUX_IPSR_DATA(IP1_1_0, MMC0_D6),
+ PINMUX_IPSR_DATA(IP1_1_0, FD6),
+ PINMUX_IPSR_DATA(IP1_3_2, EX_CS1),
+ PINMUX_IPSR_DATA(IP1_3_2, MMC0_D7),
+ PINMUX_IPSR_DATA(IP1_3_2, FD7),
+ PINMUX_IPSR_DATA(IP1_6_4, EX_CS2),
+ PINMUX_IPSR_DATA(IP1_6_4, SD1_CLK),
+ PINMUX_IPSR_DATA(IP1_6_4, MMC0_CLK),
+ PINMUX_IPSR_DATA(IP1_6_4, FALE),
+ PINMUX_IPSR_DATA(IP1_6_4, ATACS00),
+ PINMUX_IPSR_DATA(IP1_10_7, EX_CS3),
+ PINMUX_IPSR_DATA(IP1_10_7, SD1_CMD),
+ PINMUX_IPSR_DATA(IP1_10_7, MMC0_CMD),
+ PINMUX_IPSR_DATA(IP1_10_7, FRE),
+ PINMUX_IPSR_DATA(IP1_10_7, ATACS10),
+ PINMUX_IPSR_DATA(IP1_10_7, VI1_R4),
+ PINMUX_IPSR_MODSEL_DATA(IP1_10_7, RX5_B, SEL_SCIF5_1),
+ PINMUX_IPSR_MODSEL_DATA(IP1_10_7, HSCK1, SEL_HSCIF1_0),
+ PINMUX_IPSR_MODSEL_DATA(IP1_10_7, SSI_SDATA8_B, SEL_SSI8_1),
+ PINMUX_IPSR_MODSEL_DATA(IP1_10_7, RTS0_B_TANS_B, SEL_SCIF0_1),
+ PINMUX_IPSR_MODSEL_DATA(IP1_10_7, SSI_SDATA9, SEL_SSI9_0),
+ PINMUX_IPSR_DATA(IP1_14_11, EX_CS4),
+ PINMUX_IPSR_DATA(IP1_14_11, SD1_DAT0),
+ PINMUX_IPSR_DATA(IP1_14_11, MMC0_D0),
+ PINMUX_IPSR_DATA(IP1_14_11, FD0),
+ PINMUX_IPSR_DATA(IP1_14_11, ATARD0),
+ PINMUX_IPSR_DATA(IP1_14_11, VI1_R5),
+ PINMUX_IPSR_MODSEL_DATA(IP1_14_11, SCK5_B, SEL_SCIF5_1),
+ PINMUX_IPSR_DATA(IP1_14_11, HTX1),
+ PINMUX_IPSR_DATA(IP1_14_11, TX2_E),
+ PINMUX_IPSR_DATA(IP1_14_11, TX0_B),
+ PINMUX_IPSR_MODSEL_DATA(IP1_14_11, SSI_SCK9, SEL_SSI9_0),
+ PINMUX_IPSR_DATA(IP1_18_15, EX_CS5),
+ PINMUX_IPSR_DATA(IP1_18_15, SD1_DAT1),
+ PINMUX_IPSR_DATA(IP1_18_15, MMC0_D1),
+ PINMUX_IPSR_DATA(IP1_18_15, FD1),
+ PINMUX_IPSR_DATA(IP1_18_15, ATAWR0),
+ PINMUX_IPSR_DATA(IP1_18_15, VI1_R6),
+ PINMUX_IPSR_MODSEL_DATA(IP1_18_15, HRX1, SEL_HSCIF1_0),
+ PINMUX_IPSR_MODSEL_DATA(IP1_18_15, RX2_E, SEL_SCIF2_4),
+ PINMUX_IPSR_MODSEL_DATA(IP1_18_15, RX0_B, SEL_SCIF0_1),
+ PINMUX_IPSR_MODSEL_DATA(IP1_18_15, SSI_WS9, SEL_SSI9_0),
+ PINMUX_IPSR_DATA(IP1_20_19, MLB_CLK),
+ PINMUX_IPSR_DATA(IP1_20_19, PWM2),
+ PINMUX_IPSR_MODSEL_DATA(IP1_20_19, SCK4, SEL_SCIF4_0),
+ PINMUX_IPSR_DATA(IP1_22_21, MLB_SIG),
+ PINMUX_IPSR_DATA(IP1_22_21, PWM3),
+ PINMUX_IPSR_DATA(IP1_22_21, TX4),
+ PINMUX_IPSR_DATA(IP1_24_23, MLB_DAT),
+ PINMUX_IPSR_DATA(IP1_24_23, PWM4),
+ PINMUX_IPSR_MODSEL_DATA(IP1_24_23, RX4, SEL_SCIF4_0),
+ PINMUX_IPSR_DATA(IP1_28_25, HTX0),
+ PINMUX_IPSR_DATA(IP1_28_25, TX1),
+ PINMUX_IPSR_DATA(IP1_28_25, SDATA),
+ PINMUX_IPSR_MODSEL_DATA(IP1_28_25, CTS0_C, SEL_SCIF0_2),
+ PINMUX_IPSR_DATA(IP1_28_25, SUB_TCK),
+ PINMUX_IPSR_DATA(IP1_28_25, CC5_STATE2),
+ PINMUX_IPSR_DATA(IP1_28_25, CC5_STATE10),
+ PINMUX_IPSR_DATA(IP1_28_25, CC5_STATE18),
+ PINMUX_IPSR_DATA(IP1_28_25, CC5_STATE26),
+ PINMUX_IPSR_DATA(IP1_28_25, CC5_STATE34),
+
+ PINMUX_IPSR_MODSEL_DATA(IP2_3_0, HRX0, SEL_HSCIF0_0),
+ PINMUX_IPSR_MODSEL_DATA(IP2_3_0, RX1, SEL_SCIF1_0),
+ PINMUX_IPSR_DATA(IP2_3_0, SCKZ),
+ PINMUX_IPSR_MODSEL_DATA(IP2_3_0, RTS0_C_TANS_C, SEL_SCIF0_2),
+ PINMUX_IPSR_DATA(IP2_3_0, SUB_TDI),
+ PINMUX_IPSR_DATA(IP2_3_0, CC5_STATE3),
+ PINMUX_IPSR_DATA(IP2_3_0, CC5_STATE11),
+ PINMUX_IPSR_DATA(IP2_3_0, CC5_STATE19),
+ PINMUX_IPSR_DATA(IP2_3_0, CC5_STATE27),
+ PINMUX_IPSR_DATA(IP2_3_0, CC5_STATE35),
+ PINMUX_IPSR_MODSEL_DATA(IP2_7_4, HSCK0, SEL_HSCIF0_0),
+ PINMUX_IPSR_MODSEL_DATA(IP2_7_4, SCK1, SEL_SCIF1_0),
+ PINMUX_IPSR_DATA(IP2_7_4, MTS),
+ PINMUX_IPSR_DATA(IP2_7_4, PWM5),
+ PINMUX_IPSR_MODSEL_DATA(IP2_7_4, SCK0_C, SEL_SCIF0_2),
+ PINMUX_IPSR_MODSEL_DATA(IP2_7_4, SSI_SDATA9_B, SEL_SSI9_1),
+ PINMUX_IPSR_DATA(IP2_7_4, SUB_TDO),
+ PINMUX_IPSR_DATA(IP2_7_4, CC5_STATE0),
+ PINMUX_IPSR_DATA(IP2_7_4, CC5_STATE8),
+ PINMUX_IPSR_DATA(IP2_7_4, CC5_STATE16),
+ PINMUX_IPSR_DATA(IP2_7_4, CC5_STATE24),
+ PINMUX_IPSR_DATA(IP2_7_4, CC5_STATE32),
+ PINMUX_IPSR_MODSEL_DATA(IP2_11_8, HCTS0, SEL_HSCIF0_0),
+ PINMUX_IPSR_MODSEL_DATA(IP2_11_8, CTS1, SEL_SCIF1_0),
+ PINMUX_IPSR_DATA(IP2_11_8, STM),
+ PINMUX_IPSR_DATA(IP2_11_8, PWM0_D),
+ PINMUX_IPSR_MODSEL_DATA(IP2_11_8, RX0_C, SEL_SCIF0_2),
+ PINMUX_IPSR_MODSEL_DATA(IP2_11_8, SCIF_CLK_C, SEL_SCIF_2),
+ PINMUX_IPSR_DATA(IP2_11_8, SUB_TRST),
+ PINMUX_IPSR_MODSEL_DATA(IP2_11_8, TCLK1_B, SEL_TMU1_1),
+ PINMUX_IPSR_DATA(IP2_11_8, CC5_OSCOUT),
+ PINMUX_IPSR_MODSEL_DATA(IP2_15_12, HRTS0, SEL_HSCIF0_0),
+ PINMUX_IPSR_MODSEL_DATA(IP2_15_12, RTS1_TANS, SEL_SCIF1_0),
+ PINMUX_IPSR_DATA(IP2_15_12, MDATA),
+ PINMUX_IPSR_DATA(IP2_15_12, TX0_C),
+ PINMUX_IPSR_DATA(IP2_15_12, SUB_TMS),
+ PINMUX_IPSR_DATA(IP2_15_12, CC5_STATE1),
+ PINMUX_IPSR_DATA(IP2_15_12, CC5_STATE9),
+ PINMUX_IPSR_DATA(IP2_15_12, CC5_STATE17),
+ PINMUX_IPSR_DATA(IP2_15_12, CC5_STATE25),
+ PINMUX_IPSR_DATA(IP2_15_12, CC5_STATE33),
+ PINMUX_IPSR_DATA(IP2_18_16, DU0_DR0),
+ PINMUX_IPSR_DATA(IP2_18_16, LCDOUT0),
+ PINMUX_IPSR_MODSEL_DATA(IP2_18_16, DREQ0, SEL_EXBUS0_0),
+ PINMUX_IPSR_MODSEL_DATA(IP2_18_16, GPS_CLK_B, SEL_GPS_1),
+ PINMUX_IPSR_DATA(IP2_18_16, AUDATA0),
+ PINMUX_IPSR_DATA(IP2_18_16, TX5_C),
+ PINMUX_IPSR_DATA(IP2_21_19, DU0_DR1),
+ PINMUX_IPSR_DATA(IP2_21_19, LCDOUT1),
+ PINMUX_IPSR_DATA(IP2_21_19, DACK0),
+ PINMUX_IPSR_DATA(IP2_21_19, DRACK0),
+ PINMUX_IPSR_MODSEL_DATA(IP2_21_19, GPS_SIGN_B, SEL_GPS_1),
+ PINMUX_IPSR_DATA(IP2_21_19, AUDATA1),
+ PINMUX_IPSR_MODSEL_DATA(IP2_21_19, RX5_C, SEL_SCIF5_2),
+ PINMUX_IPSR_DATA(IP2_22, DU0_DR2),
+ PINMUX_IPSR_DATA(IP2_22, LCDOUT2),
+ PINMUX_IPSR_DATA(IP2_23, DU0_DR3),
+ PINMUX_IPSR_DATA(IP2_23, LCDOUT3),
+ PINMUX_IPSR_DATA(IP2_24, DU0_DR4),
+ PINMUX_IPSR_DATA(IP2_24, LCDOUT4),
+ PINMUX_IPSR_DATA(IP2_25, DU0_DR5),
+ PINMUX_IPSR_DATA(IP2_25, LCDOUT5),
+ PINMUX_IPSR_DATA(IP2_26, DU0_DR6),
+ PINMUX_IPSR_DATA(IP2_26, LCDOUT6),
+ PINMUX_IPSR_DATA(IP2_27, DU0_DR7),
+ PINMUX_IPSR_DATA(IP2_27, LCDOUT7),
+ PINMUX_IPSR_DATA(IP2_30_28, DU0_DG0),
+ PINMUX_IPSR_DATA(IP2_30_28, LCDOUT8),
+ PINMUX_IPSR_MODSEL_DATA(IP2_30_28, DREQ1, SEL_EXBUS1_0),
+ PINMUX_IPSR_MODSEL_DATA(IP2_30_28, SCL2, SEL_I2C2_0),
+ PINMUX_IPSR_DATA(IP2_30_28, AUDATA2),
+
+ PINMUX_IPSR_DATA(IP3_2_0, DU0_DG1),
+ PINMUX_IPSR_DATA(IP3_2_0, LCDOUT9),
+ PINMUX_IPSR_DATA(IP3_2_0, DACK1),
+ PINMUX_IPSR_MODSEL_DATA(IP3_2_0, SDA2, SEL_I2C2_0),
+ PINMUX_IPSR_DATA(IP3_2_0, AUDATA3),
+ PINMUX_IPSR_DATA(IP3_3, DU0_DG2),
+ PINMUX_IPSR_DATA(IP3_3, LCDOUT10),
+ PINMUX_IPSR_DATA(IP3_4, DU0_DG3),
+ PINMUX_IPSR_DATA(IP3_4, LCDOUT11),
+ PINMUX_IPSR_DATA(IP3_5, DU0_DG4),
+ PINMUX_IPSR_DATA(IP3_5, LCDOUT12),
+ PINMUX_IPSR_DATA(IP3_6, DU0_DG5),
+ PINMUX_IPSR_DATA(IP3_6, LCDOUT13),
+ PINMUX_IPSR_DATA(IP3_7, DU0_DG6),
+ PINMUX_IPSR_DATA(IP3_7, LCDOUT14),
+ PINMUX_IPSR_DATA(IP3_8, DU0_DG7),
+ PINMUX_IPSR_DATA(IP3_8, LCDOUT15),
+ PINMUX_IPSR_DATA(IP3_11_9, DU0_DB0),
+ PINMUX_IPSR_DATA(IP3_11_9, LCDOUT16),
+ PINMUX_IPSR_DATA(IP3_11_9, EX_WAIT1),
+ PINMUX_IPSR_MODSEL_DATA(IP3_11_9, SCL1, SEL_I2C1_0),
+ PINMUX_IPSR_MODSEL_DATA(IP3_11_9, TCLK1, SEL_TMU1_0),
+ PINMUX_IPSR_DATA(IP3_11_9, AUDATA4),
+ PINMUX_IPSR_DATA(IP3_14_12, DU0_DB1),
+ PINMUX_IPSR_DATA(IP3_14_12, LCDOUT17),
+ PINMUX_IPSR_DATA(IP3_14_12, EX_WAIT2),
+ PINMUX_IPSR_MODSEL_DATA(IP3_14_12, SDA1, SEL_I2C1_0),
+ PINMUX_IPSR_MODSEL_DATA(IP3_14_12, GPS_MAG_B, SEL_GPS_1),
+ PINMUX_IPSR_DATA(IP3_14_12, AUDATA5),
+ PINMUX_IPSR_MODSEL_DATA(IP3_14_12, SCK5_C, SEL_SCIF5_2),
+ PINMUX_IPSR_DATA(IP3_15, DU0_DB2),
+ PINMUX_IPSR_DATA(IP3_15, LCDOUT18),
+ PINMUX_IPSR_DATA(IP3_16, DU0_DB3),
+ PINMUX_IPSR_DATA(IP3_16, LCDOUT19),
+ PINMUX_IPSR_DATA(IP3_17, DU0_DB4),
+ PINMUX_IPSR_DATA(IP3_17, LCDOUT20),
+ PINMUX_IPSR_DATA(IP3_18, DU0_DB5),
+ PINMUX_IPSR_DATA(IP3_18, LCDOUT21),
+ PINMUX_IPSR_DATA(IP3_19, DU0_DB6),
+ PINMUX_IPSR_DATA(IP3_19, LCDOUT22),
+ PINMUX_IPSR_DATA(IP3_20, DU0_DB7),
+ PINMUX_IPSR_DATA(IP3_20, LCDOUT23),
+ PINMUX_IPSR_DATA(IP3_22_21, DU0_DOTCLKIN),
+ PINMUX_IPSR_DATA(IP3_22_21, QSTVA_QVS),
+ PINMUX_IPSR_DATA(IP3_22_21, TX3_D_IRDA_TX_D),
+ PINMUX_IPSR_MODSEL_DATA(IP3_22_21, SCL3_B, SEL_I2C3_1),
+ PINMUX_IPSR_DATA(IP3_23, DU0_DOTCLKOUT0),
+ PINMUX_IPSR_DATA(IP3_23, QCLK),
+ PINMUX_IPSR_DATA(IP3_26_24, DU0_DOTCLKOUT1),
+ PINMUX_IPSR_DATA(IP3_26_24, QSTVB_QVE),
+ PINMUX_IPSR_MODSEL_DATA(IP3_26_24, RX3_D_IRDA_RX_D, SEL_SCIF3_3),
+ PINMUX_IPSR_MODSEL_DATA(IP3_26_24, SDA3_B, SEL_I2C3_1),
+ PINMUX_IPSR_MODSEL_DATA(IP3_26_24, SDA2_C, SEL_I2C2_2),
+ PINMUX_IPSR_DATA(IP3_26_24, DACK0_B),
+ PINMUX_IPSR_DATA(IP3_26_24, DRACK0_B),
+ PINMUX_IPSR_DATA(IP3_27, DU0_EXHSYNC_DU0_HSYNC),
+ PINMUX_IPSR_DATA(IP3_27, QSTH_QHS),
+ PINMUX_IPSR_DATA(IP3_28, DU0_EXVSYNC_DU0_VSYNC),
+ PINMUX_IPSR_DATA(IP3_28, QSTB_QHE),
+ PINMUX_IPSR_DATA(IP3_31_29, DU0_EXODDF_DU0_ODDF_DISP_CDE),
+ PINMUX_IPSR_DATA(IP3_31_29, QCPV_QDE),
+ PINMUX_IPSR_DATA(IP3_31_29, CAN1_TX),
+ PINMUX_IPSR_DATA(IP3_31_29, TX2_C),
+ PINMUX_IPSR_MODSEL_DATA(IP3_31_29, SCL2_C, SEL_I2C2_2),
+ PINMUX_IPSR_DATA(IP3_31_29, REMOCON),
+
+ PINMUX_IPSR_DATA(IP4_1_0, DU0_DISP),
+ PINMUX_IPSR_DATA(IP4_1_0, QPOLA),
+ PINMUX_IPSR_MODSEL_DATA(IP4_1_0, CAN_CLK_C, SEL_CANCLK_2),
+ PINMUX_IPSR_MODSEL_DATA(IP4_1_0, SCK2_C, SEL_SCIF2_2),
+ PINMUX_IPSR_DATA(IP4_4_2, DU0_CDE),
+ PINMUX_IPSR_DATA(IP4_4_2, QPOLB),
+ PINMUX_IPSR_DATA(IP4_4_2, CAN1_RX),
+ PINMUX_IPSR_MODSEL_DATA(IP4_4_2, RX2_C, SEL_SCIF2_2),
+ PINMUX_IPSR_MODSEL_DATA(IP4_4_2, DREQ0_B, SEL_EXBUS0_1),
+ PINMUX_IPSR_MODSEL_DATA(IP4_4_2, SSI_SCK78_B, SEL_SSI7_1),
+ PINMUX_IPSR_MODSEL_DATA(IP4_4_2, SCK0_B, SEL_SCIF0_1),
+ PINMUX_IPSR_DATA(IP4_7_5, DU1_DR0),
+ PINMUX_IPSR_DATA(IP4_7_5, VI2_DATA0_VI2_B0),
+ PINMUX_IPSR_DATA(IP4_7_5, PWM6),
+ PINMUX_IPSR_DATA(IP4_7_5, SD3_CLK),
+ PINMUX_IPSR_DATA(IP4_7_5, TX3_E_IRDA_TX_E),
+ PINMUX_IPSR_DATA(IP4_7_5, AUDCK),
+ PINMUX_IPSR_MODSEL_DATA(IP4_7_5, PWMFSW0_B, SEL_PWMFSW_1),
+ PINMUX_IPSR_DATA(IP4_10_8, DU1_DR1),
+ PINMUX_IPSR_DATA(IP4_10_8, VI2_DATA1_VI2_B1),
+ PINMUX_IPSR_DATA(IP4_10_8, PWM0),
+ PINMUX_IPSR_DATA(IP4_10_8, SD3_CMD),
+ PINMUX_IPSR_MODSEL_DATA(IP4_10_8, RX3_E_IRDA_RX_E, SEL_SCIF3_4),
+ PINMUX_IPSR_DATA(IP4_10_8, AUDSYNC),
+ PINMUX_IPSR_MODSEL_DATA(IP4_10_8, CTS0_D, SEL_SCIF0_3),
+ PINMUX_IPSR_DATA(IP4_11, DU1_DR2),
+ PINMUX_IPSR_DATA(IP4_11, VI2_G0),
+ PINMUX_IPSR_DATA(IP4_12, DU1_DR3),
+ PINMUX_IPSR_DATA(IP4_12, VI2_G1),
+ PINMUX_IPSR_DATA(IP4_13, DU1_DR4),
+ PINMUX_IPSR_DATA(IP4_13, VI2_G2),
+ PINMUX_IPSR_DATA(IP4_14, DU1_DR5),
+ PINMUX_IPSR_DATA(IP4_14, VI2_G3),
+ PINMUX_IPSR_DATA(IP4_15, DU1_DR6),
+ PINMUX_IPSR_DATA(IP4_15, VI2_G4),
+ PINMUX_IPSR_DATA(IP4_16, DU1_DR7),
+ PINMUX_IPSR_DATA(IP4_16, VI2_G5),
+ PINMUX_IPSR_DATA(IP4_19_17, DU1_DG0),
+ PINMUX_IPSR_DATA(IP4_19_17, VI2_DATA2_VI2_B2),
+ PINMUX_IPSR_MODSEL_DATA(IP4_19_17, SCL1_B, SEL_I2C1_1),
+ PINMUX_IPSR_DATA(IP4_19_17, SD3_DAT2),
+ PINMUX_IPSR_MODSEL_DATA(IP4_19_17, SCK3_E, SEL_SCIF3_4),
+ PINMUX_IPSR_DATA(IP4_19_17, AUDATA6),
+ PINMUX_IPSR_DATA(IP4_19_17, TX0_D),
+ PINMUX_IPSR_DATA(IP4_22_20, DU1_DG1),
+ PINMUX_IPSR_DATA(IP4_22_20, VI2_DATA3_VI2_B3),
+ PINMUX_IPSR_MODSEL_DATA(IP4_22_20, SDA1_B, SEL_I2C1_1),
+ PINMUX_IPSR_DATA(IP4_22_20, SD3_DAT3),
+ PINMUX_IPSR_MODSEL_DATA(IP4_22_20, SCK5, SEL_SCIF5_0),
+ PINMUX_IPSR_DATA(IP4_22_20, AUDATA7),
+ PINMUX_IPSR_MODSEL_DATA(IP4_22_20, RX0_D, SEL_SCIF0_3),
+ PINMUX_IPSR_DATA(IP4_23, DU1_DG2),
+ PINMUX_IPSR_DATA(IP4_23, VI2_G6),
+ PINMUX_IPSR_DATA(IP4_24, DU1_DG3),
+ PINMUX_IPSR_DATA(IP4_24, VI2_G7),
+ PINMUX_IPSR_DATA(IP4_25, DU1_DG4),
+ PINMUX_IPSR_DATA(IP4_25, VI2_R0),
+ PINMUX_IPSR_DATA(IP4_26, DU1_DG5),
+ PINMUX_IPSR_DATA(IP4_26, VI2_R1),
+ PINMUX_IPSR_DATA(IP4_27, DU1_DG6),
+ PINMUX_IPSR_DATA(IP4_27, VI2_R2),
+ PINMUX_IPSR_DATA(IP4_28, DU1_DG7),
+ PINMUX_IPSR_DATA(IP4_28, VI2_R3),
+ PINMUX_IPSR_DATA(IP4_31_29, DU1_DB0),
+ PINMUX_IPSR_DATA(IP4_31_29, VI2_DATA4_VI2_B4),
+ PINMUX_IPSR_MODSEL_DATA(IP4_31_29, SCL2_B, SEL_I2C2_1),
+ PINMUX_IPSR_DATA(IP4_31_29, SD3_DAT0),
+ PINMUX_IPSR_DATA(IP4_31_29, TX5),
+ PINMUX_IPSR_MODSEL_DATA(IP4_31_29, SCK0_D, SEL_SCIF0_3),
+
+ PINMUX_IPSR_DATA(IP5_2_0, DU1_DB1),
+ PINMUX_IPSR_DATA(IP5_2_0, VI2_DATA5_VI2_B5),
+ PINMUX_IPSR_MODSEL_DATA(IP5_2_0, SDA2_B, SEL_I2C2_1),
+ PINMUX_IPSR_DATA(IP5_2_0, SD3_DAT1),
+ PINMUX_IPSR_MODSEL_DATA(IP5_2_0, RX5, SEL_SCIF5_0),
+ PINMUX_IPSR_MODSEL_DATA(IP5_2_0, RTS0_D_TANS_D, SEL_SCIF0_3),
+ PINMUX_IPSR_DATA(IP5_3, DU1_DB2),
+ PINMUX_IPSR_DATA(IP5_3, VI2_R4),
+ PINMUX_IPSR_DATA(IP5_4, DU1_DB3),
+ PINMUX_IPSR_DATA(IP5_4, VI2_R5),
+ PINMUX_IPSR_DATA(IP5_5, DU1_DB4),
+ PINMUX_IPSR_DATA(IP5_5, VI2_R6),
+ PINMUX_IPSR_DATA(IP5_6, DU1_DB5),
+ PINMUX_IPSR_DATA(IP5_6, VI2_R7),
+ PINMUX_IPSR_DATA(IP5_7, DU1_DB6),
+ PINMUX_IPSR_MODSEL_DATA(IP5_7, SCL2_D, SEL_I2C2_3),
+ PINMUX_IPSR_DATA(IP5_8, DU1_DB7),
+ PINMUX_IPSR_MODSEL_DATA(IP5_8, SDA2_D, SEL_I2C2_3),
+ PINMUX_IPSR_DATA(IP5_10_9, DU1_DOTCLKIN),
+ PINMUX_IPSR_DATA(IP5_10_9, VI2_CLKENB),
+ PINMUX_IPSR_MODSEL_DATA(IP5_10_9, HSPI_CS1, SEL_HSPI1_0),
+ PINMUX_IPSR_MODSEL_DATA(IP5_10_9, SCL1_D, SEL_I2C1_3),
+ PINMUX_IPSR_DATA(IP5_12_11, DU1_DOTCLKOUT),
+ PINMUX_IPSR_DATA(IP5_12_11, VI2_FIELD),
+ PINMUX_IPSR_MODSEL_DATA(IP5_12_11, SDA1_D, SEL_I2C1_3),
+ PINMUX_IPSR_DATA(IP5_14_13, DU1_EXHSYNC_DU1_HSYNC),
+ PINMUX_IPSR_DATA(IP5_14_13, VI2_HSYNC),
+ PINMUX_IPSR_DATA(IP5_14_13, VI3_HSYNC),
+ PINMUX_IPSR_DATA(IP5_16_15, DU1_EXVSYNC_DU1_VSYNC),
+ PINMUX_IPSR_DATA(IP5_16_15, VI2_VSYNC),
+ PINMUX_IPSR_DATA(IP5_16_15, VI3_VSYNC),
+ PINMUX_IPSR_DATA(IP5_20_17, DU1_EXODDF_DU1_ODDF_DISP_CDE),
+ PINMUX_IPSR_DATA(IP5_20_17, VI2_CLK),
+ PINMUX_IPSR_DATA(IP5_20_17, TX3_B_IRDA_TX_B),
+ PINMUX_IPSR_DATA(IP5_20_17, SD3_CD),
+ PINMUX_IPSR_DATA(IP5_20_17, HSPI_TX1),
+ PINMUX_IPSR_DATA(IP5_20_17, VI1_CLKENB),
+ PINMUX_IPSR_DATA(IP5_20_17, VI3_CLKENB),
+ PINMUX_IPSR_DATA(IP5_20_17, AUDIO_CLKC),
+ PINMUX_IPSR_DATA(IP5_20_17, TX2_D),
+ PINMUX_IPSR_DATA(IP5_20_17, SPEEDIN),
+ PINMUX_IPSR_MODSEL_DATA(IP5_20_17, GPS_SIGN_D, SEL_GPS_3),
+ PINMUX_IPSR_DATA(IP5_23_21, DU1_DISP),
+ PINMUX_IPSR_DATA(IP5_23_21, VI2_DATA6_VI2_B6),
+ PINMUX_IPSR_MODSEL_DATA(IP5_23_21, TCLK0, SEL_TMU0_0),
+ PINMUX_IPSR_DATA(IP5_23_21, QSTVA_B_QVS_B),
+ PINMUX_IPSR_MODSEL_DATA(IP5_23_21, HSPI_CLK1, SEL_HSPI1_0),
+ PINMUX_IPSR_MODSEL_DATA(IP5_23_21, SCK2_D, SEL_SCIF2_3),
+ PINMUX_IPSR_DATA(IP5_23_21, AUDIO_CLKOUT_B),
+ PINMUX_IPSR_MODSEL_DATA(IP5_23_21, GPS_MAG_D, SEL_GPS_3),
+ PINMUX_IPSR_DATA(IP5_27_24, DU1_CDE),
+ PINMUX_IPSR_DATA(IP5_27_24, VI2_DATA7_VI2_B7),
+ PINMUX_IPSR_MODSEL_DATA(IP5_27_24, RX3_B_IRDA_RX_B, SEL_SCIF3_1),
+ PINMUX_IPSR_DATA(IP5_27_24, SD3_WP),
+ PINMUX_IPSR_MODSEL_DATA(IP5_27_24, HSPI_RX1, SEL_HSPI1_0),
+ PINMUX_IPSR_DATA(IP5_27_24, VI1_FIELD),
+ PINMUX_IPSR_DATA(IP5_27_24, VI3_FIELD),
+ PINMUX_IPSR_DATA(IP5_27_24, AUDIO_CLKOUT),
+ PINMUX_IPSR_MODSEL_DATA(IP5_27_24, RX2_D, SEL_SCIF2_3),
+ PINMUX_IPSR_MODSEL_DATA(IP5_27_24, GPS_CLK_C, SEL_GPS_2),
+ PINMUX_IPSR_MODSEL_DATA(IP5_27_24, GPS_CLK_D, SEL_GPS_3),
+ PINMUX_IPSR_DATA(IP5_28, AUDIO_CLKA),
+ PINMUX_IPSR_DATA(IP5_28, CAN_TXCLK),
+ PINMUX_IPSR_DATA(IP5_30_29, AUDIO_CLKB),
+ PINMUX_IPSR_DATA(IP5_30_29, USB_OVC2),
+ PINMUX_IPSR_DATA(IP5_30_29, CAN_DEBUGOUT0),
+ PINMUX_IPSR_DATA(IP5_30_29, MOUT0),
+
+ PINMUX_IPSR_DATA(IP6_1_0, SSI_SCK0129),
+ PINMUX_IPSR_DATA(IP6_1_0, CAN_DEBUGOUT1),
+ PINMUX_IPSR_DATA(IP6_1_0, MOUT1),
+ PINMUX_IPSR_DATA(IP6_3_2, SSI_WS0129),
+ PINMUX_IPSR_DATA(IP6_3_2, CAN_DEBUGOUT2),
+ PINMUX_IPSR_DATA(IP6_3_2, MOUT2),
+ PINMUX_IPSR_DATA(IP6_5_4, SSI_SDATA0),
+ PINMUX_IPSR_DATA(IP6_5_4, CAN_DEBUGOUT3),
+ PINMUX_IPSR_DATA(IP6_5_4, MOUT5),
+ PINMUX_IPSR_DATA(IP6_7_6, SSI_SDATA1),
+ PINMUX_IPSR_DATA(IP6_7_6, CAN_DEBUGOUT4),
+ PINMUX_IPSR_DATA(IP6_7_6, MOUT6),
+ PINMUX_IPSR_DATA(IP6_8, SSI_SDATA2),
+ PINMUX_IPSR_DATA(IP6_8, CAN_DEBUGOUT5),
+ PINMUX_IPSR_DATA(IP6_11_9, SSI_SCK34),
+ PINMUX_IPSR_DATA(IP6_11_9, CAN_DEBUGOUT6),
+ PINMUX_IPSR_DATA(IP6_11_9, CAN0_TX_B),
+ PINMUX_IPSR_MODSEL_DATA(IP6_11_9, IERX, SEL_IE_0),
+ PINMUX_IPSR_MODSEL_DATA(IP6_11_9, SSI_SCK9_C, SEL_SSI9_2),
+ PINMUX_IPSR_DATA(IP6_14_12, SSI_WS34),
+ PINMUX_IPSR_DATA(IP6_14_12, CAN_DEBUGOUT7),
+ PINMUX_IPSR_MODSEL_DATA(IP6_14_12, CAN0_RX_B, SEL_CAN0_1),
+ PINMUX_IPSR_DATA(IP6_14_12, IETX),
+ PINMUX_IPSR_MODSEL_DATA(IP6_14_12, SSI_WS9_C, SEL_SSI9_2),
+ PINMUX_IPSR_DATA(IP6_17_15, SSI_SDATA3),
+ PINMUX_IPSR_DATA(IP6_17_15, PWM0_C),
+ PINMUX_IPSR_DATA(IP6_17_15, CAN_DEBUGOUT8),
+ PINMUX_IPSR_MODSEL_DATA(IP6_17_15, CAN_CLK_B, SEL_CANCLK_1),
+ PINMUX_IPSR_MODSEL_DATA(IP6_17_15, IECLK, SEL_IE_0),
+ PINMUX_IPSR_MODSEL_DATA(IP6_17_15, SCIF_CLK_B, SEL_SCIF_1),
+ PINMUX_IPSR_MODSEL_DATA(IP6_17_15, TCLK0_B, SEL_TMU0_1),
+ PINMUX_IPSR_DATA(IP6_19_18, SSI_SDATA4),
+ PINMUX_IPSR_DATA(IP6_19_18, CAN_DEBUGOUT9),
+ PINMUX_IPSR_MODSEL_DATA(IP6_19_18, SSI_SDATA9_C, SEL_SSI9_2),
+ PINMUX_IPSR_DATA(IP6_22_20, SSI_SCK5),
+ PINMUX_IPSR_DATA(IP6_22_20, ADICLK),
+ PINMUX_IPSR_DATA(IP6_22_20, CAN_DEBUGOUT10),
+ PINMUX_IPSR_MODSEL_DATA(IP6_22_20, SCK3, SEL_SCIF3_0),
+ PINMUX_IPSR_MODSEL_DATA(IP6_22_20, TCLK0_D, SEL_TMU0_3),
+ PINMUX_IPSR_DATA(IP6_24_23, SSI_WS5),
+ PINMUX_IPSR_MODSEL_DATA(IP6_24_23, ADICS_SAMP, SEL_ADI_0),
+ PINMUX_IPSR_DATA(IP6_24_23, CAN_DEBUGOUT11),
+ PINMUX_IPSR_DATA(IP6_24_23, TX3_IRDA_TX),
+ PINMUX_IPSR_DATA(IP6_26_25, SSI_SDATA5),
+ PINMUX_IPSR_MODSEL_DATA(IP6_26_25, ADIDATA, SEL_ADI_0),
+ PINMUX_IPSR_DATA(IP6_26_25, CAN_DEBUGOUT12),
+ PINMUX_IPSR_MODSEL_DATA(IP6_26_25, RX3_IRDA_RX, SEL_SCIF3_0),
+ PINMUX_IPSR_DATA(IP6_30_29, SSI_SCK6),
+ PINMUX_IPSR_DATA(IP6_30_29, ADICHS0),
+ PINMUX_IPSR_DATA(IP6_30_29, CAN0_TX),
+ PINMUX_IPSR_MODSEL_DATA(IP6_30_29, IERX_B, SEL_IE_1),
+
+ PINMUX_IPSR_DATA(IP7_1_0, SSI_WS6),
+ PINMUX_IPSR_DATA(IP7_1_0, ADICHS1),
+ PINMUX_IPSR_MODSEL_DATA(IP7_1_0, CAN0_RX, SEL_CAN0_0),
+ PINMUX_IPSR_DATA(IP7_1_0, IETX_B),
+ PINMUX_IPSR_DATA(IP7_3_2, SSI_SDATA6),
+ PINMUX_IPSR_DATA(IP7_3_2, ADICHS2),
+ PINMUX_IPSR_MODSEL_DATA(IP7_3_2, CAN_CLK, SEL_CANCLK_0),
+ PINMUX_IPSR_MODSEL_DATA(IP7_3_2, IECLK_B, SEL_IE_1),
+ PINMUX_IPSR_MODSEL_DATA(IP7_6_4, SSI_SCK78, SEL_SSI7_0),
+ PINMUX_IPSR_DATA(IP7_6_4, CAN_DEBUGOUT13),
+ PINMUX_IPSR_MODSEL_DATA(IP7_6_4, IRQ0_B, SEL_INT0_1),
+ PINMUX_IPSR_MODSEL_DATA(IP7_6_4, SSI_SCK9_B, SEL_SSI9_1),
+ PINMUX_IPSR_MODSEL_DATA(IP7_6_4, HSPI_CLK1_C, SEL_HSPI1_2),
+ PINMUX_IPSR_MODSEL_DATA(IP7_9_7, SSI_WS78, SEL_SSI7_0),
+ PINMUX_IPSR_DATA(IP7_9_7, CAN_DEBUGOUT14),
+ PINMUX_IPSR_MODSEL_DATA(IP7_9_7, IRQ1_B, SEL_INT1_1),
+ PINMUX_IPSR_MODSEL_DATA(IP7_9_7, SSI_WS9_B, SEL_SSI9_1),
+ PINMUX_IPSR_MODSEL_DATA(IP7_9_7, HSPI_CS1_C, SEL_HSPI1_2),
+ PINMUX_IPSR_MODSEL_DATA(IP7_12_10, SSI_SDATA7, SEL_SSI7_0),
+ PINMUX_IPSR_DATA(IP7_12_10, CAN_DEBUGOUT15),
+ PINMUX_IPSR_MODSEL_DATA(IP7_12_10, IRQ2_B, SEL_INT2_1),
+ PINMUX_IPSR_MODSEL_DATA(IP7_12_10, TCLK1_C, SEL_TMU1_2),
+ PINMUX_IPSR_DATA(IP7_12_10, HSPI_TX1_C),
+ PINMUX_IPSR_MODSEL_DATA(IP7_14_13, SSI_SDATA8, SEL_SSI8_0),
+ PINMUX_IPSR_DATA(IP7_14_13, VSP),
+ PINMUX_IPSR_MODSEL_DATA(IP7_14_13, IRQ3_B, SEL_INT3_1),
+ PINMUX_IPSR_MODSEL_DATA(IP7_14_13, HSPI_RX1_C, SEL_HSPI1_2),
+ PINMUX_IPSR_DATA(IP7_16_15, SD0_CLK),
+ PINMUX_IPSR_DATA(IP7_16_15, ATACS01),
+ PINMUX_IPSR_MODSEL_DATA(IP7_16_15, SCK1_B, SEL_SCIF1_1),
+ PINMUX_IPSR_DATA(IP7_18_17, SD0_CMD),
+ PINMUX_IPSR_DATA(IP7_18_17, ATACS11),
+ PINMUX_IPSR_DATA(IP7_18_17, TX1_B),
+ PINMUX_IPSR_DATA(IP7_18_17, CC5_TDO),
+ PINMUX_IPSR_DATA(IP7_20_19, SD0_DAT0),
+ PINMUX_IPSR_DATA(IP7_20_19, ATADIR1),
+ PINMUX_IPSR_MODSEL_DATA(IP7_20_19, RX1_B, SEL_SCIF1_1),
+ PINMUX_IPSR_DATA(IP7_20_19, CC5_TRST),
+ PINMUX_IPSR_DATA(IP7_22_21, SD0_DAT1),
+ PINMUX_IPSR_DATA(IP7_22_21, ATAG1),
+ PINMUX_IPSR_MODSEL_DATA(IP7_22_21, SCK2_B, SEL_SCIF2_1),
+ PINMUX_IPSR_DATA(IP7_22_21, CC5_TMS),
+ PINMUX_IPSR_DATA(IP7_24_23, SD0_DAT2),
+ PINMUX_IPSR_DATA(IP7_24_23, ATARD1),
+ PINMUX_IPSR_DATA(IP7_24_23, TX2_B),
+ PINMUX_IPSR_DATA(IP7_24_23, CC5_TCK),
+ PINMUX_IPSR_DATA(IP7_26_25, SD0_DAT3),
+ PINMUX_IPSR_DATA(IP7_26_25, ATAWR1),
+ PINMUX_IPSR_MODSEL_DATA(IP7_26_25, RX2_B, SEL_SCIF2_1),
+ PINMUX_IPSR_DATA(IP7_26_25, CC5_TDI),
+ PINMUX_IPSR_DATA(IP7_28_27, SD0_CD),
+ PINMUX_IPSR_MODSEL_DATA(IP7_28_27, DREQ2, SEL_EXBUS2_0),
+ PINMUX_IPSR_MODSEL_DATA(IP7_28_27, RTS1_B_TANS_B, SEL_SCIF1_1),
+ PINMUX_IPSR_DATA(IP7_30_29, SD0_WP),
+ PINMUX_IPSR_DATA(IP7_30_29, DACK2),
+ PINMUX_IPSR_MODSEL_DATA(IP7_30_29, CTS1_B, SEL_SCIF1_1),
+
+ PINMUX_IPSR_DATA(IP8_3_0, HSPI_CLK0),
+ PINMUX_IPSR_MODSEL_DATA(IP8_3_0, CTS0, SEL_SCIF0_0),
+ PINMUX_IPSR_DATA(IP8_3_0, USB_OVC0),
+ PINMUX_IPSR_DATA(IP8_3_0, AD_CLK),
+ PINMUX_IPSR_DATA(IP8_3_0, CC5_STATE4),
+ PINMUX_IPSR_DATA(IP8_3_0, CC5_STATE12),
+ PINMUX_IPSR_DATA(IP8_3_0, CC5_STATE20),
+ PINMUX_IPSR_DATA(IP8_3_0, CC5_STATE28),
+ PINMUX_IPSR_DATA(IP8_3_0, CC5_STATE36),
+ PINMUX_IPSR_DATA(IP8_7_4, HSPI_CS0),
+ PINMUX_IPSR_MODSEL_DATA(IP8_7_4, RTS0_TANS, SEL_SCIF0_0),
+ PINMUX_IPSR_DATA(IP8_7_4, USB_OVC1),
+ PINMUX_IPSR_DATA(IP8_7_4, AD_DI),
+ PINMUX_IPSR_DATA(IP8_7_4, CC5_STATE5),
+ PINMUX_IPSR_DATA(IP8_7_4, CC5_STATE13),
+ PINMUX_IPSR_DATA(IP8_7_4, CC5_STATE21),
+ PINMUX_IPSR_DATA(IP8_7_4, CC5_STATE29),
+ PINMUX_IPSR_DATA(IP8_7_4, CC5_STATE37),
+ PINMUX_IPSR_DATA(IP8_11_8, HSPI_TX0),
+ PINMUX_IPSR_DATA(IP8_11_8, TX0),
+ PINMUX_IPSR_DATA(IP8_11_8, CAN_DEBUG_HW_TRIGGER),
+ PINMUX_IPSR_DATA(IP8_11_8, AD_DO),
+ PINMUX_IPSR_DATA(IP8_11_8, CC5_STATE6),
+ PINMUX_IPSR_DATA(IP8_11_8, CC5_STATE14),
+ PINMUX_IPSR_DATA(IP8_11_8, CC5_STATE22),
+ PINMUX_IPSR_DATA(IP8_11_8, CC5_STATE30),
+ PINMUX_IPSR_DATA(IP8_11_8, CC5_STATE38),
+ PINMUX_IPSR_DATA(IP8_15_12, HSPI_RX0),
+ PINMUX_IPSR_MODSEL_DATA(IP8_15_12, RX0, SEL_SCIF0_0),
+ PINMUX_IPSR_DATA(IP8_15_12, CAN_STEP0),
+ PINMUX_IPSR_DATA(IP8_15_12, AD_NCS),
+ PINMUX_IPSR_DATA(IP8_15_12, CC5_STATE7),
+ PINMUX_IPSR_DATA(IP8_15_12, CC5_STATE15),
+ PINMUX_IPSR_DATA(IP8_15_12, CC5_STATE23),
+ PINMUX_IPSR_DATA(IP8_15_12, CC5_STATE31),
+ PINMUX_IPSR_DATA(IP8_15_12, CC5_STATE39),
+ PINMUX_IPSR_DATA(IP8_17_16, FMCLK),
+ PINMUX_IPSR_DATA(IP8_17_16, RDS_CLK),
+ PINMUX_IPSR_DATA(IP8_17_16, PCMOE),
+ PINMUX_IPSR_DATA(IP8_18, BPFCLK),
+ PINMUX_IPSR_DATA(IP8_18, PCMWE),
+ PINMUX_IPSR_DATA(IP8_19, FMIN),
+ PINMUX_IPSR_DATA(IP8_19, RDS_DATA),
+ PINMUX_IPSR_DATA(IP8_20, VI0_CLK),
+ PINMUX_IPSR_DATA(IP8_20, MMC1_CLK),
+ PINMUX_IPSR_DATA(IP8_22_21, VI0_CLKENB),
+ PINMUX_IPSR_DATA(IP8_22_21, TX1_C),
+ PINMUX_IPSR_DATA(IP8_22_21, HTX1_B),
+ PINMUX_IPSR_DATA(IP8_22_21, MT1_SYNC),
+ PINMUX_IPSR_DATA(IP8_24_23, VI0_FIELD),
+ PINMUX_IPSR_MODSEL_DATA(IP8_24_23, RX1_C, SEL_SCIF1_2),
+ PINMUX_IPSR_MODSEL_DATA(IP8_24_23, HRX1_B, SEL_HSCIF1_1),
+ PINMUX_IPSR_DATA(IP8_27_25, VI0_HSYNC),
+ PINMUX_IPSR_MODSEL_DATA(IP8_27_25, VI0_DATA0_B_VI0_B0_B, SEL_VI0_1),
+ PINMUX_IPSR_MODSEL_DATA(IP8_27_25, CTS1_C, SEL_SCIF1_2),
+ PINMUX_IPSR_DATA(IP8_27_25, TX4_D),
+ PINMUX_IPSR_DATA(IP8_27_25, MMC1_CMD),
+ PINMUX_IPSR_MODSEL_DATA(IP8_27_25, HSCK1_B, SEL_HSCIF1_1),
+ PINMUX_IPSR_DATA(IP8_30_28, VI0_VSYNC),
+ PINMUX_IPSR_MODSEL_DATA(IP8_30_28, VI0_DATA1_B_VI0_B1_B, SEL_VI0_1),
+ PINMUX_IPSR_MODSEL_DATA(IP8_30_28, RTS1_C_TANS_C, SEL_SCIF1_2),
+ PINMUX_IPSR_MODSEL_DATA(IP8_30_28, RX4_D, SEL_SCIF4_3),
+ PINMUX_IPSR_MODSEL_DATA(IP8_30_28, PWMFSW0_C, SEL_PWMFSW_2),
+
+ PINMUX_IPSR_MODSEL_DATA(IP9_1_0, VI0_DATA0_VI0_B0, SEL_VI0_0),
+ PINMUX_IPSR_MODSEL_DATA(IP9_1_0, HRTS1_B, SEL_HSCIF1_1),
+ PINMUX_IPSR_DATA(IP9_1_0, MT1_VCXO),
+ PINMUX_IPSR_MODSEL_DATA(IP9_3_2, VI0_DATA1_VI0_B1, SEL_VI0_0),
+ PINMUX_IPSR_MODSEL_DATA(IP9_3_2, HCTS1_B, SEL_HSCIF1_1),
+ PINMUX_IPSR_DATA(IP9_3_2, MT1_PWM),
+ PINMUX_IPSR_DATA(IP9_4, VI0_DATA2_VI0_B2),
+ PINMUX_IPSR_DATA(IP9_4, MMC1_D0),
+ PINMUX_IPSR_DATA(IP9_5, VI0_DATA3_VI0_B3),
+ PINMUX_IPSR_DATA(IP9_5, MMC1_D1),
+ PINMUX_IPSR_DATA(IP9_6, VI0_DATA4_VI0_B4),
+ PINMUX_IPSR_DATA(IP9_6, MMC1_D2),
+ PINMUX_IPSR_DATA(IP9_7, VI0_DATA5_VI0_B5),
+ PINMUX_IPSR_DATA(IP9_7, MMC1_D3),
+ PINMUX_IPSR_DATA(IP9_9_8, VI0_DATA6_VI0_B6),
+ PINMUX_IPSR_DATA(IP9_9_8, MMC1_D4),
+ PINMUX_IPSR_DATA(IP9_9_8, ARM_TRACEDATA_0),
+ PINMUX_IPSR_DATA(IP9_11_10, VI0_DATA7_VI0_B7),
+ PINMUX_IPSR_DATA(IP9_11_10, MMC1_D5),
+ PINMUX_IPSR_DATA(IP9_11_10, ARM_TRACEDATA_1),
+ PINMUX_IPSR_DATA(IP9_13_12, VI0_G0),
+ PINMUX_IPSR_MODSEL_DATA(IP9_13_12, SSI_SCK78_C, SEL_SSI7_2),
+ PINMUX_IPSR_MODSEL_DATA(IP9_13_12, IRQ0, SEL_INT0_0),
+ PINMUX_IPSR_DATA(IP9_13_12, ARM_TRACEDATA_2),
+ PINMUX_IPSR_DATA(IP9_15_14, VI0_G1),
+ PINMUX_IPSR_MODSEL_DATA(IP9_15_14, SSI_WS78_C, SEL_SSI7_2),
+ PINMUX_IPSR_MODSEL_DATA(IP9_15_14, IRQ1, SEL_INT1_0),
+ PINMUX_IPSR_DATA(IP9_15_14, ARM_TRACEDATA_3),
+ PINMUX_IPSR_DATA(IP9_18_16, VI0_G2),
+ PINMUX_IPSR_DATA(IP9_18_16, ETH_TXD1),
+ PINMUX_IPSR_DATA(IP9_18_16, MMC1_D6),
+ PINMUX_IPSR_DATA(IP9_18_16, ARM_TRACEDATA_4),
+ PINMUX_IPSR_DATA(IP9_18_16, TS_SPSYNC0),
+ PINMUX_IPSR_DATA(IP9_21_19, VI0_G3),
+ PINMUX_IPSR_DATA(IP9_21_19, ETH_CRS_DV),
+ PINMUX_IPSR_DATA(IP9_21_19, MMC1_D7),
+ PINMUX_IPSR_DATA(IP9_21_19, ARM_TRACEDATA_5),
+ PINMUX_IPSR_DATA(IP9_21_19, TS_SDAT0),
+ PINMUX_IPSR_DATA(IP9_23_22, VI0_G4),
+ PINMUX_IPSR_DATA(IP9_23_22, ETH_TX_EN),
+ PINMUX_IPSR_MODSEL_DATA(IP9_23_22, SD2_DAT0_B, SEL_SD2_1),
+ PINMUX_IPSR_DATA(IP9_23_22, ARM_TRACEDATA_6),
+ PINMUX_IPSR_DATA(IP9_25_24, VI0_G5),
+ PINMUX_IPSR_DATA(IP9_25_24, ETH_RX_ER),
+ PINMUX_IPSR_MODSEL_DATA(IP9_25_24, SD2_DAT1_B, SEL_SD2_1),
+ PINMUX_IPSR_DATA(IP9_25_24, ARM_TRACEDATA_7),
+ PINMUX_IPSR_DATA(IP9_27_26, VI0_G6),
+ PINMUX_IPSR_DATA(IP9_27_26, ETH_RXD0),
+ PINMUX_IPSR_MODSEL_DATA(IP9_27_26, SD2_DAT2_B, SEL_SD2_1),
+ PINMUX_IPSR_DATA(IP9_27_26, ARM_TRACEDATA_8),
+ PINMUX_IPSR_DATA(IP9_29_28, VI0_G7),
+ PINMUX_IPSR_DATA(IP9_29_28, ETH_RXD1),
+ PINMUX_IPSR_MODSEL_DATA(IP9_29_28, SD2_DAT3_B, SEL_SD2_1),
+ PINMUX_IPSR_DATA(IP9_29_28, ARM_TRACEDATA_9),
+
+ PINMUX_IPSR_DATA(IP10_2_0, VI0_R0),
+ PINMUX_IPSR_MODSEL_DATA(IP10_2_0, SSI_SDATA7_C, SEL_SSI7_2),
+ PINMUX_IPSR_MODSEL_DATA(IP10_2_0, SCK1_C, SEL_SCIF1_2),
+ PINMUX_IPSR_MODSEL_DATA(IP10_2_0, DREQ1_B, SEL_EXBUS1_0),
+ PINMUX_IPSR_DATA(IP10_2_0, ARM_TRACEDATA_10),
+ PINMUX_IPSR_MODSEL_DATA(IP10_2_0, DREQ0_C, SEL_EXBUS0_2),
+ PINMUX_IPSR_DATA(IP10_5_3, VI0_R1),
+ PINMUX_IPSR_MODSEL_DATA(IP10_5_3, SSI_SDATA8_C, SEL_SSI8_2),
+ PINMUX_IPSR_DATA(IP10_5_3, DACK1_B),
+ PINMUX_IPSR_DATA(IP10_5_3, ARM_TRACEDATA_11),
+ PINMUX_IPSR_DATA(IP10_5_3, DACK0_C),
+ PINMUX_IPSR_DATA(IP10_5_3, DRACK0_C),
+ PINMUX_IPSR_DATA(IP10_8_6, VI0_R2),
+ PINMUX_IPSR_DATA(IP10_8_6, ETH_LINK),
+ PINMUX_IPSR_DATA(IP10_8_6, SD2_CLK_B),
+ PINMUX_IPSR_MODSEL_DATA(IP10_8_6, IRQ2, SEL_INT2_0),
+ PINMUX_IPSR_DATA(IP10_8_6, ARM_TRACEDATA_12),
+ PINMUX_IPSR_DATA(IP10_11_9, VI0_R3),
+ PINMUX_IPSR_DATA(IP10_11_9, ETH_MAGIC),
+ PINMUX_IPSR_MODSEL_DATA(IP10_11_9, SD2_CMD_B, SEL_SD2_1),
+ PINMUX_IPSR_MODSEL_DATA(IP10_11_9, IRQ3, SEL_INT3_0),
+ PINMUX_IPSR_DATA(IP10_11_9, ARM_TRACEDATA_13),
+ PINMUX_IPSR_DATA(IP10_14_12, VI0_R4),
+ PINMUX_IPSR_DATA(IP10_14_12, ETH_REFCLK),
+ PINMUX_IPSR_MODSEL_DATA(IP10_14_12, SD2_CD_B, SEL_SD2_1),
+ PINMUX_IPSR_MODSEL_DATA(IP10_14_12, HSPI_CLK1_B, SEL_HSPI1_1),
+ PINMUX_IPSR_DATA(IP10_14_12, ARM_TRACEDATA_14),
+ PINMUX_IPSR_DATA(IP10_14_12, MT1_CLK),
+ PINMUX_IPSR_DATA(IP10_14_12, TS_SCK0),
+ PINMUX_IPSR_DATA(IP10_17_15, VI0_R5),
+ PINMUX_IPSR_DATA(IP10_17_15, ETH_TXD0),
+ PINMUX_IPSR_MODSEL_DATA(IP10_17_15, SD2_WP_B, SEL_SD2_1),
+ PINMUX_IPSR_MODSEL_DATA(IP10_17_15, HSPI_CS1_B, SEL_HSPI1_1),
+ PINMUX_IPSR_DATA(IP10_17_15, ARM_TRACEDATA_15),
+ PINMUX_IPSR_DATA(IP10_17_15, MT1_D),
+ PINMUX_IPSR_DATA(IP10_17_15, TS_SDEN0),
+ PINMUX_IPSR_DATA(IP10_20_18, VI0_R6),
+ PINMUX_IPSR_DATA(IP10_20_18, ETH_MDC),
+ PINMUX_IPSR_MODSEL_DATA(IP10_20_18, DREQ2_C, SEL_EXBUS2_2),
+ PINMUX_IPSR_DATA(IP10_20_18, HSPI_TX1_B),
+ PINMUX_IPSR_DATA(IP10_20_18, TRACECLK),
+ PINMUX_IPSR_DATA(IP10_20_18, MT1_BEN),
+ PINMUX_IPSR_MODSEL_DATA(IP10_20_18, PWMFSW0_D, SEL_PWMFSW_3),
+ PINMUX_IPSR_DATA(IP10_23_21, VI0_R7),
+ PINMUX_IPSR_DATA(IP10_23_21, ETH_MDIO),
+ PINMUX_IPSR_DATA(IP10_23_21, DACK2_C),
+ PINMUX_IPSR_MODSEL_DATA(IP10_23_21, HSPI_RX1_B, SEL_HSPI1_1),
+ PINMUX_IPSR_MODSEL_DATA(IP10_23_21, SCIF_CLK_D, SEL_SCIF_3),
+ PINMUX_IPSR_DATA(IP10_23_21, TRACECTL),
+ PINMUX_IPSR_DATA(IP10_23_21, MT1_PEN),
+ PINMUX_IPSR_DATA(IP10_25_24, VI1_CLK),
+ PINMUX_IPSR_MODSEL_DATA(IP10_25_24, SIM_D, SEL_SIM_0),
+ PINMUX_IPSR_MODSEL_DATA(IP10_25_24, SDA3, SEL_I2C3_0),
+ PINMUX_IPSR_DATA(IP10_28_26, VI1_HSYNC),
+ PINMUX_IPSR_DATA(IP10_28_26, VI3_CLK),
+ PINMUX_IPSR_DATA(IP10_28_26, SSI_SCK4),
+ PINMUX_IPSR_MODSEL_DATA(IP10_28_26, GPS_SIGN_C, SEL_GPS_2),
+ PINMUX_IPSR_MODSEL_DATA(IP10_28_26, PWMFSW0_E, SEL_PWMFSW_4),
+ PINMUX_IPSR_DATA(IP10_31_29, VI1_VSYNC),
+ PINMUX_IPSR_DATA(IP10_31_29, AUDIO_CLKOUT_C),
+ PINMUX_IPSR_DATA(IP10_31_29, SSI_WS4),
+ PINMUX_IPSR_DATA(IP10_31_29, SIM_CLK),
+ PINMUX_IPSR_MODSEL_DATA(IP10_31_29, GPS_MAG_C, SEL_GPS_2),
+ PINMUX_IPSR_DATA(IP10_31_29, SPV_TRST),
+ PINMUX_IPSR_MODSEL_DATA(IP10_31_29, SCL3, SEL_I2C3_0),
+
+ PINMUX_IPSR_DATA(IP11_2_0, VI1_DATA0_VI1_B0),
+ PINMUX_IPSR_MODSEL_DATA(IP11_2_0, SD2_DAT0, SEL_SD2_0),
+ PINMUX_IPSR_DATA(IP11_2_0, SIM_RST),
+ PINMUX_IPSR_DATA(IP11_2_0, SPV_TCK),
+ PINMUX_IPSR_DATA(IP11_2_0, ADICLK_B),
+ PINMUX_IPSR_DATA(IP11_5_3, VI1_DATA1_VI1_B1),
+ PINMUX_IPSR_MODSEL_DATA(IP11_5_3, SD2_DAT1, SEL_SD2_0),
+ PINMUX_IPSR_DATA(IP11_5_3, MT0_CLK),
+ PINMUX_IPSR_DATA(IP11_5_3, SPV_TMS),
+ PINMUX_IPSR_MODSEL_DATA(IP11_5_3, ADICS_B_SAMP_B, SEL_ADI_1),
+ PINMUX_IPSR_DATA(IP11_8_6, VI1_DATA2_VI1_B2),
+ PINMUX_IPSR_MODSEL_DATA(IP11_8_6, SD2_DAT2, SEL_SD2_0),
+ PINMUX_IPSR_DATA(IP11_8_6, MT0_D),
+ PINMUX_IPSR_DATA(IP11_8_6, SPVTDI),
+ PINMUX_IPSR_MODSEL_DATA(IP11_8_6, ADIDATA_B, SEL_ADI_1),
+ PINMUX_IPSR_DATA(IP11_11_9, VI1_DATA3_VI1_B3),
+ PINMUX_IPSR_MODSEL_DATA(IP11_11_9, SD2_DAT3, SEL_SD2_0),
+ PINMUX_IPSR_DATA(IP11_11_9, MT0_BEN),
+ PINMUX_IPSR_DATA(IP11_11_9, SPV_TDO),
+ PINMUX_IPSR_DATA(IP11_11_9, ADICHS0_B),
+ PINMUX_IPSR_DATA(IP11_14_12, VI1_DATA4_VI1_B4),
+ PINMUX_IPSR_DATA(IP11_14_12, SD2_CLK),
+ PINMUX_IPSR_DATA(IP11_14_12, MT0_PEN),
+ PINMUX_IPSR_DATA(IP11_14_12, SPA_TRST),
+ PINMUX_IPSR_MODSEL_DATA(IP11_14_12, HSPI_CLK1_D, SEL_HSPI1_3),
+ PINMUX_IPSR_DATA(IP11_14_12, ADICHS1_B),
+ PINMUX_IPSR_DATA(IP11_17_15, VI1_DATA5_VI1_B5),
+ PINMUX_IPSR_MODSEL_DATA(IP11_17_15, SD2_CMD, SEL_SD2_0),
+ PINMUX_IPSR_DATA(IP11_17_15, MT0_SYNC),
+ PINMUX_IPSR_DATA(IP11_17_15, SPA_TCK),
+ PINMUX_IPSR_MODSEL_DATA(IP11_17_15, HSPI_CS1_D, SEL_HSPI1_3),
+ PINMUX_IPSR_DATA(IP11_17_15, ADICHS2_B),
+ PINMUX_IPSR_DATA(IP11_20_18, VI1_DATA6_VI1_B6),
+ PINMUX_IPSR_MODSEL_DATA(IP11_20_18, SD2_CD, SEL_SD2_0),
+ PINMUX_IPSR_DATA(IP11_20_18, MT0_VCXO),
+ PINMUX_IPSR_DATA(IP11_20_18, SPA_TMS),
+ PINMUX_IPSR_DATA(IP11_20_18, HSPI_TX1_D),
+ PINMUX_IPSR_DATA(IP11_23_21, VI1_DATA7_VI1_B7),
+ PINMUX_IPSR_MODSEL_DATA(IP11_23_21, SD2_WP, SEL_SD2_0),
+ PINMUX_IPSR_DATA(IP11_23_21, MT0_PWM),
+ PINMUX_IPSR_DATA(IP11_23_21, SPA_TDI),
+ PINMUX_IPSR_MODSEL_DATA(IP11_23_21, HSPI_RX1_D, SEL_HSPI1_3),
+ PINMUX_IPSR_DATA(IP11_26_24, VI1_G0),
+ PINMUX_IPSR_DATA(IP11_26_24, VI3_DATA0),
+ PINMUX_IPSR_DATA(IP11_26_24, DU1_DOTCLKOUT1),
+ PINMUX_IPSR_DATA(IP11_26_24, TS_SCK1),
+ PINMUX_IPSR_MODSEL_DATA(IP11_26_24, DREQ2_B, SEL_EXBUS2_1),
+ PINMUX_IPSR_DATA(IP11_26_24, TX2),
+ PINMUX_IPSR_DATA(IP11_26_24, SPA_TDO),
+ PINMUX_IPSR_MODSEL_DATA(IP11_26_24, HCTS0_B, SEL_HSCIF0_1),
+ PINMUX_IPSR_DATA(IP11_29_27, VI1_G1),
+ PINMUX_IPSR_DATA(IP11_29_27, VI3_DATA1),
+ PINMUX_IPSR_DATA(IP11_29_27, SSI_SCK1),
+ PINMUX_IPSR_DATA(IP11_29_27, TS_SDEN1),
+ PINMUX_IPSR_DATA(IP11_29_27, DACK2_B),
+ PINMUX_IPSR_MODSEL_DATA(IP11_29_27, RX2, SEL_SCIF2_0),
+ PINMUX_IPSR_MODSEL_DATA(IP11_29_27, HRTS0_B, SEL_HSCIF0_1),
+
+ PINMUX_IPSR_DATA(IP12_2_0, VI1_G2),
+ PINMUX_IPSR_DATA(IP12_2_0, VI3_DATA2),
+ PINMUX_IPSR_DATA(IP12_2_0, SSI_WS1),
+ PINMUX_IPSR_DATA(IP12_2_0, TS_SPSYNC1),
+ PINMUX_IPSR_MODSEL_DATA(IP12_2_0, SCK2, SEL_SCIF2_0),
+ PINMUX_IPSR_MODSEL_DATA(IP12_2_0, HSCK0_B, SEL_HSCIF0_1),
+ PINMUX_IPSR_DATA(IP12_5_3, VI1_G3),
+ PINMUX_IPSR_DATA(IP12_5_3, VI3_DATA3),
+ PINMUX_IPSR_DATA(IP12_5_3, SSI_SCK2),
+ PINMUX_IPSR_DATA(IP12_5_3, TS_SDAT1),
+ PINMUX_IPSR_MODSEL_DATA(IP12_5_3, SCL1_C, SEL_I2C1_2),
+ PINMUX_IPSR_DATA(IP12_5_3, HTX0_B),
+ PINMUX_IPSR_DATA(IP12_8_6, VI1_G4),
+ PINMUX_IPSR_DATA(IP12_8_6, VI3_DATA4),
+ PINMUX_IPSR_DATA(IP12_8_6, SSI_WS2),
+ PINMUX_IPSR_MODSEL_DATA(IP12_8_6, SDA1_C, SEL_I2C1_2),
+ PINMUX_IPSR_DATA(IP12_8_6, SIM_RST_B),
+ PINMUX_IPSR_MODSEL_DATA(IP12_8_6, HRX0_B, SEL_HSCIF0_1),
+ PINMUX_IPSR_DATA(IP12_11_9, VI1_G5),
+ PINMUX_IPSR_DATA(IP12_11_9, VI3_DATA5),
+ PINMUX_IPSR_MODSEL_DATA(IP12_11_9, GPS_CLK, SEL_GPS_0),
+ PINMUX_IPSR_DATA(IP12_11_9, FSE),
+ PINMUX_IPSR_DATA(IP12_11_9, TX4_B),
+ PINMUX_IPSR_MODSEL_DATA(IP12_11_9, SIM_D_B, SEL_SIM_1),
+ PINMUX_IPSR_DATA(IP12_14_12, VI1_G6),
+ PINMUX_IPSR_DATA(IP12_14_12, VI3_DATA6),
+ PINMUX_IPSR_MODSEL_DATA(IP12_14_12, GPS_SIGN, SEL_GPS_0),
+ PINMUX_IPSR_DATA(IP12_14_12, FRB),
+ PINMUX_IPSR_MODSEL_DATA(IP12_14_12, RX4_B, SEL_SCIF4_1),
+ PINMUX_IPSR_DATA(IP12_14_12, SIM_CLK_B),
+ PINMUX_IPSR_DATA(IP12_17_15, VI1_G7),
+ PINMUX_IPSR_DATA(IP12_17_15, VI3_DATA7),
+ PINMUX_IPSR_MODSEL_DATA(IP12_17_15, GPS_MAG, SEL_GPS_0),
+ PINMUX_IPSR_DATA(IP12_17_15, FCE),
+ PINMUX_IPSR_MODSEL_DATA(IP12_17_15, SCK4_B, SEL_SCIF4_1),
+};
+
+static struct pinmux_gpio pinmux_gpios[] = {
+ PINMUX_GPIO_GP_ALL(),
+ GPIO_FN(AVS1), GPIO_FN(AVS2), GPIO_FN(A17), GPIO_FN(A18),
+ GPIO_FN(A19),
+
+ /* IPSR0 */
+ GPIO_FN(PENC2), GPIO_FN(SCK0), GPIO_FN(PWM1), GPIO_FN(PWMFSW0),
+ GPIO_FN(SCIF_CLK), GPIO_FN(TCLK0_C), GPIO_FN(BS), GPIO_FN(SD1_DAT2),
+ GPIO_FN(MMC0_D2), GPIO_FN(FD2), GPIO_FN(ATADIR0), GPIO_FN(SDSELF),
+ GPIO_FN(HCTS1), GPIO_FN(TX4_C), GPIO_FN(A0), GPIO_FN(SD1_DAT3),
+ GPIO_FN(MMC0_D3), GPIO_FN(FD3), GPIO_FN(A20), GPIO_FN(TX5_D),
+ GPIO_FN(HSPI_TX2_B), GPIO_FN(A21), GPIO_FN(SCK5_D),
+ GPIO_FN(HSPI_CLK2_B), GPIO_FN(A22), GPIO_FN(RX5_D),
+ GPIO_FN(HSPI_RX2_B), GPIO_FN(VI1_R0), GPIO_FN(A23), GPIO_FN(FCLE),
+ GPIO_FN(HSPI_CLK2), GPIO_FN(VI1_R1), GPIO_FN(A24), GPIO_FN(SD1_CD),
+ GPIO_FN(MMC0_D4), GPIO_FN(FD4), GPIO_FN(HSPI_CS2), GPIO_FN(VI1_R2),
+ GPIO_FN(SSI_WS78_B), GPIO_FN(A25), GPIO_FN(SD1_WP), GPIO_FN(MMC0_D5),
+ GPIO_FN(FD5), GPIO_FN(HSPI_RX2), GPIO_FN(VI1_R3), GPIO_FN(TX5_B),
+ GPIO_FN(SSI_SDATA7_B), GPIO_FN(CTS0_B), GPIO_FN(CLKOUT),
+ GPIO_FN(TX3C_IRDA_TX_C), GPIO_FN(PWM0_B), GPIO_FN(CS0),
+ GPIO_FN(HSPI_CS2_B), GPIO_FN(CS1_A26), GPIO_FN(HSPI_TX2),
+ GPIO_FN(SDSELF_B), GPIO_FN(RD_WR), GPIO_FN(FWE), GPIO_FN(ATAG0),
+ GPIO_FN(VI1_R7), GPIO_FN(HRTS1), GPIO_FN(RX4_C),
+
+ /* IPSR1 */
+ GPIO_FN(EX_CS0), GPIO_FN(RX3_C_IRDA_RX_C), GPIO_FN(MMC0_D6),
+ GPIO_FN(FD6), GPIO_FN(EX_CS1), GPIO_FN(MMC0_D7), GPIO_FN(FD7),
+ GPIO_FN(EX_CS2), GPIO_FN(SD1_CLK), GPIO_FN(MMC0_CLK), GPIO_FN(FALE),
+ GPIO_FN(ATACS00), GPIO_FN(EX_CS3), GPIO_FN(SD1_CMD), GPIO_FN(MMC0_CMD),
+ GPIO_FN(FRE), GPIO_FN(ATACS10), GPIO_FN(VI1_R4), GPIO_FN(RX5_B),
+ GPIO_FN(HSCK1), GPIO_FN(SSI_SDATA8_B), GPIO_FN(RTS0_B_TANS_B),
+ GPIO_FN(SSI_SDATA9), GPIO_FN(EX_CS4), GPIO_FN(SD1_DAT0),
+ GPIO_FN(MMC0_D0), GPIO_FN(FD0), GPIO_FN(ATARD0), GPIO_FN(VI1_R5),
+ GPIO_FN(SCK5_B), GPIO_FN(HTX1), GPIO_FN(TX2_E), GPIO_FN(TX0_B),
+ GPIO_FN(SSI_SCK9), GPIO_FN(EX_CS5), GPIO_FN(SD1_DAT1),
+ GPIO_FN(MMC0_D1), GPIO_FN(FD1), GPIO_FN(ATAWR0), GPIO_FN(VI1_R6),
+ GPIO_FN(HRX1), GPIO_FN(RX2_E), GPIO_FN(RX0_B), GPIO_FN(SSI_WS9),
+ GPIO_FN(MLB_CLK), GPIO_FN(PWM2), GPIO_FN(SCK4), GPIO_FN(MLB_SIG),
+ GPIO_FN(PWM3), GPIO_FN(TX4), GPIO_FN(MLB_DAT), GPIO_FN(PWM4),
+ GPIO_FN(RX4), GPIO_FN(HTX0), GPIO_FN(TX1), GPIO_FN(SDATA),
+ GPIO_FN(CTS0_C), GPIO_FN(SUB_TCK), GPIO_FN(CC5_STATE2),
+ GPIO_FN(CC5_STATE10), GPIO_FN(CC5_STATE18), GPIO_FN(CC5_STATE26),
+ GPIO_FN(CC5_STATE34),
+
+ /* IPSR2 */
+ GPIO_FN(HRX0), GPIO_FN(RX1), GPIO_FN(SCKZ), GPIO_FN(RTS0_C_TANS_C),
+ GPIO_FN(SUB_TDI), GPIO_FN(CC5_STATE3), GPIO_FN(CC5_STATE11),
+ GPIO_FN(CC5_STATE19), GPIO_FN(CC5_STATE27), GPIO_FN(CC5_STATE35),
+ GPIO_FN(HSCK0), GPIO_FN(SCK1), GPIO_FN(MTS), GPIO_FN(PWM5),
+ GPIO_FN(SCK0_C), GPIO_FN(SSI_SDATA9_B), GPIO_FN(SUB_TDO),
+ GPIO_FN(CC5_STATE0), GPIO_FN(CC5_STATE8), GPIO_FN(CC5_STATE16),
+ GPIO_FN(CC5_STATE24), GPIO_FN(CC5_STATE32), GPIO_FN(HCTS0),
+ GPIO_FN(CTS1), GPIO_FN(STM), GPIO_FN(PWM0_D), GPIO_FN(RX0_C),
+ GPIO_FN(SCIF_CLK_C), GPIO_FN(SUB_TRST), GPIO_FN(TCLK1_B),
+ GPIO_FN(CC5_OSCOUT), GPIO_FN(HRTS0), GPIO_FN(RTS1_TANS),
+ GPIO_FN(MDATA), GPIO_FN(TX0_C), GPIO_FN(SUB_TMS), GPIO_FN(CC5_STATE1),
+ GPIO_FN(CC5_STATE9), GPIO_FN(CC5_STATE17), GPIO_FN(CC5_STATE25),
+ GPIO_FN(CC5_STATE33), GPIO_FN(DU0_DR0), GPIO_FN(LCDOUT0),
+ GPIO_FN(DREQ0), GPIO_FN(GPS_CLK_B), GPIO_FN(AUDATA0),
+ GPIO_FN(TX5_C), GPIO_FN(DU0_DR1), GPIO_FN(LCDOUT1), GPIO_FN(DACK0),
+ GPIO_FN(DRACK0), GPIO_FN(GPS_SIGN_B), GPIO_FN(AUDATA1), GPIO_FN(RX5_C),
+ GPIO_FN(DU0_DR2), GPIO_FN(LCDOUT2), GPIO_FN(DU0_DR3), GPIO_FN(LCDOUT3),
+ GPIO_FN(DU0_DR4), GPIO_FN(LCDOUT4), GPIO_FN(DU0_DR5), GPIO_FN(LCDOUT5),
+ GPIO_FN(DU0_DR6), GPIO_FN(LCDOUT6), GPIO_FN(DU0_DR7), GPIO_FN(LCDOUT7),
+ GPIO_FN(DU0_DG0), GPIO_FN(LCDOUT8), GPIO_FN(DREQ1), GPIO_FN(SCL2),
+ GPIO_FN(AUDATA2),
+
+ /* IPSR3 */
+ GPIO_FN(DU0_DG1), GPIO_FN(LCDOUT9), GPIO_FN(DACK1), GPIO_FN(SDA2),
+ GPIO_FN(AUDATA3), GPIO_FN(DU0_DG2), GPIO_FN(LCDOUT10),
+ GPIO_FN(DU0_DG3), GPIO_FN(LCDOUT11), GPIO_FN(DU0_DG4),
+ GPIO_FN(LCDOUT12), GPIO_FN(DU0_DG5), GPIO_FN(LCDOUT13),
+ GPIO_FN(DU0_DG6), GPIO_FN(LCDOUT14), GPIO_FN(DU0_DG7),
+ GPIO_FN(LCDOUT15), GPIO_FN(DU0_DB0), GPIO_FN(LCDOUT16),
+ GPIO_FN(EX_WAIT1), GPIO_FN(SCL1), GPIO_FN(TCLK1), GPIO_FN(AUDATA4),
+ GPIO_FN(DU0_DB1), GPIO_FN(LCDOUT17), GPIO_FN(EX_WAIT2), GPIO_FN(SDA1),
+ GPIO_FN(GPS_MAG_B), GPIO_FN(AUDATA5), GPIO_FN(SCK5_C),
+ GPIO_FN(DU0_DB2), GPIO_FN(LCDOUT18), GPIO_FN(DU0_DB3),
+ GPIO_FN(LCDOUT19), GPIO_FN(DU0_DB4), GPIO_FN(LCDOUT20),
+ GPIO_FN(DU0_DB5), GPIO_FN(LCDOUT21), GPIO_FN(DU0_DB6),
+ GPIO_FN(LCDOUT22), GPIO_FN(DU0_DB7), GPIO_FN(LCDOUT23),
+ GPIO_FN(DU0_DOTCLKIN), GPIO_FN(QSTVA_QVS), GPIO_FN(TX3_D_IRDA_TX_D),
+ GPIO_FN(SCL3_B), GPIO_FN(DU0_DOTCLKOUT0), GPIO_FN(QCLK),
+ GPIO_FN(DU0_DOTCLKOUT1), GPIO_FN(QSTVB_QVE), GPIO_FN(RX3_D_IRDA_RX_D),
+ GPIO_FN(SDA3_B), GPIO_FN(SDA2_C), GPIO_FN(DACK0_B), GPIO_FN(DRACK0_B),
+ GPIO_FN(DU0_EXHSYNC_DU0_HSYNC), GPIO_FN(QSTH_QHS),
+ GPIO_FN(DU0_EXVSYNC_DU0_VSYNC), GPIO_FN(QSTB_QHE),
+ GPIO_FN(DU0_EXODDF_DU0_ODDF_DISP_CDE), GPIO_FN(QCPV_QDE),
+ GPIO_FN(CAN1_TX), GPIO_FN(TX2_C), GPIO_FN(SCL2_C), GPIO_FN(REMOCON),
+
+ /* IPSR4 */
+ GPIO_FN(DU0_DISP), GPIO_FN(QPOLA), GPIO_FN(CAN_CLK_C), GPIO_FN(SCK2_C),
+ GPIO_FN(DU0_CDE), GPIO_FN(QPOLB), GPIO_FN(CAN1_RX), GPIO_FN(RX2_C),
+ GPIO_FN(DREQ0_B), GPIO_FN(SSI_SCK78_B), GPIO_FN(SCK0_B),
+ GPIO_FN(DU1_DR0), GPIO_FN(VI2_DATA0_VI2_B0), GPIO_FN(PWM6),
+ GPIO_FN(SD3_CLK), GPIO_FN(TX3_E_IRDA_TX_E), GPIO_FN(AUDCK),
+ GPIO_FN(PWMFSW0_B), GPIO_FN(DU1_DR1), GPIO_FN(VI2_DATA1_VI2_B1),
+ GPIO_FN(PWM0), GPIO_FN(SD3_CMD), GPIO_FN(RX3_E_IRDA_RX_E),
+ GPIO_FN(AUDSYNC), GPIO_FN(CTS0_D), GPIO_FN(DU1_DR2), GPIO_FN(VI2_G0),
+ GPIO_FN(DU1_DR3), GPIO_FN(VI2_G1), GPIO_FN(DU1_DR4), GPIO_FN(VI2_G2),
+ GPIO_FN(DU1_DR5), GPIO_FN(VI2_G3), GPIO_FN(DU1_DR6), GPIO_FN(VI2_G4),
+ GPIO_FN(DU1_DR7), GPIO_FN(VI2_G5), GPIO_FN(DU1_DG0),
+ GPIO_FN(VI2_DATA2_VI2_B2), GPIO_FN(SCL1_B), GPIO_FN(SD3_DAT2),
+ GPIO_FN(SCK3_E), GPIO_FN(AUDATA6), GPIO_FN(TX0_D), GPIO_FN(DU1_DG1),
+ GPIO_FN(VI2_DATA3_VI2_B3), GPIO_FN(SDA1_B), GPIO_FN(SD3_DAT3),
+ GPIO_FN(SCK5), GPIO_FN(AUDATA7), GPIO_FN(RX0_D), GPIO_FN(DU1_DG2),
+ GPIO_FN(VI2_G6), GPIO_FN(DU1_DG3), GPIO_FN(VI2_G7), GPIO_FN(DU1_DG4),
+ GPIO_FN(VI2_R0), GPIO_FN(DU1_DG5), GPIO_FN(VI2_R1), GPIO_FN(DU1_DG6),
+ GPIO_FN(VI2_R2), GPIO_FN(DU1_DG7), GPIO_FN(VI2_R3), GPIO_FN(DU1_DB0),
+ GPIO_FN(VI2_DATA4_VI2_B4), GPIO_FN(SCL2_B), GPIO_FN(SD3_DAT0),
+ GPIO_FN(TX5), GPIO_FN(SCK0_D),
+
+ /* IPSR5 */
+ GPIO_FN(DU1_DB1), GPIO_FN(VI2_DATA5_VI2_B5), GPIO_FN(SDA2_B),
+ GPIO_FN(SD3_DAT1), GPIO_FN(RX5), GPIO_FN(RTS0_D_TANS_D),
+ GPIO_FN(DU1_DB2), GPIO_FN(VI2_R4), GPIO_FN(DU1_DB3), GPIO_FN(VI2_R5),
+ GPIO_FN(DU1_DB4), GPIO_FN(VI2_R6), GPIO_FN(DU1_DB5), GPIO_FN(VI2_R7),
+ GPIO_FN(DU1_DB6), GPIO_FN(SCL2_D), GPIO_FN(DU1_DB7), GPIO_FN(SDA2_D),
+ GPIO_FN(DU1_DOTCLKIN), GPIO_FN(VI2_CLKENB), GPIO_FN(HSPI_CS1),
+ GPIO_FN(SCL1_D), GPIO_FN(DU1_DOTCLKOUT), GPIO_FN(VI2_FIELD),
+ GPIO_FN(SDA1_D), GPIO_FN(DU1_EXHSYNC_DU1_HSYNC), GPIO_FN(VI2_HSYNC),
+ GPIO_FN(VI3_HSYNC), GPIO_FN(DU1_EXVSYNC_DU1_VSYNC), GPIO_FN(VI2_VSYNC),
+ GPIO_FN(VI3_VSYNC), GPIO_FN(DU1_EXODDF_DU1_ODDF_DISP_CDE),
+ GPIO_FN(VI2_CLK), GPIO_FN(TX3_B_IRDA_TX_B), GPIO_FN(SD3_CD),
+ GPIO_FN(HSPI_TX1), GPIO_FN(VI1_CLKENB), GPIO_FN(VI3_CLKENB),
+ GPIO_FN(AUDIO_CLKC), GPIO_FN(TX2_D), GPIO_FN(SPEEDIN),
+ GPIO_FN(GPS_SIGN_D), GPIO_FN(DU1_DISP), GPIO_FN(VI2_DATA6_VI2_B6),
+ GPIO_FN(TCLK0), GPIO_FN(QSTVA_B_QVS_B), GPIO_FN(HSPI_CLK1),
+ GPIO_FN(SCK2_D), GPIO_FN(AUDIO_CLKOUT_B), GPIO_FN(GPS_MAG_D),
+ GPIO_FN(DU1_CDE), GPIO_FN(VI2_DATA7_VI2_B7), GPIO_FN(RX3_B_IRDA_RX_B),
+ GPIO_FN(SD3_WP), GPIO_FN(HSPI_RX1), GPIO_FN(VI1_FIELD),
+ GPIO_FN(VI3_FIELD), GPIO_FN(AUDIO_CLKOUT), GPIO_FN(RX2_D),
+ GPIO_FN(GPS_CLK_C), GPIO_FN(GPS_CLK_D), GPIO_FN(AUDIO_CLKA),
+ GPIO_FN(CAN_TXCLK), GPIO_FN(AUDIO_CLKB), GPIO_FN(USB_OVC2),
+ GPIO_FN(CAN_DEBUGOUT0), GPIO_FN(MOUT0),
+
+ /* IPSR6 */
+ GPIO_FN(SSI_SCK0129), GPIO_FN(CAN_DEBUGOUT1), GPIO_FN(MOUT1),
+ GPIO_FN(SSI_WS0129), GPIO_FN(CAN_DEBUGOUT2), GPIO_FN(MOUT2),
+ GPIO_FN(SSI_SDATA0), GPIO_FN(CAN_DEBUGOUT3), GPIO_FN(MOUT5),
+ GPIO_FN(SSI_SDATA1), GPIO_FN(CAN_DEBUGOUT4), GPIO_FN(MOUT6),
+ GPIO_FN(SSI_SDATA2), GPIO_FN(CAN_DEBUGOUT5), GPIO_FN(SSI_SCK34),
+ GPIO_FN(CAN_DEBUGOUT6), GPIO_FN(CAN0_TX_B), GPIO_FN(IERX),
+ GPIO_FN(SSI_SCK9_C), GPIO_FN(SSI_WS34), GPIO_FN(CAN_DEBUGOUT7),
+ GPIO_FN(CAN0_RX_B), GPIO_FN(IETX), GPIO_FN(SSI_WS9_C),
+ GPIO_FN(SSI_SDATA3), GPIO_FN(PWM0_C), GPIO_FN(CAN_DEBUGOUT8),
+ GPIO_FN(CAN_CLK_B), GPIO_FN(IECLK), GPIO_FN(SCIF_CLK_B),
+ GPIO_FN(TCLK0_B), GPIO_FN(SSI_SDATA4), GPIO_FN(CAN_DEBUGOUT9),
+ GPIO_FN(SSI_SDATA9_C), GPIO_FN(SSI_SCK5), GPIO_FN(ADICLK),
+ GPIO_FN(CAN_DEBUGOUT10), GPIO_FN(SCK3), GPIO_FN(TCLK0_D),
+ GPIO_FN(SSI_WS5), GPIO_FN(ADICS_SAMP), GPIO_FN(CAN_DEBUGOUT11),
+ GPIO_FN(TX3_IRDA_TX), GPIO_FN(SSI_SDATA5), GPIO_FN(ADIDATA),
+ GPIO_FN(CAN_DEBUGOUT12), GPIO_FN(RX3_IRDA_RX), GPIO_FN(SSI_SCK6),
+ GPIO_FN(ADICHS0), GPIO_FN(CAN0_TX), GPIO_FN(IERX_B),
+
+ /* IPSR7 */
+ GPIO_FN(SSI_WS6), GPIO_FN(ADICHS1), GPIO_FN(CAN0_RX), GPIO_FN(IETX_B),
+ GPIO_FN(SSI_SDATA6), GPIO_FN(ADICHS2), GPIO_FN(CAN_CLK),
+ GPIO_FN(IECLK_B), GPIO_FN(SSI_SCK78), GPIO_FN(CAN_DEBUGOUT13),
+ GPIO_FN(IRQ0_B), GPIO_FN(SSI_SCK9_B), GPIO_FN(HSPI_CLK1_C),
+ GPIO_FN(SSI_WS78), GPIO_FN(CAN_DEBUGOUT14), GPIO_FN(IRQ1_B),
+ GPIO_FN(SSI_WS9_B), GPIO_FN(HSPI_CS1_C), GPIO_FN(SSI_SDATA7),
+ GPIO_FN(CAN_DEBUGOUT15), GPIO_FN(IRQ2_B), GPIO_FN(TCLK1_C),
+ GPIO_FN(HSPI_TX1_C), GPIO_FN(SSI_SDATA8), GPIO_FN(VSP),
+ GPIO_FN(IRQ3_B), GPIO_FN(HSPI_RX1_C), GPIO_FN(SD0_CLK),
+ GPIO_FN(ATACS01), GPIO_FN(SCK1_B), GPIO_FN(SD0_CMD), GPIO_FN(ATACS11),
+ GPIO_FN(TX1_B), GPIO_FN(CC5_TDO), GPIO_FN(SD0_DAT0), GPIO_FN(ATADIR1),
+ GPIO_FN(RX1_B), GPIO_FN(CC5_TRST), GPIO_FN(SD0_DAT1), GPIO_FN(ATAG1),
+ GPIO_FN(SCK2_B), GPIO_FN(CC5_TMS), GPIO_FN(SD0_DAT2), GPIO_FN(ATARD1),
+ GPIO_FN(TX2_B), GPIO_FN(CC5_TCK), GPIO_FN(SD0_DAT3), GPIO_FN(ATAWR1),
+ GPIO_FN(RX2_B), GPIO_FN(CC5_TDI), GPIO_FN(SD0_CD), GPIO_FN(DREQ2),
+ GPIO_FN(RTS1_B_TANS_B), GPIO_FN(SD0_WP), GPIO_FN(DACK2),
+ GPIO_FN(CTS1_B),
+
+ /* IPSR8 */
+ GPIO_FN(HSPI_CLK0), GPIO_FN(CTS0), GPIO_FN(USB_OVC0), GPIO_FN(AD_CLK),
+ GPIO_FN(CC5_STATE4), GPIO_FN(CC5_STATE12), GPIO_FN(CC5_STATE20),
+ GPIO_FN(CC5_STATE28), GPIO_FN(CC5_STATE36), GPIO_FN(HSPI_CS0),
+ GPIO_FN(RTS0_TANS), GPIO_FN(USB_OVC1), GPIO_FN(AD_DI),
+ GPIO_FN(CC5_STATE5), GPIO_FN(CC5_STATE13), GPIO_FN(CC5_STATE21),
+ GPIO_FN(CC5_STATE29), GPIO_FN(CC5_STATE37), GPIO_FN(HSPI_TX0),
+ GPIO_FN(TX0), GPIO_FN(CAN_DEBUG_HW_TRIGGER), GPIO_FN(AD_DO),
+ GPIO_FN(CC5_STATE6), GPIO_FN(CC5_STATE14), GPIO_FN(CC5_STATE22),
+ GPIO_FN(CC5_STATE30), GPIO_FN(CC5_STATE38), GPIO_FN(HSPI_RX0),
+ GPIO_FN(RX0), GPIO_FN(CAN_STEP0), GPIO_FN(AD_NCS), GPIO_FN(CC5_STATE7),
+ GPIO_FN(CC5_STATE15), GPIO_FN(CC5_STATE23), GPIO_FN(CC5_STATE31),
+ GPIO_FN(CC5_STATE39), GPIO_FN(FMCLK), GPIO_FN(RDS_CLK), GPIO_FN(PCMOE),
+ GPIO_FN(BPFCLK), GPIO_FN(PCMWE), GPIO_FN(FMIN), GPIO_FN(RDS_DATA),
+ GPIO_FN(VI0_CLK), GPIO_FN(MMC1_CLK), GPIO_FN(VI0_CLKENB),
+ GPIO_FN(TX1_C), GPIO_FN(HTX1_B), GPIO_FN(MT1_SYNC),
+ GPIO_FN(VI0_FIELD), GPIO_FN(RX1_C), GPIO_FN(HRX1_B),
+ GPIO_FN(VI0_HSYNC), GPIO_FN(VI0_DATA0_B_VI0_B0_B), GPIO_FN(CTS1_C),
+ GPIO_FN(TX4_D), GPIO_FN(MMC1_CMD), GPIO_FN(HSCK1_B),
+ GPIO_FN(VI0_VSYNC), GPIO_FN(VI0_DATA1_B_VI0_B1_B),
+ GPIO_FN(RTS1_C_TANS_C), GPIO_FN(RX4_D), GPIO_FN(PWMFSW0_C),
+
+ /* IPSR9 */
+ GPIO_FN(VI0_DATA0_VI0_B0), GPIO_FN(HRTS1_B), GPIO_FN(MT1_VCXO),
+ GPIO_FN(VI0_DATA1_VI0_B1), GPIO_FN(HCTS1_B), GPIO_FN(MT1_PWM),
+ GPIO_FN(VI0_DATA2_VI0_B2), GPIO_FN(MMC1_D0), GPIO_FN(VI0_DATA3_VI0_B3),
+ GPIO_FN(MMC1_D1), GPIO_FN(VI0_DATA4_VI0_B4), GPIO_FN(MMC1_D2),
+ GPIO_FN(VI0_DATA5_VI0_B5), GPIO_FN(MMC1_D3), GPIO_FN(VI0_DATA6_VI0_B6),
+ GPIO_FN(MMC1_D4), GPIO_FN(ARM_TRACEDATA_0), GPIO_FN(VI0_DATA7_VI0_B7),
+ GPIO_FN(MMC1_D5), GPIO_FN(ARM_TRACEDATA_1), GPIO_FN(VI0_G0),
+ GPIO_FN(SSI_SCK78_C), GPIO_FN(IRQ0), GPIO_FN(ARM_TRACEDATA_2),
+ GPIO_FN(VI0_G1), GPIO_FN(SSI_WS78_C), GPIO_FN(IRQ1),
+ GPIO_FN(ARM_TRACEDATA_3), GPIO_FN(VI0_G2), GPIO_FN(ETH_TXD1),
+ GPIO_FN(MMC1_D6), GPIO_FN(ARM_TRACEDATA_4), GPIO_FN(TS_SPSYNC0),
+ GPIO_FN(VI0_G3), GPIO_FN(ETH_CRS_DV), GPIO_FN(MMC1_D7),
+ GPIO_FN(ARM_TRACEDATA_5), GPIO_FN(TS_SDAT0), GPIO_FN(VI0_G4),
+ GPIO_FN(ETH_TX_EN), GPIO_FN(SD2_DAT0_B), GPIO_FN(ARM_TRACEDATA_6),
+ GPIO_FN(VI0_G5), GPIO_FN(ETH_RX_ER), GPIO_FN(SD2_DAT1_B),
+ GPIO_FN(ARM_TRACEDATA_7), GPIO_FN(VI0_G6), GPIO_FN(ETH_RXD0),
+ GPIO_FN(SD2_DAT2_B), GPIO_FN(ARM_TRACEDATA_8), GPIO_FN(VI0_G7),
+ GPIO_FN(ETH_RXD1), GPIO_FN(SD2_DAT3_B), GPIO_FN(ARM_TRACEDATA_9),
+
+ /* IPSR10 */
+ GPIO_FN(VI0_R0), GPIO_FN(SSI_SDATA7_C), GPIO_FN(SCK1_C),
+ GPIO_FN(DREQ1_B), GPIO_FN(ARM_TRACEDATA_10), GPIO_FN(DREQ0_C),
+ GPIO_FN(VI0_R1), GPIO_FN(SSI_SDATA8_C), GPIO_FN(DACK1_B),
+ GPIO_FN(ARM_TRACEDATA_11), GPIO_FN(DACK0_C), GPIO_FN(DRACK0_C),
+ GPIO_FN(VI0_R2), GPIO_FN(ETH_LINK), GPIO_FN(SD2_CLK_B), GPIO_FN(IRQ2),
+ GPIO_FN(ARM_TRACEDATA_12), GPIO_FN(VI0_R3), GPIO_FN(ETH_MAGIC),
+ GPIO_FN(SD2_CMD_B), GPIO_FN(IRQ3), GPIO_FN(ARM_TRACEDATA_13),
+ GPIO_FN(VI0_R4), GPIO_FN(ETH_REFCLK), GPIO_FN(SD2_CD_B),
+ GPIO_FN(HSPI_CLK1_B), GPIO_FN(ARM_TRACEDATA_14), GPIO_FN(MT1_CLK),
+ GPIO_FN(TS_SCK0), GPIO_FN(VI0_R5), GPIO_FN(ETH_TXD0),
+ GPIO_FN(SD2_WP_B), GPIO_FN(HSPI_CS1_B), GPIO_FN(ARM_TRACEDATA_15),
+ GPIO_FN(MT1_D), GPIO_FN(TS_SDEN0), GPIO_FN(VI0_R6), GPIO_FN(ETH_MDC),
+ GPIO_FN(DREQ2_C), GPIO_FN(HSPI_TX1_B), GPIO_FN(TRACECLK),
+ GPIO_FN(MT1_BEN), GPIO_FN(PWMFSW0_D), GPIO_FN(VI0_R7),
+ GPIO_FN(ETH_MDIO), GPIO_FN(DACK2_C), GPIO_FN(HSPI_RX1_B),
+ GPIO_FN(SCIF_CLK_D), GPIO_FN(TRACECTL), GPIO_FN(MT1_PEN),
+ GPIO_FN(VI1_CLK), GPIO_FN(SIM_D), GPIO_FN(SDA3), GPIO_FN(VI1_HSYNC),
+ GPIO_FN(VI3_CLK), GPIO_FN(SSI_SCK4), GPIO_FN(GPS_SIGN_C),
+ GPIO_FN(PWMFSW0_E), GPIO_FN(VI1_VSYNC), GPIO_FN(AUDIO_CLKOUT_C),
+ GPIO_FN(SSI_WS4), GPIO_FN(SIM_CLK), GPIO_FN(GPS_MAG_C),
+ GPIO_FN(SPV_TRST), GPIO_FN(SCL3),
+
+ /* IPSR11 */
+ GPIO_FN(VI1_DATA0_VI1_B0), GPIO_FN(SD2_DAT0), GPIO_FN(SIM_RST),
+ GPIO_FN(SPV_TCK), GPIO_FN(ADICLK_B), GPIO_FN(VI1_DATA1_VI1_B1),
+ GPIO_FN(SD2_DAT1), GPIO_FN(MT0_CLK), GPIO_FN(SPV_TMS),
+ GPIO_FN(ADICS_B_SAMP_B), GPIO_FN(VI1_DATA2_VI1_B2), GPIO_FN(SD2_DAT2),
+ GPIO_FN(MT0_D), GPIO_FN(SPVTDI), GPIO_FN(ADIDATA_B),
+ GPIO_FN(VI1_DATA3_VI1_B3), GPIO_FN(SD2_DAT3), GPIO_FN(MT0_BEN),
+ GPIO_FN(SPV_TDO), GPIO_FN(ADICHS0_B), GPIO_FN(VI1_DATA4_VI1_B4),
+ GPIO_FN(SD2_CLK), GPIO_FN(MT0_PEN), GPIO_FN(SPA_TRST),
+ GPIO_FN(HSPI_CLK1_D), GPIO_FN(ADICHS1_B), GPIO_FN(VI1_DATA5_VI1_B5),
+ GPIO_FN(SD2_CMD), GPIO_FN(MT0_SYNC), GPIO_FN(SPA_TCK),
+ GPIO_FN(HSPI_CS1_D), GPIO_FN(ADICHS2_B), GPIO_FN(VI1_DATA6_VI1_B6),
+ GPIO_FN(SD2_CD), GPIO_FN(MT0_VCXO), GPIO_FN(SPA_TMS),
+ GPIO_FN(HSPI_TX1_D), GPIO_FN(VI1_DATA7_VI1_B7), GPIO_FN(SD2_WP),
+ GPIO_FN(MT0_PWM), GPIO_FN(SPA_TDI), GPIO_FN(HSPI_RX1_D),
+ GPIO_FN(VI1_G0), GPIO_FN(VI3_DATA0), GPIO_FN(DU1_DOTCLKOUT1),
+ GPIO_FN(TS_SCK1), GPIO_FN(DREQ2_B), GPIO_FN(TX2), GPIO_FN(SPA_TDO),
+ GPIO_FN(HCTS0_B), GPIO_FN(VI1_G1), GPIO_FN(VI3_DATA1),
+ GPIO_FN(SSI_SCK1), GPIO_FN(TS_SDEN1), GPIO_FN(DACK2_B), GPIO_FN(RX2),
+ GPIO_FN(HRTS0_B),
+
+ /* IPSR12 */
+ GPIO_FN(VI1_G2), GPIO_FN(VI3_DATA2), GPIO_FN(SSI_WS1),
+ GPIO_FN(TS_SPSYNC1), GPIO_FN(SCK2), GPIO_FN(HSCK0_B), GPIO_FN(VI1_G3),
+ GPIO_FN(VI3_DATA3), GPIO_FN(SSI_SCK2), GPIO_FN(TS_SDAT1),
+ GPIO_FN(SCL1_C), GPIO_FN(HTX0_B), GPIO_FN(VI1_G4), GPIO_FN(VI3_DATA4),
+ GPIO_FN(SSI_WS2), GPIO_FN(SDA1_C), GPIO_FN(SIM_RST_B),
+ GPIO_FN(HRX0_B), GPIO_FN(VI1_G5), GPIO_FN(VI3_DATA5),
+ GPIO_FN(GPS_CLK), GPIO_FN(FSE), GPIO_FN(TX4_B), GPIO_FN(SIM_D_B),
+ GPIO_FN(VI1_G6), GPIO_FN(VI3_DATA6), GPIO_FN(GPS_SIGN), GPIO_FN(FRB),
+ GPIO_FN(RX4_B), GPIO_FN(SIM_CLK_B), GPIO_FN(VI1_G7),
+ GPIO_FN(VI3_DATA7), GPIO_FN(GPS_MAG), GPIO_FN(FCE), GPIO_FN(SCK4_B),
+};
+
+static struct pinmux_cfg_reg pinmux_config_regs[] = {
+ { PINMUX_CFG_REG("GPSR0", 0xfffc0004, 32, 1) {
+ GP_0_31_FN, FN_IP3_31_29,
+ GP_0_30_FN, FN_IP3_26_24,
+ GP_0_29_FN, FN_IP3_22_21,
+ GP_0_28_FN, FN_IP3_14_12,
+ GP_0_27_FN, FN_IP3_11_9,
+ GP_0_26_FN, FN_IP3_2_0,
+ GP_0_25_FN, FN_IP2_30_28,
+ GP_0_24_FN, FN_IP2_21_19,
+ GP_0_23_FN, FN_IP2_18_16,
+ GP_0_22_FN, FN_IP0_30_28,
+ GP_0_21_FN, FN_IP0_5_3,
+ GP_0_20_FN, FN_IP1_18_15,
+ GP_0_19_FN, FN_IP1_14_11,
+ GP_0_18_FN, FN_IP1_10_7,
+ GP_0_17_FN, FN_IP1_6_4,
+ GP_0_16_FN, FN_IP1_3_2,
+ GP_0_15_FN, FN_IP1_1_0,
+ GP_0_14_FN, FN_IP0_27_26,
+ GP_0_13_FN, FN_IP0_25,
+ GP_0_12_FN, FN_IP0_24_23,
+ GP_0_11_FN, FN_IP0_22_19,
+ GP_0_10_FN, FN_IP0_18_16,
+ GP_0_9_FN, FN_IP0_15_14,
+ GP_0_8_FN, FN_IP0_13_12,
+ GP_0_7_FN, FN_IP0_11_10,
+ GP_0_6_FN, FN_IP0_9_8,
+ GP_0_5_FN, FN_A19,
+ GP_0_4_FN, FN_A18,
+ GP_0_3_FN, FN_A17,
+ GP_0_2_FN, FN_IP0_7_6,
+ GP_0_1_FN, FN_AVS2,
+ GP_0_0_FN, FN_AVS1 }
+ },
+ { PINMUX_CFG_REG("GPSR1", 0xfffc0008, 32, 1) {
+ GP_1_31_FN, FN_IP5_23_21,
+ GP_1_30_FN, FN_IP5_20_17,
+ GP_1_29_FN, FN_IP5_16_15,
+ GP_1_28_FN, FN_IP5_14_13,
+ GP_1_27_FN, FN_IP5_12_11,
+ GP_1_26_FN, FN_IP5_10_9,
+ GP_1_25_FN, FN_IP5_8,
+ GP_1_24_FN, FN_IP5_7,
+ GP_1_23_FN, FN_IP5_6,
+ GP_1_22_FN, FN_IP5_5,
+ GP_1_21_FN, FN_IP5_4,
+ GP_1_20_FN, FN_IP5_3,
+ GP_1_19_FN, FN_IP5_2_0,
+ GP_1_18_FN, FN_IP4_31_29,
+ GP_1_17_FN, FN_IP4_28,
+ GP_1_16_FN, FN_IP4_27,
+ GP_1_15_FN, FN_IP4_26,
+ GP_1_14_FN, FN_IP4_25,
+ GP_1_13_FN, FN_IP4_24,
+ GP_1_12_FN, FN_IP4_23,
+ GP_1_11_FN, FN_IP4_22_20,
+ GP_1_10_FN, FN_IP4_19_17,
+ GP_1_9_FN, FN_IP4_16,
+ GP_1_8_FN, FN_IP4_15,
+ GP_1_7_FN, FN_IP4_14,
+ GP_1_6_FN, FN_IP4_13,
+ GP_1_5_FN, FN_IP4_12,
+ GP_1_4_FN, FN_IP4_11,
+ GP_1_3_FN, FN_IP4_10_8,
+ GP_1_2_FN, FN_IP4_7_5,
+ GP_1_1_FN, FN_IP4_4_2,
+ GP_1_0_FN, FN_IP4_1_0 }
+ },
+ { PINMUX_CFG_REG("GPSR2", 0xfffc000c, 32, 1) {
+ GP_2_31_FN, FN_IP10_28_26,
+ GP_2_30_FN, FN_IP10_25_24,
+ GP_2_29_FN, FN_IP10_23_21,
+ GP_2_28_FN, FN_IP10_20_18,
+ GP_2_27_FN, FN_IP10_17_15,
+ GP_2_26_FN, FN_IP10_14_12,
+ GP_2_25_FN, FN_IP10_11_9,
+ GP_2_24_FN, FN_IP10_8_6,
+ GP_2_23_FN, FN_IP10_5_3,
+ GP_2_22_FN, FN_IP10_2_0,
+ GP_2_21_FN, FN_IP9_29_28,
+ GP_2_20_FN, FN_IP9_27_26,
+ GP_2_19_FN, FN_IP9_25_24,
+ GP_2_18_FN, FN_IP9_23_22,
+ GP_2_17_FN, FN_IP9_21_19,
+ GP_2_16_FN, FN_IP9_18_16,
+ GP_2_15_FN, FN_IP9_15_14,
+ GP_2_14_FN, FN_IP9_13_12,
+ GP_2_13_FN, FN_IP9_11_10,
+ GP_2_12_FN, FN_IP9_9_8,
+ GP_2_11_FN, FN_IP9_7,
+ GP_2_10_FN, FN_IP9_6,
+ GP_2_9_FN, FN_IP9_5,
+ GP_2_8_FN, FN_IP9_4,
+ GP_2_7_FN, FN_IP9_3_2,
+ GP_2_6_FN, FN_IP9_1_0,
+ GP_2_5_FN, FN_IP8_30_28,
+ GP_2_4_FN, FN_IP8_27_25,
+ GP_2_3_FN, FN_IP8_24_23,
+ GP_2_2_FN, FN_IP8_22_21,
+ GP_2_1_FN, FN_IP8_20,
+ GP_2_0_FN, FN_IP5_27_24 }
+ },
+ { PINMUX_CFG_REG("GPSR3", 0xfffc0010, 32, 1) {
+ GP_3_31_FN, FN_IP6_3_2,
+ GP_3_30_FN, FN_IP6_1_0,
+ GP_3_29_FN, FN_IP5_30_29,
+ GP_3_28_FN, FN_IP5_28,
+ GP_3_27_FN, FN_IP1_24_23,
+ GP_3_26_FN, FN_IP1_22_21,
+ GP_3_25_FN, FN_IP1_20_19,
+ GP_3_24_FN, FN_IP7_26_25,
+ GP_3_23_FN, FN_IP7_24_23,
+ GP_3_22_FN, FN_IP7_22_21,
+ GP_3_21_FN, FN_IP7_20_19,
+ GP_3_20_FN, FN_IP7_30_29,
+ GP_3_19_FN, FN_IP7_28_27,
+ GP_3_18_FN, FN_IP7_18_17,
+ GP_3_17_FN, FN_IP7_16_15,
+ GP_3_16_FN, FN_IP12_17_15,
+ GP_3_15_FN, FN_IP12_14_12,
+ GP_3_14_FN, FN_IP12_11_9,
+ GP_3_13_FN, FN_IP12_8_6,
+ GP_3_12_FN, FN_IP12_5_3,
+ GP_3_11_FN, FN_IP12_2_0,
+ GP_3_10_FN, FN_IP11_29_27,
+ GP_3_9_FN, FN_IP11_26_24,
+ GP_3_8_FN, FN_IP11_23_21,
+ GP_3_7_FN, FN_IP11_20_18,
+ GP_3_6_FN, FN_IP11_17_15,
+ GP_3_5_FN, FN_IP11_14_12,
+ GP_3_4_FN, FN_IP11_11_9,
+ GP_3_3_FN, FN_IP11_8_6,
+ GP_3_2_FN, FN_IP11_5_3,
+ GP_3_1_FN, FN_IP11_2_0,
+ GP_3_0_FN, FN_IP10_31_29 }
+ },
+ { PINMUX_CFG_REG("GPSR4", 0xfffc0014, 32, 1) {
+ GP_4_31_FN, FN_IP8_19,
+ GP_4_30_FN, FN_IP8_18,
+ GP_4_29_FN, FN_IP8_17_16,
+ GP_4_28_FN, FN_IP0_2_0,
+ GP_4_27_FN, FN_PENC1,
+ GP_4_26_FN, FN_PENC0,
+ GP_4_25_FN, FN_IP8_15_12,
+ GP_4_24_FN, FN_IP8_11_8,
+ GP_4_23_FN, FN_IP8_7_4,
+ GP_4_22_FN, FN_IP8_3_0,
+ GP_4_21_FN, FN_IP2_3_0,
+ GP_4_20_FN, FN_IP1_28_25,
+ GP_4_19_FN, FN_IP2_15_12,
+ GP_4_18_FN, FN_IP2_11_8,
+ GP_4_17_FN, FN_IP2_7_4,
+ GP_4_16_FN, FN_IP7_14_13,
+ GP_4_15_FN, FN_IP7_12_10,
+ GP_4_14_FN, FN_IP7_9_7,
+ GP_4_13_FN, FN_IP7_6_4,
+ GP_4_12_FN, FN_IP7_3_2,
+ GP_4_11_FN, FN_IP7_1_0,
+ GP_4_10_FN, FN_IP6_30_29,
+ GP_4_9_FN, FN_IP6_26_25,
+ GP_4_8_FN, FN_IP6_24_23,
+ GP_4_7_FN, FN_IP6_22_20,
+ GP_4_6_FN, FN_IP6_19_18,
+ GP_4_5_FN, FN_IP6_17_15,
+ GP_4_4_FN, FN_IP6_14_12,
+ GP_4_3_FN, FN_IP6_11_9,
+ GP_4_2_FN, FN_IP6_8,
+ GP_4_1_FN, FN_IP6_7_6,
+ GP_4_0_FN, FN_IP6_5_4 }
+ },
+ { PINMUX_CFG_REG("GPSR5", 0xfffc0018, 32, 1) {
+ GP_5_31_FN, FN_IP3_5,
+ GP_5_30_FN, FN_IP3_4,
+ GP_5_29_FN, FN_IP3_3,
+ GP_5_28_FN, FN_IP2_27,
+ GP_5_27_FN, FN_IP2_26,
+ GP_5_26_FN, FN_IP2_25,
+ GP_5_25_FN, FN_IP2_24,
+ GP_5_24_FN, FN_IP2_23,
+ GP_5_23_FN, FN_IP2_22,
+ GP_5_22_FN, FN_IP3_28,
+ GP_5_21_FN, FN_IP3_27,
+ GP_5_20_FN, FN_IP3_23,
+ GP_5_19_FN, FN_EX_WAIT0,
+ GP_5_18_FN, FN_WE1,
+ GP_5_17_FN, FN_WE0,
+ GP_5_16_FN, FN_RD,
+ GP_5_15_FN, FN_A16,
+ GP_5_14_FN, FN_A15,
+ GP_5_13_FN, FN_A14,
+ GP_5_12_FN, FN_A13,
+ GP_5_11_FN, FN_A12,
+ GP_5_10_FN, FN_A11,
+ GP_5_9_FN, FN_A10,
+ GP_5_8_FN, FN_A9,
+ GP_5_7_FN, FN_A8,
+ GP_5_6_FN, FN_A7,
+ GP_5_5_FN, FN_A6,
+ GP_5_4_FN, FN_A5,
+ GP_5_3_FN, FN_A4,
+ GP_5_2_FN, FN_A3,
+ GP_5_1_FN, FN_A2,
+ GP_5_0_FN, FN_A1 }
+ },
+ { PINMUX_CFG_REG("GPSR6", 0xfffc001c, 32, 1) {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ GP_6_8_FN, FN_IP3_20,
+ GP_6_7_FN, FN_IP3_19,
+ GP_6_6_FN, FN_IP3_18,
+ GP_6_5_FN, FN_IP3_17,
+ GP_6_4_FN, FN_IP3_16,
+ GP_6_3_FN, FN_IP3_15,
+ GP_6_2_FN, FN_IP3_8,
+ GP_6_1_FN, FN_IP3_7,
+ GP_6_0_FN, FN_IP3_6 }
+ },
+
+ { PINMUX_CFG_REG_VAR("IPSR0", 0xfffc0020, 32,
+ 1, 3, 2, 1, 2, 4, 3, 2, 2, 2, 2, 2, 3, 3) {
+ /* IP0_31 [1] */
+ 0, 0,
+ /* IP0_30_28 [3] */
+ FN_RD_WR, FN_FWE, FN_ATAG0, FN_VI1_R7,
+ FN_HRTS1, FN_RX4_C, 0, 0,
+ /* IP0_27_26 [2] */
+ FN_CS1_A26, FN_HSPI_TX2, FN_SDSELF_B, 0,
+ /* IP0_25 [1] */
+ FN_CS0, FN_HSPI_CS2_B,
+ /* IP0_24_23 [2] */
+ FN_CLKOUT, FN_TX3C_IRDA_TX_C, FN_PWM0_B, 0,
+ /* IP0_22_19 [4] */
+ FN_A25, FN_SD1_WP, FN_MMC0_D5, FN_FD5,
+ FN_HSPI_RX2, FN_VI1_R3, FN_TX5_B, FN_SSI_SDATA7_B,
+ FN_CTS0_B, 0, 0, 0,
+ 0, 0, 0, 0,
+ /* IP0_18_16 [3] */
+ FN_A24, FN_SD1_CD, FN_MMC0_D4, FN_FD4,
+ FN_HSPI_CS2, FN_VI1_R2, FN_SSI_WS78_B, 0,
+ /* IP0_15_14 [2] */
+ FN_A23, FN_FCLE, FN_HSPI_CLK2, FN_VI1_R1,
+ /* IP0_13_12 [2] */
+ FN_A22, FN_RX5_D, FN_HSPI_RX2_B, FN_VI1_R0,
+ /* IP0_11_10 [2] */
+ FN_A21, FN_SCK5_D, FN_HSPI_CLK2_B, 0,
+ /* IP0_9_8 [2] */
+ FN_A20, FN_TX5_D, FN_HSPI_TX2_B, 0,
+ /* IP0_7_6 [2] */
+ FN_A0, FN_SD1_DAT3, FN_MMC0_D3, FN_FD3,
+ /* IP0_5_3 [3] */
+ FN_BS, FN_SD1_DAT2, FN_MMC0_D2, FN_FD2,
+ FN_ATADIR0, FN_SDSELF, FN_HCTS1, FN_TX4_C,
+ /* IP0_2_0 [3] */
+ FN_PENC2, FN_SCK0, FN_PWM1, FN_PWMFSW0,
+ FN_SCIF_CLK, FN_TCLK0_C, 0, 0 }
+ },
+ { PINMUX_CFG_REG_VAR("IPSR1", 0xfffc0024, 32,
+ 3, 4, 2, 2, 2, 4, 4, 4, 3, 2, 2) {
+ /* IP1_31_29 [3] */
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ /* IP1_28_25 [4] */
+ FN_HTX0, FN_TX1, FN_SDATA, FN_CTS0_C,
+ FN_SUB_TCK, FN_CC5_STATE2, FN_CC5_STATE10, FN_CC5_STATE18,
+ FN_CC5_STATE26, FN_CC5_STATE34, 0, 0,
+ 0, 0, 0, 0,
+ /* IP1_24_23 [2] */
+ FN_MLB_DAT, FN_PWM4, FN_RX4, 0,
+ /* IP1_22_21 [2] */
+ FN_MLB_SIG, FN_PWM3, FN_TX4, 0,
+ /* IP1_20_19 [2] */
+ FN_MLB_CLK, FN_PWM2, FN_SCK4, 0,
+ /* IP1_18_15 [4] */
+ FN_EX_CS5, FN_SD1_DAT1, FN_MMC0_D1, FN_FD1,
+ FN_ATAWR0, FN_VI1_R6, FN_HRX1, FN_RX2_E,
+ FN_RX0_B, FN_SSI_WS9, 0, 0,
+ 0, 0, 0, 0,
+ /* IP1_14_11 [4] */
+ FN_EX_CS4, FN_SD1_DAT0, FN_MMC0_D0, FN_FD0,
+ FN_ATARD0, FN_VI1_R5, FN_SCK5_B, FN_HTX1,
+ FN_TX2_E, FN_TX0_B, FN_SSI_SCK9, 0,
+ 0, 0, 0, 0,
+ /* IP1_10_7 [4] */
+ FN_EX_CS3, FN_SD1_CMD, FN_MMC0_CMD, FN_FRE,
+ FN_ATACS10, FN_VI1_R4, FN_RX5_B, FN_HSCK1,
+ FN_SSI_SDATA8_B, FN_RTS0_B_TANS_B, FN_SSI_SDATA9, 0,
+ 0, 0, 0, 0,
+ /* IP1_6_4 [3] */
+ FN_EX_CS2, FN_SD1_CLK, FN_MMC0_CLK, FN_FALE,
+ FN_ATACS00, 0, 0, 0,
+ /* IP1_3_2 [2] */
+ FN_EX_CS1, FN_MMC0_D7, FN_FD7, 0,
+ /* IP1_1_0 [2] */
+ FN_EX_CS0, FN_RX3_C_IRDA_RX_C, FN_MMC0_D6, FN_FD6 }
+ },
+ { PINMUX_CFG_REG_VAR("IPSR2", 0xfffc0028, 32,
+ 1, 3, 1, 1, 1, 1, 1, 1, 3, 3, 4, 4, 4, 4) {
+ /* IP2_31 [1] */
+ 0, 0,
+ /* IP2_30_28 [3] */
+ FN_DU0_DG0, FN_LCDOUT8, FN_DREQ1, FN_SCL2,
+ FN_AUDATA2, 0, 0, 0,
+ /* IP2_27 [1] */
+ FN_DU0_DR7, FN_LCDOUT7,
+ /* IP2_26 [1] */
+ FN_DU0_DR6, FN_LCDOUT6,
+ /* IP2_25 [1] */
+ FN_DU0_DR5, FN_LCDOUT5,
+ /* IP2_24 [1] */
+ FN_DU0_DR4, FN_LCDOUT4,
+ /* IP2_23 [1] */
+ FN_DU0_DR3, FN_LCDOUT3,
+ /* IP2_22 [1] */
+ FN_DU0_DR2, FN_LCDOUT2,
+ /* IP2_21_19 [3] */
+ FN_DU0_DR1, FN_LCDOUT1, FN_DACK0, FN_DRACK0,
+ FN_GPS_SIGN_B, FN_AUDATA1, FN_RX5_C, 0,
+ /* IP2_18_16 [3] */
+ FN_DU0_DR0, FN_LCDOUT0, FN_DREQ0, FN_GPS_CLK_B,
+ FN_AUDATA0, FN_TX5_C, 0, 0,
+ /* IP2_15_12 [4] */
+ FN_HRTS0, FN_RTS1_TANS, FN_MDATA, FN_TX0_C,
+ FN_SUB_TMS, FN_CC5_STATE1, FN_CC5_STATE9, FN_CC5_STATE17,
+ FN_CC5_STATE25, FN_CC5_STATE33, 0, 0,
+ 0, 0, 0, 0,
+ /* IP2_11_8 [4] */
+ FN_HCTS0, FN_CTS1, FN_STM, FN_PWM0_D,
+ FN_RX0_C, FN_SCIF_CLK_C, FN_SUB_TRST, FN_TCLK1_B,
+ FN_CC5_OSCOUT, 0, 0, 0,
+ 0, 0, 0, 0,
+ /* IP2_7_4 [4] */
+ FN_HSCK0, FN_SCK1, FN_MTS, FN_PWM5,
+ FN_SCK0_C, FN_SSI_SDATA9_B, FN_SUB_TDO, FN_CC5_STATE0,
+ FN_CC5_STATE8, FN_CC5_STATE16, FN_CC5_STATE24, FN_CC5_STATE32,
+ 0, 0, 0, 0,
+ /* IP2_3_0 [4] */
+ FN_HRX0, FN_RX1, FN_SCKZ, FN_RTS0_C_TANS_C,
+ FN_SUB_TDI, FN_CC5_STATE3, FN_CC5_STATE11, FN_CC5_STATE19,
+ FN_CC5_STATE27, FN_CC5_STATE35, 0, 0,
+ 0, 0, 0, 0 }
+ },
+ { PINMUX_CFG_REG_VAR("IPSR3", 0xfffc002c, 32,
+ 3, 1, 1, 3, 1, 2, 1, 1, 1, 1, 1,
+ 1, 3, 3, 1, 1, 1, 1, 1, 1, 3) {
+ /* IP3_31_29 [3] */
+ FN_DU0_EXODDF_DU0_ODDF_DISP_CDE, FN_QCPV_QDE, FN_CAN1_TX, FN_TX2_C,
+ FN_SCL2_C, FN_REMOCON, 0, 0,
+ /* IP3_28 [1] */
+ FN_DU0_EXVSYNC_DU0_VSYNC, FN_QSTB_QHE,
+ /* IP3_27 [1] */
+ FN_DU0_EXHSYNC_DU0_HSYNC, FN_QSTH_QHS,
+ /* IP3_26_24 [3] */
+ FN_DU0_DOTCLKOUT1, FN_QSTVB_QVE, FN_RX3_D_IRDA_RX_D, FN_SDA3_B,
+ FN_SDA2_C, FN_DACK0_B, FN_DRACK0_B, 0,
+ /* IP3_23 [1] */
+ FN_DU0_DOTCLKOUT0, FN_QCLK,
+ /* IP3_22_21 [2] */
+ FN_DU0_DOTCLKIN, FN_QSTVA_QVS, FN_TX3_D_IRDA_TX_D, FN_SCL3_B,
+ /* IP3_20 [1] */
+ FN_DU0_DB7, FN_LCDOUT23,
+ /* IP3_19 [1] */
+ FN_DU0_DB6, FN_LCDOUT22,
+ /* IP3_18 [1] */
+ FN_DU0_DB5, FN_LCDOUT21,
+ /* IP3_17 [1] */
+ FN_DU0_DB4, FN_LCDOUT20,
+ /* IP3_16 [1] */
+ FN_DU0_DB3, FN_LCDOUT19,
+ /* IP3_15 [1] */
+ FN_DU0_DB2, FN_LCDOUT18,
+ /* IP3_14_12 [3] */
+ FN_DU0_DB1, FN_LCDOUT17, FN_EX_WAIT2, FN_SDA1,
+ FN_GPS_MAG_B, FN_AUDATA5, FN_SCK5_C, 0,
+ /* IP3_11_9 [3] */
+ FN_DU0_DB0, FN_LCDOUT16, FN_EX_WAIT1, FN_SCL1,
+ FN_TCLK1, FN_AUDATA4, 0, 0,
+ /* IP3_8 [1] */
+ FN_DU0_DG7, FN_LCDOUT15,
+ /* IP3_7 [1] */
+ FN_DU0_DG6, FN_LCDOUT14,
+ /* IP3_6 [1] */
+ FN_DU0_DG5, FN_LCDOUT13,
+ /* IP3_5 [1] */
+ FN_DU0_DG4, FN_LCDOUT12,
+ /* IP3_4 [1] */
+ FN_DU0_DG3, FN_LCDOUT11,
+ /* IP3_3 [1] */
+ FN_DU0_DG2, FN_LCDOUT10,
+ /* IP3_2_0 [3] */
+ FN_DU0_DG1, FN_LCDOUT9, FN_DACK1, FN_SDA2,
+ FN_AUDATA3, 0, 0, 0 }
+ },
+ { PINMUX_CFG_REG_VAR("IPSR4", 0xfffc0030, 32,
+ 3, 1, 1, 1, 1, 1, 1, 3, 3, 1,
+ 1, 1, 1, 1, 1, 1, 3, 3, 3, 2) {
+ /* IP4_31_29 [3] */
+ FN_DU1_DB0, FN_VI2_DATA4_VI2_B4, FN_SCL2_B, FN_SD3_DAT0,
+ FN_TX5, FN_SCK0_D, 0, 0,
+ /* IP4_28 [1] */
+ FN_DU1_DG7, FN_VI2_R3,
+ /* IP4_27 [1] */
+ FN_DU1_DG6, FN_VI2_R2,
+ /* IP4_26 [1] */
+ FN_DU1_DG5, FN_VI2_R1,
+ /* IP4_25 [1] */
+ FN_DU1_DG4, FN_VI2_R0,
+ /* IP4_24 [1] */
+ FN_DU1_DG3, FN_VI2_G7,
+ /* IP4_23 [1] */
+ FN_DU1_DG2, FN_VI2_G6,
+ /* IP4_22_20 [3] */
+ FN_DU1_DG1, FN_VI2_DATA3_VI2_B3, FN_SDA1_B, FN_SD3_DAT3,
+ FN_SCK5, FN_AUDATA7, FN_RX0_D, 0,
+ /* IP4_19_17 [3] */
+ FN_DU1_DG0, FN_VI2_DATA2_VI2_B2, FN_SCL1_B, FN_SD3_DAT2,
+ FN_SCK3_E, FN_AUDATA6, FN_TX0_D, 0,
+ /* IP4_16 [1] */
+ FN_DU1_DR7, FN_VI2_G5,
+ /* IP4_15 [1] */
+ FN_DU1_DR6, FN_VI2_G4,
+ /* IP4_14 [1] */
+ FN_DU1_DR5, FN_VI2_G3,
+ /* IP4_13 [1] */
+ FN_DU1_DR4, FN_VI2_G2,
+ /* IP4_12 [1] */
+ FN_DU1_DR3, FN_VI2_G1,
+ /* IP4_11 [1] */
+ FN_DU1_DR2, FN_VI2_G0,
+ /* IP4_10_8 [3] */
+ FN_DU1_DR1, FN_VI2_DATA1_VI2_B1, FN_PWM0, FN_SD3_CMD,
+ FN_RX3_E_IRDA_RX_E, FN_AUDSYNC, FN_CTS0_D, 0,
+ /* IP4_7_5 [3] */
+ FN_DU1_DR0, FN_VI2_DATA0_VI2_B0, FN_PWM6, FN_SD3_CLK,
+ FN_TX3_E_IRDA_TX_E, FN_AUDCK, FN_PWMFSW0_B, 0,
+ /* IP4_4_2 [3] */
+ FN_DU0_CDE, FN_QPOLB, FN_CAN1_RX, FN_RX2_C,
+ FN_DREQ0_B, FN_SSI_SCK78_B, FN_SCK0_B, 0,
+ /* IP4_1_0 [2] */
+ FN_DU0_DISP, FN_QPOLA, FN_CAN_CLK_C, FN_SCK2_C }
+ },
+ { PINMUX_CFG_REG_VAR("IPSR5", 0xfffc0034, 32,
+ 1, 2, 1, 4, 3, 4, 2, 2,
+ 2, 2, 1, 1, 1, 1, 1, 1, 3) {
+ /* IP5_31 [1] */
+ 0, 0,
+ /* IP5_30_29 [2] */
+ FN_AUDIO_CLKB, FN_USB_OVC2, FN_CAN_DEBUGOUT0, FN_MOUT0,
+ /* IP5_28 [1] */
+ FN_AUDIO_CLKA, FN_CAN_TXCLK,
+ /* IP5_27_24 [4] */
+ FN_DU1_CDE, FN_VI2_DATA7_VI2_B7, FN_RX3_B_IRDA_RX_B, FN_SD3_WP,
+ FN_HSPI_RX1, FN_VI1_FIELD, FN_VI3_FIELD, FN_AUDIO_CLKOUT,
+ FN_RX2_D, FN_GPS_CLK_C, FN_GPS_CLK_D, 0,
+ 0, 0, 0, 0,
+ /* IP5_23_21 [3] */
+ FN_DU1_DISP, FN_VI2_DATA6_VI2_B6, FN_TCLK0, FN_QSTVA_B_QVS_B,
+ FN_HSPI_CLK1, FN_SCK2_D, FN_AUDIO_CLKOUT_B, FN_GPS_MAG_D,
+ /* IP5_20_17 [4] */
+ FN_DU1_EXODDF_DU1_ODDF_DISP_CDE, FN_VI2_CLK, FN_TX3_B_IRDA_TX_B,
+ FN_SD3_CD, FN_HSPI_TX1, FN_VI1_CLKENB, FN_VI3_CLKENB,
+ FN_AUDIO_CLKC, FN_TX2_D, FN_SPEEDIN, FN_GPS_SIGN_D, 0,
+ 0, 0, 0, 0,
+ /* IP5_16_15 [2] */
+ FN_DU1_EXVSYNC_DU1_VSYNC, FN_VI2_VSYNC, FN_VI3_VSYNC, 0,
+ /* IP5_14_13 [2] */
+ FN_DU1_EXHSYNC_DU1_HSYNC, FN_VI2_HSYNC, FN_VI3_HSYNC, 0,
+ /* IP5_12_11 [2] */
+ FN_DU1_DOTCLKOUT, FN_VI2_FIELD, FN_SDA1_D, 0,
+ /* IP5_10_9 [2] */
+ FN_DU1_DOTCLKIN, FN_VI2_CLKENB, FN_HSPI_CS1, FN_SCL1_D,
+ /* IP5_8 [1] */
+ FN_DU1_DB7, FN_SDA2_D,
+ /* IP5_7 [1] */
+ FN_DU1_DB6, FN_SCL2_D,
+ /* IP5_6 [1] */
+ FN_DU1_DB5, FN_VI2_R7,
+ /* IP5_5 [1] */
+ FN_DU1_DB4, FN_VI2_R6,
+ /* IP5_4 [1] */
+ FN_DU1_DB3, FN_VI2_R5,
+ /* IP5_3 [1] */
+ FN_DU1_DB2, FN_VI2_R4,
+ /* IP5_2_0 [3] */
+ FN_DU1_DB1, FN_VI2_DATA5_VI2_B5, FN_SDA2_B, FN_SD3_DAT1,
+ FN_RX5, FN_RTS0_D_TANS_D, 0, 0 }
+ },
+ { PINMUX_CFG_REG_VAR("IPSR6", 0xfffc0038, 32,
+ 1, 2, 2, 2, 2, 3, 2, 3, 3, 3, 1, 2, 2, 2, 2) {
+ /* IP6_31 [1] */
+ 0, 0,
+ /* IP6_30_29 [2] */
+ FN_SSI_SCK6, FN_ADICHS0, FN_CAN0_TX, FN_IERX_B,
+ /* IP_28_27 [2] */
+ 0, 0, 0, 0,
+ /* IP6_26_25 [2] */
+ FN_SSI_SDATA5, FN_ADIDATA, FN_CAN_DEBUGOUT12, FN_RX3_IRDA_RX,
+ /* IP6_24_23 [2] */
+ FN_SSI_WS5, FN_ADICS_SAMP, FN_CAN_DEBUGOUT11, FN_TX3_IRDA_TX,
+ /* IP6_22_20 [3] */
+ FN_SSI_SCK5, FN_ADICLK, FN_CAN_DEBUGOUT10, FN_SCK3,
+ FN_TCLK0_D, 0, 0, 0,
+ /* IP6_19_18 [2] */
+ FN_SSI_SDATA4, FN_CAN_DEBUGOUT9, FN_SSI_SDATA9_C, 0,
+ /* IP6_17_15 [3] */
+ FN_SSI_SDATA3, FN_PWM0_C, FN_CAN_DEBUGOUT8, FN_CAN_CLK_B,
+ FN_IECLK, FN_SCIF_CLK_B, FN_TCLK0_B, 0,
+ /* IP6_14_12 [3] */
+ FN_SSI_WS34, FN_CAN_DEBUGOUT7, FN_CAN0_RX_B, FN_IETX,
+ FN_SSI_WS9_C, 0, 0, 0,
+ /* IP6_11_9 [3] */
+ FN_SSI_SCK34, FN_CAN_DEBUGOUT6, FN_CAN0_TX_B, FN_IERX,
+ FN_SSI_SCK9_C, 0, 0, 0,
+ /* IP6_8 [1] */
+ FN_SSI_SDATA2, FN_CAN_DEBUGOUT5,
+ /* IP6_7_6 [2] */
+ FN_SSI_SDATA1, FN_CAN_DEBUGOUT4, FN_MOUT6, 0,
+ /* IP6_5_4 [2] */
+ FN_SSI_SDATA0, FN_CAN_DEBUGOUT3, FN_MOUT5, 0,
+ /* IP6_3_2 [2] */
+ FN_SSI_WS0129, FN_CAN_DEBUGOUT2, FN_MOUT2, 0,
+ /* IP6_1_0 [2] */
+ FN_SSI_SCK0129, FN_CAN_DEBUGOUT1, FN_MOUT1, 0 }
+ },
+ { PINMUX_CFG_REG_VAR("IPSR7", 0xfffc003c, 32,
+ 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 2, 2) {
+ /* IP7_31 [1] */
+ 0, 0,
+ /* IP7_30_29 [2] */
+ FN_SD0_WP, FN_DACK2, FN_CTS1_B, 0,
+ /* IP7_28_27 [2] */
+ FN_SD0_CD, FN_DREQ2, FN_RTS1_B_TANS_B, 0,
+ /* IP7_26_25 [2] */
+ FN_SD0_DAT3, FN_ATAWR1, FN_RX2_B, FN_CC5_TDI,
+ /* IP7_24_23 [2] */
+ FN_SD0_DAT2, FN_ATARD1, FN_TX2_B, FN_CC5_TCK,
+ /* IP7_22_21 [2] */
+ FN_SD0_DAT1, FN_ATAG1, FN_SCK2_B, FN_CC5_TMS,
+ /* IP7_20_19 [2] */
+ FN_SD0_DAT0, FN_ATADIR1, FN_RX1_B, FN_CC5_TRST,
+ /* IP7_18_17 [2] */
+ FN_SD0_CMD, FN_ATACS11, FN_TX1_B, FN_CC5_TDO,
+ /* IP7_16_15 [2] */
+ FN_SD0_CLK, FN_ATACS01, FN_SCK1_B, 0,
+ /* IP7_14_13 [2] */
+ FN_SSI_SDATA8, FN_VSP, FN_IRQ3_B, FN_HSPI_RX1_C,
+ /* IP7_12_10 [3] */
+ FN_SSI_SDATA7, FN_CAN_DEBUGOUT15, FN_IRQ2_B, FN_TCLK1_C,
+ FN_HSPI_TX1_C, 0, 0, 0,
+ /* IP7_9_7 [3] */
+ FN_SSI_WS78, FN_CAN_DEBUGOUT14, FN_IRQ1_B, FN_SSI_WS9_B,
+ FN_HSPI_CS1_C, 0, 0, 0,
+ /* IP7_6_4 [3] */
+ FN_SSI_SCK78, FN_CAN_DEBUGOUT13, FN_IRQ0_B, FN_SSI_SCK9_B,
+ FN_HSPI_CLK1_C, 0, 0, 0,
+ /* IP7_3_2 [2] */
+ FN_SSI_SDATA6, FN_ADICHS2, FN_CAN_CLK, FN_IECLK_B,
+ /* IP7_1_0 [2] */
+ FN_SSI_WS6, FN_ADICHS1, FN_CAN0_RX, FN_IETX_B }
+ },
+ { PINMUX_CFG_REG_VAR("IPSR8", 0xfffc0040, 32,
+ 1, 3, 3, 2, 2, 1, 1, 1, 2, 4, 4, 4, 4) {
+ /* IP8_31 [1] */
+ 0, 0,
+ /* IP8_30_28 [3] */
+ FN_VI0_VSYNC, FN_VI0_DATA1_B_VI0_B1_B, FN_RTS1_C_TANS_C, FN_RX4_D,
+ FN_PWMFSW0_C, 0, 0, 0,
+ /* IP8_27_25 [3] */
+ FN_VI0_HSYNC, FN_VI0_DATA0_B_VI0_B0_B, FN_CTS1_C, FN_TX4_D,
+ FN_MMC1_CMD, FN_HSCK1_B, 0, 0,
+ /* IP8_24_23 [2] */
+ FN_VI0_FIELD, FN_RX1_C, FN_HRX1_B, 0,
+ /* IP8_22_21 [2] */
+ FN_VI0_CLKENB, FN_TX1_C, FN_HTX1_B, FN_MT1_SYNC,
+ /* IP8_20 [1] */
+ FN_VI0_CLK, FN_MMC1_CLK,
+ /* IP8_19 [1] */
+ FN_FMIN, FN_RDS_DATA,
+ /* IP8_18 [1] */
+ FN_BPFCLK, FN_PCMWE,
+ /* IP8_17_16 [2] */
+ FN_FMCLK, FN_RDS_CLK, FN_PCMOE, 0,
+ /* IP8_15_12 [4] */
+ FN_HSPI_RX0, FN_RX0, FN_CAN_STEP0, FN_AD_NCS,
+ FN_CC5_STATE7, FN_CC5_STATE15, FN_CC5_STATE23, FN_CC5_STATE31,
+ FN_CC5_STATE39, 0, 0, 0,
+ 0, 0, 0, 0,
+ /* IP8_11_8 [4] */
+ FN_HSPI_TX0, FN_TX0, FN_CAN_DEBUG_HW_TRIGGER, FN_AD_DO,
+ FN_CC5_STATE6, FN_CC5_STATE14, FN_CC5_STATE22, FN_CC5_STATE30,
+ FN_CC5_STATE38, 0, 0, 0,
+ 0, 0, 0, 0,
+ /* IP8_7_4 [4] */
+ FN_HSPI_CS0, FN_RTS0_TANS, FN_USB_OVC1, FN_AD_DI,
+ FN_CC5_STATE5, FN_CC5_STATE13, FN_CC5_STATE21, FN_CC5_STATE29,
+ FN_CC5_STATE37, 0, 0, 0,
+ 0, 0, 0, 0,
+ /* IP8_3_0 [4] */
+ FN_HSPI_CLK0, FN_CTS0, FN_USB_OVC0, FN_AD_CLK,
+ FN_CC5_STATE4, FN_CC5_STATE12, FN_CC5_STATE20, FN_CC5_STATE28,
+ FN_CC5_STATE36, 0, 0, 0,
+ 0, 0, 0, 0 }
+ },
+ { PINMUX_CFG_REG_VAR("IPSR9", 0xfffc0044, 32,
+ 2, 2, 2, 2, 2, 3, 3, 2, 2,
+ 2, 2, 1, 1, 1, 1, 2, 2) {
+ /* IP9_31_30 [2] */
+ 0, 0, 0, 0,
+ /* IP9_29_28 [2] */
+ FN_VI0_G7, FN_ETH_RXD1, FN_SD2_DAT3_B, FN_ARM_TRACEDATA_9,
+ /* IP9_27_26 [2] */
+ FN_VI0_G6, FN_ETH_RXD0, FN_SD2_DAT2_B, FN_ARM_TRACEDATA_8,
+ /* IP9_25_24 [2] */
+ FN_VI0_G5, FN_ETH_RX_ER, FN_SD2_DAT1_B, FN_ARM_TRACEDATA_7,
+ /* IP9_23_22 [2] */
+ FN_VI0_G4, FN_ETH_TX_EN, FN_SD2_DAT0_B, FN_ARM_TRACEDATA_6,
+ /* IP9_21_19 [3] */
+ FN_VI0_G3, FN_ETH_CRS_DV, FN_MMC1_D7, FN_ARM_TRACEDATA_5,
+ FN_TS_SDAT0, 0, 0, 0,
+ /* IP9_18_16 [3] */
+ FN_VI0_G2, FN_ETH_TXD1, FN_MMC1_D6, FN_ARM_TRACEDATA_4,
+ FN_TS_SPSYNC0, 0, 0, 0,
+ /* IP9_15_14 [2] */
+ FN_VI0_G1, FN_SSI_WS78_C, FN_IRQ1, FN_ARM_TRACEDATA_3,
+ /* IP9_13_12 [2] */
+ FN_VI0_G0, FN_SSI_SCK78_C, FN_IRQ0, FN_ARM_TRACEDATA_2,
+ /* IP9_11_10 [2] */
+ FN_VI0_DATA7_VI0_B7, FN_MMC1_D5, FN_ARM_TRACEDATA_1, 0,
+ /* IP9_9_8 [2] */
+ FN_VI0_DATA6_VI0_B6, FN_MMC1_D4, FN_ARM_TRACEDATA_0, 0,
+ /* IP9_7 [1] */
+ FN_VI0_DATA5_VI0_B5, FN_MMC1_D3,
+ /* IP9_6 [1] */
+ FN_VI0_DATA4_VI0_B4, FN_MMC1_D2,
+ /* IP9_5 [1] */
+ FN_VI0_DATA3_VI0_B3, FN_MMC1_D1,
+ /* IP9_4 [1] */
+ FN_VI0_DATA2_VI0_B2, FN_MMC1_D0,
+ /* IP9_3_2 [2] */
+ FN_VI0_DATA1_VI0_B1, FN_HCTS1_B, FN_MT1_PWM, 0,
+ /* IP9_1_0 [2] */
+ FN_VI0_DATA0_VI0_B0, FN_HRTS1_B, FN_MT1_VCXO, 0 }
+ },
+ { PINMUX_CFG_REG_VAR("IPSR10", 0xfffc0048, 32,
+ 3, 3, 2, 3, 3, 3, 3, 3, 3, 3, 3) {
+ /* IP10_31_29 [3] */
+ FN_VI1_VSYNC, FN_AUDIO_CLKOUT_C, FN_SSI_WS4, FN_SIM_CLK,
+ FN_GPS_MAG_C, FN_SPV_TRST, FN_SCL3, 0,
+ /* IP10_28_26 [3] */
+ FN_VI1_HSYNC, FN_VI3_CLK, FN_SSI_SCK4, FN_GPS_SIGN_C,
+ FN_PWMFSW0_E, 0, 0, 0,
+ /* IP10_25_24 [2] */
+ FN_VI1_CLK, FN_SIM_D, FN_SDA3, 0,
+ /* IP10_23_21 [3] */
+ FN_VI0_R7, FN_ETH_MDIO, FN_DACK2_C, FN_HSPI_RX1_B,
+ FN_SCIF_CLK_D, FN_TRACECTL, FN_MT1_PEN, 0,
+ /* IP10_20_18 [3] */
+ FN_VI0_R6, FN_ETH_MDC, FN_DREQ2_C, FN_HSPI_TX1_B,
+ FN_TRACECLK, FN_MT1_BEN, FN_PWMFSW0_D, 0,
+ /* IP10_17_15 [3] */
+ FN_VI0_R5, FN_ETH_TXD0, FN_SD2_WP_B, FN_HSPI_CS1_B,
+ FN_ARM_TRACEDATA_15, FN_MT1_D, FN_TS_SDEN0, 0,
+ /* IP10_14_12 [3] */
+ FN_VI0_R4, FN_ETH_REFCLK, FN_SD2_CD_B, FN_HSPI_CLK1_B,
+ FN_ARM_TRACEDATA_14, FN_MT1_CLK, FN_TS_SCK0, 0,
+ /* IP10_11_9 [3] */
+ FN_VI0_R3, FN_ETH_MAGIC, FN_SD2_CMD_B, FN_IRQ3,
+ FN_ARM_TRACEDATA_13, 0, 0, 0,
+ /* IP10_8_6 [3] */
+ FN_VI0_R2, FN_ETH_LINK, FN_SD2_CLK_B, FN_IRQ2,
+ FN_ARM_TRACEDATA_12, 0, 0, 0,
+ /* IP10_5_3 [3] */
+ FN_VI0_R1, FN_SSI_SDATA8_C, FN_DACK1_B, FN_ARM_TRACEDATA_11,
+ FN_DACK0_C, FN_DRACK0_C, 0, 0,
+ /* IP10_2_0 [3] */
+ FN_VI0_R0, FN_SSI_SDATA7_C, FN_SCK1_C, FN_DREQ1_B,
+ FN_ARM_TRACEDATA_10, FN_DREQ0_C, 0, 0 }
+ },
+ { PINMUX_CFG_REG_VAR("IPSR11", 0xfffc004c, 32,
+ 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3) {
+ /* IP11_31_30 [2] */
+ 0, 0, 0, 0,
+ /* IP11_29_27 [3] */
+ FN_VI1_G1, FN_VI3_DATA1, FN_SSI_SCK1, FN_TS_SDEN1,
+ FN_DACK2_B, FN_RX2, FN_HRTS0_B, 0,
+ /* IP11_26_24 [3] */
+ FN_VI1_G0, FN_VI3_DATA0, FN_DU1_DOTCLKOUT1, FN_TS_SCK1,
+ FN_DREQ2_B, FN_TX2, FN_SPA_TDO, FN_HCTS0_B,
+ /* IP11_23_21 [3] */
+ FN_VI1_DATA7_VI1_B7, FN_SD2_WP, FN_MT0_PWM, FN_SPA_TDI,
+ FN_HSPI_RX1_D, 0, 0, 0,
+ /* IP11_20_18 [3] */
+ FN_VI1_DATA6_VI1_B6, FN_SD2_CD, FN_MT0_VCXO, FN_SPA_TMS,
+ FN_HSPI_TX1_D, 0, 0, 0,
+ /* IP11_17_15 [3] */
+ FN_VI1_DATA5_VI1_B5, FN_SD2_CMD, FN_MT0_SYNC, FN_SPA_TCK,
+ FN_HSPI_CS1_D, FN_ADICHS2_B, 0, 0,
+ /* IP11_14_12 [3] */
+ FN_VI1_DATA4_VI1_B4, FN_SD2_CLK, FN_MT0_PEN, FN_SPA_TRST,
+ FN_HSPI_CLK1_D, FN_ADICHS1_B, 0, 0,
+ /* IP11_11_9 [3] */
+ FN_VI1_DATA3_VI1_B3, FN_SD2_DAT3, FN_MT0_BEN, FN_SPV_TDO,
+ FN_ADICHS0_B, 0, 0, 0,
+ /* IP11_8_6 [3] */
+ FN_VI1_DATA2_VI1_B2, FN_SD2_DAT2, FN_MT0_D, FN_SPVTDI,
+ FN_ADIDATA_B, 0, 0, 0,
+ /* IP11_5_3 [3] */
+ FN_VI1_DATA1_VI1_B1, FN_SD2_DAT1, FN_MT0_CLK, FN_SPV_TMS,
+ FN_ADICS_B_SAMP_B, 0, 0, 0,
+ /* IP11_2_0 [3] */
+ FN_VI1_DATA0_VI1_B0, FN_SD2_DAT0, FN_SIM_RST, FN_SPV_TCK,
+ FN_ADICLK_B, 0, 0, 0 }
+ },
+ { PINMUX_CFG_REG_VAR("IPSR12", 0xfffc0050, 32,
+ 4, 4, 4, 2, 3, 3, 3, 3, 3, 3) {
+ /* IP12_31_28 [4] */
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ /* IP12_27_24 [4] */
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ /* IP12_23_20 [4] */
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ /* IP12_19_18 [2] */
+ 0, 0, 0, 0,
+ /* IP12_17_15 [3] */
+ FN_VI1_G7, FN_VI3_DATA7, FN_GPS_MAG, FN_FCE,
+ FN_SCK4_B, 0, 0, 0,
+ /* IP12_14_12 [3] */
+ FN_VI1_G6, FN_VI3_DATA6, FN_GPS_SIGN, FN_FRB,
+ FN_RX4_B, FN_SIM_CLK_B, 0, 0,
+ /* IP12_11_9 [3] */
+ FN_VI1_G5, FN_VI3_DATA5, FN_GPS_CLK, FN_FSE,
+ FN_TX4_B, FN_SIM_D_B, 0, 0,
+ /* IP12_8_6 [3] */
+ FN_VI1_G4, FN_VI3_DATA4, FN_SSI_WS2, FN_SDA1_C,
+ FN_SIM_RST_B, FN_HRX0_B, 0, 0,
+ /* IP12_5_3 [3] */
+ FN_VI1_G3, FN_VI3_DATA3, FN_SSI_SCK2, FN_TS_SDAT1,
+ FN_SCL1_C, FN_HTX0_B, 0, 0,
+ /* IP12_2_0 [3] */
+ FN_VI1_G2, FN_VI3_DATA2, FN_SSI_WS1, FN_TS_SPSYNC1,
+ FN_SCK2, FN_HSCK0_B, 0, 0 }
+ },
+ { PINMUX_CFG_REG_VAR("MOD_SEL", 0xfffc0090, 32,
+ 2, 2, 3, 3, 2, 2, 2, 2, 2,
+ 1, 1, 1, 1, 1, 1, 1, 2, 1, 2) {
+ /* SEL_SCIF5 [2] */
+ FN_SEL_SCIF5_0, FN_SEL_SCIF5_1, FN_SEL_SCIF5_2, FN_SEL_SCIF5_3,
+ /* SEL_SCIF4 [2] */
+ FN_SEL_SCIF4_0, FN_SEL_SCIF4_1, FN_SEL_SCIF4_2, FN_SEL_SCIF4_3,
+ /* SEL_SCIF3 [3] */
+ FN_SEL_SCIF3_0, FN_SEL_SCIF3_1, FN_SEL_SCIF3_2, FN_SEL_SCIF3_3,
+ FN_SEL_SCIF3_4, 0, 0, 0,
+ /* SEL_SCIF2 [3] */
+ FN_SEL_SCIF2_0, FN_SEL_SCIF2_1, FN_SEL_SCIF2_2, FN_SEL_SCIF2_3,
+ FN_SEL_SCIF2_4, 0, 0, 0,
+ /* SEL_SCIF1 [2] */
+ FN_SEL_SCIF1_0, FN_SEL_SCIF1_1, FN_SEL_SCIF1_2, 0,
+ /* SEL_SCIF0 [2] */
+ FN_SEL_SCIF0_0, FN_SEL_SCIF0_1, FN_SEL_SCIF0_2, FN_SEL_SCIF0_3,
+ /* SEL_SSI9 [2] */
+ FN_SEL_SSI9_0, FN_SEL_SSI9_1, FN_SEL_SSI9_2, 0,
+ /* SEL_SSI8 [2] */
+ FN_SEL_SSI8_0, FN_SEL_SSI8_1, FN_SEL_SSI8_2, 0,
+ /* SEL_SSI7 [2] */
+ FN_SEL_SSI7_0, FN_SEL_SSI7_1, FN_SEL_SSI7_2, 0,
+ /* SEL_VI0 [1] */
+ FN_SEL_VI0_0, FN_SEL_VI0_1,
+ /* SEL_SD2 [1] */
+ FN_SEL_SD2_0, FN_SEL_SD2_1,
+ /* SEL_INT3 [1] */
+ FN_SEL_INT3_0, FN_SEL_INT3_1,
+ /* SEL_INT2 [1] */
+ FN_SEL_INT2_0, FN_SEL_INT2_1,
+ /* SEL_INT1 [1] */
+ FN_SEL_INT1_0, FN_SEL_INT1_1,
+ /* SEL_INT0 [1] */
+ FN_SEL_INT0_0, FN_SEL_INT0_1,
+ /* SEL_IE [1] */
+ FN_SEL_IE_0, FN_SEL_IE_1,
+ /* SEL_EXBUS2 [2] */
+ FN_SEL_EXBUS2_0, FN_SEL_EXBUS2_1, FN_SEL_EXBUS2_2, 0,
+ /* SEL_EXBUS1 [1] */
+ FN_SEL_EXBUS1_0, FN_SEL_EXBUS1_1,
+ /* SEL_EXBUS0 [2] */
+ FN_SEL_EXBUS0_0, FN_SEL_EXBUS0_1, FN_SEL_EXBUS0_2, 0 }
+ },
+ { PINMUX_CFG_REG_VAR("MOD_SEL2", 0xfffc0094, 32,
+ 2, 2, 2, 2, 1, 1, 1, 3, 1,
+ 2, 2, 2, 2, 1, 1, 2, 1, 2, 2) {
+ /* SEL_TMU1 [2] */
+ FN_SEL_TMU1_0, FN_SEL_TMU1_1, FN_SEL_TMU1_2, 0,
+ /* SEL_TMU0 [2] */
+ FN_SEL_TMU0_0, FN_SEL_TMU0_1, FN_SEL_TMU0_2, FN_SEL_TMU0_3,
+ /* SEL_SCIF [2] */
+ FN_SEL_SCIF_0, FN_SEL_SCIF_1, FN_SEL_SCIF_2, FN_SEL_SCIF_3,
+ /* SEL_CANCLK [2] */
+ FN_SEL_CANCLK_0, FN_SEL_CANCLK_1, FN_SEL_CANCLK_2,
+ /* SEL_CAN0 [1] */
+ FN_SEL_CAN0_0, FN_SEL_CAN0_1,
+ /* SEL_HSCIF1 [1] */
+ FN_SEL_HSCIF1_0, FN_SEL_HSCIF1_1,
+ /* SEL_HSCIF0 [1] */
+ FN_SEL_HSCIF0_0, FN_SEL_HSCIF0_1,
+ /* SEL_PWMFSW [3] */
+ FN_SEL_PWMFSW_0, FN_SEL_PWMFSW_1, FN_SEL_PWMFSW_2,
+ FN_SEL_PWMFSW_3, FN_SEL_PWMFSW_4, 0, 0, 0,
+ /* SEL_ADI [1] */
+ FN_SEL_ADI_0, FN_SEL_ADI_1,
+ /* [2] */
+ 0, 0, 0, 0,
+ /* [2] */
+ 0, 0, 0, 0,
+ /* [2] */
+ 0, 0, 0, 0,
+ /* SEL_GPS [2] */
+ FN_SEL_GPS_0, FN_SEL_GPS_1, FN_SEL_GPS_2, FN_SEL_GPS_3,
+ /* SEL_SIM [1] */
+ FN_SEL_SIM_0, FN_SEL_SIM_1,
+ /* SEL_HSPI2 [1] */
+ FN_SEL_HSPI2_0, FN_SEL_HSPI2_1,
+ /* SEL_HSPI1 [2] */
+ FN_SEL_HSPI1_0, FN_SEL_HSPI1_1, FN_SEL_HSPI1_2, FN_SEL_HSPI1_3,
+ /* SEL_I2C3 [1] */
+ FN_SEL_I2C3_0, FN_SEL_I2C3_1,
+ /* SEL_I2C2 [2] */
+ FN_SEL_I2C2_0, FN_SEL_I2C2_1, FN_SEL_I2C2_2, FN_SEL_I2C2_3,
+ /* SEL_I2C1 [2] */
+ FN_SEL_I2C1_0, FN_SEL_I2C1_1, FN_SEL_I2C1_2, FN_SEL_I2C1_3 }
+ },
+ { PINMUX_CFG_REG("INOUTSEL0", 0xffc40004, 32, 1) { GP_INOUTSEL(0) } },
+ { PINMUX_CFG_REG("INOUTSEL1", 0xffc41004, 32, 1) { GP_INOUTSEL(1) } },
+ { PINMUX_CFG_REG("INOUTSEL2", 0xffc42004, 32, 1) { GP_INOUTSEL(2) } },
+ { PINMUX_CFG_REG("INOUTSEL3", 0xffc43004, 32, 1) { GP_INOUTSEL(3) } },
+ { PINMUX_CFG_REG("INOUTSEL4", 0xffc44004, 32, 1) { GP_INOUTSEL(4) } },
+ { PINMUX_CFG_REG("INOUTSEL5", 0xffc45004, 32, 1) { GP_INOUTSEL(5) } },
+ { PINMUX_CFG_REG("INOUTSEL6", 0xffc46004, 32, 1) {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ GP_6_8_IN, GP_6_8_OUT,
+ GP_6_7_IN, GP_6_7_OUT,
+ GP_6_6_IN, GP_6_6_OUT,
+ GP_6_5_IN, GP_6_5_OUT,
+ GP_6_4_IN, GP_6_4_OUT,
+ GP_6_3_IN, GP_6_3_OUT,
+ GP_6_2_IN, GP_6_2_OUT,
+ GP_6_1_IN, GP_6_1_OUT,
+ GP_6_0_IN, GP_6_0_OUT, }
+ },
+ { },
+};
+
+static struct pinmux_data_reg pinmux_data_regs[] = {
+ { PINMUX_DATA_REG("INDT0", 0xffc40008, 32) { GP_INDT(0) } },
+ { PINMUX_DATA_REG("INDT1", 0xffc41008, 32) { GP_INDT(1) } },
+ { PINMUX_DATA_REG("INDT2", 0xffc42008, 32) { GP_INDT(2) } },
+ { PINMUX_DATA_REG("INDT3", 0xffc43008, 32) { GP_INDT(3) } },
+ { PINMUX_DATA_REG("INDT4", 0xffc44008, 32) { GP_INDT(4) } },
+ { PINMUX_DATA_REG("INDT5", 0xffc45008, 32) { GP_INDT(5) } },
+ { PINMUX_DATA_REG("INDT6", 0xffc46008, 32) {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, GP_6_8_DATA,
+ GP_6_7_DATA, GP_6_6_DATA, GP_6_5_DATA, GP_6_4_DATA,
+ GP_6_3_DATA, GP_6_2_DATA, GP_6_1_DATA, GP_6_0_DATA }
+ },
+ { },
+};
+
+static struct resource r8a7779_pfc_resources[] = {
+ [0] = {
+ .start = 0xfffc0000,
+ .end = 0xfffc023b,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 0xffc40000,
+ .end = 0xffc46fff,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static struct pinmux_info r8a7779_pinmux_info = {
+ .name = "r8a7779_pfc",
+
+ .resource = r8a7779_pfc_resources,
+ .num_resources = ARRAY_SIZE(r8a7779_pfc_resources),
+
+ .unlock_reg = 0xfffc0000, /* PMMR */
+
+ .reserved_id = PINMUX_RESERVED,
+ .data = { PINMUX_DATA_BEGIN, PINMUX_DATA_END },
+ .input = { PINMUX_INPUT_BEGIN, PINMUX_INPUT_END },
+ .output = { PINMUX_OUTPUT_BEGIN, PINMUX_OUTPUT_END },
+ .mark = { PINMUX_MARK_BEGIN, PINMUX_MARK_END },
+ .function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END },
+
+ .first_gpio = GPIO_GP_0_0,
+ .last_gpio = GPIO_FN_SCK4_B,
+
+ .gpios = pinmux_gpios,
+ .cfg_regs = pinmux_config_regs,
+ .data_regs = pinmux_data_regs,
+
+ .gpio_data = pinmux_data,
+ .gpio_data_size = ARRAY_SIZE(pinmux_data),
+};
+
+void r8a7779_pinmux_init(void)
+{
+ register_pinmux(&r8a7779_pinmux_info);
+}
diff --git a/arch/arm/mach-shmobile/platsmp.c b/arch/arm/mach-shmobile/platsmp.c
index c49a833..9933812 100644
--- a/arch/arm/mach-shmobile/platsmp.c
+++ b/arch/arm/mach-shmobile/platsmp.c
@@ -22,12 +22,16 @@
#include <mach/common.h>
#define is_sh73a0() (machine_is_ag5evm() || machine_is_kota2())
+#define is_r8a7779() machine_is_marzen()
static unsigned int __init shmobile_smp_get_core_count(void)
{
if (is_sh73a0())
return sh73a0_get_core_count();
+ if (is_r8a7779())
+ return r8a7779_get_core_count();
+
return 1;
}
@@ -35,6 +39,17 @@
{
if (is_sh73a0())
sh73a0_smp_prepare_cpus();
+
+ if (is_r8a7779())
+ r8a7779_smp_prepare_cpus();
+}
+
+int shmobile_platform_cpu_kill(unsigned int cpu)
+{
+ if (is_r8a7779())
+ return r8a7779_platform_cpu_kill(cpu);
+
+ return 1;
}
void __cpuinit platform_secondary_init(unsigned int cpu)
@@ -43,6 +58,9 @@
if (is_sh73a0())
sh73a0_secondary_init(cpu);
+
+ if (is_r8a7779())
+ r8a7779_secondary_init(cpu);
}
int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
@@ -50,6 +68,9 @@
if (is_sh73a0())
return sh73a0_boot_secondary(cpu);
+ if (is_r8a7779())
+ return r8a7779_boot_secondary(cpu);
+
return -ENOSYS;
}
diff --git a/arch/arm/mach-shmobile/pm-r8a7779.c b/arch/arm/mach-shmobile/pm-r8a7779.c
new file mode 100644
index 0000000..c38ba7b
--- /dev/null
+++ b/arch/arm/mach-shmobile/pm-r8a7779.c
@@ -0,0 +1,249 @@
+/*
+ * r8a7779 Power management support
+ *
+ * Copyright (C) 2011 Renesas Solutions Corp.
+ * Copyright (C) 2011 Magnus Damm
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/pm.h>
+#include <linux/suspend.h>
+#include <linux/err.h>
+#include <linux/pm_clock.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/console.h>
+#include <asm/system.h>
+#include <asm/io.h>
+#include <mach/common.h>
+#include <mach/r8a7779.h>
+
+static void __iomem *r8a7779_sysc_base;
+
+/* SYSC */
+#define SYSCSR 0x00
+#define SYSCISR 0x04
+#define SYSCISCR 0x08
+#define SYSCIER 0x0c
+#define SYSCIMR 0x10
+#define PWRSR0 0x40
+#define PWRSR1 0x80
+#define PWRSR2 0xc0
+#define PWRSR3 0x100
+#define PWRSR4 0x140
+
+#define PWRSR_OFFS 0x00
+#define PWROFFCR_OFFS 0x04
+#define PWRONCR_OFFS 0x0c
+#define PWRER_OFFS 0x14
+
+#define SYSCSR_RETRIES 100
+#define SYSCSR_DELAY_US 1
+
+#define SYSCISR_RETRIES 1000
+#define SYSCISR_DELAY_US 1
+
+#if defined(CONFIG_PM) || defined(CONFIG_SMP)
+
+static DEFINE_SPINLOCK(r8a7779_sysc_lock); /* SMP CPUs + I/O devices */
+
+static int r8a7779_sysc_pwr_on_off(struct r8a7779_pm_ch *r8a7779_ch,
+ int sr_bit, int reg_offs)
+{
+ int k;
+
+ for (k = 0; k < SYSCSR_RETRIES; k++) {
+ if (ioread32(r8a7779_sysc_base + SYSCSR) & (1 << sr_bit))
+ break;
+ udelay(SYSCSR_DELAY_US);
+ }
+
+ if (k == SYSCSR_RETRIES)
+ return -EAGAIN;
+
+ iowrite32(1 << r8a7779_ch->chan_bit,
+ r8a7779_sysc_base + r8a7779_ch->chan_offs + reg_offs);
+
+ return 0;
+}
+
+static int r8a7779_sysc_pwr_off(struct r8a7779_pm_ch *r8a7779_ch)
+{
+ return r8a7779_sysc_pwr_on_off(r8a7779_ch, 0, PWROFFCR_OFFS);
+}
+
+static int r8a7779_sysc_pwr_on(struct r8a7779_pm_ch *r8a7779_ch)
+{
+ return r8a7779_sysc_pwr_on_off(r8a7779_ch, 1, PWRONCR_OFFS);
+}
+
+static int r8a7779_sysc_update(struct r8a7779_pm_ch *r8a7779_ch,
+ int (*on_off_fn)(struct r8a7779_pm_ch *))
+{
+ unsigned int isr_mask = 1 << r8a7779_ch->isr_bit;
+ unsigned int chan_mask = 1 << r8a7779_ch->chan_bit;
+ unsigned int status;
+ unsigned long flags;
+ int ret = 0;
+ int k;
+
+ spin_lock_irqsave(&r8a7779_sysc_lock, flags);
+
+ iowrite32(isr_mask, r8a7779_sysc_base + SYSCISCR);
+
+ do {
+ ret = on_off_fn(r8a7779_ch);
+ if (ret)
+ goto out;
+
+ status = ioread32(r8a7779_sysc_base +
+ r8a7779_ch->chan_offs + PWRER_OFFS);
+ } while (status & chan_mask);
+
+ for (k = 0; k < SYSCISR_RETRIES; k++) {
+ if (ioread32(r8a7779_sysc_base + SYSCISR) & isr_mask)
+ break;
+ udelay(SYSCISR_DELAY_US);
+ }
+
+ if (k == SYSCISR_RETRIES)
+ ret = -EIO;
+
+ iowrite32(isr_mask, r8a7779_sysc_base + SYSCISCR);
+
+ out:
+ spin_unlock_irqrestore(&r8a7779_sysc_lock, flags);
+
+ pr_debug("r8a7779 power domain %d: %02x %02x %02x %02x %02x -> %d\n",
+ r8a7779_ch->isr_bit, ioread32(r8a7779_sysc_base + PWRSR0),
+ ioread32(r8a7779_sysc_base + PWRSR1),
+ ioread32(r8a7779_sysc_base + PWRSR2),
+ ioread32(r8a7779_sysc_base + PWRSR3),
+ ioread32(r8a7779_sysc_base + PWRSR4), ret);
+ return ret;
+}
+
+int r8a7779_sysc_power_down(struct r8a7779_pm_ch *r8a7779_ch)
+{
+ return r8a7779_sysc_update(r8a7779_ch, r8a7779_sysc_pwr_off);
+}
+
+int r8a7779_sysc_power_up(struct r8a7779_pm_ch *r8a7779_ch)
+{
+ return r8a7779_sysc_update(r8a7779_ch, r8a7779_sysc_pwr_on);
+}
+
+static void __init r8a7779_sysc_init(void)
+{
+ r8a7779_sysc_base = ioremap_nocache(0xffd85000, PAGE_SIZE);
+ if (!r8a7779_sysc_base)
+ panic("unable to ioremap r8a7779 SYSC hardware block\n");
+
+ /* enable all interrupt sources, but do not use interrupt handler */
+ iowrite32(0x0131000e, r8a7779_sysc_base + SYSCIER);
+ iowrite32(0, r8a7779_sysc_base + SYSCIMR);
+}
+
+#else /* CONFIG_PM || CONFIG_SMP */
+
+static inline void r8a7779_sysc_init(void) {}
+
+#endif /* CONFIG_PM || CONFIG_SMP */
+
+#ifdef CONFIG_PM
+
+static int pd_power_down(struct generic_pm_domain *genpd)
+{
+ return r8a7779_sysc_power_down(to_r8a7779_ch(genpd));
+}
+
+static int pd_power_up(struct generic_pm_domain *genpd)
+{
+ return r8a7779_sysc_power_up(to_r8a7779_ch(genpd));
+}
+
+static bool pd_is_off(struct generic_pm_domain *genpd)
+{
+ struct r8a7779_pm_ch *r8a7779_ch = to_r8a7779_ch(genpd);
+ unsigned int st;
+
+ st = ioread32(r8a7779_sysc_base + r8a7779_ch->chan_offs + PWRSR_OFFS);
+ if (st & (1 << r8a7779_ch->chan_bit))
+ return true;
+
+ return false;
+}
+
+static bool pd_active_wakeup(struct device *dev)
+{
+ return true;
+}
+
+void r8a7779_init_pm_domain(struct r8a7779_pm_domain *r8a7779_pd)
+{
+ struct generic_pm_domain *genpd = &r8a7779_pd->genpd;
+
+ pm_genpd_init(genpd, NULL, false);
+ genpd->dev_ops.stop = pm_clk_suspend;
+ genpd->dev_ops.start = pm_clk_resume;
+ genpd->dev_ops.active_wakeup = pd_active_wakeup;
+ genpd->dev_irq_safe = true;
+ genpd->power_off = pd_power_down;
+ genpd->power_on = pd_power_up;
+
+ if (pd_is_off(&r8a7779_pd->genpd))
+ pd_power_up(&r8a7779_pd->genpd);
+}
+
+void r8a7779_add_device_to_domain(struct r8a7779_pm_domain *r8a7779_pd,
+ struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+
+ pm_genpd_add_device(&r8a7779_pd->genpd, dev);
+ if (pm_clk_no_clocks(dev))
+ pm_clk_add(dev, NULL);
+}
+
+struct r8a7779_pm_domain r8a7779_sh4a = {
+ .ch = {
+ .chan_offs = 0x80, /* PWRSR1 .. PWRER1 */
+ .isr_bit = 16, /* SH4A */
+ }
+};
+
+struct r8a7779_pm_domain r8a7779_sgx = {
+ .ch = {
+ .chan_offs = 0xc0, /* PWRSR2 .. PWRER2 */
+ .isr_bit = 20, /* SGX */
+ }
+};
+
+struct r8a7779_pm_domain r8a7779_vdp1 = {
+ .ch = {
+ .chan_offs = 0x100, /* PWRSR3 .. PWRER3 */
+ .isr_bit = 21, /* VDP */
+ }
+};
+
+struct r8a7779_pm_domain r8a7779_impx3 = {
+ .ch = {
+ .chan_offs = 0x140, /* PWRSR4 .. PWRER4 */
+ .isr_bit = 24, /* IMP */
+ }
+};
+
+#endif /* CONFIG_PM */
+
+void __init r8a7779_pm_init(void)
+{
+ static int once;
+
+ if (!once++)
+ r8a7779_sysc_init();
+}
diff --git a/arch/arm/mach-shmobile/setup-r8a7740.c b/arch/arm/mach-shmobile/setup-r8a7740.c
new file mode 100644
index 0000000..986dca6
--- /dev/null
+++ b/arch/arm/mach-shmobile/setup-r8a7740.c
@@ -0,0 +1,352 @@
+/*
+ * R8A7740 processor support
+ *
+ * Copyright (C) 2011 Renesas Solutions Corp.
+ * Copyright (C) 2011 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+ *
+ * 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; version 2 of the License.
+ *
+ * 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 <linux/delay.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <linux/serial_sci.h>
+#include <linux/sh_timer.h>
+#include <mach/r8a7740.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+/* SCIFA0 */
+static struct plat_sci_port scif0_platform_data = {
+ .mapbase = 0xe6c40000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .scscr = SCSCR_RE | SCSCR_TE,
+ .scbrr_algo_id = SCBRR_ALGO_4,
+ .type = PORT_SCIFA,
+ .irqs = SCIx_IRQ_MUXED(evt2irq(0x0c00)),
+};
+
+static struct platform_device scif0_device = {
+ .name = "sh-sci",
+ .id = 0,
+ .dev = {
+ .platform_data = &scif0_platform_data,
+ },
+};
+
+/* SCIFA1 */
+static struct plat_sci_port scif1_platform_data = {
+ .mapbase = 0xe6c50000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .scscr = SCSCR_RE | SCSCR_TE,
+ .scbrr_algo_id = SCBRR_ALGO_4,
+ .type = PORT_SCIFA,
+ .irqs = SCIx_IRQ_MUXED(evt2irq(0x0c20)),
+};
+
+static struct platform_device scif1_device = {
+ .name = "sh-sci",
+ .id = 1,
+ .dev = {
+ .platform_data = &scif1_platform_data,
+ },
+};
+
+/* SCIFA2 */
+static struct plat_sci_port scif2_platform_data = {
+ .mapbase = 0xe6c60000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .scscr = SCSCR_RE | SCSCR_TE,
+ .scbrr_algo_id = SCBRR_ALGO_4,
+ .type = PORT_SCIFA,
+ .irqs = SCIx_IRQ_MUXED(evt2irq(0x0c40)),
+};
+
+static struct platform_device scif2_device = {
+ .name = "sh-sci",
+ .id = 2,
+ .dev = {
+ .platform_data = &scif2_platform_data,
+ },
+};
+
+/* SCIFA3 */
+static struct plat_sci_port scif3_platform_data = {
+ .mapbase = 0xe6c70000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .scscr = SCSCR_RE | SCSCR_TE,
+ .scbrr_algo_id = SCBRR_ALGO_4,
+ .type = PORT_SCIFA,
+ .irqs = SCIx_IRQ_MUXED(evt2irq(0x0c60)),
+};
+
+static struct platform_device scif3_device = {
+ .name = "sh-sci",
+ .id = 3,
+ .dev = {
+ .platform_data = &scif3_platform_data,
+ },
+};
+
+/* SCIFA4 */
+static struct plat_sci_port scif4_platform_data = {
+ .mapbase = 0xe6c80000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .scscr = SCSCR_RE | SCSCR_TE,
+ .scbrr_algo_id = SCBRR_ALGO_4,
+ .type = PORT_SCIFA,
+ .irqs = SCIx_IRQ_MUXED(evt2irq(0x0d20)),
+};
+
+static struct platform_device scif4_device = {
+ .name = "sh-sci",
+ .id = 4,
+ .dev = {
+ .platform_data = &scif4_platform_data,
+ },
+};
+
+/* SCIFA5 */
+static struct plat_sci_port scif5_platform_data = {
+ .mapbase = 0xe6cb0000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .scscr = SCSCR_RE | SCSCR_TE,
+ .scbrr_algo_id = SCBRR_ALGO_4,
+ .type = PORT_SCIFA,
+ .irqs = SCIx_IRQ_MUXED(evt2irq(0x0d40)),
+};
+
+static struct platform_device scif5_device = {
+ .name = "sh-sci",
+ .id = 5,
+ .dev = {
+ .platform_data = &scif5_platform_data,
+ },
+};
+
+/* SCIFA6 */
+static struct plat_sci_port scif6_platform_data = {
+ .mapbase = 0xe6cc0000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .scscr = SCSCR_RE | SCSCR_TE,
+ .scbrr_algo_id = SCBRR_ALGO_4,
+ .type = PORT_SCIFA,
+ .irqs = SCIx_IRQ_MUXED(evt2irq(0x04c0)),
+};
+
+static struct platform_device scif6_device = {
+ .name = "sh-sci",
+ .id = 6,
+ .dev = {
+ .platform_data = &scif6_platform_data,
+ },
+};
+
+/* SCIFA7 */
+static struct plat_sci_port scif7_platform_data = {
+ .mapbase = 0xe6cd0000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .scscr = SCSCR_RE | SCSCR_TE,
+ .scbrr_algo_id = SCBRR_ALGO_4,
+ .type = PORT_SCIFA,
+ .irqs = SCIx_IRQ_MUXED(evt2irq(0x04e0)),
+};
+
+static struct platform_device scif7_device = {
+ .name = "sh-sci",
+ .id = 7,
+ .dev = {
+ .platform_data = &scif7_platform_data,
+ },
+};
+
+/* SCIFB */
+static struct plat_sci_port scifb_platform_data = {
+ .mapbase = 0xe6c30000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .scscr = SCSCR_RE | SCSCR_TE,
+ .scbrr_algo_id = SCBRR_ALGO_4,
+ .type = PORT_SCIFB,
+ .irqs = SCIx_IRQ_MUXED(evt2irq(0x0d60)),
+};
+
+static struct platform_device scifb_device = {
+ .name = "sh-sci",
+ .id = 8,
+ .dev = {
+ .platform_data = &scifb_platform_data,
+ },
+};
+
+/* CMT */
+static struct sh_timer_config cmt10_platform_data = {
+ .name = "CMT10",
+ .channel_offset = 0x10,
+ .timer_bit = 0,
+ .clockevent_rating = 125,
+ .clocksource_rating = 125,
+};
+
+static struct resource cmt10_resources[] = {
+ [0] = {
+ .name = "CMT10",
+ .start = 0xe6138010,
+ .end = 0xe613801b,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = evt2irq(0x0b00),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device cmt10_device = {
+ .name = "sh_cmt",
+ .id = 10,
+ .dev = {
+ .platform_data = &cmt10_platform_data,
+ },
+ .resource = cmt10_resources,
+ .num_resources = ARRAY_SIZE(cmt10_resources),
+};
+
+static struct platform_device *r8a7740_early_devices[] __initdata = {
+ &scif0_device,
+ &scif1_device,
+ &scif2_device,
+ &scif3_device,
+ &scif4_device,
+ &scif5_device,
+ &scif6_device,
+ &scif7_device,
+ &scifb_device,
+ &cmt10_device,
+};
+
+/* I2C */
+static struct resource i2c0_resources[] = {
+ [0] = {
+ .name = "IIC0",
+ .start = 0xfff20000,
+ .end = 0xfff20425 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = intcs_evt2irq(0xe00),
+ .end = intcs_evt2irq(0xe60),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource i2c1_resources[] = {
+ [0] = {
+ .name = "IIC1",
+ .start = 0xe6c20000,
+ .end = 0xe6c20425 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = evt2irq(0x780), /* IIC1_ALI1 */
+ .end = evt2irq(0x7e0), /* IIC1_DTEI1 */
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device i2c0_device = {
+ .name = "i2c-sh_mobile",
+ .id = 0,
+ .resource = i2c0_resources,
+ .num_resources = ARRAY_SIZE(i2c0_resources),
+};
+
+static struct platform_device i2c1_device = {
+ .name = "i2c-sh_mobile",
+ .id = 1,
+ .resource = i2c1_resources,
+ .num_resources = ARRAY_SIZE(i2c1_resources),
+};
+
+static struct platform_device *r8a7740_late_devices[] __initdata = {
+ &i2c0_device,
+ &i2c1_device,
+};
+
+#define ICCR 0x0004
+#define ICSTART 0x0070
+
+#define i2c_read(reg, offset) ioread8(reg + offset)
+#define i2c_write(reg, offset, data) iowrite8(data, reg + offset)
+
+/*
+ * r8a7740 chip has lasting errata on I2C I/O pad reset.
+ * this is work-around for it.
+ */
+static void r8a7740_i2c_workaround(struct platform_device *pdev)
+{
+ struct resource *res;
+ void __iomem *reg;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (unlikely(!res)) {
+ pr_err("r8a7740 i2c workaround fail (cannot find resource)\n");
+ return;
+ }
+
+ reg = ioremap(res->start, resource_size(res));
+ if (unlikely(!reg)) {
+ pr_err("r8a7740 i2c workaround fail (cannot map IO)\n");
+ return;
+ }
+
+ i2c_write(reg, ICCR, i2c_read(reg, ICCR) | 0x80);
+ i2c_read(reg, ICCR); /* dummy read */
+
+ i2c_write(reg, ICSTART, i2c_read(reg, ICSTART) | 0x10);
+ i2c_read(reg, ICSTART); /* dummy read */
+
+ mdelay(100);
+
+ i2c_write(reg, ICCR, 0x01);
+ i2c_read(reg, ICCR);
+ i2c_write(reg, ICSTART, 0x00);
+ i2c_read(reg, ICSTART);
+
+ i2c_write(reg, ICCR, 0x10);
+ mdelay(100);
+ i2c_write(reg, ICCR, 0x00);
+ mdelay(100);
+ i2c_write(reg, ICCR, 0x10);
+ mdelay(100);
+
+ iounmap(reg);
+}
+
+void __init r8a7740_add_standard_devices(void)
+{
+ /* I2C work-around */
+ r8a7740_i2c_workaround(&i2c0_device);
+ r8a7740_i2c_workaround(&i2c1_device);
+
+ platform_add_devices(r8a7740_early_devices,
+ ARRAY_SIZE(r8a7740_early_devices));
+ platform_add_devices(r8a7740_late_devices,
+ ARRAY_SIZE(r8a7740_late_devices));
+}
+
+void __init r8a7740_add_early_devices(void)
+{
+ early_platform_add_devices(r8a7740_early_devices,
+ ARRAY_SIZE(r8a7740_early_devices));
+}
diff --git a/arch/arm/mach-shmobile/setup-r8a7779.c b/arch/arm/mach-shmobile/setup-r8a7779.c
new file mode 100644
index 0000000..4725663
--- /dev/null
+++ b/arch/arm/mach-shmobile/setup-r8a7779.c
@@ -0,0 +1,239 @@
+/*
+ * r8a7779 processor support
+ *
+ * Copyright (C) 2011 Renesas Solutions Corp.
+ * Copyright (C) 2011 Magnus Damm
+ *
+ * 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; version 2 of the License.
+ *
+ * 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 <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/input.h>
+#include <linux/io.h>
+#include <linux/serial_sci.h>
+#include <linux/sh_intc.h>
+#include <linux/sh_timer.h>
+#include <mach/hardware.h>
+#include <mach/r8a7779.h>
+#include <mach/common.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+static struct plat_sci_port scif0_platform_data = {
+ .mapbase = 0xffe40000,
+ .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP,
+ .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1,
+ .scbrr_algo_id = SCBRR_ALGO_2,
+ .type = PORT_SCIF,
+ .irqs = { gic_spi(88), gic_spi(88),
+ gic_spi(88), gic_spi(88) },
+};
+
+static struct platform_device scif0_device = {
+ .name = "sh-sci",
+ .id = 0,
+ .dev = {
+ .platform_data = &scif0_platform_data,
+ },
+};
+
+static struct plat_sci_port scif1_platform_data = {
+ .mapbase = 0xffe41000,
+ .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP,
+ .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1,
+ .scbrr_algo_id = SCBRR_ALGO_2,
+ .type = PORT_SCIF,
+ .irqs = { gic_spi(89), gic_spi(89),
+ gic_spi(89), gic_spi(89) },
+};
+
+static struct platform_device scif1_device = {
+ .name = "sh-sci",
+ .id = 1,
+ .dev = {
+ .platform_data = &scif1_platform_data,
+ },
+};
+
+static struct plat_sci_port scif2_platform_data = {
+ .mapbase = 0xffe42000,
+ .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP,
+ .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1,
+ .scbrr_algo_id = SCBRR_ALGO_2,
+ .type = PORT_SCIF,
+ .irqs = { gic_spi(90), gic_spi(90),
+ gic_spi(90), gic_spi(90) },
+};
+
+static struct platform_device scif2_device = {
+ .name = "sh-sci",
+ .id = 2,
+ .dev = {
+ .platform_data = &scif2_platform_data,
+ },
+};
+
+static struct plat_sci_port scif3_platform_data = {
+ .mapbase = 0xffe43000,
+ .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP,
+ .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1,
+ .scbrr_algo_id = SCBRR_ALGO_2,
+ .type = PORT_SCIF,
+ .irqs = { gic_spi(91), gic_spi(91),
+ gic_spi(91), gic_spi(91) },
+};
+
+static struct platform_device scif3_device = {
+ .name = "sh-sci",
+ .id = 3,
+ .dev = {
+ .platform_data = &scif3_platform_data,
+ },
+};
+
+static struct plat_sci_port scif4_platform_data = {
+ .mapbase = 0xffe44000,
+ .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP,
+ .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1,
+ .scbrr_algo_id = SCBRR_ALGO_2,
+ .type = PORT_SCIF,
+ .irqs = { gic_spi(92), gic_spi(92),
+ gic_spi(92), gic_spi(92) },
+};
+
+static struct platform_device scif4_device = {
+ .name = "sh-sci",
+ .id = 4,
+ .dev = {
+ .platform_data = &scif4_platform_data,
+ },
+};
+
+static struct plat_sci_port scif5_platform_data = {
+ .mapbase = 0xffe45000,
+ .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP,
+ .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1,
+ .scbrr_algo_id = SCBRR_ALGO_2,
+ .type = PORT_SCIF,
+ .irqs = { gic_spi(93), gic_spi(93),
+ gic_spi(93), gic_spi(93) },
+};
+
+static struct platform_device scif5_device = {
+ .name = "sh-sci",
+ .id = 5,
+ .dev = {
+ .platform_data = &scif5_platform_data,
+ },
+};
+
+/* TMU */
+static struct sh_timer_config tmu00_platform_data = {
+ .name = "TMU00",
+ .channel_offset = 0x4,
+ .timer_bit = 0,
+ .clockevent_rating = 200,
+};
+
+static struct resource tmu00_resources[] = {
+ [0] = {
+ .name = "TMU00",
+ .start = 0xffd80008,
+ .end = 0xffd80013,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = gic_spi(32),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tmu00_device = {
+ .name = "sh_tmu",
+ .id = 0,
+ .dev = {
+ .platform_data = &tmu00_platform_data,
+ },
+ .resource = tmu00_resources,
+ .num_resources = ARRAY_SIZE(tmu00_resources),
+};
+
+static struct sh_timer_config tmu01_platform_data = {
+ .name = "TMU01",
+ .channel_offset = 0x10,
+ .timer_bit = 1,
+ .clocksource_rating = 200,
+};
+
+static struct resource tmu01_resources[] = {
+ [0] = {
+ .name = "TMU01",
+ .start = 0xffd80014,
+ .end = 0xffd8001f,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = gic_spi(33),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tmu01_device = {
+ .name = "sh_tmu",
+ .id = 1,
+ .dev = {
+ .platform_data = &tmu01_platform_data,
+ },
+ .resource = tmu01_resources,
+ .num_resources = ARRAY_SIZE(tmu01_resources),
+};
+
+static struct platform_device *r8a7779_early_devices[] __initdata = {
+ &scif0_device,
+ &scif1_device,
+ &scif2_device,
+ &scif3_device,
+ &scif4_device,
+ &scif5_device,
+ &tmu00_device,
+ &tmu01_device,
+};
+
+static struct platform_device *r8a7779_late_devices[] __initdata = {
+};
+
+void __init r8a7779_add_standard_devices(void)
+{
+ r8a7779_pm_init();
+
+ r8a7779_init_pm_domain(&r8a7779_sh4a);
+ r8a7779_init_pm_domain(&r8a7779_sgx);
+ r8a7779_init_pm_domain(&r8a7779_vdp1);
+ r8a7779_init_pm_domain(&r8a7779_impx3);
+
+ platform_add_devices(r8a7779_early_devices,
+ ARRAY_SIZE(r8a7779_early_devices));
+ platform_add_devices(r8a7779_late_devices,
+ ARRAY_SIZE(r8a7779_late_devices));
+}
+
+void __init r8a7779_add_early_devices(void)
+{
+ early_platform_add_devices(r8a7779_early_devices,
+ ARRAY_SIZE(r8a7779_early_devices));
+}
diff --git a/arch/arm/mach-shmobile/setup-sh7372.c b/arch/arm/mach-shmobile/setup-sh7372.c
index c197f9d..1ea89be 100644
--- a/arch/arm/mach-shmobile/setup-sh7372.c
+++ b/arch/arm/mach-shmobile/setup-sh7372.c
@@ -504,7 +504,7 @@
.flags = IORESOURCE_MEM,
},
{
- /* DMA error IRQ */
+ .name = "error_irq",
.start = evt2irq(0x20c0),
.end = evt2irq(0x20c0),
.flags = IORESOURCE_IRQ,
@@ -532,7 +532,7 @@
.flags = IORESOURCE_MEM,
},
{
- /* DMA error IRQ */
+ .name = "error_irq",
.start = evt2irq(0x21c0),
.end = evt2irq(0x21c0),
.flags = IORESOURCE_IRQ,
@@ -560,7 +560,7 @@
.flags = IORESOURCE_MEM,
},
{
- /* DMA error IRQ */
+ .name = "error_irq",
.start = evt2irq(0x22c0),
.end = evt2irq(0x22c0),
.flags = IORESOURCE_IRQ,
diff --git a/arch/arm/mach-shmobile/setup-sh73a0.c b/arch/arm/mach-shmobile/setup-sh73a0.c
index e46821c..20e71e5 100644
--- a/arch/arm/mach-shmobile/setup-sh73a0.c
+++ b/arch/arm/mach-shmobile/setup-sh73a0.c
@@ -607,7 +607,7 @@
.flags = IORESOURCE_MEM,
},
{
- /* DMA error IRQ */
+ .name = "error_irq",
.start = gic_spi(129),
.end = gic_spi(129),
.flags = IORESOURCE_IRQ,
diff --git a/arch/arm/mach-shmobile/smp-r8a7779.c b/arch/arm/mach-shmobile/smp-r8a7779.c
new file mode 100644
index 0000000..cc97ef8
--- /dev/null
+++ b/arch/arm/mach-shmobile/smp-r8a7779.c
@@ -0,0 +1,153 @@
+/*
+ * SMP support for R-Mobile / SH-Mobile - r8a7779 portion
+ *
+ * Copyright (C) 2011 Renesas Solutions Corp.
+ * Copyright (C) 2011 Magnus Damm
+ *
+ * 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; version 2 of the License.
+ *
+ * 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 <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/smp.h>
+#include <linux/spinlock.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <mach/common.h>
+#include <mach/r8a7779.h>
+#include <asm/smp_scu.h>
+#include <asm/smp_twd.h>
+#include <asm/hardware/gic.h>
+
+#define AVECR 0xfe700040
+
+static struct r8a7779_pm_ch r8a7779_ch_cpu1 = {
+ .chan_offs = 0x40, /* PWRSR0 .. PWRER0 */
+ .chan_bit = 1, /* ARM1 */
+ .isr_bit = 1, /* ARM1 */
+};
+
+static struct r8a7779_pm_ch r8a7779_ch_cpu2 = {
+ .chan_offs = 0x40, /* PWRSR0 .. PWRER0 */
+ .chan_bit = 2, /* ARM2 */
+ .isr_bit = 2, /* ARM2 */
+};
+
+static struct r8a7779_pm_ch r8a7779_ch_cpu3 = {
+ .chan_offs = 0x40, /* PWRSR0 .. PWRER0 */
+ .chan_bit = 3, /* ARM3 */
+ .isr_bit = 3, /* ARM3 */
+};
+
+static struct r8a7779_pm_ch *r8a7779_ch_cpu[4] = {
+ [1] = &r8a7779_ch_cpu1,
+ [2] = &r8a7779_ch_cpu2,
+ [3] = &r8a7779_ch_cpu3,
+};
+
+static void __iomem *scu_base_addr(void)
+{
+ return (void __iomem *)0xf0000000;
+}
+
+static DEFINE_SPINLOCK(scu_lock);
+static unsigned long tmp;
+
+static void modify_scu_cpu_psr(unsigned long set, unsigned long clr)
+{
+ void __iomem *scu_base = scu_base_addr();
+
+ spin_lock(&scu_lock);
+ tmp = __raw_readl(scu_base + 8);
+ tmp &= ~clr;
+ tmp |= set;
+ spin_unlock(&scu_lock);
+
+ /* disable cache coherency after releasing the lock */
+ __raw_writel(tmp, scu_base + 8);
+}
+
+unsigned int __init r8a7779_get_core_count(void)
+{
+ void __iomem *scu_base = scu_base_addr();
+
+#ifdef CONFIG_HAVE_ARM_TWD
+ /* twd_base needs to be initialized before percpu_timer_setup() */
+ twd_base = (void __iomem *)0xf0000600;
+#endif
+
+ return scu_get_core_count(scu_base);
+}
+
+int r8a7779_platform_cpu_kill(unsigned int cpu)
+{
+ struct r8a7779_pm_ch *ch = NULL;
+ int ret = -EIO;
+
+ cpu = cpu_logical_map(cpu);
+
+ /* disable cache coherency */
+ modify_scu_cpu_psr(3 << (cpu * 8), 0);
+
+ if (cpu < ARRAY_SIZE(r8a7779_ch_cpu))
+ ch = r8a7779_ch_cpu[cpu];
+
+ if (ch)
+ ret = r8a7779_sysc_power_down(ch);
+
+ return ret ? ret : 1;
+}
+
+void __cpuinit r8a7779_secondary_init(unsigned int cpu)
+{
+ gic_secondary_init(0);
+}
+
+int __cpuinit r8a7779_boot_secondary(unsigned int cpu)
+{
+ struct r8a7779_pm_ch *ch = NULL;
+ int ret = -EIO;
+
+ cpu = cpu_logical_map(cpu);
+
+ /* enable cache coherency */
+ modify_scu_cpu_psr(0, 3 << (cpu * 8));
+
+ if (cpu < ARRAY_SIZE(r8a7779_ch_cpu))
+ ch = r8a7779_ch_cpu[cpu];
+
+ if (ch)
+ ret = r8a7779_sysc_power_up(ch);
+
+ return ret;
+}
+
+void __init r8a7779_smp_prepare_cpus(void)
+{
+ int cpu = cpu_logical_map(0);
+
+ scu_enable(scu_base_addr());
+
+ /* Map the reset vector (in headsmp.S) */
+ __raw_writel(__pa(shmobile_secondary_vector), __io(AVECR));
+
+ /* enable cache coherency on CPU0 */
+ modify_scu_cpu_psr(0, 3 << (cpu * 8));
+
+ r8a7779_pm_init();
+
+ /* power off secondary CPUs */
+ r8a7779_platform_cpu_kill(1);
+ r8a7779_platform_cpu_kill(2);
+ r8a7779_platform_cpu_kill(3);
+}
diff --git a/arch/arm/mach-tegra/board-harmony.c b/arch/arm/mach-tegra/board-harmony.c
index a0f9634..789bdc9 100644
--- a/arch/arm/mach-tegra/board-harmony.c
+++ b/arch/arm/mach-tegra/board-harmony.c
@@ -90,11 +90,11 @@
.micdet_delay = 100,
.gpio_base = HARMONY_GPIO_WM8903(0),
.gpio_cfg = {
- WM8903_GPIO_NO_CONFIG,
- WM8903_GPIO_NO_CONFIG,
0,
- WM8903_GPIO_NO_CONFIG,
- WM8903_GPIO_NO_CONFIG,
+ 0,
+ WM8903_GPIO_CONFIG_ZERO,
+ 0,
+ 0,
},
};
diff --git a/arch/arm/mach-tegra/board-seaboard.c b/arch/arm/mach-tegra/board-seaboard.c
index cfc74d4..ebac65f 100644
--- a/arch/arm/mach-tegra/board-seaboard.c
+++ b/arch/arm/mach-tegra/board-seaboard.c
@@ -172,11 +172,11 @@
.micdet_delay = 100,
.gpio_base = SEABOARD_GPIO_WM8903(0),
.gpio_cfg = {
- WM8903_GPIO_NO_CONFIG,
- WM8903_GPIO_NO_CONFIG,
0,
- WM8903_GPIO_NO_CONFIG,
- WM8903_GPIO_NO_CONFIG,
+ 0,
+ WM8903_GPIO_CONFIG_ZERO,
+ 0,
+ 0,
},
};
diff --git a/arch/arm/mach-tegra/pcie.c b/arch/arm/mach-tegra/pcie.c
index ec63c6b..af8b634 100644
--- a/arch/arm/mach-tegra/pcie.c
+++ b/arch/arm/mach-tegra/pcie.c
@@ -408,7 +408,7 @@
pp->res[0].flags = IORESOURCE_IO;
if (request_resource(&ioport_resource, &pp->res[0]))
panic("Request PCIe IO resource failed\n");
- sys->resource[0] = &pp->res[0];
+ pci_add_resource(&sys->resources, &pp->res[0]);
/*
* IORESOURCE_MEM
@@ -427,7 +427,7 @@
pp->res[1].flags = IORESOURCE_MEM;
if (request_resource(&iomem_resource, &pp->res[1]))
panic("Request PCIe Memory resource failed\n");
- sys->resource[1] = &pp->res[1];
+ pci_add_resource(&sys->resources, &pp->res[1]);
/*
* IORESOURCE_MEM | IORESOURCE_PREFETCH
@@ -446,7 +446,7 @@
pp->res[2].flags = IORESOURCE_MEM | IORESOURCE_PREFETCH;
if (request_resource(&iomem_resource, &pp->res[2]))
panic("Request PCIe Prefetch Memory resource failed\n");
- sys->resource[2] = &pp->res[2];
+ pci_add_resource(&sys->resources, &pp->res[2]);
return 1;
}
@@ -467,7 +467,8 @@
pp = tegra_pcie.port + nr;
pp->root_bus_nr = sys->busnr;
- return pci_scan_bus(sys->busnr, &tegra_pcie_ops, sys);
+ return pci_scan_root_bus(NULL, sys->busnr, &tegra_pcie_ops, sys,
+ &sys->resources);
}
static struct hw_pci tegra_pcie_hw __initdata = {
diff --git a/arch/arm/mach-versatile/pci.c b/arch/arm/mach-versatile/pci.c
index c898deb..90069bc 100644
--- a/arch/arm/mach-versatile/pci.c
+++ b/arch/arm/mach-versatile/pci.c
@@ -191,7 +191,7 @@
.flags = IORESOURCE_MEM | IORESOURCE_PREFETCH,
};
-static int __init pci_versatile_setup_resources(struct resource **resource)
+static int __init pci_versatile_setup_resources(struct list_head *resources)
{
int ret = 0;
@@ -215,13 +215,13 @@
}
/*
- * bus->resource[0] is the IO resource for this bus
- * bus->resource[1] is the mem resource for this bus
- * bus->resource[2] is the prefetch mem resource for this bus
+ * the IO resource for this bus
+ * the mem resource for this bus
+ * the prefetch mem resource for this bus
*/
- resource[0] = &io_mem;
- resource[1] = &non_mem;
- resource[2] = &pre_mem;
+ pci_add_resource(resources, &io_mem);
+ pci_add_resource(resources, &non_mem);
+ pci_add_resource(resources, &pre_mem);
goto out;
@@ -250,7 +250,7 @@
if (nr == 0) {
sys->mem_offset = 0;
- ret = pci_versatile_setup_resources(sys->resource);
+ ret = pci_versatile_setup_resources(&sys->resources);
if (ret < 0) {
printk("pci_versatile_setup: resources... oops?\n");
goto out;
@@ -306,7 +306,8 @@
struct pci_bus * __init pci_versatile_scan_bus(int nr, struct pci_sys_data *sys)
{
- return pci_scan_bus(sys->busnr, &pci_versatile_ops, sys);
+ return pci_scan_root_bus(NULL, sys->busnr, &pci_versatile_ops, sys,
+ &sys->resources);
}
void __init pci_versatile_preinit(void)
diff --git a/arch/arm/plat-iop/pci.c b/arch/arm/plat-iop/pci.c
index 845549c..f4d40a2 100644
--- a/arch/arm/plat-iop/pci.c
+++ b/arch/arm/plat-iop/pci.c
@@ -215,16 +215,16 @@
sys->mem_offset = IOP3XX_PCI_LOWER_MEM_PA - *IOP3XX_OMWTVR0;
sys->io_offset = IOP3XX_PCI_LOWER_IO_PA - *IOP3XX_OIOWTVR;
- sys->resource[0] = &res[0];
- sys->resource[1] = &res[1];
- sys->resource[2] = NULL;
+ pci_add_resource(&sys->resources, &res[0]);
+ pci_add_resource(&sys->resources, &res[1]);
return 1;
}
struct pci_bus *iop3xx_pci_scan_bus(int nr, struct pci_sys_data *sys)
{
- return pci_scan_bus(sys->busnr, &iop3xx_ops, sys);
+ return pci_scan_root_bus(NULL, sys->busnr, &iop3xx_ops, sys,
+ &sys->resources);
}
void __init iop3xx_atu_setup(void)
diff --git a/arch/arm/plat-omap/cpu-omap.c b/arch/arm/plat-omap/cpu-omap.c
deleted file mode 100644
index da4f68d..0000000
--- a/arch/arm/plat-omap/cpu-omap.c
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * linux/arch/arm/plat-omap/cpu-omap.c
- *
- * CPU frequency scaling for OMAP
- *
- * Copyright (C) 2005 Nokia Corporation
- * Written by Tony Lindgren <tony@atomide.com>
- *
- * Based on cpu-sa1110.c, Copyright (C) 2001 Russell King
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/cpufreq.h>
-#include <linux/delay.h>
-#include <linux/init.h>
-#include <linux/err.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-
-#include <mach/hardware.h>
-#include <plat/clock.h>
-#include <asm/system.h>
-
-#define VERY_HI_RATE 900000000
-
-static struct cpufreq_frequency_table *freq_table;
-
-#ifdef CONFIG_ARCH_OMAP1
-#define MPU_CLK "mpu"
-#else
-#define MPU_CLK "virt_prcm_set"
-#endif
-
-static struct clk *mpu_clk;
-
-/* TODO: Add support for SDRAM timing changes */
-
-static int omap_verify_speed(struct cpufreq_policy *policy)
-{
- if (freq_table)
- return cpufreq_frequency_table_verify(policy, freq_table);
-
- if (policy->cpu)
- return -EINVAL;
-
- cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq,
- policy->cpuinfo.max_freq);
-
- policy->min = clk_round_rate(mpu_clk, policy->min * 1000) / 1000;
- policy->max = clk_round_rate(mpu_clk, policy->max * 1000) / 1000;
- cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq,
- policy->cpuinfo.max_freq);
- return 0;
-}
-
-static unsigned int omap_getspeed(unsigned int cpu)
-{
- unsigned long rate;
-
- if (cpu)
- return 0;
-
- rate = clk_get_rate(mpu_clk) / 1000;
- return rate;
-}
-
-static int omap_target(struct cpufreq_policy *policy,
- unsigned int target_freq,
- unsigned int relation)
-{
- struct cpufreq_freqs freqs;
- int ret = 0;
-
- /* Ensure desired rate is within allowed range. Some govenors
- * (ondemand) will just pass target_freq=0 to get the minimum. */
- if (target_freq < policy->min)
- target_freq = policy->min;
- if (target_freq > policy->max)
- target_freq = policy->max;
-
- freqs.old = omap_getspeed(0);
- freqs.new = clk_round_rate(mpu_clk, target_freq * 1000) / 1000;
- freqs.cpu = 0;
-
- if (freqs.old == freqs.new)
- return ret;
-
- cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
-#ifdef CONFIG_CPU_FREQ_DEBUG
- printk(KERN_DEBUG "cpufreq-omap: transition: %u --> %u\n",
- freqs.old, freqs.new);
-#endif
- ret = clk_set_rate(mpu_clk, freqs.new * 1000);
- cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
-
- return ret;
-}
-
-static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy)
-{
- int result = 0;
-
- mpu_clk = clk_get(NULL, MPU_CLK);
- if (IS_ERR(mpu_clk))
- return PTR_ERR(mpu_clk);
-
- if (policy->cpu != 0)
- return -EINVAL;
-
- policy->cur = policy->min = policy->max = omap_getspeed(0);
-
- clk_init_cpufreq_table(&freq_table);
- if (freq_table) {
- result = cpufreq_frequency_table_cpuinfo(policy, freq_table);
- if (!result)
- cpufreq_frequency_table_get_attr(freq_table,
- policy->cpu);
- } else {
- policy->cpuinfo.min_freq = clk_round_rate(mpu_clk, 0) / 1000;
- policy->cpuinfo.max_freq = clk_round_rate(mpu_clk,
- VERY_HI_RATE) / 1000;
- }
-
- /* FIXME: what's the actual transition time? */
- policy->cpuinfo.transition_latency = 300 * 1000;
-
- return 0;
-}
-
-static int omap_cpu_exit(struct cpufreq_policy *policy)
-{
- clk_exit_cpufreq_table(&freq_table);
- clk_put(mpu_clk);
- return 0;
-}
-
-static struct freq_attr *omap_cpufreq_attr[] = {
- &cpufreq_freq_attr_scaling_available_freqs,
- NULL,
-};
-
-static struct cpufreq_driver omap_driver = {
- .flags = CPUFREQ_STICKY,
- .verify = omap_verify_speed,
- .target = omap_target,
- .get = omap_getspeed,
- .init = omap_cpu_init,
- .exit = omap_cpu_exit,
- .name = "omap",
- .attr = omap_cpufreq_attr,
-};
-
-static int __init omap_cpufreq_init(void)
-{
- return cpufreq_register_driver(&omap_driver);
-}
-
-arch_initcall(omap_cpufreq_init);
-
-/*
- * if ever we want to remove this, upon cleanup call:
- *
- * cpufreq_unregister_driver()
- * cpufreq_frequency_table_put_attr()
- */
-
diff --git a/arch/blackfin/include/asm/pci.h b/arch/blackfin/include/asm/pci.h
index 99cae2e..74352c4 100644
--- a/arch/blackfin/include/asm/pci.h
+++ b/arch/blackfin/include/asm/pci.h
@@ -10,10 +10,6 @@
#define PCIBIOS_MIN_IO 0x00001000
#define PCIBIOS_MIN_MEM 0x10000000
-static inline void pcibios_set_master(struct pci_dev *dev)
-{
- /* No special bus mastering setup handling */
-}
static inline void pcibios_penalize_isa_irq(int irq)
{
/* We don't do dynamic PCI IRQ allocation */
diff --git a/arch/frv/Kconfig b/arch/frv/Kconfig
index bbbf7927..a685910 100644
--- a/arch/frv/Kconfig
+++ b/arch/frv/Kconfig
@@ -8,6 +8,7 @@
select HAVE_GENERIC_HARDIRQS
select GENERIC_IRQ_SHOW
select ARCH_HAVE_NMI_SAFE_CMPXCHG
+ select GENERIC_CPU_DEVICES
config ZONE_DMA
bool
diff --git a/arch/frv/mb93090-mb00/pci-frv.c b/arch/frv/mb93090-mb00/pci-frv.c
index 6b4fb28..c281217 100644
--- a/arch/frv/mb93090-mb00/pci-frv.c
+++ b/arch/frv/mb93090-mb00/pci-frv.c
@@ -194,23 +194,3 @@
pcibios_allocate_resources(1);
pcibios_assign_resources();
}
-
-/*
- * If we set up a device for bus mastering, we need to check the latency
- * timer as certain crappy BIOSes forget to set it properly.
- */
-unsigned int pcibios_max_latency = 255;
-
-void pcibios_set_master(struct pci_dev *dev)
-{
- u8 lat;
- pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
- if (lat < 16)
- lat = (64 <= pcibios_max_latency) ? 64 : pcibios_max_latency;
- else if (lat > pcibios_max_latency)
- lat = pcibios_max_latency;
- else
- return;
- printk(KERN_DEBUG "PCI: Setting latency timer of device %s to %d\n", pci_name(dev), lat);
- pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat);
-}
diff --git a/arch/frv/mb93090-mb00/pci-frv.h b/arch/frv/mb93090-mb00/pci-frv.h
index f3fe5591..089eeba 100644
--- a/arch/frv/mb93090-mb00/pci-frv.h
+++ b/arch/frv/mb93090-mb00/pci-frv.h
@@ -26,8 +26,6 @@
/* pci-frv.c */
-extern unsigned int pcibios_max_latency;
-
void pcibios_resource_survey(void);
/* pci-vdk.c */
diff --git a/arch/frv/mb93090-mb00/pci-vdk.c b/arch/frv/mb93090-mb00/pci-vdk.c
index f8dd37e..6b0b82f 100644
--- a/arch/frv/mb93090-mb00/pci-vdk.c
+++ b/arch/frv/mb93090-mb00/pci-vdk.c
@@ -327,11 +327,6 @@
printk("### PCIBIOS_FIXUP_BUS(%d)\n",bus->number);
#endif
- if (bus->number == 0) {
- bus->resource[0] = &pci_ioport_resource;
- bus->resource[1] = &pci_iomem_resource;
- }
-
pci_read_bridge_bases(bus);
if (bus->number == 0) {
@@ -357,6 +352,7 @@
int __init pcibios_init(void)
{
struct pci_ops *dir = NULL;
+ LIST_HEAD(resources);
if (!mb93090_mb00_detected)
return -ENXIO;
@@ -420,7 +416,10 @@
}
printk("PCI: Probing PCI hardware\n");
- pci_root_bus = pci_scan_bus(0, pci_root_ops, NULL);
+ pci_add_resource(&resources, &pci_ioport_resource);
+ pci_add_resource(&resources, &pci_iomem_resource);
+ pci_root_bus = pci_scan_root_bus(NULL, 0, pci_root_ops, NULL,
+ &resources);
pcibios_irq_init();
pcibios_fixup_peer_bridges();
diff --git a/arch/h8300/Kconfig b/arch/h8300/Kconfig
index d1f377f..56e890d 100644
--- a/arch/h8300/Kconfig
+++ b/arch/h8300/Kconfig
@@ -4,6 +4,7 @@
select HAVE_IDE
select HAVE_GENERIC_HARDIRQS
select GENERIC_IRQ_SHOW
+ select GENERIC_CPU_DEVICES
config SYMBOL_PREFIX
string
diff --git a/arch/h8300/include/asm/pci.h b/arch/h8300/include/asm/pci.h
index cc97620..0b2acaa 100644
--- a/arch/h8300/include/asm/pci.h
+++ b/arch/h8300/include/asm/pci.h
@@ -9,11 +9,6 @@
#define pcibios_assign_all_busses() 0
-static inline void pcibios_set_master(struct pci_dev *dev)
-{
- /* No special bus mastering setup handling */
-}
-
static inline void pcibios_penalize_isa_irq(int irq, int active)
{
/* We don't do dynamic PCI IRQ allocation */
diff --git a/arch/ia64/include/asm/pci.h b/arch/ia64/include/asm/pci.h
index 127dd7b..279b38a 100644
--- a/arch/ia64/include/asm/pci.h
+++ b/arch/ia64/include/asm/pci.h
@@ -43,12 +43,6 @@
#define PCI_DMA_BUS_IS_PHYS (ia64_max_iommu_merge_mask == ~0UL)
static inline void
-pcibios_set_master (struct pci_dev *dev)
-{
- /* No special bus mastering setup handling */
-}
-
-static inline void
pcibios_penalize_isa_irq (int irq, int active)
{
/* We don't do dynamic PCI IRQ allocation */
diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c
index 2c27714..f82f5d4 100644
--- a/arch/ia64/pci/pci.c
+++ b/arch/ia64/pci/pci.c
@@ -134,6 +134,7 @@
struct pci_root_info {
struct acpi_device *bridge;
struct pci_controller *controller;
+ struct list_head resources;
char *name;
};
@@ -315,26 +316,15 @@
&window->resource);
}
+ /* HP's firmware has a hack to work around a Windows bug.
+ * Ignore these tiny memory ranges */
+ if (!((window->resource.flags & IORESOURCE_MEM) &&
+ (window->resource.end - window->resource.start < 16)))
+ pci_add_resource(&info->resources, &window->resource);
+
return AE_OK;
}
-static void __devinit
-pcibios_setup_root_windows(struct pci_bus *bus, struct pci_controller *ctrl)
-{
- int i;
-
- pci_bus_remove_resources(bus);
- for (i = 0; i < ctrl->windows; i++) {
- struct resource *res = &ctrl->window[i].resource;
- /* HP's firmware has a hack to work around a Windows bug.
- * Ignore these tiny memory ranges */
- if ((res->flags & IORESOURCE_MEM) &&
- (res->end - res->start < 16))
- continue;
- pci_bus_add_resource(bus, res, 0);
- }
-}
-
struct pci_bus * __devinit
pci_acpi_scan_root(struct acpi_pci_root *root)
{
@@ -343,6 +333,7 @@
int bus = root->secondary.start;
struct pci_controller *controller;
unsigned int windows = 0;
+ struct pci_root_info info;
struct pci_bus *pbus;
char *name;
int pxm;
@@ -359,11 +350,10 @@
controller->node = pxm_to_node(pxm);
#endif
+ INIT_LIST_HEAD(&info.resources);
acpi_walk_resources(device->handle, METHOD_NAME__CRS, count_window,
&windows);
if (windows) {
- struct pci_root_info info;
-
controller->window =
kmalloc_node(sizeof(*controller->window) * windows,
GFP_KERNEL, controller->node);
@@ -387,8 +377,14 @@
* should handle the case here, but it appears that IA64 hasn't
* such quirk. So we just ignore the case now.
*/
- pbus = pci_scan_bus_parented(NULL, bus, &pci_root_ops, controller);
+ pbus = pci_create_root_bus(NULL, bus, &pci_root_ops, controller,
+ &info.resources);
+ if (!pbus) {
+ pci_free_resource_list(&info.resources);
+ return NULL;
+ }
+ pbus->subordinate = pci_scan_child_bus(pbus);
return pbus;
out3:
@@ -504,14 +500,15 @@
if (b->self) {
pci_read_bridge_bases(b);
pcibios_fixup_bridge_resources(b->self);
- } else {
- pcibios_setup_root_windows(b, b->sysdata);
}
list_for_each_entry(dev, &b->devices, bus_list)
pcibios_fixup_device_resources(dev);
platform_pci_fixup_bus(b);
+}
- return;
+void pcibios_set_master (struct pci_dev *dev)
+{
+ /* No special bus mastering setup handling */
}
void __devinit
diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig
index 99c3636..ae413d4 100644
--- a/arch/m68k/Kconfig
+++ b/arch/m68k/Kconfig
@@ -6,6 +6,7 @@
select HAVE_GENERIC_HARDIRQS
select GENERIC_IRQ_SHOW
select ARCH_HAVE_NMI_SAFE_CMPXCHG if RMW_INSNS
+ select GENERIC_CPU_DEVICES
config RWSEM_GENERIC_SPINLOCK
bool
diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig
index f0eead7..74f23a4 100644
--- a/arch/microblaze/Kconfig
+++ b/arch/microblaze/Kconfig
@@ -18,6 +18,7 @@
select GENERIC_IRQ_PROBE
select GENERIC_IRQ_SHOW
select GENERIC_PCI_IOMAP
+ select GENERIC_CPU_DEVICES
config SWAP
def_bool n
diff --git a/arch/microblaze/include/asm/pci-bridge.h b/arch/microblaze/include/asm/pci-bridge.h
index 32764cd..e9834b2 100644
--- a/arch/microblaze/include/asm/pci-bridge.h
+++ b/arch/microblaze/include/asm/pci-bridge.h
@@ -140,7 +140,6 @@
/* Allocate & free a PCI host bridge structure */
extern struct pci_controller *pcibios_alloc_controller(struct device_node *dev);
extern void pcibios_free_controller(struct pci_controller *phb);
-extern void pcibios_setup_phb_resources(struct pci_controller *hose);
#endif /* __KERNEL__ */
#endif /* _ASM_MICROBLAZE_PCI_BRIDGE_H */
diff --git a/arch/microblaze/include/asm/pci.h b/arch/microblaze/include/asm/pci.h
index 1dd9d6b..0331376 100644
--- a/arch/microblaze/include/asm/pci.h
+++ b/arch/microblaze/include/asm/pci.h
@@ -42,11 +42,6 @@
*/
#define pcibios_assign_all_busses() 0
-static inline void pcibios_set_master(struct pci_dev *dev)
-{
- /* No special bus mastering setup handling */
-}
-
static inline void pcibios_penalize_isa_irq(int irq, int active)
{
/* We don't do dynamic PCI IRQ allocation */
diff --git a/arch/microblaze/pci/pci-common.c b/arch/microblaze/pci/pci-common.c
index 0d71b2e..85f2ac1 100644
--- a/arch/microblaze/pci/pci-common.c
+++ b/arch/microblaze/pci/pci-common.c
@@ -190,6 +190,11 @@
return device_create_file(&pdev->dev, &dev_attr_devspec);
}
+void pcibios_set_master(struct pci_dev *dev)
+{
+ /* No special bus mastering setup handling */
+}
+
char __devinit *pcibios_setup(char *str)
{
return str;
@@ -1019,7 +1024,6 @@
struct pci_dev *dev = bus->self;
pci_bus_for_each_resource(bus, res, i) {
- res = bus->resource[i];
if (!res)
continue;
if (!res->flags)
@@ -1219,7 +1223,6 @@
pci_domain_nr(bus), bus->number);
pci_bus_for_each_resource(bus, res, i) {
- res = bus->resource[i];
if (!res || !res->flags
|| res->start > res->end || res->parent)
continue;
@@ -1510,14 +1513,18 @@
return pci_enable_resources(dev, mask);
}
-void __devinit pcibios_setup_phb_resources(struct pci_controller *hose)
+static void __devinit pcibios_setup_phb_resources(struct pci_controller *hose, struct list_head *resources)
{
- struct pci_bus *bus = hose->bus;
struct resource *res;
int i;
/* Hookup PHB IO resource */
- bus->resource[0] = res = &hose->io_resource;
+ res = &hose->io_resource;
+
+ /* Fixup IO space offset */
+ io_offset = (unsigned long)hose->io_base_virt - isa_io_base;
+ res->start = (res->start + io_offset) & 0xffffffffu;
+ res->end = (res->end + io_offset) & 0xffffffffu;
if (!res->flags) {
printk(KERN_WARNING "PCI: I/O resource not set for host"
@@ -1528,6 +1535,7 @@
res->end = res->start + IO_SPACE_LIMIT;
res->flags = IORESOURCE_IO;
}
+ pci_add_resource(resources, res);
pr_debug("PCI: PHB IO resource = %016llx-%016llx [%lx]\n",
(unsigned long long)res->start,
@@ -1550,7 +1558,7 @@
res->flags = IORESOURCE_MEM;
}
- bus->resource[i+1] = res;
+ pci_add_resource(resources, res);
pr_debug("PCI: PHB MEM resource %d = %016llx-%016llx [%lx]\n",
i, (unsigned long long)res->start,
@@ -1573,34 +1581,27 @@
static void __devinit pcibios_scan_phb(struct pci_controller *hose)
{
+ LIST_HEAD(resources);
struct pci_bus *bus;
struct device_node *node = hose->dn;
- unsigned long io_offset;
- struct resource *res = &hose->io_resource;
pr_debug("PCI: Scanning PHB %s\n",
node ? node->full_name : "<NO NAME>");
- /* Create an empty bus for the toplevel */
- bus = pci_create_bus(hose->parent, hose->first_busno, hose->ops, hose);
+ pcibios_setup_phb_resources(hose, &resources);
+
+ bus = pci_scan_root_bus(hose->parent, hose->first_busno,
+ hose->ops, hose, &resources);
if (bus == NULL) {
printk(KERN_ERR "Failed to create bus for PCI domain %04x\n",
hose->global_number);
+ pci_free_resource_list(&resources);
return;
}
bus->secondary = hose->first_busno;
hose->bus = bus;
- /* Fixup IO space offset */
- io_offset = (unsigned long)hose->io_base_virt - isa_io_base;
- res->start = (res->start + io_offset) & 0xffffffffu;
- res->end = (res->end + io_offset) & 0xffffffffu;
-
- /* Wire up PHB bus resources */
- pcibios_setup_phb_resources(hose);
-
- /* Scan children */
- hose->last_busno = bus->subordinate = pci_scan_child_bus(bus);
+ hose->last_busno = bus->subordinate;
}
static int __init pcibios_init(void)
@@ -1614,8 +1615,6 @@
list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
hose->last_busno = 0xff;
pcibios_scan_phb(hose);
- printk(KERN_INFO "calling pci_bus_add_devices()\n");
- pci_bus_add_devices(hose->bus);
if (next_busno <= hose->last_busno)
next_busno = hose->last_busno + 1;
}
diff --git a/arch/mips/pci/pci.c b/arch/mips/pci/pci.c
index 41af7fa..fa8e378 100644
--- a/arch/mips/pci/pci.c
+++ b/arch/mips/pci/pci.c
@@ -81,6 +81,7 @@
{
static int next_busno;
static int need_domain_info;
+ LIST_HEAD(resources);
struct pci_bus *bus;
if (!hose->iommu)
@@ -89,7 +90,13 @@
if (hose->get_busno && pci_probe_only)
next_busno = (*hose->get_busno)();
- bus = pci_scan_bus(next_busno, hose->pci_ops, hose);
+ pci_add_resource(&resources, hose->mem_resource);
+ pci_add_resource(&resources, hose->io_resource);
+ bus = pci_scan_root_bus(NULL, next_busno, hose->pci_ops, hose,
+ &resources);
+ if (!bus)
+ pci_free_resource_list(&resources);
+
hose->bus = bus;
need_domain_info = need_domain_info || hose->index;
@@ -205,27 +212,6 @@
return 0;
}
-/*
- * If we set up a device for bus mastering, we need to check the latency
- * timer as certain crappy BIOSes forget to set it properly.
- */
-static unsigned int pcibios_max_latency = 255;
-
-void pcibios_set_master(struct pci_dev *dev)
-{
- u8 lat;
- pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
- if (lat < 16)
- lat = (64 <= pcibios_max_latency) ? 64 : pcibios_max_latency;
- else if (lat > pcibios_max_latency)
- lat = pcibios_max_latency;
- else
- return;
- printk(KERN_DEBUG "PCI: Setting latency timer of device %s to %d\n",
- pci_name(dev), lat);
- pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat);
-}
-
unsigned int pcibios_assign_all_busses(void)
{
return (pci_probe & PCI_ASSIGN_ALL_BUSSES) ? 1 : 0;
@@ -266,15 +252,11 @@
{
/* Propagate hose info into the subordinate devices. */
- struct pci_controller *hose = bus->sysdata;
struct list_head *ln;
struct pci_dev *dev = bus->self;
- if (!dev) {
- bus->resource[0] = hose->io_resource;
- bus->resource[1] = hose->mem_resource;
- } else if (pci_probe_only &&
- (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) {
+ if (pci_probe_only && dev &&
+ (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) {
pci_read_bridge_bases(bus);
pcibios_fixup_device_resources(dev, bus);
}
diff --git a/arch/mn10300/unit-asb2305/pci-asb2305.c b/arch/mn10300/unit-asb2305/pci-asb2305.c
index 8e6763e..c4e2e79 100644
--- a/arch/mn10300/unit-asb2305/pci-asb2305.c
+++ b/arch/mn10300/unit-asb2305/pci-asb2305.c
@@ -213,28 +213,6 @@
pcibios_allocate_resources(1);
}
-/*
- * If we set up a device for bus mastering, we need to check the latency
- * timer as certain crappy BIOSes forget to set it properly.
- */
-unsigned int pcibios_max_latency = 255;
-
-void pcibios_set_master(struct pci_dev *dev)
-{
- u8 lat;
-
- pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
-
- if (lat < 16)
- lat = (64 <= pcibios_max_latency) ? 64 : pcibios_max_latency;
- else if (lat > pcibios_max_latency)
- lat = pcibios_max_latency;
- else
- return;
-
- pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat);
-}
-
int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
enum pci_mmap_state mmap_state, int write_combine)
{
diff --git a/arch/mn10300/unit-asb2305/pci-asb2305.h b/arch/mn10300/unit-asb2305/pci-asb2305.h
index c3fa294..1194fe4 100644
--- a/arch/mn10300/unit-asb2305/pci-asb2305.h
+++ b/arch/mn10300/unit-asb2305/pci-asb2305.h
@@ -31,8 +31,6 @@
/* pci-asb2305.c */
-extern unsigned int pcibios_max_latency;
-
extern void pcibios_resource_survey(void);
/* pci.c */
diff --git a/arch/mn10300/unit-asb2305/pci.c b/arch/mn10300/unit-asb2305/pci.c
index a4954fe..a7c5f08 100644
--- a/arch/mn10300/unit-asb2305/pci.c
+++ b/arch/mn10300/unit-asb2305/pci.c
@@ -380,11 +380,6 @@
{
struct pci_dev *dev;
- if (bus->number == 0) {
- bus->resource[0] = &pci_ioport_resource;
- bus->resource[1] = &pci_iomem_resource;
- }
-
if (bus->self) {
pci_read_bridge_bases(bus);
pcibios_fixup_device_resources(bus->self);
@@ -402,6 +397,8 @@
*/
static int __init pcibios_init(void)
{
+ LIST_HEAD(resources);
+
ioport_resource.start = 0xA0000000;
ioport_resource.end = 0xDFFFFFFF;
iomem_resource.start = 0xA0000000;
@@ -423,7 +420,10 @@
printk(KERN_INFO "PCI: Probing PCI hardware [mempage %08x]\n",
MEM_PAGING_REG);
- pci_root_bus = pci_scan_bus(0, &pci_direct_ampci, NULL);
+ pci_add_resource(&resources, &pci_ioport_resource);
+ pci_add_resource(&resources, &pci_iomem_resource);
+ pci_root_bus = pci_scan_root_bus(NULL, 0, &pci_direct_ampci, NULL,
+ &resources);
pcibios_irq_init();
pcibios_fixup_irqs();
diff --git a/arch/openrisc/Kconfig b/arch/openrisc/Kconfig
index 081a54f..bc428b5 100644
--- a/arch/openrisc/Kconfig
+++ b/arch/openrisc/Kconfig
@@ -15,6 +15,7 @@
select GENERIC_IRQ_PROBE
select GENERIC_IRQ_SHOW
select GENERIC_IOMAP
+ select GENERIC_CPU_DEVICES
config MMU
def_bool y
diff --git a/arch/powerpc/include/asm/pci-bridge.h b/arch/powerpc/include/asm/pci-bridge.h
index 882b6aa..5d48765 100644
--- a/arch/powerpc/include/asm/pci-bridge.h
+++ b/arch/powerpc/include/asm/pci-bridge.h
@@ -226,7 +226,6 @@
/* Allocate & free a PCI host bridge structure */
extern struct pci_controller *pcibios_alloc_controller(struct device_node *dev);
extern void pcibios_free_controller(struct pci_controller *phb);
-extern void pcibios_setup_phb_resources(struct pci_controller *hose);
#ifdef CONFIG_PCI
extern int pcibios_vaddr_is_ioport(void __iomem *address);
diff --git a/arch/powerpc/include/asm/pci.h b/arch/powerpc/include/asm/pci.h
index 1c92013..f54b3d2 100644
--- a/arch/powerpc/include/asm/pci.h
+++ b/arch/powerpc/include/asm/pci.h
@@ -46,11 +46,6 @@
#define pcibios_assign_all_busses() \
(pci_has_flag(PCI_REASSIGN_ALL_BUS))
-static inline void pcibios_set_master(struct pci_dev *dev)
-{
- /* No special bus mastering setup handling */
-}
-
static inline void pcibios_penalize_isa_irq(int irq, int active)
{
/* We don't do dynamic PCI IRQ allocation */
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
index fa4a573..cce98d7 100644
--- a/arch/powerpc/kernel/pci-common.c
+++ b/arch/powerpc/kernel/pci-common.c
@@ -1131,6 +1131,11 @@
}
}
+void pcibios_set_master(struct pci_dev *dev)
+{
+ /* No special bus mastering setup handling */
+}
+
void __devinit pcibios_fixup_bus(struct pci_bus *bus)
{
/* When called from the generic PCI probe, read PCI<->PCI bridge
@@ -1560,14 +1565,13 @@
return pci_enable_resources(dev, mask);
}
-void __devinit pcibios_setup_phb_resources(struct pci_controller *hose)
+static void __devinit pcibios_setup_phb_resources(struct pci_controller *hose, struct list_head *resources)
{
- struct pci_bus *bus = hose->bus;
struct resource *res;
int i;
/* Hookup PHB IO resource */
- bus->resource[0] = res = &hose->io_resource;
+ res = &hose->io_resource;
if (!res->flags) {
printk(KERN_WARNING "PCI: I/O resource not set for host"
@@ -1585,6 +1589,7 @@
(unsigned long long)res->start,
(unsigned long long)res->end,
(unsigned long)res->flags);
+ pci_add_resource(resources, res);
/* Hookup PHB Memory resources */
for (i = 0; i < 3; ++i) {
@@ -1602,12 +1607,12 @@
res->flags = IORESOURCE_MEM;
#endif /* CONFIG_PPC32 */
}
- bus->resource[i+1] = res;
pr_debug("PCI: PHB MEM resource %d = %016llx-%016llx [%lx]\n", i,
(unsigned long long)res->start,
(unsigned long long)res->end,
(unsigned long)res->flags);
+ pci_add_resource(resources, res);
}
pr_debug("PCI: PHB MEM offset = %016llx\n",
@@ -1701,6 +1706,7 @@
*/
void __devinit pcibios_scan_phb(struct pci_controller *hose)
{
+ LIST_HEAD(resources);
struct pci_bus *bus;
struct device_node *node = hose->dn;
int mode;
@@ -1708,21 +1714,23 @@
pr_debug("PCI: Scanning PHB %s\n",
node ? node->full_name : "<NO NAME>");
- /* Create an empty bus for the toplevel */
- bus = pci_create_bus(hose->parent, hose->first_busno, hose->ops, hose);
- if (bus == NULL) {
- pr_err("Failed to create bus for PCI domain %04x\n",
- hose->global_number);
- return;
- }
- bus->secondary = hose->first_busno;
- hose->bus = bus;
-
/* Get some IO space for the new PHB */
pcibios_setup_phb_io_space(hose);
/* Wire up PHB bus resources */
- pcibios_setup_phb_resources(hose);
+ pcibios_setup_phb_resources(hose, &resources);
+
+ /* Create an empty bus for the toplevel */
+ bus = pci_create_root_bus(hose->parent, hose->first_busno,
+ hose->ops, hose, &resources);
+ if (bus == NULL) {
+ pr_err("Failed to create bus for PCI domain %04x\n",
+ hose->global_number);
+ pci_free_resource_list(&resources);
+ return;
+ }
+ bus->secondary = hose->first_busno;
+ hose->bus = bus;
/* Get probe mode and perform scan */
mode = PCI_PROBE_NORMAL;
diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c
index bcf4bf9..3318d39 100644
--- a/arch/powerpc/kernel/pci_64.c
+++ b/arch/powerpc/kernel/pci_64.c
@@ -131,30 +131,13 @@
#endif /* CONFIG_HOTPLUG */
-int __devinit pcibios_map_io_space(struct pci_bus *bus)
+static int __devinit pcibios_map_phb_io_space(struct pci_controller *hose)
{
struct vm_struct *area;
unsigned long phys_page;
unsigned long size_page;
unsigned long io_virt_offset;
- struct pci_controller *hose;
- WARN_ON(bus == NULL);
-
- /* If this not a PHB, nothing to do, page tables still exist and
- * thus HPTEs will be faulted in when needed
- */
- if (bus->self) {
- pr_debug("IO mapping for PCI-PCI bridge %s\n",
- pci_name(bus->self));
- pr_debug(" virt=0x%016llx...0x%016llx\n",
- bus->resource[0]->start + _IO_BASE,
- bus->resource[0]->end + _IO_BASE);
- return 0;
- }
-
- /* Get the host bridge */
- hose = pci_bus_to_host(bus);
phys_page = _ALIGN_DOWN(hose->io_base_phys, PAGE_SIZE);
size_page = _ALIGN_UP(hose->pci_io_size, PAGE_SIZE);
@@ -198,11 +181,30 @@
return 0;
}
+
+int __devinit pcibios_map_io_space(struct pci_bus *bus)
+{
+ WARN_ON(bus == NULL);
+
+ /* If this not a PHB, nothing to do, page tables still exist and
+ * thus HPTEs will be faulted in when needed
+ */
+ if (bus->self) {
+ pr_debug("IO mapping for PCI-PCI bridge %s\n",
+ pci_name(bus->self));
+ pr_debug(" virt=0x%016llx...0x%016llx\n",
+ bus->resource[0]->start + _IO_BASE,
+ bus->resource[0]->end + _IO_BASE);
+ return 0;
+ }
+
+ return pcibios_map_phb_io_space(pci_bus_to_host(bus));
+}
EXPORT_SYMBOL_GPL(pcibios_map_io_space);
void __devinit pcibios_setup_phb_io_space(struct pci_controller *hose)
{
- pcibios_map_io_space(hose->bus);
+ pcibios_map_phb_io_space(hose);
}
#define IOBASE_BRIDGE_NUMBER 0
diff --git a/arch/score/Kconfig b/arch/score/Kconfig
index 3df65d3..4b28577 100644
--- a/arch/score/Kconfig
+++ b/arch/score/Kconfig
@@ -8,6 +8,7 @@
select HAVE_MEMBLOCK
select HAVE_MEMBLOCK_NODE_MAP
select ARCH_DISCARD_MEMBLOCK
+ select GENERIC_CPU_DEVICES
choice
prompt "System type"
diff --git a/arch/sh/boards/board-magicpanelr2.c b/arch/sh/boards/board-magicpanelr2.c
index 93f5039..b2ca1d9 100644
--- a/arch/sh/boards/board-magicpanelr2.c
+++ b/arch/sh/boards/board-magicpanelr2.c
@@ -25,9 +25,6 @@
#define LAN9115_READY (__raw_readl(0xA8000084UL) & 0x00000001UL)
-/* Prefer cmdline over RedBoot */
-static const char *probes[] = { "cmdlinepart", "RedBoot", NULL };
-
/* Wait until reset finished. Timeout is 100ms. */
static int __init ethernet_reset_finished(void)
{
@@ -293,8 +290,6 @@
.resource = heartbeat_resources,
};
-static struct mtd_partition *parsed_partitions;
-
static struct mtd_partition mpr2_partitions[] = {
/* Reserved for bootloader, read-only */
{
@@ -318,6 +313,8 @@
};
static struct physmap_flash_data flash_data = {
+ .parts = mpr2_partitions,
+ .nr_parts = ARRAY_SIZE(mpr2_partitions),
.width = 2,
};
@@ -337,32 +334,6 @@
},
};
-static struct mtd_info *flash_mtd;
-
-static struct map_info mpr2_flash_map = {
- .name = "Magic Panel R2 Flash",
- .size = 0x2000000UL,
- .bankwidth = 2,
-};
-
-static void __init set_mtd_partitions(void)
-{
- int nr_parts = 0;
-
- simple_map_init(&mpr2_flash_map);
- flash_mtd = do_map_probe("cfi_probe", &mpr2_flash_map);
- nr_parts = parse_mtd_partitions(flash_mtd, probes,
- &parsed_partitions, 0);
- /* If there is no partition table, used the hard coded table */
- if (nr_parts <= 0) {
- flash_data.parts = mpr2_partitions;
- flash_data.nr_parts = ARRAY_SIZE(mpr2_partitions);
- } else {
- flash_data.nr_parts = nr_parts;
- flash_data.parts = parsed_partitions;
- }
-}
-
/*
* Add all resources to the platform_device
*/
@@ -376,7 +347,6 @@
static int __init mpr2_devices_setup(void)
{
- set_mtd_partitions();
return platform_add_devices(mpr2_devices, ARRAY_SIZE(mpr2_devices));
}
device_initcall(mpr2_devices_setup);
diff --git a/arch/sh/boards/board-sh7757lcr.c b/arch/sh/boards/board-sh7757lcr.c
index 895e337..0838154 100644
--- a/arch/sh/boards/board-sh7757lcr.c
+++ b/arch/sh/boards/board-sh7757lcr.c
@@ -19,6 +19,7 @@
#include <linux/mmc/sh_mmcif.h>
#include <linux/mmc/sh_mobile_sdhi.h>
#include <linux/sh_eth.h>
+#include <linux/usb/renesas_usbhs.h>
#include <cpu/sh7757.h>
#include <asm/heartbeat.h>
@@ -264,6 +265,43 @@
},
};
+static int usbhs0_get_id(struct platform_device *pdev)
+{
+ return USBHS_GADGET;
+}
+
+static struct renesas_usbhs_platform_info usb0_data = {
+ .platform_callback = {
+ .get_id = usbhs0_get_id,
+ },
+ .driver_param = {
+ .buswait_bwait = 5,
+ }
+};
+
+static struct resource usb0_resources[] = {
+ [0] = {
+ .start = 0xfe450000,
+ .end = 0xfe4501ff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 50,
+ .end = 50,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device usb0_device = {
+ .name = "renesas_usbhs",
+ .id = 0,
+ .dev = {
+ .platform_data = &usb0_data,
+ },
+ .num_resources = ARRAY_SIZE(usb0_resources),
+ .resource = usb0_resources,
+};
+
static struct platform_device *sh7757lcr_devices[] __initdata = {
&heartbeat_device,
&sh7757_eth0_device,
@@ -272,6 +310,7 @@
&sh7757_eth_giga1_device,
&sh_mmcif_device,
&sdhi_device,
+ &usb0_device,
};
static struct flash_platform_data spi_flash_data = {
diff --git a/arch/sh/boards/mach-ap325rxa/setup.c b/arch/sh/boards/mach-ap325rxa/setup.c
index 7030f4c..74d49c0 100644
--- a/arch/sh/boards/mach-ap325rxa/setup.c
+++ b/arch/sh/boards/mach-ap325rxa/setup.c
@@ -249,9 +249,6 @@
.dev = {
.platform_data = &lcdc_info,
},
- .archdata = {
- .hwblk_id = HWBLK_LCDC,
- },
};
static void camera_power(int val)
@@ -424,9 +421,6 @@
.dev = {
.platform_data = &sh_mobile_ceu_info,
},
- .archdata = {
- .hwblk_id = HWBLK_CEU,
- },
};
static struct resource sdhi0_cn3_resources[] = {
@@ -454,9 +448,6 @@
.dev = {
.platform_data = &sdhi0_cn3_data,
},
- .archdata = {
- .hwblk_id = HWBLK_SDHI0,
- },
};
static struct resource sdhi1_cn7_resources[] = {
@@ -484,9 +475,6 @@
.dev = {
.platform_data = &sdhi1_cn7_data,
},
- .archdata = {
- .hwblk_id = HWBLK_SDHI1,
- },
};
static struct i2c_board_info __initdata ap325rxa_i2c_devices[] = {
diff --git a/arch/sh/boards/mach-ecovec24/setup.c b/arch/sh/boards/mach-ecovec24/setup.c
index 92ddce4..9a19fb0 100644
--- a/arch/sh/boards/mach-ecovec24/setup.c
+++ b/arch/sh/boards/mach-ecovec24/setup.c
@@ -156,9 +156,6 @@
},
.num_resources = ARRAY_SIZE(sh_eth_resources),
.resource = sh_eth_resources,
- .archdata = {
- .hwblk_id = HWBLK_ETHER,
- },
};
/* USB0 host */
@@ -278,9 +275,6 @@
},
.num_resources = ARRAY_SIZE(usbhs_resources),
.resource = usbhs_resources,
- .archdata = {
- .hwblk_id = HWBLK_USB1,
- },
};
/* LCDC */
@@ -366,9 +360,6 @@
.dev = {
.platform_data = &lcdc_info,
},
- .archdata = {
- .hwblk_id = HWBLK_LCDC,
- },
};
/* CEU0 */
@@ -400,9 +391,6 @@
.dev = {
.platform_data = &sh_mobile_ceu0_info,
},
- .archdata = {
- .hwblk_id = HWBLK_CEU0,
- },
};
/* CEU1 */
@@ -434,9 +422,6 @@
.dev = {
.platform_data = &sh_mobile_ceu1_info,
},
- .archdata = {
- .hwblk_id = HWBLK_CEU1,
- },
};
/* I2C device */
@@ -491,9 +476,6 @@
.dev = {
.platform_data = &keysc_info,
},
- .archdata = {
- .hwblk_id = HWBLK_KEYSC,
- },
};
/* TouchScreen */
@@ -568,9 +550,6 @@
.dev = {
.platform_data = &sdhi0_info,
},
- .archdata = {
- .hwblk_id = HWBLK_SDHI0,
- },
};
#if !defined(CONFIG_MMC_SH_MMCIF) && !defined(CONFIG_MMC_SH_MMCIF_MODULE)
@@ -608,9 +587,6 @@
.dev = {
.platform_data = &sdhi1_info,
},
- .archdata = {
- .hwblk_id = HWBLK_SDHI1,
- },
};
#endif /* CONFIG_MMC_SH_MMCIF */
@@ -676,9 +652,6 @@
},
.num_resources = ARRAY_SIZE(msiof0_resources),
.resource = msiof0_resources,
- .archdata = {
- .hwblk_id = HWBLK_MSIOF0,
- },
};
#endif
@@ -818,9 +791,6 @@
.dev = {
.platform_data = &fsi_info,
},
- .archdata = {
- .hwblk_id = HWBLK_SPU, /* FSI needs SPU hwblk */
- },
};
/* IrDA */
@@ -882,9 +852,6 @@
.dev = {
.platform_data = &sh_vou_pdata,
},
- .archdata = {
- .hwblk_id = HWBLK_VOU,
- },
};
#if defined(CONFIG_MMC_SH_MMCIF) || defined(CONFIG_MMC_SH_MMCIF_MODULE)
@@ -936,9 +903,6 @@
},
.num_resources = ARRAY_SIZE(sh_mmcif_resources),
.resource = sh_mmcif_resources,
- .archdata = {
- .hwblk_id = HWBLK_MMC,
- },
};
#endif
diff --git a/arch/sh/boards/mach-kfr2r09/setup.c b/arch/sh/boards/mach-kfr2r09/setup.c
index f65271a..5c3c713 100644
--- a/arch/sh/boards/mach-kfr2r09/setup.c
+++ b/arch/sh/boards/mach-kfr2r09/setup.c
@@ -122,9 +122,6 @@
.dev = {
.platform_data = &kfr2r09_sh_keysc_info,
},
- .archdata = {
- .hwblk_id = HWBLK_KEYSC,
- },
};
static const struct fb_videomode kfr2r09_lcdc_modes[] = {
@@ -191,9 +188,6 @@
.dev = {
.platform_data = &kfr2r09_sh_lcdc_info,
},
- .archdata = {
- .hwblk_id = HWBLK_LCDC,
- },
};
static struct r8a66597_platdata kfr2r09_usb0_gadget_data = {
@@ -254,9 +248,6 @@
.dev = {
.platform_data = &sh_mobile_ceu_info,
},
- .archdata = {
- .hwblk_id = HWBLK_CEU0,
- },
};
static struct i2c_board_info kfr2r09_i2c_camera = {
@@ -377,9 +368,6 @@
.dev = {
.platform_data = &sh7724_sdhi0_data,
},
- .archdata = {
- .hwblk_id = HWBLK_SDHI0,
- },
};
static struct platform_device *kfr2r09_devices[] __initdata = {
diff --git a/arch/sh/boards/mach-migor/setup.c b/arch/sh/boards/mach-migor/setup.c
index e4c8119..f8f9377 100644
--- a/arch/sh/boards/mach-migor/setup.c
+++ b/arch/sh/boards/mach-migor/setup.c
@@ -99,9 +99,6 @@
.dev = {
.platform_data = &sh_keysc_info,
},
- .archdata = {
- .hwblk_id = HWBLK_KEYSC,
- },
};
static struct mtd_partition migor_nor_flash_partitions[] =
@@ -300,9 +297,6 @@
.dev = {
.platform_data = &sh_mobile_lcdc_info,
},
- .archdata = {
- .hwblk_id = HWBLK_LCDC,
- },
};
static struct clk *camera_clk;
@@ -390,9 +384,6 @@
.dev = {
.platform_data = &sh_mobile_ceu_info,
},
- .archdata = {
- .hwblk_id = HWBLK_CEU,
- },
};
static struct resource sdhi_cn9_resources[] = {
@@ -421,9 +412,6 @@
.dev = {
.platform_data = &sh7724_sdhi_data,
},
- .archdata = {
- .hwblk_id = HWBLK_SDHI,
- },
};
static struct i2c_board_info migor_i2c_devices[] = {
diff --git a/arch/sh/boards/mach-rsk/setup.c b/arch/sh/boards/mach-rsk/setup.c
index a5c0df7..895f030 100644
--- a/arch/sh/boards/mach-rsk/setup.c
+++ b/arch/sh/boards/mach-rsk/setup.c
@@ -15,12 +15,12 @@
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/physmap.h>
-#ifdef CONFIG_MTD
#include <linux/mtd/map.h>
-#endif
#include <asm/machvec.h>
#include <asm/io.h>
+static const char *part_probes[] = { "cmdlinepart", NULL };
+
static struct mtd_partition rsk_partitions[] = {
{
.name = "Bootloader",
@@ -39,9 +39,10 @@
};
static struct physmap_flash_data flash_data = {
- .parts = rsk_partitions,
- .nr_parts = ARRAY_SIZE(rsk_partitions),
- .width = 2,
+ .parts = rsk_partitions,
+ .nr_parts = ARRAY_SIZE(rsk_partitions),
+ .width = 2,
+ .part_probe_types = part_probes,
};
static struct resource flash_resource = {
@@ -60,44 +61,12 @@
},
};
-#ifdef CONFIG_MTD
-static const char *probes[] = { "cmdlinepart", NULL };
-
-static struct map_info rsk_flash_map = {
- .name = "RSK+ Flash",
- .size = 0x400000,
- .bankwidth = 2,
-};
-
-static struct mtd_info *flash_mtd;
-
-static struct mtd_partition *parsed_partitions;
-
-static void __init set_mtd_partitions(void)
-{
- int nr_parts = 0;
-
- simple_map_init(&rsk_flash_map);
- flash_mtd = do_map_probe("cfi_probe", &rsk_flash_map);
- nr_parts = parse_mtd_partitions(flash_mtd, probes,
- &parsed_partitions, 0);
- /* If there is no partition table, used the hard coded table */
- if (nr_parts > 0) {
- flash_data.nr_parts = nr_parts;
- flash_data.parts = parsed_partitions;
- }
-}
-#else
-static inline void set_mtd_partitions(void) {}
-#endif
-
static struct platform_device *rsk_devices[] __initdata = {
&flash_device,
};
static int __init rsk_devices_setup(void)
{
- set_mtd_partitions();
return platform_add_devices(rsk_devices,
ARRAY_SIZE(rsk_devices));
}
diff --git a/arch/sh/boards/mach-se/7722/setup.c b/arch/sh/boards/mach-se/7722/setup.c
index 80a4e57..e1963fe 100644
--- a/arch/sh/boards/mach-se/7722/setup.c
+++ b/arch/sh/boards/mach-se/7722/setup.c
@@ -127,9 +127,6 @@
.dev = {
.platform_data = &sh_keysc_info,
},
- .archdata = {
- .hwblk_id = HWBLK_KEYSC,
- },
};
static struct platform_device *se7722_devices[] __initdata = {
diff --git a/arch/sh/boards/mach-se/7724/setup.c b/arch/sh/boards/mach-se/7724/setup.c
index b747c0a..2585733 100644
--- a/arch/sh/boards/mach-se/7724/setup.c
+++ b/arch/sh/boards/mach-se/7724/setup.c
@@ -210,9 +210,6 @@
.dev = {
.platform_data = &lcdc_info,
},
- .archdata = {
- .hwblk_id = HWBLK_LCDC,
- },
};
/* CEU0 */
@@ -244,9 +241,6 @@
.dev = {
.platform_data = &sh_mobile_ceu0_info,
},
- .archdata = {
- .hwblk_id = HWBLK_CEU0,
- },
};
/* CEU1 */
@@ -278,9 +272,6 @@
.dev = {
.platform_data = &sh_mobile_ceu1_info,
},
- .archdata = {
- .hwblk_id = HWBLK_CEU1,
- },
};
/* FSI */
@@ -310,13 +301,22 @@
.dev = {
.platform_data = &fsi_info,
},
- .archdata = {
- .hwblk_id = HWBLK_SPU, /* FSI needs SPU hwblk */
- },
+};
+
+static struct fsi_ak4642_info fsi_ak4642_info = {
+ .name = "AK4642",
+ .card = "FSIA-AK4642",
+ .cpu_dai = "fsia-dai",
+ .codec = "ak4642-codec.0-0012",
+ .platform = "sh_fsi.0",
+ .id = FSI_PORT_A,
};
static struct platform_device fsi_ak4642_device = {
- .name = "sh_fsi_a_ak4642",
+ .name = "fsi-ak4642-audio",
+ .dev = {
+ .platform_data = &fsi_ak4642_info,
+ },
};
/* KEYSC in SoC (Needs SW33-2 set to ON) */
@@ -355,9 +355,6 @@
.dev = {
.platform_data = &keysc_info,
},
- .archdata = {
- .hwblk_id = HWBLK_KEYSC,
- },
};
/* SH Eth */
@@ -386,9 +383,6 @@
},
.num_resources = ARRAY_SIZE(sh_eth_resources),
.resource = sh_eth_resources,
- .archdata = {
- .hwblk_id = HWBLK_ETHER,
- },
};
static struct r8a66597_platdata sh7724_usb0_host_data = {
@@ -418,9 +412,6 @@
},
.num_resources = ARRAY_SIZE(sh7724_usb0_host_resources),
.resource = sh7724_usb0_host_resources,
- .archdata = {
- .hwblk_id = HWBLK_USB0,
- },
};
static struct r8a66597_platdata sh7724_usb1_gadget_data = {
@@ -479,9 +470,6 @@
.dev = {
.platform_data = &sh7724_sdhi0_data,
},
- .archdata = {
- .hwblk_id = HWBLK_SDHI0,
- },
};
static struct resource sdhi1_cn8_resources[] = {
@@ -511,9 +499,6 @@
.dev = {
.platform_data = &sh7724_sdhi1_data,
},
- .archdata = {
- .hwblk_id = HWBLK_SDHI1,
- },
};
/* IrDA */
@@ -576,9 +561,6 @@
.dev = {
.platform_data = &sh_vou_pdata,
},
- .archdata = {
- .hwblk_id = HWBLK_VOU,
- },
};
static struct platform_device *ms7724se_devices[] __initdata = {
diff --git a/arch/sh/drivers/pci/pci.c b/arch/sh/drivers/pci/pci.c
index 11aaf2f..8f18dd0 100644
--- a/arch/sh/drivers/pci/pci.c
+++ b/arch/sh/drivers/pci/pci.c
@@ -36,9 +36,15 @@
{
static int next_busno;
static int need_domain_info;
+ LIST_HEAD(resources);
+ int i;
struct pci_bus *bus;
- bus = pci_scan_bus(next_busno, hose->pci_ops, hose);
+ for (i = 0; i < hose->nr_resources; i++)
+ pci_add_resource(&resources, hose->resources + i);
+
+ bus = pci_scan_root_bus(NULL, next_busno, hose->pci_ops, hose,
+ &resources);
hose->bus = bus;
need_domain_info = need_domain_info || hose->index;
@@ -55,6 +61,8 @@
pci_bus_size_bridges(bus);
pci_bus_assign_resources(bus);
pci_enable_bridges(bus);
+ } else {
+ pci_free_resource_list(&resources);
}
}
@@ -162,16 +170,8 @@
*/
void __devinit pcibios_fixup_bus(struct pci_bus *bus)
{
- struct pci_dev *dev = bus->self;
+ struct pci_dev *dev;
struct list_head *ln;
- struct pci_channel *hose = bus->sysdata;
-
- if (!dev) {
- int i;
-
- for (i = 0; i < hose->nr_resources; i++)
- bus->resource[i] = hose->resources + i;
- }
for (ln = bus->devices.next; ln != &bus->devices; ln = ln->next) {
dev = pci_dev_b(ln);
@@ -243,27 +243,6 @@
return pci_enable_resources(dev, mask);
}
-/*
- * If we set up a device for bus mastering, we need to check and set
- * the latency timer as it may not be properly set.
- */
-static unsigned int pcibios_max_latency = 255;
-
-void pcibios_set_master(struct pci_dev *dev)
-{
- u8 lat;
- pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
- if (lat < 16)
- lat = (64 <= pcibios_max_latency) ? 64 : pcibios_max_latency;
- else if (lat > pcibios_max_latency)
- lat = pcibios_max_latency;
- else
- return;
- printk(KERN_INFO "PCI: Setting latency timer of device %s to %d\n",
- pci_name(dev), lat);
- pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat);
-}
-
void __init pcibios_update_irq(struct pci_dev *dev, int irq)
{
pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
diff --git a/arch/sh/include/asm/device.h b/arch/sh/include/asm/device.h
index b16debf..a1c9c0d 100644
--- a/arch/sh/include/asm/device.h
+++ b/arch/sh/include/asm/device.h
@@ -14,15 +14,5 @@
void plat_early_device_setup(void);
-#define PDEV_ARCHDATA_FLAG_INIT 0
-#define PDEV_ARCHDATA_FLAG_IDLE 1
-#define PDEV_ARCHDATA_FLAG_SUSP 2
-
struct pdev_archdata {
- int hwblk_id;
-#ifdef CONFIG_PM_RUNTIME
- unsigned long flags;
- struct list_head entry;
- struct mutex mutex;
-#endif
};
diff --git a/arch/sh/include/asm/hwblk.h b/arch/sh/include/asm/hwblk.h
deleted file mode 100644
index 855e945..0000000
--- a/arch/sh/include/asm/hwblk.h
+++ /dev/null
@@ -1,70 +0,0 @@
-#ifndef __ASM_SH_HWBLK_H
-#define __ASM_SH_HWBLK_H
-
-#include <asm/clock.h>
-#include <asm/io.h>
-
-#define HWBLK_CNT_USAGE 0
-#define HWBLK_CNT_IDLE 1
-#define HWBLK_CNT_DEVICES 2
-#define HWBLK_CNT_NR 3
-
-#define HWBLK_AREA_FLAG_PARENT (1 << 0) /* valid parent */
-
-#define HWBLK_AREA(_flags, _parent) \
-{ \
- .flags = _flags, \
- .parent = _parent, \
-}
-
-struct hwblk_area {
- int cnt[HWBLK_CNT_NR];
- unsigned char parent;
- unsigned char flags;
-};
-
-#define HWBLK(_mstp, _bit, _area) \
-{ \
- .mstp = (void __iomem *)_mstp, \
- .bit = _bit, \
- .area = _area, \
-}
-
-struct hwblk {
- void __iomem *mstp;
- unsigned char bit;
- unsigned char area;
- int cnt[HWBLK_CNT_NR];
-};
-
-struct hwblk_info {
- struct hwblk_area *areas;
- int nr_areas;
- struct hwblk *hwblks;
- int nr_hwblks;
-};
-
-/* Should be defined by processor-specific code */
-int arch_hwblk_init(void);
-int arch_hwblk_sleep_mode(void);
-
-int hwblk_register(struct hwblk_info *info);
-int hwblk_init(void);
-
-void hwblk_enable(struct hwblk_info *info, int hwblk);
-void hwblk_disable(struct hwblk_info *info, int hwblk);
-
-void hwblk_cnt_inc(struct hwblk_info *info, int hwblk, int cnt);
-void hwblk_cnt_dec(struct hwblk_info *info, int hwblk, int cnt);
-
-/* allow clocks to enable and disable hardware blocks */
-#define SH_HWBLK_CLK(_hwblk, _parent, _flags) \
-[_hwblk] = { \
- .parent = _parent, \
- .arch_flags = _hwblk, \
- .flags = _flags, \
-}
-
-int sh_hwblk_clk_register(struct clk *clks, int nr);
-
-#endif /* __ASM_SH_HWBLK_H */
diff --git a/arch/sh/include/cpu-sh4/cpu/sh7722.h b/arch/sh/include/cpu-sh4/cpu/sh7722.h
index bd06227..3bb74e5 100644
--- a/arch/sh/include/cpu-sh4/cpu/sh7722.h
+++ b/arch/sh/include/cpu-sh4/cpu/sh7722.h
@@ -222,14 +222,11 @@
};
enum {
- HWBLK_UNKNOWN = 0,
- HWBLK_TLB, HWBLK_IC, HWBLK_OC, HWBLK_URAM, HWBLK_XYMEM,
- HWBLK_INTC, HWBLK_DMAC, HWBLK_SHYWAY, HWBLK_HUDI,
- HWBLK_UBC, HWBLK_TMU, HWBLK_CMT, HWBLK_RWDT, HWBLK_FLCTL,
- HWBLK_SCIF0, HWBLK_SCIF1, HWBLK_SCIF2, HWBLK_SIO,
- HWBLK_SIOF0, HWBLK_SIOF1, HWBLK_IIC, HWBLK_RTC,
- HWBLK_TPU, HWBLK_IRDA, HWBLK_SDHI, HWBLK_SIM, HWBLK_KEYSC,
- HWBLK_TSIF, HWBLK_USBF, HWBLK_2DG, HWBLK_SIU, HWBLK_VOU,
+ HWBLK_URAM, HWBLK_XYMEM,
+ HWBLK_TMU, HWBLK_CMT, HWBLK_RWDT, HWBLK_FLCTL,
+ HWBLK_SCIF0, HWBLK_SCIF1, HWBLK_SCIF2, HWBLK_IIC, HWBLK_RTC,
+ HWBLK_SDHI, HWBLK_KEYSC,
+ HWBLK_USBF, HWBLK_2DG, HWBLK_SIU, HWBLK_VOU,
HWBLK_JPU, HWBLK_BEU, HWBLK_CEU, HWBLK_VEU, HWBLK_VPU,
HWBLK_LCDC,
HWBLK_NR,
diff --git a/arch/sh/include/cpu-sh4/cpu/sh7723.h b/arch/sh/include/cpu-sh4/cpu/sh7723.h
index 9b36fae..6fae50c 100644
--- a/arch/sh/include/cpu-sh4/cpu/sh7723.h
+++ b/arch/sh/include/cpu-sh4/cpu/sh7723.h
@@ -266,10 +266,9 @@
};
enum {
- HWBLK_UNKNOWN = 0,
HWBLK_TLB, HWBLK_IC, HWBLK_OC, HWBLK_L2C, HWBLK_ILMEM, HWBLK_FPU,
HWBLK_INTC, HWBLK_DMAC0, HWBLK_SHYWAY,
- HWBLK_HUDI, HWBLK_DBG, HWBLK_UBC, HWBLK_SUBC,
+ HWBLK_HUDI, HWBLK_UBC,
HWBLK_TMU0, HWBLK_CMT, HWBLK_RWDT, HWBLK_DMAC1, HWBLK_TMU1,
HWBLK_FLCTL,
HWBLK_SCIF0, HWBLK_SCIF1, HWBLK_SCIF2,
diff --git a/arch/sh/include/cpu-sh4/cpu/sh7724.h b/arch/sh/include/cpu-sh4/cpu/sh7724.h
index cbc47e6..38859f9 100644
--- a/arch/sh/include/cpu-sh4/cpu/sh7724.h
+++ b/arch/sh/include/cpu-sh4/cpu/sh7724.h
@@ -268,10 +268,9 @@
};
enum {
- HWBLK_UNKNOWN = 0,
HWBLK_TLB, HWBLK_IC, HWBLK_OC, HWBLK_RSMEM, HWBLK_ILMEM, HWBLK_L2C,
HWBLK_FPU, HWBLK_INTC, HWBLK_DMAC0, HWBLK_SHYWAY,
- HWBLK_HUDI, HWBLK_DBG, HWBLK_UBC,
+ HWBLK_HUDI, HWBLK_UBC,
HWBLK_TMU0, HWBLK_CMT, HWBLK_RWDT, HWBLK_DMAC1, HWBLK_TMU1,
HWBLK_SCIF0, HWBLK_SCIF1, HWBLK_SCIF2, HWBLK_SCIF3,
HWBLK_SCIF4, HWBLK_SCIF5, HWBLK_MSIOF0, HWBLK_MSIOF1,
@@ -314,5 +313,6 @@
extern struct clk sh7724_fsimcka_clk;
extern struct clk sh7724_fsimckb_clk;
+extern struct clk sh7724_dv_clki;
#endif /* __ASM_SH7724_H__ */
diff --git a/arch/sh/kernel/cpu/Makefile b/arch/sh/kernel/cpu/Makefile
index ae95935..fa58bfd 100644
--- a/arch/sh/kernel/cpu/Makefile
+++ b/arch/sh/kernel/cpu/Makefile
@@ -18,4 +18,4 @@
obj-$(CONFIG_SH_ADC) += adc.o
obj-$(CONFIG_SH_CLK_CPG_LEGACY) += clock-cpg.o
-obj-y += irq/ init.o clock.o fpu.o hwblk.o proc.o
+obj-y += irq/ init.o clock.o fpu.o proc.o
diff --git a/arch/sh/kernel/cpu/hwblk.c b/arch/sh/kernel/cpu/hwblk.c
deleted file mode 100644
index 3e985aa..0000000
--- a/arch/sh/kernel/cpu/hwblk.c
+++ /dev/null
@@ -1,159 +0,0 @@
-#include <linux/clk.h>
-#include <linux/compiler.h>
-#include <linux/io.h>
-#include <linux/spinlock.h>
-#include <asm/suspend.h>
-#include <asm/hwblk.h>
-#include <asm/clock.h>
-
-static DEFINE_SPINLOCK(hwblk_lock);
-
-static void hwblk_area_mod_cnt(struct hwblk_info *info,
- int area, int counter, int value, int goal)
-{
- struct hwblk_area *hap = info->areas + area;
-
- hap->cnt[counter] += value;
-
- if (hap->cnt[counter] != goal)
- return;
-
- if (hap->flags & HWBLK_AREA_FLAG_PARENT)
- hwblk_area_mod_cnt(info, hap->parent, counter, value, goal);
-}
-
-
-static int __hwblk_mod_cnt(struct hwblk_info *info, int hwblk,
- int counter, int value, int goal)
-{
- struct hwblk *hp = info->hwblks + hwblk;
-
- hp->cnt[counter] += value;
- if (hp->cnt[counter] == goal)
- hwblk_area_mod_cnt(info, hp->area, counter, value, goal);
-
- return hp->cnt[counter];
-}
-
-static void hwblk_mod_cnt(struct hwblk_info *info, int hwblk,
- int counter, int value, int goal)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&hwblk_lock, flags);
- __hwblk_mod_cnt(info, hwblk, counter, value, goal);
- spin_unlock_irqrestore(&hwblk_lock, flags);
-}
-
-void hwblk_cnt_inc(struct hwblk_info *info, int hwblk, int counter)
-{
- hwblk_mod_cnt(info, hwblk, counter, 1, 1);
-}
-
-void hwblk_cnt_dec(struct hwblk_info *info, int hwblk, int counter)
-{
- hwblk_mod_cnt(info, hwblk, counter, -1, 0);
-}
-
-void hwblk_enable(struct hwblk_info *info, int hwblk)
-{
- struct hwblk *hp = info->hwblks + hwblk;
- unsigned long tmp;
- unsigned long flags;
- int ret;
-
- spin_lock_irqsave(&hwblk_lock, flags);
-
- ret = __hwblk_mod_cnt(info, hwblk, HWBLK_CNT_USAGE, 1, 1);
- if (ret == 1) {
- tmp = __raw_readl(hp->mstp);
- tmp &= ~(1 << hp->bit);
- __raw_writel(tmp, hp->mstp);
- }
-
- spin_unlock_irqrestore(&hwblk_lock, flags);
-}
-
-void hwblk_disable(struct hwblk_info *info, int hwblk)
-{
- struct hwblk *hp = info->hwblks + hwblk;
- unsigned long tmp;
- unsigned long flags;
- int ret;
-
- spin_lock_irqsave(&hwblk_lock, flags);
-
- ret = __hwblk_mod_cnt(info, hwblk, HWBLK_CNT_USAGE, -1, 0);
- if (ret == 0) {
- tmp = __raw_readl(hp->mstp);
- tmp |= 1 << hp->bit;
- __raw_writel(tmp, hp->mstp);
- }
-
- spin_unlock_irqrestore(&hwblk_lock, flags);
-}
-
-struct hwblk_info *hwblk_info;
-
-int __init hwblk_register(struct hwblk_info *info)
-{
- hwblk_info = info;
- return 0;
-}
-
-int __init __weak arch_hwblk_init(void)
-{
- return 0;
-}
-
-int __weak arch_hwblk_sleep_mode(void)
-{
- return SUSP_SH_SLEEP;
-}
-
-int __init hwblk_init(void)
-{
- return arch_hwblk_init();
-}
-
-/* allow clocks to enable and disable hardware blocks */
-static int sh_hwblk_clk_enable(struct clk *clk)
-{
- if (!hwblk_info)
- return -ENOENT;
-
- hwblk_enable(hwblk_info, clk->arch_flags);
- return 0;
-}
-
-static void sh_hwblk_clk_disable(struct clk *clk)
-{
- if (hwblk_info)
- hwblk_disable(hwblk_info, clk->arch_flags);
-}
-
-static struct clk_ops sh_hwblk_clk_ops = {
- .enable = sh_hwblk_clk_enable,
- .disable = sh_hwblk_clk_disable,
- .recalc = followparent_recalc,
-};
-
-int __init sh_hwblk_clk_register(struct clk *clks, int nr)
-{
- struct clk *clkp;
- int ret = 0;
- int k;
-
- for (k = 0; !ret && (k < nr); k++) {
- clkp = clks + k;
-
- /* skip over clocks using hwblk 0 (HWBLK_UNKNOWN) */
- if (!clkp->arch_flags)
- continue;
-
- clkp->ops = &sh_hwblk_clk_ops;
- ret |= clk_register(clkp);
- }
-
- return ret;
-}
diff --git a/arch/sh/kernel/cpu/sh4/sq.c b/arch/sh/kernel/cpu/sh4/sq.c
index a8140f0..0a47bd3 100644
--- a/arch/sh/kernel/cpu/sh4/sq.c
+++ b/arch/sh/kernel/cpu/sh4/sq.c
@@ -337,7 +337,7 @@
.default_attrs = sq_sysfs_attrs,
};
-static int __devinit sq_dev_add(struct device *dev)
+static int sq_dev_add(struct device *dev, struct subsys_interface *sif)
{
unsigned int cpu = dev->id;
struct kobject *kobj;
@@ -355,7 +355,7 @@
return error;
}
-static int __devexit sq_dev_remove(struct device *dev)
+static int sq_dev_remove(struct device *dev, struct subsys_interface *sif)
{
unsigned int cpu = dev->id;
struct kobject *kobj = sq_kobject[cpu];
@@ -365,10 +365,10 @@
}
static struct subsys_interface sq_interface = {
- .name = "sq"
+ .name = "sq",
.subsys = &cpu_subsys,
.add_dev = sq_dev_add,
- .remove_dev = __devexit_p(sq_dev_remove),
+ .remove_dev = sq_dev_remove,
};
static int __init sq_api_init(void)
diff --git a/arch/sh/kernel/cpu/sh4a/Makefile b/arch/sh/kernel/cpu/sh4a/Makefile
index c57fb28..0b22d10 100644
--- a/arch/sh/kernel/cpu/sh4a/Makefile
+++ b/arch/sh/kernel/cpu/sh4a/Makefile
@@ -27,9 +27,9 @@
clock-$(CONFIG_CPU_SUBTYPE_SH7785) := clock-sh7785.o
clock-$(CONFIG_CPU_SUBTYPE_SH7786) := clock-sh7786.o
clock-$(CONFIG_CPU_SUBTYPE_SH7343) := clock-sh7343.o
-clock-$(CONFIG_CPU_SUBTYPE_SH7722) := clock-sh7722.o hwblk-sh7722.o
-clock-$(CONFIG_CPU_SUBTYPE_SH7723) := clock-sh7723.o hwblk-sh7723.o
-clock-$(CONFIG_CPU_SUBTYPE_SH7724) := clock-sh7724.o hwblk-sh7724.o
+clock-$(CONFIG_CPU_SUBTYPE_SH7722) := clock-sh7722.o
+clock-$(CONFIG_CPU_SUBTYPE_SH7723) := clock-sh7723.o
+clock-$(CONFIG_CPU_SUBTYPE_SH7724) := clock-sh7724.o
clock-$(CONFIG_CPU_SUBTYPE_SH7366) := clock-sh7366.o
clock-$(CONFIG_CPU_SUBTYPE_SHX3) := clock-shx3.o
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7722.c b/arch/sh/kernel/cpu/sh4a/clock-sh7722.c
index c9a4808..212c72e 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7722.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7722.c
@@ -22,8 +22,8 @@
#include <linux/kernel.h>
#include <linux/io.h>
#include <linux/clkdev.h>
+#include <linux/sh_clk.h>
#include <asm/clock.h>
-#include <asm/hwblk.h>
#include <cpu/sh7722.h>
/* SH7722 registers */
@@ -33,6 +33,9 @@
#define SCLKBCR 0xa415000c
#define IRDACLKCR 0xa4150018
#define PLLCR 0xa4150024
+#define MSTPCR0 0xa4150030
+#define MSTPCR1 0xa4150034
+#define MSTPCR2 0xa4150038
#define DLLFRQ 0xa4150050
/* Fixed 32 KHz root clock for RTC and Power Management purposes */
@@ -148,31 +151,31 @@
};
static struct clk mstp_clks[HWBLK_NR] = {
- SH_HWBLK_CLK(HWBLK_URAM, &div4_clks[DIV4_U], CLK_ENABLE_ON_INIT),
- SH_HWBLK_CLK(HWBLK_XYMEM, &div4_clks[DIV4_B], CLK_ENABLE_ON_INIT),
- SH_HWBLK_CLK(HWBLK_TMU, &div4_clks[DIV4_P], 0),
- SH_HWBLK_CLK(HWBLK_CMT, &r_clk, 0),
- SH_HWBLK_CLK(HWBLK_RWDT, &r_clk, 0),
- SH_HWBLK_CLK(HWBLK_FLCTL, &div4_clks[DIV4_P], 0),
- SH_HWBLK_CLK(HWBLK_SCIF0, &div4_clks[DIV4_P], 0),
- SH_HWBLK_CLK(HWBLK_SCIF1, &div4_clks[DIV4_P], 0),
- SH_HWBLK_CLK(HWBLK_SCIF2, &div4_clks[DIV4_P], 0),
+ [HWBLK_URAM] = SH_CLK_MSTP32(&div4_clks[DIV4_U], MSTPCR0, 28, CLK_ENABLE_ON_INIT),
+ [HWBLK_XYMEM] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR0, 26, CLK_ENABLE_ON_INIT),
+ [HWBLK_TMU] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 15, 0),
+ [HWBLK_CMT] = SH_CLK_MSTP32(&r_clk, MSTPCR0, 14, 0),
+ [HWBLK_RWDT] = SH_CLK_MSTP32(&r_clk, MSTPCR0, 13, 0),
+ [HWBLK_FLCTL] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 10, 0),
+ [HWBLK_SCIF0] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 7, 0),
+ [HWBLK_SCIF1] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 6, 0),
+ [HWBLK_SCIF2] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 5, 0),
- SH_HWBLK_CLK(HWBLK_IIC, &div4_clks[DIV4_P], 0),
- SH_HWBLK_CLK(HWBLK_RTC, &r_clk, 0),
+ [HWBLK_IIC] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR1, 9, 0),
+ [HWBLK_RTC] = SH_CLK_MSTP32(&r_clk, MSTPCR1, 8, 0),
- SH_HWBLK_CLK(HWBLK_SDHI, &div4_clks[DIV4_P], 0),
- SH_HWBLK_CLK(HWBLK_KEYSC, &r_clk, 0),
- SH_HWBLK_CLK(HWBLK_USBF, &div4_clks[DIV4_P], 0),
- SH_HWBLK_CLK(HWBLK_2DG, &div4_clks[DIV4_B], 0),
- SH_HWBLK_CLK(HWBLK_SIU, &div4_clks[DIV4_B], 0),
- SH_HWBLK_CLK(HWBLK_VOU, &div4_clks[DIV4_B], 0),
- SH_HWBLK_CLK(HWBLK_JPU, &div4_clks[DIV4_B], 0),
- SH_HWBLK_CLK(HWBLK_BEU, &div4_clks[DIV4_B], 0),
- SH_HWBLK_CLK(HWBLK_CEU, &div4_clks[DIV4_B], 0),
- SH_HWBLK_CLK(HWBLK_VEU, &div4_clks[DIV4_B], 0),
- SH_HWBLK_CLK(HWBLK_VPU, &div4_clks[DIV4_B], 0),
- SH_HWBLK_CLK(HWBLK_LCDC, &div4_clks[DIV4_P], 0),
+ [HWBLK_SDHI] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR2, 18, 0),
+ [HWBLK_KEYSC] = SH_CLK_MSTP32(&r_clk, MSTPCR2, 14, 0),
+ [HWBLK_USBF] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR2, 11, 0),
+ [HWBLK_2DG] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR2, 9, 0),
+ [HWBLK_SIU] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR2, 8, 0),
+ [HWBLK_JPU] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR2, 6, 0),
+ [HWBLK_VOU] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR2, 5, 0),
+ [HWBLK_BEU] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR2, 4, 0),
+ [HWBLK_CEU] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR2, 3, 0),
+ [HWBLK_VEU] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR2, 2, 0),
+ [HWBLK_VPU] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR2, 1, 0),
+ [HWBLK_LCDC] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR2, 0, 0),
};
static struct clk_lookup lookups[] = {
@@ -205,27 +208,27 @@
CLKDEV_ICK_ID("tmu_fck", "sh_tmu.2", &mstp_clks[HWBLK_TMU]),
CLKDEV_CON_ID("cmt_fck", &mstp_clks[HWBLK_CMT]),
- CLKDEV_CON_ID("rwdt0", &mstp_clks[HWBLK_RWDT]),
+ CLKDEV_DEV_ID("sh-wdt.0", &mstp_clks[HWBLK_RWDT]),
CLKDEV_CON_ID("flctl0", &mstp_clks[HWBLK_FLCTL]),
- CLKDEV_ICK_ID("sci_fck", "sh-sci.0", &mstp_clks[HWBLK_SCIF0]),
- CLKDEV_ICK_ID("sci_fck", "sh-sci.1", &mstp_clks[HWBLK_SCIF1]),
- CLKDEV_ICK_ID("sci_fck", "sh-sci.2", &mstp_clks[HWBLK_SCIF2]),
+ CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[HWBLK_SCIF0]),
+ CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[HWBLK_SCIF1]),
+ CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[HWBLK_SCIF2]),
CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[HWBLK_IIC]),
CLKDEV_CON_ID("rtc0", &mstp_clks[HWBLK_RTC]),
- CLKDEV_CON_ID("sdhi0", &mstp_clks[HWBLK_SDHI]),
- CLKDEV_CON_ID("keysc0", &mstp_clks[HWBLK_KEYSC]),
+ CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[HWBLK_SDHI]),
+ CLKDEV_DEV_ID("sh_keysc.0", &mstp_clks[HWBLK_KEYSC]),
CLKDEV_CON_ID("usbf0", &mstp_clks[HWBLK_USBF]),
CLKDEV_CON_ID("2dg0", &mstp_clks[HWBLK_2DG]),
- CLKDEV_CON_ID("siu0", &mstp_clks[HWBLK_SIU]),
- CLKDEV_CON_ID("vou0", &mstp_clks[HWBLK_VOU]),
+ CLKDEV_DEV_ID("siu-pcm-audio", &mstp_clks[HWBLK_SIU]),
+ CLKDEV_DEV_ID("sh-vou.0", &mstp_clks[HWBLK_VOU]),
CLKDEV_CON_ID("jpu0", &mstp_clks[HWBLK_JPU]),
CLKDEV_CON_ID("beu0", &mstp_clks[HWBLK_BEU]),
- CLKDEV_CON_ID("ceu0", &mstp_clks[HWBLK_CEU]),
+ CLKDEV_DEV_ID("sh_mobile_ceu.0", &mstp_clks[HWBLK_CEU]),
CLKDEV_CON_ID("veu0", &mstp_clks[HWBLK_VEU]),
CLKDEV_CON_ID("vpu0", &mstp_clks[HWBLK_VPU]),
- CLKDEV_CON_ID("lcdc0", &mstp_clks[HWBLK_LCDC]),
+ CLKDEV_DEV_ID("sh_mobile_lcdc_fb.0", &mstp_clks[HWBLK_LCDC]),
};
int __init arch_clk_init(void)
@@ -258,7 +261,7 @@
ret = sh_clk_div6_register(div6_clks, DIV6_NR);
if (!ret)
- ret = sh_hwblk_clk_register(mstp_clks, HWBLK_NR);
+ ret = sh_clk_mstp32_register(mstp_clks, HWBLK_NR);
return ret;
}
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7723.c b/arch/sh/kernel/cpu/sh4a/clock-sh7723.c
index 3cc3827..2f8c917 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7723.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7723.c
@@ -23,8 +23,8 @@
#include <linux/io.h>
#include <linux/clk.h>
#include <linux/clkdev.h>
+#include <linux/sh_clk.h>
#include <asm/clock.h>
-#include <asm/hwblk.h>
#include <cpu/sh7723.h>
/* SH7723 registers */
@@ -34,6 +34,9 @@
#define SCLKBCR 0xa415000c
#define IRDACLKCR 0xa4150018
#define PLLCR 0xa4150024
+#define MSTPCR0 0xa4150030
+#define MSTPCR1 0xa4150034
+#define MSTPCR2 0xa4150038
#define DLLFRQ 0xa4150050
/* Fixed 32 KHz root clock for RTC and Power Management purposes */
@@ -149,55 +152,55 @@
static struct clk mstp_clks[] = {
/* See page 60 of Datasheet V1.0: Overview -> Block Diagram */
- SH_HWBLK_CLK(HWBLK_TLB, &div4_clks[DIV4_I], CLK_ENABLE_ON_INIT),
- SH_HWBLK_CLK(HWBLK_IC, &div4_clks[DIV4_I], CLK_ENABLE_ON_INIT),
- SH_HWBLK_CLK(HWBLK_OC, &div4_clks[DIV4_I], CLK_ENABLE_ON_INIT),
- SH_HWBLK_CLK(HWBLK_L2C, &div4_clks[DIV4_SH], CLK_ENABLE_ON_INIT),
- SH_HWBLK_CLK(HWBLK_ILMEM, &div4_clks[DIV4_I], CLK_ENABLE_ON_INIT),
- SH_HWBLK_CLK(HWBLK_FPU, &div4_clks[DIV4_I], CLK_ENABLE_ON_INIT),
- SH_HWBLK_CLK(HWBLK_INTC, &div4_clks[DIV4_I], CLK_ENABLE_ON_INIT),
- SH_HWBLK_CLK(HWBLK_DMAC0, &div4_clks[DIV4_B], 0),
- SH_HWBLK_CLK(HWBLK_SHYWAY, &div4_clks[DIV4_SH], CLK_ENABLE_ON_INIT),
- SH_HWBLK_CLK(HWBLK_HUDI, &div4_clks[DIV4_P], 0),
- SH_HWBLK_CLK(HWBLK_UBC, &div4_clks[DIV4_I], 0),
- SH_HWBLK_CLK(HWBLK_TMU0, &div4_clks[DIV4_P], 0),
- SH_HWBLK_CLK(HWBLK_CMT, &r_clk, 0),
- SH_HWBLK_CLK(HWBLK_RWDT, &r_clk, 0),
- SH_HWBLK_CLK(HWBLK_DMAC1, &div4_clks[DIV4_B], 0),
- SH_HWBLK_CLK(HWBLK_TMU1, &div4_clks[DIV4_P], 0),
- SH_HWBLK_CLK(HWBLK_FLCTL, &div4_clks[DIV4_P], 0),
- SH_HWBLK_CLK(HWBLK_SCIF0, &div4_clks[DIV4_P], 0),
- SH_HWBLK_CLK(HWBLK_SCIF1, &div4_clks[DIV4_P], 0),
- SH_HWBLK_CLK(HWBLK_SCIF2, &div4_clks[DIV4_P], 0),
- SH_HWBLK_CLK(HWBLK_SCIF3, &div4_clks[DIV4_B], 0),
- SH_HWBLK_CLK(HWBLK_SCIF4, &div4_clks[DIV4_B], 0),
- SH_HWBLK_CLK(HWBLK_SCIF5, &div4_clks[DIV4_B], 0),
- SH_HWBLK_CLK(HWBLK_MSIOF0, &div4_clks[DIV4_B], 0),
- SH_HWBLK_CLK(HWBLK_MSIOF1, &div4_clks[DIV4_B], 0),
- SH_HWBLK_CLK(HWBLK_MERAM, &div4_clks[DIV4_SH], 0),
+ [HWBLK_TLB] = SH_CLK_MSTP32(&div4_clks[DIV4_I], MSTPCR0, 31, CLK_ENABLE_ON_INIT),
+ [HWBLK_IC] = SH_CLK_MSTP32(&div4_clks[DIV4_I], MSTPCR0, 30, CLK_ENABLE_ON_INIT),
+ [HWBLK_OC] = SH_CLK_MSTP32(&div4_clks[DIV4_I], MSTPCR0, 29, CLK_ENABLE_ON_INIT),
+ [HWBLK_L2C] = SH_CLK_MSTP32(&div4_clks[DIV4_SH], MSTPCR0, 28, CLK_ENABLE_ON_INIT),
+ [HWBLK_ILMEM] = SH_CLK_MSTP32(&div4_clks[DIV4_I], MSTPCR0, 27, CLK_ENABLE_ON_INIT),
+ [HWBLK_FPU] = SH_CLK_MSTP32(&div4_clks[DIV4_I], MSTPCR0, 24, CLK_ENABLE_ON_INIT),
+ [HWBLK_INTC] = SH_CLK_MSTP32(&div4_clks[DIV4_I], MSTPCR0, 22, CLK_ENABLE_ON_INIT),
+ [HWBLK_DMAC0] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR0, 21, 0),
+ [HWBLK_SHYWAY] = SH_CLK_MSTP32(&div4_clks[DIV4_SH], MSTPCR0, 20, CLK_ENABLE_ON_INIT),
+ [HWBLK_HUDI] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 19, 0),
+ [HWBLK_UBC] = SH_CLK_MSTP32(&div4_clks[DIV4_I], MSTPCR0, 17, 0),
+ [HWBLK_TMU0] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 15, 0),
+ [HWBLK_CMT] = SH_CLK_MSTP32(&r_clk, MSTPCR0, 14, 0),
+ [HWBLK_RWDT] = SH_CLK_MSTP32(&r_clk, MSTPCR0, 13, 0),
+ [HWBLK_DMAC1] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR0, 12, 0),
+ [HWBLK_TMU1] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 11, 0),
+ [HWBLK_FLCTL] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 10, 0),
+ [HWBLK_SCIF0] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 9, 0),
+ [HWBLK_SCIF1] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 8, 0),
+ [HWBLK_SCIF2] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 7, 0),
+ [HWBLK_SCIF3] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR0, 6, 0),
+ [HWBLK_SCIF4] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR0, 5, 0),
+ [HWBLK_SCIF5] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR0, 4, 0),
+ [HWBLK_MSIOF0] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR0, 2, 0),
+ [HWBLK_MSIOF1] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR0, 1, 0),
+ [HWBLK_MERAM] = SH_CLK_MSTP32(&div4_clks[DIV4_SH], MSTPCR0, 0, 0),
- SH_HWBLK_CLK(HWBLK_IIC, &div4_clks[DIV4_P], 0),
- SH_HWBLK_CLK(HWBLK_RTC, &r_clk, 0),
+ [HWBLK_IIC] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR1, 9, 0),
+ [HWBLK_RTC] = SH_CLK_MSTP32(&r_clk, MSTPCR1, 8, 0),
- SH_HWBLK_CLK(HWBLK_ATAPI, &div4_clks[DIV4_SH], 0),
- SH_HWBLK_CLK(HWBLK_ADC, &div4_clks[DIV4_P], 0),
- SH_HWBLK_CLK(HWBLK_TPU, &div4_clks[DIV4_B], 0),
- SH_HWBLK_CLK(HWBLK_IRDA, &div4_clks[DIV4_P], 0),
- SH_HWBLK_CLK(HWBLK_TSIF, &div4_clks[DIV4_B], 0),
- SH_HWBLK_CLK(HWBLK_ICB, &div4_clks[DIV4_B], CLK_ENABLE_ON_INIT),
- SH_HWBLK_CLK(HWBLK_SDHI0, &div4_clks[DIV4_B], 0),
- SH_HWBLK_CLK(HWBLK_SDHI1, &div4_clks[DIV4_B], 0),
- SH_HWBLK_CLK(HWBLK_KEYSC, &r_clk, 0),
- SH_HWBLK_CLK(HWBLK_USB, &div4_clks[DIV4_B], 0),
- SH_HWBLK_CLK(HWBLK_2DG, &div4_clks[DIV4_B], 0),
- SH_HWBLK_CLK(HWBLK_SIU, &div4_clks[DIV4_B], 0),
- SH_HWBLK_CLK(HWBLK_VEU2H1, &div4_clks[DIV4_B], 0),
- SH_HWBLK_CLK(HWBLK_VOU, &div4_clks[DIV4_B], 0),
- SH_HWBLK_CLK(HWBLK_BEU, &div4_clks[DIV4_B], 0),
- SH_HWBLK_CLK(HWBLK_CEU, &div4_clks[DIV4_B], 0),
- SH_HWBLK_CLK(HWBLK_VEU2H0, &div4_clks[DIV4_B], 0),
- SH_HWBLK_CLK(HWBLK_VPU, &div4_clks[DIV4_B], 0),
- SH_HWBLK_CLK(HWBLK_LCDC, &div4_clks[DIV4_B], 0),
+ [HWBLK_ATAPI] = SH_CLK_MSTP32(&div4_clks[DIV4_SH], MSTPCR2, 28, 0),
+ [HWBLK_ADC] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR2, 27, 0),
+ [HWBLK_TPU] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR2, 25, 0),
+ [HWBLK_IRDA] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR2, 24, 0),
+ [HWBLK_TSIF] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR2, 22, 0),
+ [HWBLK_ICB] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR2, 21, CLK_ENABLE_ON_INIT),
+ [HWBLK_SDHI0] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR2, 18, 0),
+ [HWBLK_SDHI1] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR2, 17, 0),
+ [HWBLK_KEYSC] = SH_CLK_MSTP32(&r_clk, MSTPCR2, 14, 0),
+ [HWBLK_USB] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR2, 11, 0),
+ [HWBLK_2DG] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR2, 10, 0),
+ [HWBLK_SIU] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR2, 8, 0),
+ [HWBLK_VEU2H1] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR2, 6, 0),
+ [HWBLK_VOU] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR2, 5, 0),
+ [HWBLK_BEU] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR2, 4, 0),
+ [HWBLK_CEU] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR2, 3, 0),
+ [HWBLK_VEU2H0] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR2, 2, 0),
+ [HWBLK_VPU] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR2, 1, 0),
+ [HWBLK_LCDC] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR2, 0, 0),
};
static struct clk_lookup lookups[] = {
@@ -229,80 +232,17 @@
CLKDEV_CON_ID("ilmem0", &mstp_clks[HWBLK_ILMEM]),
CLKDEV_CON_ID("fpu0", &mstp_clks[HWBLK_FPU]),
CLKDEV_CON_ID("intc0", &mstp_clks[HWBLK_INTC]),
- CLKDEV_CON_ID("dmac0", &mstp_clks[HWBLK_DMAC0]),
+ CLKDEV_DEV_ID("sh-dma-engine.0", &mstp_clks[HWBLK_DMAC0]),
CLKDEV_CON_ID("sh0", &mstp_clks[HWBLK_SHYWAY]),
CLKDEV_CON_ID("hudi0", &mstp_clks[HWBLK_HUDI]),
CLKDEV_CON_ID("ubc0", &mstp_clks[HWBLK_UBC]),
- {
- /* TMU0 */
- .dev_id = "sh_tmu.0",
- .con_id = "tmu_fck",
- .clk = &mstp_clks[HWBLK_TMU0],
- }, {
- /* TMU1 */
- .dev_id = "sh_tmu.1",
- .con_id = "tmu_fck",
- .clk = &mstp_clks[HWBLK_TMU0],
- }, {
- /* TMU2 */
- .dev_id = "sh_tmu.2",
- .con_id = "tmu_fck",
- .clk = &mstp_clks[HWBLK_TMU0],
- },
CLKDEV_CON_ID("cmt_fck", &mstp_clks[HWBLK_CMT]),
- CLKDEV_CON_ID("rwdt0", &mstp_clks[HWBLK_RWDT]),
- CLKDEV_CON_ID("dmac1", &mstp_clks[HWBLK_DMAC1]),
- {
- /* TMU3 */
- .dev_id = "sh_tmu.3",
- .con_id = "tmu_fck",
- .clk = &mstp_clks[HWBLK_TMU1],
- }, {
- /* TMU4 */
- .dev_id = "sh_tmu.4",
- .con_id = "tmu_fck",
- .clk = &mstp_clks[HWBLK_TMU1],
- }, {
- /* TMU5 */
- .dev_id = "sh_tmu.5",
- .con_id = "tmu_fck",
- .clk = &mstp_clks[HWBLK_TMU1],
- },
+ CLKDEV_DEV_ID("sh-wdt.0", &mstp_clks[HWBLK_RWDT]),
+ CLKDEV_DEV_ID("sh-dma-engine.1", &mstp_clks[HWBLK_DMAC1]),
CLKDEV_CON_ID("flctl0", &mstp_clks[HWBLK_FLCTL]),
- {
- /* SCIF0 */
- .dev_id = "sh-sci.0",
- .con_id = "sci_fck",
- .clk = &mstp_clks[HWBLK_SCIF0],
- }, {
- /* SCIF1 */
- .dev_id = "sh-sci.1",
- .con_id = "sci_fck",
- .clk = &mstp_clks[HWBLK_SCIF1],
- }, {
- /* SCIF2 */
- .dev_id = "sh-sci.2",
- .con_id = "sci_fck",
- .clk = &mstp_clks[HWBLK_SCIF2],
- }, {
- /* SCIF3 */
- .dev_id = "sh-sci.3",
- .con_id = "sci_fck",
- .clk = &mstp_clks[HWBLK_SCIF3],
- }, {
- /* SCIF4 */
- .dev_id = "sh-sci.4",
- .con_id = "sci_fck",
- .clk = &mstp_clks[HWBLK_SCIF4],
- }, {
- /* SCIF5 */
- .dev_id = "sh-sci.5",
- .con_id = "sci_fck",
- .clk = &mstp_clks[HWBLK_SCIF5],
- },
- CLKDEV_CON_ID("msiof0", &mstp_clks[HWBLK_MSIOF0]),
- CLKDEV_CON_ID("msiof1", &mstp_clks[HWBLK_MSIOF1]),
- CLKDEV_CON_ID("meram0", &mstp_clks[HWBLK_MERAM]),
+ CLKDEV_DEV_ID("spi_sh_msiof.0", &mstp_clks[HWBLK_MSIOF0]),
+ CLKDEV_DEV_ID("spi_sh_msiof.1", &mstp_clks[HWBLK_MSIOF1]),
+ CLKDEV_DEV_ID("sh_mobile_meram.0", &mstp_clks[HWBLK_MERAM]),
CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[HWBLK_IIC]),
CLKDEV_CON_ID("rtc0", &mstp_clks[HWBLK_RTC]),
CLKDEV_CON_ID("atapi0", &mstp_clks[HWBLK_ATAPI]),
@@ -311,19 +251,34 @@
CLKDEV_CON_ID("irda0", &mstp_clks[HWBLK_IRDA]),
CLKDEV_CON_ID("tsif0", &mstp_clks[HWBLK_TSIF]),
CLKDEV_CON_ID("icb0", &mstp_clks[HWBLK_ICB]),
- CLKDEV_CON_ID("sdhi0", &mstp_clks[HWBLK_SDHI0]),
- CLKDEV_CON_ID("sdhi1", &mstp_clks[HWBLK_SDHI1]),
- CLKDEV_CON_ID("keysc0", &mstp_clks[HWBLK_KEYSC]),
+ CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[HWBLK_SDHI0]),
+ CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[HWBLK_SDHI1]),
+ CLKDEV_DEV_ID("sh_keysc.0", &mstp_clks[HWBLK_KEYSC]),
CLKDEV_CON_ID("usb0", &mstp_clks[HWBLK_USB]),
CLKDEV_CON_ID("2dg0", &mstp_clks[HWBLK_2DG]),
- CLKDEV_CON_ID("siu0", &mstp_clks[HWBLK_SIU]),
+ CLKDEV_DEV_ID("siu-pcm-audio", &mstp_clks[HWBLK_SIU]),
CLKDEV_CON_ID("veu1", &mstp_clks[HWBLK_VEU2H1]),
- CLKDEV_CON_ID("vou0", &mstp_clks[HWBLK_VOU]),
+ CLKDEV_DEV_ID("sh-vou.0", &mstp_clks[HWBLK_VOU]),
CLKDEV_CON_ID("beu0", &mstp_clks[HWBLK_BEU]),
- CLKDEV_CON_ID("ceu0", &mstp_clks[HWBLK_CEU]),
+ CLKDEV_DEV_ID("sh_mobile_ceu.0", &mstp_clks[HWBLK_CEU]),
CLKDEV_CON_ID("veu0", &mstp_clks[HWBLK_VEU2H0]),
CLKDEV_CON_ID("vpu0", &mstp_clks[HWBLK_VPU]),
- CLKDEV_CON_ID("lcdc0", &mstp_clks[HWBLK_LCDC]),
+
+ CLKDEV_ICK_ID("tmu_fck", "sh_tmu.0", &mstp_clks[HWBLK_TMU0]),
+ CLKDEV_ICK_ID("tmu_fck", "sh_tmu.1", &mstp_clks[HWBLK_TMU0]),
+ CLKDEV_ICK_ID("tmu_fck", "sh_tmu.2", &mstp_clks[HWBLK_TMU0]),
+ CLKDEV_ICK_ID("tmu_fck", "sh_tmu.3", &mstp_clks[HWBLK_TMU1]),
+ CLKDEV_ICK_ID("tmu_fck", "sh_tmu.4", &mstp_clks[HWBLK_TMU1]),
+ CLKDEV_ICK_ID("tmu_fck", "sh_tmu.5", &mstp_clks[HWBLK_TMU1]),
+
+ CLKDEV_ICK_ID("sci_fck", "sh-sci.0", &mstp_clks[HWBLK_SCIF0]),
+ CLKDEV_ICK_ID("sci_fck", "sh-sci.1", &mstp_clks[HWBLK_SCIF1]),
+ CLKDEV_ICK_ID("sci_fck", "sh-sci.2", &mstp_clks[HWBLK_SCIF2]),
+ CLKDEV_ICK_ID("sci_fck", "sh-sci.3", &mstp_clks[HWBLK_SCIF3]),
+ CLKDEV_ICK_ID("sci_fck", "sh-sci.4", &mstp_clks[HWBLK_SCIF4]),
+ CLKDEV_ICK_ID("sci_fck", "sh-sci.5", &mstp_clks[HWBLK_SCIF5]),
+
+ CLKDEV_DEV_ID("sh_mobile_lcdc_fb.0", &mstp_clks[HWBLK_LCDC]),
};
int __init arch_clk_init(void)
@@ -356,7 +311,7 @@
ret = sh_clk_div6_register(div6_clks, DIV6_NR);
if (!ret)
- ret = sh_hwblk_clk_register(mstp_clks, HWBLK_NR);
+ ret = sh_clk_mstp32_register(mstp_clks, HWBLK_NR);
return ret;
}
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7724.c b/arch/sh/kernel/cpu/sh4a/clock-sh7724.c
index 8668f55..b3c039a 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7724.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7724.c
@@ -23,8 +23,8 @@
#include <linux/io.h>
#include <linux/clk.h>
#include <linux/clkdev.h>
+#include <linux/sh_clk.h>
#include <asm/clock.h>
-#include <asm/hwblk.h>
#include <cpu/sh7724.h>
/* SH7724 registers */
@@ -35,6 +35,9 @@
#define FCLKBCR 0xa415000c
#define IRDACLKCR 0xa4150018
#define PLLCR 0xa4150024
+#define MSTPCR0 0xa4150030
+#define MSTPCR1 0xa4150034
+#define MSTPCR2 0xa4150038
#define SPUCLKCR 0xa415003c
#define FLLFRQ 0xa4150050
#define LSTATS 0xa4150060
@@ -111,13 +114,16 @@
.parent = &pll_clk,
};
-/* External input clock (pin name: FSIMCKA/FSIMCKB ) */
+/* External input clock (pin name: FSIMCKA/FSIMCKB/DV_CLKI ) */
struct clk sh7724_fsimcka_clk = {
};
struct clk sh7724_fsimckb_clk = {
};
+struct clk sh7724_dv_clki = {
+};
+
static struct clk *main_clks[] = {
&r_clk,
&extal_clk,
@@ -126,6 +132,7 @@
&div3_clk,
&sh7724_fsimcka_clk,
&sh7724_fsimckb_clk,
+ &sh7724_dv_clki,
};
static void div4_kick(struct clk *clk)
@@ -163,17 +170,20 @@
[DIV4_M1] = DIV4(FRQCRB, 4, 0x2f7c, CLK_ENABLE_ON_INIT),
};
-enum { DIV6_V, DIV6_I, DIV6_S, DIV6_NR };
-
-static struct clk div6_clks[DIV6_NR] = {
- [DIV6_V] = SH_CLK_DIV6(&div3_clk, VCLKCR, 0),
- [DIV6_I] = SH_CLK_DIV6(&div3_clk, IRDACLKCR, 0),
- [DIV6_S] = SH_CLK_DIV6(&div3_clk, SPUCLKCR, CLK_ENABLE_ON_INIT),
-};
-
-enum { DIV6_FA, DIV6_FB, DIV6_REPARENT_NR };
+enum { DIV6_V, DIV6_I, DIV6_S, DIV6_FA, DIV6_FB, DIV6_NR };
/* Indices are important - they are the actual src selecting values */
+static struct clk *common_parent[] = {
+ [0] = &div3_clk,
+ [1] = NULL,
+};
+
+static struct clk *vclkcr_parent[8] = {
+ [0] = &div3_clk,
+ [2] = &sh7724_dv_clki,
+ [4] = &extal_clk,
+};
+
static struct clk *fclkacr_parent[] = {
[0] = &div3_clk,
[1] = NULL,
@@ -188,68 +198,74 @@
[3] = NULL,
};
-static struct clk div6_reparent_clks[DIV6_REPARENT_NR] = {
- [DIV6_FA] = SH_CLK_DIV6_EXT(&div3_clk, FCLKACR, 0,
+static struct clk div6_clks[DIV6_NR] = {
+ [DIV6_V] = SH_CLK_DIV6_EXT(VCLKCR, 0,
+ vclkcr_parent, ARRAY_SIZE(vclkcr_parent), 12, 3),
+ [DIV6_I] = SH_CLK_DIV6_EXT(IRDACLKCR, 0,
+ common_parent, ARRAY_SIZE(common_parent), 6, 1),
+ [DIV6_S] = SH_CLK_DIV6_EXT(SPUCLKCR, CLK_ENABLE_ON_INIT,
+ common_parent, ARRAY_SIZE(common_parent), 6, 1),
+ [DIV6_FA] = SH_CLK_DIV6_EXT(FCLKACR, 0,
fclkacr_parent, ARRAY_SIZE(fclkacr_parent), 6, 2),
- [DIV6_FB] = SH_CLK_DIV6_EXT(&div3_clk, FCLKBCR, 0,
+ [DIV6_FB] = SH_CLK_DIV6_EXT(FCLKBCR, 0,
fclkbcr_parent, ARRAY_SIZE(fclkbcr_parent), 6, 2),
};
static struct clk mstp_clks[HWBLK_NR] = {
- SH_HWBLK_CLK(HWBLK_TLB, &div4_clks[DIV4_I], CLK_ENABLE_ON_INIT),
- SH_HWBLK_CLK(HWBLK_IC, &div4_clks[DIV4_I], CLK_ENABLE_ON_INIT),
- SH_HWBLK_CLK(HWBLK_OC, &div4_clks[DIV4_I], CLK_ENABLE_ON_INIT),
- SH_HWBLK_CLK(HWBLK_RSMEM, &div4_clks[DIV4_B], CLK_ENABLE_ON_INIT),
- SH_HWBLK_CLK(HWBLK_ILMEM, &div4_clks[DIV4_I], CLK_ENABLE_ON_INIT),
- SH_HWBLK_CLK(HWBLK_L2C, &div4_clks[DIV4_SH], CLK_ENABLE_ON_INIT),
- SH_HWBLK_CLK(HWBLK_FPU, &div4_clks[DIV4_I], CLK_ENABLE_ON_INIT),
- SH_HWBLK_CLK(HWBLK_INTC, &div4_clks[DIV4_P], CLK_ENABLE_ON_INIT),
- SH_HWBLK_CLK(HWBLK_DMAC0, &div4_clks[DIV4_B], 0),
- SH_HWBLK_CLK(HWBLK_SHYWAY, &div4_clks[DIV4_SH], CLK_ENABLE_ON_INIT),
- SH_HWBLK_CLK(HWBLK_HUDI, &div4_clks[DIV4_P], 0),
- SH_HWBLK_CLK(HWBLK_UBC, &div4_clks[DIV4_I], 0),
- SH_HWBLK_CLK(HWBLK_TMU0, &div4_clks[DIV4_P], 0),
- SH_HWBLK_CLK(HWBLK_CMT, &r_clk, 0),
- SH_HWBLK_CLK(HWBLK_RWDT, &r_clk, 0),
- SH_HWBLK_CLK(HWBLK_DMAC1, &div4_clks[DIV4_B], 0),
- SH_HWBLK_CLK(HWBLK_TMU1, &div4_clks[DIV4_P], 0),
- SH_HWBLK_CLK(HWBLK_SCIF0, &div4_clks[DIV4_P], 0),
- SH_HWBLK_CLK(HWBLK_SCIF1, &div4_clks[DIV4_P], 0),
- SH_HWBLK_CLK(HWBLK_SCIF2, &div4_clks[DIV4_P], 0),
- SH_HWBLK_CLK(HWBLK_SCIF3, &div4_clks[DIV4_B], 0),
- SH_HWBLK_CLK(HWBLK_SCIF4, &div4_clks[DIV4_B], 0),
- SH_HWBLK_CLK(HWBLK_SCIF5, &div4_clks[DIV4_B], 0),
- SH_HWBLK_CLK(HWBLK_MSIOF0, &div4_clks[DIV4_B], 0),
- SH_HWBLK_CLK(HWBLK_MSIOF1, &div4_clks[DIV4_B], 0),
+ [HWBLK_TLB] = SH_CLK_MSTP32(&div4_clks[DIV4_I], MSTPCR0, 31, CLK_ENABLE_ON_INIT),
+ [HWBLK_IC] = SH_CLK_MSTP32(&div4_clks[DIV4_I], MSTPCR0, 30, CLK_ENABLE_ON_INIT),
+ [HWBLK_OC] = SH_CLK_MSTP32(&div4_clks[DIV4_I], MSTPCR0, 29, CLK_ENABLE_ON_INIT),
+ [HWBLK_RSMEM] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR0, 28, CLK_ENABLE_ON_INIT),
+ [HWBLK_ILMEM] = SH_CLK_MSTP32(&div4_clks[DIV4_I], MSTPCR0, 27, CLK_ENABLE_ON_INIT),
+ [HWBLK_L2C] = SH_CLK_MSTP32(&div4_clks[DIV4_SH], MSTPCR0, 26, CLK_ENABLE_ON_INIT),
+ [HWBLK_FPU] = SH_CLK_MSTP32(&div4_clks[DIV4_I], MSTPCR0, 24, CLK_ENABLE_ON_INIT),
+ [HWBLK_INTC] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 22, CLK_ENABLE_ON_INIT),
+ [HWBLK_DMAC0] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR0, 21, 0),
+ [HWBLK_SHYWAY] = SH_CLK_MSTP32(&div4_clks[DIV4_SH], MSTPCR0, 20, CLK_ENABLE_ON_INIT),
+ [HWBLK_HUDI] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 19, 0),
+ [HWBLK_UBC] = SH_CLK_MSTP32(&div4_clks[DIV4_I], MSTPCR0, 17, 0),
+ [HWBLK_TMU0] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 15, 0),
+ [HWBLK_CMT] = SH_CLK_MSTP32(&r_clk, MSTPCR0, 14, 0),
+ [HWBLK_RWDT] = SH_CLK_MSTP32(&r_clk, MSTPCR0, 13, 0),
+ [HWBLK_DMAC1] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR0, 12, 0),
+ [HWBLK_TMU1] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 10, 0),
+ [HWBLK_SCIF0] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 9, 0),
+ [HWBLK_SCIF1] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 8, 0),
+ [HWBLK_SCIF2] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 7, 0),
+ [HWBLK_SCIF3] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR0, 6, 0),
+ [HWBLK_SCIF4] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR0, 5, 0),
+ [HWBLK_SCIF5] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR0, 4, 0),
+ [HWBLK_MSIOF0] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR0, 2, 0),
+ [HWBLK_MSIOF1] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR0, 1, 0),
- SH_HWBLK_CLK(HWBLK_KEYSC, &r_clk, 0),
- SH_HWBLK_CLK(HWBLK_RTC, &r_clk, 0),
- SH_HWBLK_CLK(HWBLK_IIC0, &div4_clks[DIV4_P], 0),
- SH_HWBLK_CLK(HWBLK_IIC1, &div4_clks[DIV4_P], 0),
+ [HWBLK_KEYSC] = SH_CLK_MSTP32(&r_clk, MSTPCR1, 12, 0),
+ [HWBLK_RTC] = SH_CLK_MSTP32(&r_clk, MSTPCR1, 11, 0),
+ [HWBLK_IIC0] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR1, 9, 0),
+ [HWBLK_IIC1] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR1, 8, 0),
- SH_HWBLK_CLK(HWBLK_MMC, &div4_clks[DIV4_B], 0),
- SH_HWBLK_CLK(HWBLK_ETHER, &div4_clks[DIV4_B], 0),
- SH_HWBLK_CLK(HWBLK_ATAPI, &div4_clks[DIV4_B], 0),
- SH_HWBLK_CLK(HWBLK_TPU, &div4_clks[DIV4_B], 0),
- SH_HWBLK_CLK(HWBLK_IRDA, &div4_clks[DIV4_P], 0),
- SH_HWBLK_CLK(HWBLK_TSIF, &div4_clks[DIV4_B], 0),
- SH_HWBLK_CLK(HWBLK_USB1, &div4_clks[DIV4_B], 0),
- SH_HWBLK_CLK(HWBLK_USB0, &div4_clks[DIV4_B], 0),
- SH_HWBLK_CLK(HWBLK_2DG, &div4_clks[DIV4_B], 0),
- SH_HWBLK_CLK(HWBLK_SDHI0, &div4_clks[DIV4_B], 0),
- SH_HWBLK_CLK(HWBLK_SDHI1, &div4_clks[DIV4_B], 0),
- SH_HWBLK_CLK(HWBLK_VEU1, &div4_clks[DIV4_B], 0),
- SH_HWBLK_CLK(HWBLK_CEU1, &div4_clks[DIV4_B], 0),
- SH_HWBLK_CLK(HWBLK_BEU1, &div4_clks[DIV4_B], 0),
- SH_HWBLK_CLK(HWBLK_2DDMAC, &div4_clks[DIV4_SH], 0),
- SH_HWBLK_CLK(HWBLK_SPU, &div4_clks[DIV4_B], 0),
- SH_HWBLK_CLK(HWBLK_JPU, &div4_clks[DIV4_B], 0),
- SH_HWBLK_CLK(HWBLK_VOU, &div4_clks[DIV4_B], 0),
- SH_HWBLK_CLK(HWBLK_BEU0, &div4_clks[DIV4_B], 0),
- SH_HWBLK_CLK(HWBLK_CEU0, &div4_clks[DIV4_B], 0),
- SH_HWBLK_CLK(HWBLK_VEU0, &div4_clks[DIV4_B], 0),
- SH_HWBLK_CLK(HWBLK_VPU, &div4_clks[DIV4_B], 0),
- SH_HWBLK_CLK(HWBLK_LCDC, &div4_clks[DIV4_B], 0),
+ [HWBLK_MMC] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR2, 29, 0),
+ [HWBLK_ETHER] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR2, 28, 0),
+ [HWBLK_ATAPI] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR2, 26, 0),
+ [HWBLK_TPU] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR2, 25, 0),
+ [HWBLK_IRDA] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR2, 24, 0),
+ [HWBLK_TSIF] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR2, 22, 0),
+ [HWBLK_USB1] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR2, 21, 0),
+ [HWBLK_USB0] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR2, 20, 0),
+ [HWBLK_2DG] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR2, 19, 0),
+ [HWBLK_SDHI0] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR2, 18, 0),
+ [HWBLK_SDHI1] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR2, 17, 0),
+ [HWBLK_VEU1] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR2, 15, 0),
+ [HWBLK_CEU1] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR2, 13, 0),
+ [HWBLK_BEU1] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR2, 12, 0),
+ [HWBLK_2DDMAC] = SH_CLK_MSTP32(&div4_clks[DIV4_SH], MSTPCR2, 10, 0),
+ [HWBLK_SPU] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR2, 9, 0),
+ [HWBLK_JPU] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR2, 6, 0),
+ [HWBLK_VOU] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR2, 5, 0),
+ [HWBLK_BEU0] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR2, 4, 0),
+ [HWBLK_CEU0] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR2, 3, 0),
+ [HWBLK_VEU0] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR2, 2, 0),
+ [HWBLK_VPU] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR2, 1, 0),
+ [HWBLK_LCDC] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR2, 0, 0),
};
static struct clk_lookup lookups[] = {
@@ -269,8 +285,8 @@
/* DIV6 clocks */
CLKDEV_CON_ID("video_clk", &div6_clks[DIV6_V]),
- CLKDEV_CON_ID("fsia_clk", &div6_reparent_clks[DIV6_FA]),
- CLKDEV_CON_ID("fsib_clk", &div6_reparent_clks[DIV6_FB]),
+ CLKDEV_CON_ID("fsia_clk", &div6_clks[DIV6_FA]),
+ CLKDEV_CON_ID("fsib_clk", &div6_clks[DIV6_FB]),
CLKDEV_CON_ID("irda_clk", &div6_clks[DIV6_I]),
CLKDEV_CON_ID("spu_clk", &div6_clks[DIV6_S]),
@@ -283,7 +299,7 @@
CLKDEV_CON_ID("l2c0", &mstp_clks[HWBLK_L2C]),
CLKDEV_CON_ID("fpu0", &mstp_clks[HWBLK_FPU]),
CLKDEV_CON_ID("intc0", &mstp_clks[HWBLK_INTC]),
- CLKDEV_CON_ID("dmac0", &mstp_clks[HWBLK_DMAC0]),
+ CLKDEV_DEV_ID("sh-dma-engine.0", &mstp_clks[HWBLK_DMAC0]),
CLKDEV_CON_ID("sh0", &mstp_clks[HWBLK_SHYWAY]),
CLKDEV_CON_ID("hudi0", &mstp_clks[HWBLK_HUDI]),
CLKDEV_CON_ID("ubc0", &mstp_clks[HWBLK_UBC]),
@@ -294,26 +310,26 @@
CLKDEV_ICK_ID("tmu_fck", "sh_tmu.3", &mstp_clks[HWBLK_TMU1]),
CLKDEV_CON_ID("cmt_fck", &mstp_clks[HWBLK_CMT]),
- CLKDEV_CON_ID("rwdt0", &mstp_clks[HWBLK_RWDT]),
- CLKDEV_CON_ID("dmac1", &mstp_clks[HWBLK_DMAC1]),
+ CLKDEV_DEV_ID("sh-wdt.0", &mstp_clks[HWBLK_RWDT]),
+ CLKDEV_DEV_ID("sh-dma-engine.1", &mstp_clks[HWBLK_DMAC1]),
CLKDEV_ICK_ID("tmu_fck", "sh_tmu.4", &mstp_clks[HWBLK_TMU1]),
CLKDEV_ICK_ID("tmu_fck", "sh_tmu.5", &mstp_clks[HWBLK_TMU1]),
- CLKDEV_ICK_ID("sci_fck", "sh-sci.0", &mstp_clks[HWBLK_SCIF0]),
- CLKDEV_ICK_ID("sci_fck", "sh-sci.1", &mstp_clks[HWBLK_SCIF1]),
- CLKDEV_ICK_ID("sci_fck", "sh-sci.2", &mstp_clks[HWBLK_SCIF2]),
- CLKDEV_ICK_ID("sci_fck", "sh-sci.3", &mstp_clks[HWBLK_SCIF3]),
- CLKDEV_ICK_ID("sci_fck", "sh-sci.4", &mstp_clks[HWBLK_SCIF4]),
- CLKDEV_ICK_ID("sci_fck", "sh-sci.5", &mstp_clks[HWBLK_SCIF5]),
+ CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[HWBLK_SCIF0]),
+ CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[HWBLK_SCIF1]),
+ CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[HWBLK_SCIF2]),
+ CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[HWBLK_SCIF3]),
+ CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[HWBLK_SCIF4]),
+ CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[HWBLK_SCIF5]),
- CLKDEV_CON_ID("msiof0", &mstp_clks[HWBLK_MSIOF0]),
- CLKDEV_CON_ID("msiof1", &mstp_clks[HWBLK_MSIOF1]),
- CLKDEV_CON_ID("keysc0", &mstp_clks[HWBLK_KEYSC]),
+ CLKDEV_DEV_ID("spi_sh_msiof.0", &mstp_clks[HWBLK_MSIOF0]),
+ CLKDEV_DEV_ID("spi_sh_msiof.1", &mstp_clks[HWBLK_MSIOF1]),
+ CLKDEV_DEV_ID("sh_keysc.0", &mstp_clks[HWBLK_KEYSC]),
CLKDEV_CON_ID("rtc0", &mstp_clks[HWBLK_RTC]),
CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[HWBLK_IIC0]),
CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[HWBLK_IIC1]),
- CLKDEV_CON_ID("mmc0", &mstp_clks[HWBLK_MMC]),
- CLKDEV_CON_ID("eth0", &mstp_clks[HWBLK_ETHER]),
+ CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[HWBLK_MMC]),
+ CLKDEV_DEV_ID("sh-eth.0", &mstp_clks[HWBLK_ETHER]),
CLKDEV_CON_ID("atapi0", &mstp_clks[HWBLK_ATAPI]),
CLKDEV_CON_ID("tpu0", &mstp_clks[HWBLK_TPU]),
CLKDEV_CON_ID("irda0", &mstp_clks[HWBLK_IRDA]),
@@ -321,20 +337,20 @@
CLKDEV_CON_ID("usb1", &mstp_clks[HWBLK_USB1]),
CLKDEV_CON_ID("usb0", &mstp_clks[HWBLK_USB0]),
CLKDEV_CON_ID("2dg0", &mstp_clks[HWBLK_2DG]),
- CLKDEV_CON_ID("sdhi0", &mstp_clks[HWBLK_SDHI0]),
- CLKDEV_CON_ID("sdhi1", &mstp_clks[HWBLK_SDHI1]),
+ CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[HWBLK_SDHI0]),
+ CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[HWBLK_SDHI1]),
CLKDEV_CON_ID("veu1", &mstp_clks[HWBLK_VEU1]),
- CLKDEV_CON_ID("ceu1", &mstp_clks[HWBLK_CEU1]),
+ CLKDEV_DEV_ID("sh_mobile_ceu.1", &mstp_clks[HWBLK_CEU1]),
CLKDEV_CON_ID("beu1", &mstp_clks[HWBLK_BEU1]),
CLKDEV_CON_ID("2ddmac0", &mstp_clks[HWBLK_2DDMAC]),
CLKDEV_CON_ID("spu0", &mstp_clks[HWBLK_SPU]),
CLKDEV_CON_ID("jpu0", &mstp_clks[HWBLK_JPU]),
- CLKDEV_CON_ID("vou0", &mstp_clks[HWBLK_VOU]),
+ CLKDEV_DEV_ID("sh-vou.0", &mstp_clks[HWBLK_VOU]),
CLKDEV_CON_ID("beu0", &mstp_clks[HWBLK_BEU0]),
- CLKDEV_CON_ID("ceu0", &mstp_clks[HWBLK_CEU0]),
+ CLKDEV_DEV_ID("sh_mobile_ceu.0", &mstp_clks[HWBLK_CEU0]),
CLKDEV_CON_ID("veu0", &mstp_clks[HWBLK_VEU0]),
CLKDEV_CON_ID("vpu0", &mstp_clks[HWBLK_VPU]),
- CLKDEV_CON_ID("lcdc0", &mstp_clks[HWBLK_LCDC]),
+ CLKDEV_DEV_ID("sh_mobile_lcdc_fb.0", &mstp_clks[HWBLK_LCDC]),
};
int __init arch_clk_init(void)
@@ -356,13 +372,10 @@
ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table);
if (!ret)
- ret = sh_clk_div6_register(div6_clks, DIV6_NR);
+ ret = sh_clk_div6_reparent_register(div6_clks, DIV6_NR);
if (!ret)
- ret = sh_clk_div6_reparent_register(div6_reparent_clks, DIV6_REPARENT_NR);
-
- if (!ret)
- ret = sh_hwblk_clk_register(mstp_clks, HWBLK_NR);
+ ret = sh_clk_mstp32_register(mstp_clks, HWBLK_NR);
return ret;
}
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7757.c b/arch/sh/kernel/cpu/sh4a/clock-sh7757.c
index 19222da..0fbff14 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7757.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7757.c
@@ -129,7 +129,7 @@
CLKDEV_ICK_ID("sci_fck", "sh-sci.0", &mstp_clks[MSTP110]),
CLKDEV_CON_ID("usb_fck", &mstp_clks[MSTP103]),
- CLKDEV_CON_ID("usb0", &mstp_clks[MSTP102]),
+ CLKDEV_DEV_ID("renesas_usbhs.0", &mstp_clks[MSTP102]),
CLKDEV_CON_ID("mmc0", &mstp_clks[MSTP220]),
};
diff --git a/arch/sh/kernel/cpu/sh4a/hwblk-sh7722.c b/arch/sh/kernel/cpu/sh4a/hwblk-sh7722.c
deleted file mode 100644
index a288b5d..0000000
--- a/arch/sh/kernel/cpu/sh4a/hwblk-sh7722.c
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * arch/sh/kernel/cpu/sh4a/hwblk-sh7722.c
- *
- * SH7722 hardware block support
- *
- * Copyright (C) 2009 Magnus Damm
- *
- * 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
- *
- * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/io.h>
-#include <asm/suspend.h>
-#include <asm/hwblk.h>
-#include <cpu/sh7722.h>
-
-/* SH7722 registers */
-#define MSTPCR0 0xa4150030
-#define MSTPCR1 0xa4150034
-#define MSTPCR2 0xa4150038
-
-/* SH7722 Power Domains */
-enum { CORE_AREA, SUB_AREA, CORE_AREA_BM };
-static struct hwblk_area sh7722_hwblk_area[] = {
- [CORE_AREA] = HWBLK_AREA(0, 0),
- [CORE_AREA_BM] = HWBLK_AREA(HWBLK_AREA_FLAG_PARENT, CORE_AREA),
- [SUB_AREA] = HWBLK_AREA(0, 0),
-};
-
-/* Table mapping HWBLK to Module Stop Bit and Power Domain */
-static struct hwblk sh7722_hwblk[HWBLK_NR] = {
- [HWBLK_TLB] = HWBLK(MSTPCR0, 31, CORE_AREA),
- [HWBLK_IC] = HWBLK(MSTPCR0, 30, CORE_AREA),
- [HWBLK_OC] = HWBLK(MSTPCR0, 29, CORE_AREA),
- [HWBLK_URAM] = HWBLK(MSTPCR0, 28, CORE_AREA),
- [HWBLK_XYMEM] = HWBLK(MSTPCR0, 26, CORE_AREA),
- [HWBLK_INTC] = HWBLK(MSTPCR0, 22, CORE_AREA),
- [HWBLK_DMAC] = HWBLK(MSTPCR0, 21, CORE_AREA_BM),
- [HWBLK_SHYWAY] = HWBLK(MSTPCR0, 20, CORE_AREA),
- [HWBLK_HUDI] = HWBLK(MSTPCR0, 19, CORE_AREA),
- [HWBLK_UBC] = HWBLK(MSTPCR0, 17, CORE_AREA),
- [HWBLK_TMU] = HWBLK(MSTPCR0, 15, CORE_AREA),
- [HWBLK_CMT] = HWBLK(MSTPCR0, 14, SUB_AREA),
- [HWBLK_RWDT] = HWBLK(MSTPCR0, 13, SUB_AREA),
- [HWBLK_FLCTL] = HWBLK(MSTPCR0, 10, CORE_AREA),
- [HWBLK_SCIF0] = HWBLK(MSTPCR0, 7, CORE_AREA),
- [HWBLK_SCIF1] = HWBLK(MSTPCR0, 6, CORE_AREA),
- [HWBLK_SCIF2] = HWBLK(MSTPCR0, 5, CORE_AREA),
- [HWBLK_SIO] = HWBLK(MSTPCR0, 3, CORE_AREA),
- [HWBLK_SIOF0] = HWBLK(MSTPCR0, 2, CORE_AREA),
- [HWBLK_SIOF1] = HWBLK(MSTPCR0, 1, CORE_AREA),
-
- [HWBLK_IIC] = HWBLK(MSTPCR1, 9, CORE_AREA),
- [HWBLK_RTC] = HWBLK(MSTPCR1, 8, SUB_AREA),
-
- [HWBLK_TPU] = HWBLK(MSTPCR2, 25, CORE_AREA),
- [HWBLK_IRDA] = HWBLK(MSTPCR2, 24, CORE_AREA),
- [HWBLK_SDHI] = HWBLK(MSTPCR2, 18, CORE_AREA),
- [HWBLK_SIM] = HWBLK(MSTPCR2, 16, CORE_AREA),
- [HWBLK_KEYSC] = HWBLK(MSTPCR2, 14, SUB_AREA),
- [HWBLK_TSIF] = HWBLK(MSTPCR2, 13, SUB_AREA),
- [HWBLK_USBF] = HWBLK(MSTPCR2, 11, CORE_AREA),
- [HWBLK_2DG] = HWBLK(MSTPCR2, 9, CORE_AREA_BM),
- [HWBLK_SIU] = HWBLK(MSTPCR2, 8, CORE_AREA),
- [HWBLK_JPU] = HWBLK(MSTPCR2, 6, CORE_AREA_BM),
- [HWBLK_VOU] = HWBLK(MSTPCR2, 5, CORE_AREA_BM),
- [HWBLK_BEU] = HWBLK(MSTPCR2, 4, CORE_AREA_BM),
- [HWBLK_CEU] = HWBLK(MSTPCR2, 3, CORE_AREA_BM),
- [HWBLK_VEU] = HWBLK(MSTPCR2, 2, CORE_AREA_BM),
- [HWBLK_VPU] = HWBLK(MSTPCR2, 1, CORE_AREA_BM),
- [HWBLK_LCDC] = HWBLK(MSTPCR2, 0, CORE_AREA_BM),
-};
-
-static struct hwblk_info sh7722_hwblk_info = {
- .areas = sh7722_hwblk_area,
- .nr_areas = ARRAY_SIZE(sh7722_hwblk_area),
- .hwblks = sh7722_hwblk,
- .nr_hwblks = ARRAY_SIZE(sh7722_hwblk),
-};
-
-int arch_hwblk_sleep_mode(void)
-{
- if (!sh7722_hwblk_area[CORE_AREA].cnt[HWBLK_CNT_USAGE])
- return SUSP_SH_STANDBY | SUSP_SH_SF;
-
- if (!sh7722_hwblk_area[CORE_AREA_BM].cnt[HWBLK_CNT_USAGE])
- return SUSP_SH_SLEEP | SUSP_SH_SF;
-
- return SUSP_SH_SLEEP;
-}
-
-int __init arch_hwblk_init(void)
-{
- return hwblk_register(&sh7722_hwblk_info);
-}
diff --git a/arch/sh/kernel/cpu/sh4a/hwblk-sh7723.c b/arch/sh/kernel/cpu/sh4a/hwblk-sh7723.c
deleted file mode 100644
index a7f4684..0000000
--- a/arch/sh/kernel/cpu/sh4a/hwblk-sh7723.c
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * arch/sh/kernel/cpu/sh4a/hwblk-sh7723.c
- *
- * SH7723 hardware block support
- *
- * Copyright (C) 2009 Magnus Damm
- *
- * 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
- *
- * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/io.h>
-#include <asm/suspend.h>
-#include <asm/hwblk.h>
-#include <cpu/sh7723.h>
-
-/* SH7723 registers */
-#define MSTPCR0 0xa4150030
-#define MSTPCR1 0xa4150034
-#define MSTPCR2 0xa4150038
-
-/* SH7723 Power Domains */
-enum { CORE_AREA, SUB_AREA, CORE_AREA_BM };
-static struct hwblk_area sh7723_hwblk_area[] = {
- [CORE_AREA] = HWBLK_AREA(0, 0),
- [CORE_AREA_BM] = HWBLK_AREA(HWBLK_AREA_FLAG_PARENT, CORE_AREA),
- [SUB_AREA] = HWBLK_AREA(0, 0),
-};
-
-/* Table mapping HWBLK to Module Stop Bit and Power Domain */
-static struct hwblk sh7723_hwblk[HWBLK_NR] = {
- [HWBLK_TLB] = HWBLK(MSTPCR0, 31, CORE_AREA),
- [HWBLK_IC] = HWBLK(MSTPCR0, 30, CORE_AREA),
- [HWBLK_OC] = HWBLK(MSTPCR0, 29, CORE_AREA),
- [HWBLK_L2C] = HWBLK(MSTPCR0, 28, CORE_AREA),
- [HWBLK_ILMEM] = HWBLK(MSTPCR0, 27, CORE_AREA),
- [HWBLK_FPU] = HWBLK(MSTPCR0, 24, CORE_AREA),
- [HWBLK_INTC] = HWBLK(MSTPCR0, 22, CORE_AREA),
- [HWBLK_DMAC0] = HWBLK(MSTPCR0, 21, CORE_AREA_BM),
- [HWBLK_SHYWAY] = HWBLK(MSTPCR0, 20, CORE_AREA),
- [HWBLK_HUDI] = HWBLK(MSTPCR0, 19, CORE_AREA),
- [HWBLK_DBG] = HWBLK(MSTPCR0, 18, CORE_AREA),
- [HWBLK_UBC] = HWBLK(MSTPCR0, 17, CORE_AREA),
- [HWBLK_SUBC] = HWBLK(MSTPCR0, 16, CORE_AREA),
- [HWBLK_TMU0] = HWBLK(MSTPCR0, 15, CORE_AREA),
- [HWBLK_CMT] = HWBLK(MSTPCR0, 14, SUB_AREA),
- [HWBLK_RWDT] = HWBLK(MSTPCR0, 13, SUB_AREA),
- [HWBLK_DMAC1] = HWBLK(MSTPCR0, 12, CORE_AREA_BM),
- [HWBLK_TMU1] = HWBLK(MSTPCR0, 11, CORE_AREA),
- [HWBLK_FLCTL] = HWBLK(MSTPCR0, 10, CORE_AREA),
- [HWBLK_SCIF0] = HWBLK(MSTPCR0, 9, CORE_AREA),
- [HWBLK_SCIF1] = HWBLK(MSTPCR0, 8, CORE_AREA),
- [HWBLK_SCIF2] = HWBLK(MSTPCR0, 7, CORE_AREA),
- [HWBLK_SCIF3] = HWBLK(MSTPCR0, 6, CORE_AREA),
- [HWBLK_SCIF4] = HWBLK(MSTPCR0, 5, CORE_AREA),
- [HWBLK_SCIF5] = HWBLK(MSTPCR0, 4, CORE_AREA),
- [HWBLK_MSIOF0] = HWBLK(MSTPCR0, 2, CORE_AREA),
- [HWBLK_MSIOF1] = HWBLK(MSTPCR0, 1, CORE_AREA),
- [HWBLK_MERAM] = HWBLK(MSTPCR0, 0, CORE_AREA),
-
- [HWBLK_IIC] = HWBLK(MSTPCR1, 9, CORE_AREA),
- [HWBLK_RTC] = HWBLK(MSTPCR1, 8, SUB_AREA),
-
- [HWBLK_ATAPI] = HWBLK(MSTPCR2, 28, CORE_AREA_BM),
- [HWBLK_ADC] = HWBLK(MSTPCR2, 27, CORE_AREA),
- [HWBLK_TPU] = HWBLK(MSTPCR2, 25, CORE_AREA),
- [HWBLK_IRDA] = HWBLK(MSTPCR2, 24, CORE_AREA),
- [HWBLK_TSIF] = HWBLK(MSTPCR2, 22, CORE_AREA),
- [HWBLK_ICB] = HWBLK(MSTPCR2, 21, CORE_AREA_BM),
- [HWBLK_SDHI0] = HWBLK(MSTPCR2, 18, CORE_AREA),
- [HWBLK_SDHI1] = HWBLK(MSTPCR2, 17, CORE_AREA),
- [HWBLK_KEYSC] = HWBLK(MSTPCR2, 14, SUB_AREA),
- [HWBLK_USB] = HWBLK(MSTPCR2, 11, CORE_AREA),
- [HWBLK_2DG] = HWBLK(MSTPCR2, 10, CORE_AREA_BM),
- [HWBLK_SIU] = HWBLK(MSTPCR2, 8, CORE_AREA),
- [HWBLK_VEU2H1] = HWBLK(MSTPCR2, 6, CORE_AREA_BM),
- [HWBLK_VOU] = HWBLK(MSTPCR2, 5, CORE_AREA_BM),
- [HWBLK_BEU] = HWBLK(MSTPCR2, 4, CORE_AREA_BM),
- [HWBLK_CEU] = HWBLK(MSTPCR2, 3, CORE_AREA_BM),
- [HWBLK_VEU2H0] = HWBLK(MSTPCR2, 2, CORE_AREA_BM),
- [HWBLK_VPU] = HWBLK(MSTPCR2, 1, CORE_AREA_BM),
- [HWBLK_LCDC] = HWBLK(MSTPCR2, 0, CORE_AREA_BM),
-};
-
-static struct hwblk_info sh7723_hwblk_info = {
- .areas = sh7723_hwblk_area,
- .nr_areas = ARRAY_SIZE(sh7723_hwblk_area),
- .hwblks = sh7723_hwblk,
- .nr_hwblks = ARRAY_SIZE(sh7723_hwblk),
-};
-
-int arch_hwblk_sleep_mode(void)
-{
- if (!sh7723_hwblk_area[CORE_AREA].cnt[HWBLK_CNT_USAGE])
- return SUSP_SH_STANDBY | SUSP_SH_SF;
-
- if (!sh7723_hwblk_area[CORE_AREA_BM].cnt[HWBLK_CNT_USAGE])
- return SUSP_SH_SLEEP | SUSP_SH_SF;
-
- return SUSP_SH_SLEEP;
-}
-
-int __init arch_hwblk_init(void)
-{
- return hwblk_register(&sh7723_hwblk_info);
-}
diff --git a/arch/sh/kernel/cpu/sh4a/hwblk-sh7724.c b/arch/sh/kernel/cpu/sh4a/hwblk-sh7724.c
deleted file mode 100644
index 1613ad6..0000000
--- a/arch/sh/kernel/cpu/sh4a/hwblk-sh7724.c
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * arch/sh/kernel/cpu/sh4a/hwblk-sh7724.c
- *
- * SH7724 hardware block support
- *
- * Copyright (C) 2009 Magnus Damm
- *
- * 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
- *
- * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/io.h>
-#include <asm/suspend.h>
-#include <asm/hwblk.h>
-#include <cpu/sh7724.h>
-
-/* SH7724 registers */
-#define MSTPCR0 0xa4150030
-#define MSTPCR1 0xa4150034
-#define MSTPCR2 0xa4150038
-
-/* SH7724 Power Domains */
-enum { CORE_AREA, SUB_AREA, CORE_AREA_BM };
-static struct hwblk_area sh7724_hwblk_area[] = {
- [CORE_AREA] = HWBLK_AREA(0, 0),
- [CORE_AREA_BM] = HWBLK_AREA(HWBLK_AREA_FLAG_PARENT, CORE_AREA),
- [SUB_AREA] = HWBLK_AREA(0, 0),
-};
-
-/* Table mapping HWBLK to Module Stop Bit and Power Domain */
-static struct hwblk sh7724_hwblk[HWBLK_NR] = {
- [HWBLK_TLB] = HWBLK(MSTPCR0, 31, CORE_AREA),
- [HWBLK_IC] = HWBLK(MSTPCR0, 30, CORE_AREA),
- [HWBLK_OC] = HWBLK(MSTPCR0, 29, CORE_AREA),
- [HWBLK_RSMEM] = HWBLK(MSTPCR0, 28, CORE_AREA),
- [HWBLK_ILMEM] = HWBLK(MSTPCR0, 27, CORE_AREA),
- [HWBLK_L2C] = HWBLK(MSTPCR0, 26, CORE_AREA),
- [HWBLK_FPU] = HWBLK(MSTPCR0, 24, CORE_AREA),
- [HWBLK_INTC] = HWBLK(MSTPCR0, 22, CORE_AREA),
- [HWBLK_DMAC0] = HWBLK(MSTPCR0, 21, CORE_AREA_BM),
- [HWBLK_SHYWAY] = HWBLK(MSTPCR0, 20, CORE_AREA),
- [HWBLK_HUDI] = HWBLK(MSTPCR0, 19, CORE_AREA),
- [HWBLK_DBG] = HWBLK(MSTPCR0, 18, CORE_AREA),
- [HWBLK_UBC] = HWBLK(MSTPCR0, 17, CORE_AREA),
- [HWBLK_TMU0] = HWBLK(MSTPCR0, 15, CORE_AREA),
- [HWBLK_CMT] = HWBLK(MSTPCR0, 14, SUB_AREA),
- [HWBLK_RWDT] = HWBLK(MSTPCR0, 13, SUB_AREA),
- [HWBLK_DMAC1] = HWBLK(MSTPCR0, 12, CORE_AREA_BM),
- [HWBLK_TMU1] = HWBLK(MSTPCR0, 10, CORE_AREA),
- [HWBLK_SCIF0] = HWBLK(MSTPCR0, 9, CORE_AREA),
- [HWBLK_SCIF1] = HWBLK(MSTPCR0, 8, CORE_AREA),
- [HWBLK_SCIF2] = HWBLK(MSTPCR0, 7, CORE_AREA),
- [HWBLK_SCIF3] = HWBLK(MSTPCR0, 6, CORE_AREA),
- [HWBLK_SCIF4] = HWBLK(MSTPCR0, 5, CORE_AREA),
- [HWBLK_SCIF5] = HWBLK(MSTPCR0, 4, CORE_AREA),
- [HWBLK_MSIOF0] = HWBLK(MSTPCR0, 2, CORE_AREA),
- [HWBLK_MSIOF1] = HWBLK(MSTPCR0, 1, CORE_AREA),
-
- [HWBLK_KEYSC] = HWBLK(MSTPCR1, 12, SUB_AREA),
- [HWBLK_RTC] = HWBLK(MSTPCR1, 11, SUB_AREA),
- [HWBLK_IIC0] = HWBLK(MSTPCR1, 9, CORE_AREA),
- [HWBLK_IIC1] = HWBLK(MSTPCR1, 8, CORE_AREA),
-
- [HWBLK_MMC] = HWBLK(MSTPCR2, 29, CORE_AREA),
- [HWBLK_ETHER] = HWBLK(MSTPCR2, 28, CORE_AREA_BM),
- [HWBLK_ATAPI] = HWBLK(MSTPCR2, 26, CORE_AREA_BM),
- [HWBLK_TPU] = HWBLK(MSTPCR2, 25, CORE_AREA),
- [HWBLK_IRDA] = HWBLK(MSTPCR2, 24, CORE_AREA),
- [HWBLK_TSIF] = HWBLK(MSTPCR2, 22, CORE_AREA),
- [HWBLK_USB1] = HWBLK(MSTPCR2, 21, CORE_AREA),
- [HWBLK_USB0] = HWBLK(MSTPCR2, 20, CORE_AREA),
- [HWBLK_2DG] = HWBLK(MSTPCR2, 19, CORE_AREA_BM),
- [HWBLK_SDHI0] = HWBLK(MSTPCR2, 18, CORE_AREA),
- [HWBLK_SDHI1] = HWBLK(MSTPCR2, 17, CORE_AREA),
- [HWBLK_VEU1] = HWBLK(MSTPCR2, 15, CORE_AREA_BM),
- [HWBLK_CEU1] = HWBLK(MSTPCR2, 13, CORE_AREA_BM),
- [HWBLK_BEU1] = HWBLK(MSTPCR2, 12, CORE_AREA_BM),
- [HWBLK_2DDMAC] = HWBLK(MSTPCR2, 10, CORE_AREA_BM),
- [HWBLK_SPU] = HWBLK(MSTPCR2, 9, CORE_AREA_BM),
- [HWBLK_JPU] = HWBLK(MSTPCR2, 6, CORE_AREA_BM),
- [HWBLK_VOU] = HWBLK(MSTPCR2, 5, CORE_AREA_BM),
- [HWBLK_BEU0] = HWBLK(MSTPCR2, 4, CORE_AREA_BM),
- [HWBLK_CEU0] = HWBLK(MSTPCR2, 3, CORE_AREA_BM),
- [HWBLK_VEU0] = HWBLK(MSTPCR2, 2, CORE_AREA_BM),
- [HWBLK_VPU] = HWBLK(MSTPCR2, 1, CORE_AREA_BM),
- [HWBLK_LCDC] = HWBLK(MSTPCR2, 0, CORE_AREA_BM),
-};
-
-static struct hwblk_info sh7724_hwblk_info = {
- .areas = sh7724_hwblk_area,
- .nr_areas = ARRAY_SIZE(sh7724_hwblk_area),
- .hwblks = sh7724_hwblk,
- .nr_hwblks = ARRAY_SIZE(sh7724_hwblk),
-};
-
-int arch_hwblk_sleep_mode(void)
-{
- if (!sh7724_hwblk_area[CORE_AREA].cnt[HWBLK_CNT_USAGE])
- return SUSP_SH_STANDBY | SUSP_SH_SF;
-
- if (!sh7724_hwblk_area[CORE_AREA_BM].cnt[HWBLK_CNT_USAGE])
- return SUSP_SH_SLEEP | SUSP_SH_SF;
-
- return SUSP_SH_SLEEP;
-}
-
-int __init arch_hwblk_init(void)
-{
- return hwblk_register(&sh7724_hwblk_info);
-}
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c
index 278a0e5..8420d4b 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c
@@ -146,7 +146,7 @@
.flags = IORESOURCE_MEM,
},
{
- /* DMA error IRQ */
+ .name = "error_irq",
.start = 78,
.end = 78,
.flags = IORESOURCE_IRQ,
@@ -173,9 +173,6 @@
.dev = {
.platform_data = &dma_platform_data,
},
- .archdata = {
- .hwblk_id = HWBLK_DMAC,
- },
};
/* Serial */
@@ -264,9 +261,6 @@
.id = -1,
.num_resources = ARRAY_SIZE(rtc_resources),
.resource = rtc_resources,
- .archdata = {
- .hwblk_id = HWBLK_RTC,
- },
};
static struct m66592_platdata usbf_platdata = {
@@ -297,9 +291,6 @@
},
.num_resources = ARRAY_SIZE(usbf_resources),
.resource = usbf_resources,
- .archdata = {
- .hwblk_id = HWBLK_USBF,
- },
};
static struct resource iic_resources[] = {
@@ -321,9 +312,6 @@
.id = 0, /* "i2c0" clock */
.num_resources = ARRAY_SIZE(iic_resources),
.resource = iic_resources,
- .archdata = {
- .hwblk_id = HWBLK_IIC,
- },
};
static struct uio_info vpu_platform_data = {
@@ -352,9 +340,6 @@
},
.resource = vpu_resources,
.num_resources = ARRAY_SIZE(vpu_resources),
- .archdata = {
- .hwblk_id = HWBLK_VPU,
- },
};
static struct uio_info veu_platform_data = {
@@ -383,9 +368,6 @@
},
.resource = veu_resources,
.num_resources = ARRAY_SIZE(veu_resources),
- .archdata = {
- .hwblk_id = HWBLK_VEU,
- },
};
static struct uio_info jpu_platform_data = {
@@ -414,9 +396,6 @@
},
.resource = jpu_resources,
.num_resources = ARRAY_SIZE(jpu_resources),
- .archdata = {
- .hwblk_id = HWBLK_JPU,
- },
};
static struct sh_timer_config cmt_platform_data = {
@@ -446,9 +425,6 @@
},
.resource = cmt_resources,
.num_resources = ARRAY_SIZE(cmt_resources),
- .archdata = {
- .hwblk_id = HWBLK_CMT,
- },
};
static struct sh_timer_config tmu0_platform_data = {
@@ -477,9 +453,6 @@
},
.resource = tmu0_resources,
.num_resources = ARRAY_SIZE(tmu0_resources),
- .archdata = {
- .hwblk_id = HWBLK_TMU,
- },
};
static struct sh_timer_config tmu1_platform_data = {
@@ -508,9 +481,6 @@
},
.resource = tmu1_resources,
.num_resources = ARRAY_SIZE(tmu1_resources),
- .archdata = {
- .hwblk_id = HWBLK_TMU,
- },
};
static struct sh_timer_config tmu2_platform_data = {
@@ -538,9 +508,6 @@
},
.resource = tmu2_resources,
.num_resources = ARRAY_SIZE(tmu2_resources),
- .archdata = {
- .hwblk_id = HWBLK_TMU,
- },
};
static struct siu_platform siu_platform_data = {
@@ -571,9 +538,6 @@
},
.resource = siu_resources,
.num_resources = ARRAY_SIZE(siu_resources),
- .archdata = {
- .hwblk_id = HWBLK_SIU,
- },
};
static struct platform_device *sh7722_devices[] __initdata = {
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7723.c b/arch/sh/kernel/cpu/sh4a/setup-sh7723.c
index 3c2810d..a188c9e 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7723.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7723.c
@@ -158,9 +158,6 @@
},
.resource = vpu_resources,
.num_resources = ARRAY_SIZE(vpu_resources),
- .archdata = {
- .hwblk_id = HWBLK_VPU,
- },
};
static struct uio_info veu0_platform_data = {
@@ -189,9 +186,6 @@
},
.resource = veu0_resources,
.num_resources = ARRAY_SIZE(veu0_resources),
- .archdata = {
- .hwblk_id = HWBLK_VEU2H0,
- },
};
static struct uio_info veu1_platform_data = {
@@ -220,9 +214,6 @@
},
.resource = veu1_resources,
.num_resources = ARRAY_SIZE(veu1_resources),
- .archdata = {
- .hwblk_id = HWBLK_VEU2H1,
- },
};
static struct sh_timer_config cmt_platform_data = {
@@ -252,9 +243,6 @@
},
.resource = cmt_resources,
.num_resources = ARRAY_SIZE(cmt_resources),
- .archdata = {
- .hwblk_id = HWBLK_CMT,
- },
};
static struct sh_timer_config tmu0_platform_data = {
@@ -283,9 +271,6 @@
},
.resource = tmu0_resources,
.num_resources = ARRAY_SIZE(tmu0_resources),
- .archdata = {
- .hwblk_id = HWBLK_TMU0,
- },
};
static struct sh_timer_config tmu1_platform_data = {
@@ -314,9 +299,6 @@
},
.resource = tmu1_resources,
.num_resources = ARRAY_SIZE(tmu1_resources),
- .archdata = {
- .hwblk_id = HWBLK_TMU0,
- },
};
static struct sh_timer_config tmu2_platform_data = {
@@ -344,9 +326,6 @@
},
.resource = tmu2_resources,
.num_resources = ARRAY_SIZE(tmu2_resources),
- .archdata = {
- .hwblk_id = HWBLK_TMU0,
- },
};
static struct sh_timer_config tmu3_platform_data = {
@@ -374,9 +353,6 @@
},
.resource = tmu3_resources,
.num_resources = ARRAY_SIZE(tmu3_resources),
- .archdata = {
- .hwblk_id = HWBLK_TMU1,
- },
};
static struct sh_timer_config tmu4_platform_data = {
@@ -404,9 +380,6 @@
},
.resource = tmu4_resources,
.num_resources = ARRAY_SIZE(tmu4_resources),
- .archdata = {
- .hwblk_id = HWBLK_TMU1,
- },
};
static struct sh_timer_config tmu5_platform_data = {
@@ -434,9 +407,6 @@
},
.resource = tmu5_resources,
.num_resources = ARRAY_SIZE(tmu5_resources),
- .archdata = {
- .hwblk_id = HWBLK_TMU1,
- },
};
static struct resource rtc_resources[] = {
@@ -467,9 +437,6 @@
.id = -1,
.num_resources = ARRAY_SIZE(rtc_resources),
.resource = rtc_resources,
- .archdata = {
- .hwblk_id = HWBLK_RTC,
- },
};
static struct r8a66597_platdata r8a66597_data = {
@@ -499,9 +466,6 @@
},
.num_resources = ARRAY_SIZE(sh7723_usb_host_resources),
.resource = sh7723_usb_host_resources,
- .archdata = {
- .hwblk_id = HWBLK_USB,
- },
};
static struct resource iic_resources[] = {
@@ -523,9 +487,6 @@
.id = 0, /* "i2c0" clock */
.num_resources = ARRAY_SIZE(iic_resources),
.resource = iic_resources,
- .archdata = {
- .hwblk_id = HWBLK_IIC,
- },
};
static struct platform_device *sh7723_devices[] __initdata = {
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7724.c b/arch/sh/kernel/cpu/sh4a/setup-sh7724.c
index a37dd72..4c671cf 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7724.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7724.c
@@ -214,7 +214,7 @@
.flags = IORESOURCE_MEM,
},
{
- /* DMA error IRQ */
+ .name = "error_irq",
.start = 78,
.end = 78,
.flags = IORESOURCE_IRQ,
@@ -248,7 +248,7 @@
.flags = IORESOURCE_MEM,
},
{
- /* DMA error IRQ */
+ .name = "error_irq",
.start = 74,
.end = 74,
.flags = IORESOURCE_IRQ,
@@ -275,9 +275,6 @@
.dev = {
.platform_data = &dma_platform_data,
},
- .archdata = {
- .hwblk_id = HWBLK_DMAC0,
- },
};
static struct platform_device dma1_device = {
@@ -288,9 +285,6 @@
.dev = {
.platform_data = &dma_platform_data,
},
- .archdata = {
- .hwblk_id = HWBLK_DMAC1,
- },
};
/* Serial */
@@ -434,9 +428,6 @@
.id = -1,
.num_resources = ARRAY_SIZE(rtc_resources),
.resource = rtc_resources,
- .archdata = {
- .hwblk_id = HWBLK_RTC,
- },
};
/* I2C0 */
@@ -459,9 +450,6 @@
.id = 0, /* "i2c0" clock */
.num_resources = ARRAY_SIZE(iic0_resources),
.resource = iic0_resources,
- .archdata = {
- .hwblk_id = HWBLK_IIC0,
- },
};
/* I2C1 */
@@ -484,9 +472,6 @@
.id = 1, /* "i2c1" clock */
.num_resources = ARRAY_SIZE(iic1_resources),
.resource = iic1_resources,
- .archdata = {
- .hwblk_id = HWBLK_IIC1,
- },
};
/* VPU */
@@ -516,9 +501,6 @@
},
.resource = vpu_resources,
.num_resources = ARRAY_SIZE(vpu_resources),
- .archdata = {
- .hwblk_id = HWBLK_VPU,
- },
};
/* VEU0 */
@@ -548,9 +530,6 @@
},
.resource = veu0_resources,
.num_resources = ARRAY_SIZE(veu0_resources),
- .archdata = {
- .hwblk_id = HWBLK_VEU0,
- },
};
/* VEU1 */
@@ -580,9 +559,6 @@
},
.resource = veu1_resources,
.num_resources = ARRAY_SIZE(veu1_resources),
- .archdata = {
- .hwblk_id = HWBLK_VEU1,
- },
};
/* BEU0 */
@@ -612,9 +588,6 @@
},
.resource = beu0_resources,
.num_resources = ARRAY_SIZE(beu0_resources),
- .archdata = {
- .hwblk_id = HWBLK_BEU0,
- },
};
/* BEU1 */
@@ -644,9 +617,6 @@
},
.resource = beu1_resources,
.num_resources = ARRAY_SIZE(beu1_resources),
- .archdata = {
- .hwblk_id = HWBLK_BEU1,
- },
};
static struct sh_timer_config cmt_platform_data = {
@@ -676,9 +646,6 @@
},
.resource = cmt_resources,
.num_resources = ARRAY_SIZE(cmt_resources),
- .archdata = {
- .hwblk_id = HWBLK_CMT,
- },
};
static struct sh_timer_config tmu0_platform_data = {
@@ -707,9 +674,6 @@
},
.resource = tmu0_resources,
.num_resources = ARRAY_SIZE(tmu0_resources),
- .archdata = {
- .hwblk_id = HWBLK_TMU0,
- },
};
static struct sh_timer_config tmu1_platform_data = {
@@ -738,9 +702,6 @@
},
.resource = tmu1_resources,
.num_resources = ARRAY_SIZE(tmu1_resources),
- .archdata = {
- .hwblk_id = HWBLK_TMU0,
- },
};
static struct sh_timer_config tmu2_platform_data = {
@@ -768,9 +729,6 @@
},
.resource = tmu2_resources,
.num_resources = ARRAY_SIZE(tmu2_resources),
- .archdata = {
- .hwblk_id = HWBLK_TMU0,
- },
};
@@ -799,9 +757,6 @@
},
.resource = tmu3_resources,
.num_resources = ARRAY_SIZE(tmu3_resources),
- .archdata = {
- .hwblk_id = HWBLK_TMU1,
- },
};
static struct sh_timer_config tmu4_platform_data = {
@@ -829,9 +784,6 @@
},
.resource = tmu4_resources,
.num_resources = ARRAY_SIZE(tmu4_resources),
- .archdata = {
- .hwblk_id = HWBLK_TMU1,
- },
};
static struct sh_timer_config tmu5_platform_data = {
@@ -859,9 +811,6 @@
},
.resource = tmu5_resources,
.num_resources = ARRAY_SIZE(tmu5_resources),
- .archdata = {
- .hwblk_id = HWBLK_TMU1,
- },
};
/* JPU */
@@ -891,9 +840,6 @@
},
.resource = jpu_resources,
.num_resources = ARRAY_SIZE(jpu_resources),
- .archdata = {
- .hwblk_id = HWBLK_JPU,
- },
};
/* SPU2DSP0 */
@@ -923,9 +869,6 @@
},
.resource = spu0_resources,
.num_resources = ARRAY_SIZE(spu0_resources),
- .archdata = {
- .hwblk_id = HWBLK_SPU,
- },
};
/* SPU2DSP1 */
@@ -955,9 +898,6 @@
},
.resource = spu1_resources,
.num_resources = ARRAY_SIZE(spu1_resources),
- .archdata = {
- .hwblk_id = HWBLK_SPU,
- },
};
static struct platform_device *sh7724_devices[] __initdata = {
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7757.c b/arch/sh/kernel/cpu/sh4a/setup-sh7757.c
index 0555929..a7b2da6 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7757.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7757.c
@@ -465,6 +465,7 @@
.flags = IORESOURCE_MEM,
},
{
+ .name = "error_irq",
.start = 34,
.end = 34,
.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_SHAREABLE,
@@ -486,7 +487,7 @@
.flags = IORESOURCE_MEM,
},
{
- /* DMA error */
+ .name = "error_irq",
.start = 34,
.end = 34,
.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_SHAREABLE,
@@ -556,7 +557,7 @@
.flags = IORESOURCE_MEM,
},
{
- /* DMA error */
+ .name = "error_irq",
.start = 323,
.end = 323,
.flags = IORESOURCE_IRQ,
@@ -590,7 +591,7 @@
.flags = IORESOURCE_MEM,
},
{
- /* DMA error */
+ .name = "error_irq",
.start = 324,
.end = 324,
.flags = IORESOURCE_IRQ,
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7780.c b/arch/sh/kernel/cpu/sh4a/setup-sh7780.c
index 3d4d207..d431b00 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7780.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7780.c
@@ -322,6 +322,7 @@
},
{
/* Real DMA error IRQ is 38, and channel IRQs are 34-37, 44-45 */
+ .name = "error_irq",
.start = 34,
.end = 34,
.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_SHAREABLE,
@@ -338,6 +339,7 @@
/* DMAC1 has no DMARS */
{
/* Real DMA error IRQ is 38, and channel IRQs are 46-47, 92-95 */
+ .name = "error_irq",
.start = 46,
.end = 46,
.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_SHAREABLE,
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7785.c b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c
index b29e634..81588ef 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7785.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c
@@ -376,6 +376,7 @@
},
{
/* Real DMA error IRQ is 39, and channel IRQs are 33-38 */
+ .name = "error_irq",
.start = 33,
.end = 33,
.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_SHAREABLE,
@@ -392,6 +393,7 @@
/* DMAC1 has no DMARS */
{
/* Real DMA error IRQ is 58, and channel IRQs are 52-57 */
+ .name = "error_irq",
.start = 52,
.end = 52,
.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_SHAREABLE,
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7786.c b/arch/sh/kernel/cpu/sh4a/setup-sh7786.c
index dd5e709..599022d 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7786.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7786.c
@@ -518,7 +518,7 @@
.end = 0xfe00900b,
.flags = IORESOURCE_MEM,
}, {
- /* DMA error IRQ */
+ .name = "error_irq",
.start = evt2irq(0x5c0),
.end = evt2irq(0x5c0),
.flags = IORESOURCE_IRQ,
diff --git a/arch/sh/kernel/cpu/shmobile/Makefile b/arch/sh/kernel/cpu/shmobile/Makefile
index a39f88e..e8a5111 100644
--- a/arch/sh/kernel/cpu/shmobile/Makefile
+++ b/arch/sh/kernel/cpu/shmobile/Makefile
@@ -5,4 +5,3 @@
# Power Management & Sleep mode
obj-$(CONFIG_PM) += pm.o sleep.o
obj-$(CONFIG_CPU_IDLE) += cpuidle.o
-obj-$(CONFIG_PM_RUNTIME) += pm_runtime.o
diff --git a/arch/sh/kernel/cpu/shmobile/cpuidle.c b/arch/sh/kernel/cpu/shmobile/cpuidle.c
index 1cc257c..6d62eb4 100644
--- a/arch/sh/kernel/cpu/shmobile/cpuidle.c
+++ b/arch/sh/kernel/cpu/shmobile/cpuidle.c
@@ -17,7 +17,6 @@
#include <linux/export.h>
#include <asm/suspend.h>
#include <asm/uaccess.h>
-#include <asm/hwblk.h>
static unsigned long cpuidle_mode[] = {
SUSP_SH_SLEEP, /* regular sleep mode */
@@ -29,7 +28,7 @@
struct cpuidle_driver *drv,
int index)
{
- unsigned long allowed_mode = arch_hwblk_sleep_mode();
+ unsigned long allowed_mode = SUSP_SH_SLEEP;
ktime_t before, after;
int requested_state = index;
int allowed_state;
diff --git a/arch/sh/kernel/cpu/shmobile/pm_runtime.c b/arch/sh/kernel/cpu/shmobile/pm_runtime.c
deleted file mode 100644
index bf280c8..0000000
--- a/arch/sh/kernel/cpu/shmobile/pm_runtime.c
+++ /dev/null
@@ -1,319 +0,0 @@
-/*
- * arch/sh/kernel/cpu/shmobile/pm_runtime.c
- *
- * Runtime PM support code for SuperH Mobile
- *
- * Copyright (C) 2009 Magnus Damm
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- */
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/io.h>
-#include <linux/pm_runtime.h>
-#include <linux/platform_device.h>
-#include <linux/mutex.h>
-#include <asm/hwblk.h>
-
-static DEFINE_SPINLOCK(hwblk_lock);
-static LIST_HEAD(hwblk_idle_list);
-static struct work_struct hwblk_work;
-
-extern struct hwblk_info *hwblk_info;
-
-static void platform_pm_runtime_not_idle(struct platform_device *pdev)
-{
- unsigned long flags;
-
- /* remove device from idle list */
- spin_lock_irqsave(&hwblk_lock, flags);
- if (test_bit(PDEV_ARCHDATA_FLAG_IDLE, &pdev->archdata.flags)) {
- list_del(&pdev->archdata.entry);
- __clear_bit(PDEV_ARCHDATA_FLAG_IDLE, &pdev->archdata.flags);
- }
- spin_unlock_irqrestore(&hwblk_lock, flags);
-}
-
-static int __platform_pm_runtime_resume(struct platform_device *pdev)
-{
- struct device *d = &pdev->dev;
- struct pdev_archdata *ad = &pdev->archdata;
- int hwblk = ad->hwblk_id;
- int ret = -ENOSYS;
-
- dev_dbg(d, "__platform_pm_runtime_resume() [%d]\n", hwblk);
-
- if (d->driver) {
- hwblk_enable(hwblk_info, hwblk);
- ret = 0;
-
- if (test_bit(PDEV_ARCHDATA_FLAG_SUSP, &ad->flags)) {
- if (d->driver->pm && d->driver->pm->runtime_resume)
- ret = d->driver->pm->runtime_resume(d);
-
- if (!ret)
- clear_bit(PDEV_ARCHDATA_FLAG_SUSP, &ad->flags);
- else
- hwblk_disable(hwblk_info, hwblk);
- }
- }
-
- dev_dbg(d, "__platform_pm_runtime_resume() [%d] - returns %d\n",
- hwblk, ret);
-
- return ret;
-}
-
-static int __platform_pm_runtime_suspend(struct platform_device *pdev)
-{
- struct device *d = &pdev->dev;
- struct pdev_archdata *ad = &pdev->archdata;
- int hwblk = ad->hwblk_id;
- int ret = -ENOSYS;
-
- dev_dbg(d, "__platform_pm_runtime_suspend() [%d]\n", hwblk);
-
- if (d->driver) {
- BUG_ON(!test_bit(PDEV_ARCHDATA_FLAG_IDLE, &ad->flags));
- ret = 0;
-
- if (d->driver->pm && d->driver->pm->runtime_suspend) {
- hwblk_enable(hwblk_info, hwblk);
- ret = d->driver->pm->runtime_suspend(d);
- hwblk_disable(hwblk_info, hwblk);
- }
-
- if (!ret) {
- set_bit(PDEV_ARCHDATA_FLAG_SUSP, &ad->flags);
- platform_pm_runtime_not_idle(pdev);
- hwblk_cnt_dec(hwblk_info, hwblk, HWBLK_CNT_IDLE);
- }
- }
-
- dev_dbg(d, "__platform_pm_runtime_suspend() [%d] - returns %d\n",
- hwblk, ret);
-
- return ret;
-}
-
-static void platform_pm_runtime_work(struct work_struct *work)
-{
- struct platform_device *pdev;
- unsigned long flags;
- int ret;
-
- /* go through the idle list and suspend one device at a time */
- do {
- spin_lock_irqsave(&hwblk_lock, flags);
- if (list_empty(&hwblk_idle_list))
- pdev = NULL;
- else
- pdev = list_first_entry(&hwblk_idle_list,
- struct platform_device,
- archdata.entry);
- spin_unlock_irqrestore(&hwblk_lock, flags);
-
- if (pdev) {
- mutex_lock(&pdev->archdata.mutex);
- ret = __platform_pm_runtime_suspend(pdev);
-
- /* at this point the platform device may be:
- * suspended: ret = 0, FLAG_SUSP set, clock stopped
- * failed: ret < 0, FLAG_IDLE set, clock stopped
- */
- mutex_unlock(&pdev->archdata.mutex);
- } else {
- ret = -ENODEV;
- }
- } while (!ret);
-}
-
-/* this function gets called from cpuidle context when all devices in the
- * main power domain are unused but some are counted as idle, ie the hwblk
- * counter values are (HWBLK_CNT_USAGE == 0) && (HWBLK_CNT_IDLE != 0)
- */
-void platform_pm_runtime_suspend_idle(void)
-{
- queue_work(pm_wq, &hwblk_work);
-}
-
-static int default_platform_runtime_suspend(struct device *dev)
-{
- struct platform_device *pdev = to_platform_device(dev);
- struct pdev_archdata *ad = &pdev->archdata;
- unsigned long flags;
- int hwblk = ad->hwblk_id;
- int ret = 0;
-
- dev_dbg(dev, "%s() [%d]\n", __func__, hwblk);
-
- /* ignore off-chip platform devices */
- if (!hwblk)
- goto out;
-
- /* interrupt context not allowed */
- might_sleep();
-
- /* catch misconfigured drivers not starting with resume */
- if (test_bit(PDEV_ARCHDATA_FLAG_INIT, &ad->flags)) {
- ret = -EINVAL;
- goto out;
- }
-
- /* serialize */
- mutex_lock(&ad->mutex);
-
- /* disable clock */
- hwblk_disable(hwblk_info, hwblk);
-
- /* put device on idle list */
- spin_lock_irqsave(&hwblk_lock, flags);
- list_add_tail(&ad->entry, &hwblk_idle_list);
- __set_bit(PDEV_ARCHDATA_FLAG_IDLE, &ad->flags);
- spin_unlock_irqrestore(&hwblk_lock, flags);
-
- /* increase idle count */
- hwblk_cnt_inc(hwblk_info, hwblk, HWBLK_CNT_IDLE);
-
- /* at this point the platform device is:
- * idle: ret = 0, FLAG_IDLE set, clock stopped
- */
- mutex_unlock(&ad->mutex);
-
-out:
- dev_dbg(dev, "%s() [%d] returns %d\n",
- __func__, hwblk, ret);
-
- return ret;
-}
-
-static int default_platform_runtime_resume(struct device *dev)
-{
- struct platform_device *pdev = to_platform_device(dev);
- struct pdev_archdata *ad = &pdev->archdata;
- int hwblk = ad->hwblk_id;
- int ret = 0;
-
- dev_dbg(dev, "%s() [%d]\n", __func__, hwblk);
-
- /* ignore off-chip platform devices */
- if (!hwblk)
- goto out;
-
- /* interrupt context not allowed */
- might_sleep();
-
- /* serialize */
- mutex_lock(&ad->mutex);
-
- /* make sure device is removed from idle list */
- platform_pm_runtime_not_idle(pdev);
-
- /* decrease idle count */
- if (!test_bit(PDEV_ARCHDATA_FLAG_INIT, &pdev->archdata.flags) &&
- !test_bit(PDEV_ARCHDATA_FLAG_SUSP, &pdev->archdata.flags))
- hwblk_cnt_dec(hwblk_info, hwblk, HWBLK_CNT_IDLE);
-
- /* resume the device if needed */
- ret = __platform_pm_runtime_resume(pdev);
-
- /* the driver has been initialized now, so clear the init flag */
- clear_bit(PDEV_ARCHDATA_FLAG_INIT, &pdev->archdata.flags);
-
- /* at this point the platform device may be:
- * resumed: ret = 0, flags = 0, clock started
- * failed: ret < 0, FLAG_SUSP set, clock stopped
- */
- mutex_unlock(&ad->mutex);
-out:
- dev_dbg(dev, "%s() [%d] returns %d\n",
- __func__, hwblk, ret);
-
- return ret;
-}
-
-static int default_platform_runtime_idle(struct device *dev)
-{
- struct platform_device *pdev = to_platform_device(dev);
- int hwblk = pdev->archdata.hwblk_id;
- int ret = 0;
-
- dev_dbg(dev, "%s() [%d]\n", __func__, hwblk);
-
- /* ignore off-chip platform devices */
- if (!hwblk)
- goto out;
-
- /* interrupt context not allowed, use pm_runtime_put()! */
- might_sleep();
-
- /* suspend synchronously to disable clocks immediately */
- ret = pm_runtime_suspend(dev);
-out:
- dev_dbg(dev, "%s() [%d] done!\n", __func__, hwblk);
- return ret;
-}
-
-static struct dev_pm_domain default_pm_domain = {
- .ops = {
- .runtime_suspend = default_platform_runtime_suspend,
- .runtime_resume = default_platform_runtime_resume,
- .runtime_idle = default_platform_runtime_idle,
- USE_PLATFORM_PM_SLEEP_OPS
- },
-};
-
-static int platform_bus_notify(struct notifier_block *nb,
- unsigned long action, void *data)
-{
- struct device *dev = data;
- struct platform_device *pdev = to_platform_device(dev);
- int hwblk = pdev->archdata.hwblk_id;
-
- /* ignore off-chip platform devices */
- if (!hwblk)
- return 0;
-
- switch (action) {
- case BUS_NOTIFY_ADD_DEVICE:
- INIT_LIST_HEAD(&pdev->archdata.entry);
- mutex_init(&pdev->archdata.mutex);
- /* platform devices without drivers should be disabled */
- hwblk_enable(hwblk_info, hwblk);
- hwblk_disable(hwblk_info, hwblk);
- /* make sure driver re-inits itself once */
- __set_bit(PDEV_ARCHDATA_FLAG_INIT, &pdev->archdata.flags);
- dev->pm_domain = &default_pm_domain;
- break;
- /* TODO: add BUS_NOTIFY_BIND_DRIVER and increase idle count */
- case BUS_NOTIFY_BOUND_DRIVER:
- /* keep track of number of devices in use per hwblk */
- hwblk_cnt_inc(hwblk_info, hwblk, HWBLK_CNT_DEVICES);
- break;
- case BUS_NOTIFY_UNBOUND_DRIVER:
- /* keep track of number of devices in use per hwblk */
- hwblk_cnt_dec(hwblk_info, hwblk, HWBLK_CNT_DEVICES);
- /* make sure driver re-inits itself once */
- __set_bit(PDEV_ARCHDATA_FLAG_INIT, &pdev->archdata.flags);
- break;
- case BUS_NOTIFY_DEL_DEVICE:
- dev->pm_domain = NULL;
- break;
- }
- return 0;
-}
-
-static struct notifier_block platform_bus_notifier = {
- .notifier_call = platform_bus_notify
-};
-
-static int __init sh_pm_runtime_init(void)
-{
- INIT_WORK(&hwblk_work, platform_pm_runtime_work);
-
- bus_register_notifier(&platform_bus_type, &platform_bus_notifier);
- return 0;
-}
-core_initcall(sh_pm_runtime_init);
diff --git a/arch/sh/kernel/entry-common.S b/arch/sh/kernel/entry-common.S
index 2b15ae6..f67601c 100644
--- a/arch/sh/kernel/entry-common.S
+++ b/arch/sh/kernel/entry-common.S
@@ -145,6 +145,7 @@
mov r15, r4
mov r12, r5 ! set arg1(save_r0)
mov r0, r6
+ sti
mov.l 2f, r1
mov.l 3f, r0
jmp @r1
diff --git a/arch/sh/kernel/signal_32.c b/arch/sh/kernel/signal_32.c
index 579cd2c..a7a55ed 100644
--- a/arch/sh/kernel/signal_32.c
+++ b/arch/sh/kernel/signal_32.c
@@ -588,9 +588,6 @@
if (!user_mode(regs))
return;
- if (try_to_freeze())
- goto no_signal;
-
if (current_thread_info()->status & TS_RESTORE_SIGMASK)
oldset = ¤t->saved_sigmask;
else
@@ -618,7 +615,6 @@
return;
}
-no_signal:
/* Did we come from a system call? */
if (regs->tra >= 0) {
/* Restart the system call - no handlers present */
diff --git a/arch/sh/kernel/signal_64.c b/arch/sh/kernel/signal_64.c
index 5a9f1f1..6b5603f 100644
--- a/arch/sh/kernel/signal_64.c
+++ b/arch/sh/kernel/signal_64.c
@@ -98,9 +98,6 @@
if (!user_mode(regs))
return 1;
- if (try_to_freeze())
- goto no_signal;
-
if (current_thread_info()->status & TS_RESTORE_SIGMASK)
oldset = ¤t->saved_sigmask;
else if (!oldset)
@@ -125,7 +122,6 @@
}
}
-no_signal:
/* Did we come from a system call? */
if (regs->syscall_nr >= 0) {
/* Restart the system call - no handlers present */
diff --git a/arch/sh/kernel/time.c b/arch/sh/kernel/time.c
index 8a0072d..552c8fc 100644
--- a/arch/sh/kernel/time.c
+++ b/arch/sh/kernel/time.c
@@ -21,7 +21,6 @@
#include <linux/smp.h>
#include <linux/rtc.h>
#include <asm/clock.h>
-#include <asm/hwblk.h>
#include <asm/rtc.h>
/* Dummy RTC ops */
@@ -110,7 +109,6 @@
if (board_time_init)
board_time_init();
- hwblk_init();
clk_init();
late_time_init = sh_late_time_init;
diff --git a/arch/sh/mm/cache-sh2a.c b/arch/sh/mm/cache-sh2a.c
index 1f51225..ae08cbb 100644
--- a/arch/sh/mm/cache-sh2a.c
+++ b/arch/sh/mm/cache-sh2a.c
@@ -15,35 +15,78 @@
#include <asm/cacheflush.h>
#include <asm/io.h>
+/*
+ * The maximum number of pages we support up to when doing ranged dcache
+ * flushing. Anything exceeding this will simply flush the dcache in its
+ * entirety.
+ */
+#define MAX_OCACHE_PAGES 32
+#define MAX_ICACHE_PAGES 32
+
+static void sh2a_flush_oc_line(unsigned long v, int way)
+{
+ unsigned long addr = (v & 0x000007f0) | (way << 11);
+ unsigned long data;
+
+ data = __raw_readl(CACHE_OC_ADDRESS_ARRAY | addr);
+ if ((data & CACHE_PHYSADDR_MASK) == (v & CACHE_PHYSADDR_MASK)) {
+ data &= ~SH_CACHE_UPDATED;
+ __raw_writel(data, CACHE_OC_ADDRESS_ARRAY | addr);
+ }
+}
+
+static void sh2a_invalidate_line(unsigned long cache_addr, unsigned long v)
+{
+ /* Set associative bit to hit all ways */
+ unsigned long addr = (v & 0x000007f0) | SH_CACHE_ASSOC;
+ __raw_writel((addr & CACHE_PHYSADDR_MASK), cache_addr | addr);
+}
+
+/*
+ * Write back the dirty D-caches, but not invalidate them.
+ */
static void sh2a__flush_wback_region(void *start, int size)
{
+#ifdef CONFIG_CACHE_WRITEBACK
unsigned long v;
unsigned long begin, end;
unsigned long flags;
+ int nr_ways;
begin = (unsigned long)start & ~(L1_CACHE_BYTES-1);
end = ((unsigned long)start + size + L1_CACHE_BYTES-1)
& ~(L1_CACHE_BYTES-1);
+ nr_ways = current_cpu_data.dcache.ways;
local_irq_save(flags);
jump_to_uncached();
- for (v = begin; v < end; v+=L1_CACHE_BYTES) {
- unsigned long addr = CACHE_OC_ADDRESS_ARRAY | (v & 0x000007f0);
+ /* If there are too many pages then flush the entire cache */
+ if (((end - begin) >> PAGE_SHIFT) >= MAX_OCACHE_PAGES) {
+ begin = CACHE_OC_ADDRESS_ARRAY;
+ end = begin + (nr_ways * current_cpu_data.dcache.way_size);
+
+ for (v = begin; v < end; v += L1_CACHE_BYTES) {
+ unsigned long data = __raw_readl(v);
+ if (data & SH_CACHE_UPDATED)
+ __raw_writel(data & ~SH_CACHE_UPDATED, v);
+ }
+ } else {
int way;
- for (way = 0; way < 4; way++) {
- unsigned long data = __raw_readl(addr | (way << 11));
- if ((data & CACHE_PHYSADDR_MASK) == (v & CACHE_PHYSADDR_MASK)) {
- data &= ~SH_CACHE_UPDATED;
- __raw_writel(data, addr | (way << 11));
- }
+ for (way = 0; way < nr_ways; way++) {
+ for (v = begin; v < end; v += L1_CACHE_BYTES)
+ sh2a_flush_oc_line(v, way);
}
}
back_to_cached();
local_irq_restore(flags);
+#endif
}
+/*
+ * Write back the dirty D-caches and invalidate them.
+ */
static void sh2a__flush_purge_region(void *start, int size)
{
unsigned long v;
@@ -58,13 +101,22 @@
jump_to_uncached();
for (v = begin; v < end; v+=L1_CACHE_BYTES) {
- __raw_writel((v & CACHE_PHYSADDR_MASK),
- CACHE_OC_ADDRESS_ARRAY | (v & 0x000007f0) | 0x00000008);
+#ifdef CONFIG_CACHE_WRITEBACK
+ int way;
+ int nr_ways = current_cpu_data.dcache.ways;
+ for (way = 0; way < nr_ways; way++)
+ sh2a_flush_oc_line(v, way);
+#endif
+ sh2a_invalidate_line(CACHE_OC_ADDRESS_ARRAY, v);
}
+
back_to_cached();
local_irq_restore(flags);
}
+/*
+ * Invalidate the D-caches, but no write back please
+ */
static void sh2a__flush_invalidate_region(void *start, int size)
{
unsigned long v;
@@ -74,29 +126,25 @@
begin = (unsigned long)start & ~(L1_CACHE_BYTES-1);
end = ((unsigned long)start + size + L1_CACHE_BYTES-1)
& ~(L1_CACHE_BYTES-1);
+
local_irq_save(flags);
jump_to_uncached();
-#ifdef CONFIG_CACHE_WRITEBACK
- __raw_writel(__raw_readl(CCR) | CCR_OCACHE_INVALIDATE, CCR);
- /* I-cache invalidate */
- for (v = begin; v < end; v+=L1_CACHE_BYTES) {
- __raw_writel((v & CACHE_PHYSADDR_MASK),
- CACHE_IC_ADDRESS_ARRAY | (v & 0x000007f0) | 0x00000008);
+ /* If there are too many pages then just blow the cache */
+ if (((end - begin) >> PAGE_SHIFT) >= MAX_OCACHE_PAGES) {
+ __raw_writel(__raw_readl(CCR) | CCR_OCACHE_INVALIDATE, CCR);
+ } else {
+ for (v = begin; v < end; v += L1_CACHE_BYTES)
+ sh2a_invalidate_line(CACHE_OC_ADDRESS_ARRAY, v);
}
-#else
- for (v = begin; v < end; v+=L1_CACHE_BYTES) {
- __raw_writel((v & CACHE_PHYSADDR_MASK),
- CACHE_IC_ADDRESS_ARRAY | (v & 0x000007f0) | 0x00000008);
- __raw_writel((v & CACHE_PHYSADDR_MASK),
- CACHE_OC_ADDRESS_ARRAY | (v & 0x000007f0) | 0x00000008);
- }
-#endif
+
back_to_cached();
local_irq_restore(flags);
}
-/* WBack O-Cache and flush I-Cache */
+/*
+ * Write back the range of D-cache, and purge the I-cache.
+ */
static void sh2a_flush_icache_range(void *args)
{
struct flusher_data *data = args;
@@ -107,23 +155,20 @@
start = data->addr1 & ~(L1_CACHE_BYTES-1);
end = (data->addr2 + L1_CACHE_BYTES-1) & ~(L1_CACHE_BYTES-1);
+#ifdef CONFIG_CACHE_WRITEBACK
+ sh2a__flush_wback_region((void *)start, end-start);
+#endif
+
local_irq_save(flags);
jump_to_uncached();
- for (v = start; v < end; v+=L1_CACHE_BYTES) {
- unsigned long addr = (v & 0x000007f0);
- int way;
- /* O-Cache writeback */
- for (way = 0; way < 4; way++) {
- unsigned long data = __raw_readl(CACHE_OC_ADDRESS_ARRAY | addr | (way << 11));
- if ((data & CACHE_PHYSADDR_MASK) == (v & CACHE_PHYSADDR_MASK)) {
- data &= ~SH_CACHE_UPDATED;
- __raw_writel(data, CACHE_OC_ADDRESS_ARRAY | addr | (way << 11));
- }
- }
- /* I-Cache invalidate */
- __raw_writel(addr,
- CACHE_IC_ADDRESS_ARRAY | addr | 0x00000008);
+ /* I-Cache invalidate */
+ /* If there are too many pages then just blow the cache */
+ if (((end - start) >> PAGE_SHIFT) >= MAX_ICACHE_PAGES) {
+ __raw_writel(__raw_readl(CCR) | CCR_ICACHE_INVALIDATE, CCR);
+ } else {
+ for (v = start; v < end; v += L1_CACHE_BYTES)
+ sh2a_invalidate_line(CACHE_IC_ADDRESS_ARRAY, v);
}
back_to_cached();
diff --git a/arch/sparc/include/asm/pci_32.h b/arch/sparc/include/asm/pci_32.h
index 02939ab..6de7f7b 100644
--- a/arch/sparc/include/asm/pci_32.h
+++ b/arch/sparc/include/asm/pci_32.h
@@ -16,11 +16,6 @@
#define PCI_IRQ_NONE 0xffffffff
-static inline void pcibios_set_master(struct pci_dev *dev)
-{
- /* No special bus mastering setup handling */
-}
-
static inline void pcibios_penalize_isa_irq(int irq, int active)
{
/* We don't do dynamic PCI IRQ allocation */
diff --git a/arch/sparc/include/asm/pci_64.h b/arch/sparc/include/asm/pci_64.h
index 2614d96..755a4bb 100644
--- a/arch/sparc/include/asm/pci_64.h
+++ b/arch/sparc/include/asm/pci_64.h
@@ -16,11 +16,6 @@
#define PCI_IRQ_NONE 0xffffffff
-static inline void pcibios_set_master(struct pci_dev *dev)
-{
- /* No special bus mastering setup handling */
-}
-
static inline void pcibios_penalize_isa_irq(int irq, int active)
{
/* We don't do dynamic PCI IRQ allocation */
diff --git a/arch/sparc/kernel/leon_pci.c b/arch/sparc/kernel/leon_pci.c
index f1cf6ef..c7bec25f 100644
--- a/arch/sparc/kernel/leon_pci.c
+++ b/arch/sparc/kernel/leon_pci.c
@@ -19,22 +19,22 @@
*/
void leon_pci_init(struct platform_device *ofdev, struct leon_pci_info *info)
{
+ LIST_HEAD(resources);
struct pci_bus *root_bus;
- root_bus = pci_scan_bus_parented(&ofdev->dev, 0, info->ops, info);
+ pci_add_resource(&resources, &info->io_space);
+ pci_add_resource(&resources, &info->mem_space);
+
+ root_bus = pci_scan_root_bus(&ofdev->dev, 0, info->ops, info,
+ &resources);
if (root_bus) {
- root_bus->resource[0] = &info->io_space;
- root_bus->resource[1] = &info->mem_space;
- root_bus->resource[2] = NULL;
-
- /* Init all PCI devices into PCI tree */
- pci_bus_add_devices(root_bus);
-
/* Setup IRQs of all devices using custom routines */
pci_fixup_irqs(pci_common_swizzle, info->map_irq);
/* Assign devices with resources */
pci_assign_unassigned_resources();
+ } else {
+ pci_free_resource_list(&resources);
}
}
@@ -83,15 +83,6 @@
int i, has_io, has_mem;
u16 cmd;
- /* Generic PCI bus probing sets these to point at
- * &io{port,mem}_resouce which is wrong for us.
- */
- if (pbus->self == NULL) {
- pbus->resource[0] = &info->io_space;
- pbus->resource[1] = &info->mem_space;
- pbus->resource[2] = NULL;
- }
-
list_for_each_entry(dev, &pbus->devices, bus_list) {
/*
* We can not rely on that the bootloader has enabled I/O
diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c
index 31111e3..bb8bc2e 100644
--- a/arch/sparc/kernel/pci.c
+++ b/arch/sparc/kernel/pci.c
@@ -685,23 +685,25 @@
struct pci_bus * __devinit pci_scan_one_pbm(struct pci_pbm_info *pbm,
struct device *parent)
{
+ LIST_HEAD(resources);
struct device_node *node = pbm->op->dev.of_node;
struct pci_bus *bus;
printk("PCI: Scanning PBM %s\n", node->full_name);
- bus = pci_create_bus(parent, pbm->pci_first_busno, pbm->pci_ops, pbm);
+ pci_add_resource(&resources, &pbm->io_space);
+ pci_add_resource(&resources, &pbm->mem_space);
+ bus = pci_create_root_bus(parent, pbm->pci_first_busno, pbm->pci_ops,
+ pbm, &resources);
if (!bus) {
printk(KERN_ERR "Failed to create bus for %s\n",
node->full_name);
+ pci_free_resource_list(&resources);
return NULL;
}
bus->secondary = pbm->pci_first_busno;
bus->subordinate = pbm->pci_last_busno;
- bus->resource[0] = &pbm->io_space;
- bus->resource[1] = &pbm->mem_space;
-
pci_of_scan_bus(pbm, node, bus);
pci_bus_add_devices(bus);
pci_bus_register_of_sysfs(bus);
@@ -711,13 +713,6 @@
void __devinit pcibios_fixup_bus(struct pci_bus *pbus)
{
- struct pci_pbm_info *pbm = pbus->sysdata;
-
- /* Generic PCI bus probing sets these to point at
- * &io{port,mem}_resouce which is wrong for us.
- */
- pbus->resource[0] = &pbm->io_space;
- pbus->resource[1] = &pbm->mem_space;
}
void pcibios_update_irq(struct pci_dev *pdev, int irq)
@@ -1083,6 +1078,11 @@
*end = rp->end - offset;
}
+void pcibios_set_master(struct pci_dev *dev)
+{
+ /* No special bus mastering setup handling */
+}
+
static int __init pcibios_init(void)
{
pci_dfl_cache_line_size = 64 >> 2;
diff --git a/arch/tile/include/asm/pci.h b/arch/tile/include/asm/pci.h
index 1d25fea..5d5a635 100644
--- a/arch/tile/include/asm/pci.h
+++ b/arch/tile/include/asm/pci.h
@@ -76,13 +76,6 @@
return 1;
}
-/*
- * No special bus mastering setup handling.
- */
-static inline void pcibios_set_master(struct pci_dev *dev)
-{
-}
-
#define PCIBIOS_MIN_MEM 0
#define PCIBIOS_MIN_IO 0
diff --git a/arch/tile/kernel/pci.c b/arch/tile/kernel/pci.c
index 2556793..a1bb59e 100644
--- a/arch/tile/kernel/pci.c
+++ b/arch/tile/kernel/pci.c
@@ -395,6 +395,11 @@
/* Nothing needs to be done. */
}
+void pcibios_set_master(struct pci_dev *dev)
+{
+ /* No special bus mastering setup handling. */
+}
+
/*
* This can be called from the generic PCI layer, but doesn't need to
* do anything.
diff --git a/arch/um/Kconfig.common b/arch/um/Kconfig.common
index a923483..b37ae70 100644
--- a/arch/um/Kconfig.common
+++ b/arch/um/Kconfig.common
@@ -8,6 +8,7 @@
default y
select HAVE_GENERIC_HARDIRQS
select GENERIC_IRQ_SHOW
+ select GENERIC_CPU_DEVICES
config MMU
bool
diff --git a/arch/unicore32/include/asm/pci.h b/arch/unicore32/include/asm/pci.h
index c5b28b4..dd38677 100644
--- a/arch/unicore32/include/asm/pci.h
+++ b/arch/unicore32/include/asm/pci.h
@@ -17,11 +17,6 @@
#include <asm-generic/pci.h>
#include <mach/hardware.h> /* for PCIBIOS_MIN_* */
-static inline void pcibios_set_master(struct pci_dev *dev)
-{
- /* No special bus mastering setup handling */
-}
-
static inline void pcibios_penalize_isa_irq(int irq, int active)
{
/* We don't do dynamic PCI IRQ allocation */
diff --git a/arch/unicore32/kernel/pci.c b/arch/unicore32/kernel/pci.c
index 4892fbb..a8f07fe 100644
--- a/arch/unicore32/kernel/pci.c
+++ b/arch/unicore32/kernel/pci.c
@@ -309,6 +309,11 @@
return str;
}
+void pcibios_set_master(struct pci_dev *dev)
+{
+ /* No special bus mastering setup handling */
+}
+
/*
* From arch/i386/kernel/pci-i386.c:
*
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 1a31254..a150f4c 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -420,12 +420,14 @@
depends on PCI
depends on PCI_GOANY
depends on X86_IO_APIC
+ select X86_INTEL_MID
+ select SFI
+ select DW_APB_TIMER
select APB_TIMER
select I2C
select SPI
select INTEL_SCU_IPC
select X86_PLATFORM_DEVICES
- select X86_INTEL_MID
---help---
Moorestown is Intel's Low Power Intel Architecture (LPIA) based Moblin
Internet Device(MID) platform. Moorestown consists of two chips:
@@ -434,6 +436,26 @@
nor standard legacy replacement devices/features. e.g. Moorestown does
not contain i8259, i8254, HPET, legacy BIOS, most of the io ports.
+config X86_MDFLD
+ bool "Medfield MID platform"
+ depends on PCI
+ depends on PCI_GOANY
+ depends on X86_IO_APIC
+ select X86_INTEL_MID
+ select SFI
+ select DW_APB_TIMER
+ select APB_TIMER
+ select I2C
+ select SPI
+ select INTEL_SCU_IPC
+ select X86_PLATFORM_DEVICES
+ ---help---
+ Medfield is Intel's Low Power Intel Architecture (LPIA) based Moblin
+ Internet Device(MID) platform.
+ Unlike standard x86 PCs, Medfield does not have many legacy devices
+ nor standard legacy replacement devices/features. e.g. Medfield does
+ not contain i8259, i8254, HPET, legacy BIOS, most of the io ports.
+
endif
config X86_RDC321X
@@ -631,7 +653,7 @@
config X86_CYCLONE_TIMER
def_bool y
- depends on X86_32_NON_STANDARD
+ depends on X86_SUMMIT
source "arch/x86/Kconfig.cpu"
@@ -659,9 +681,10 @@
depends on HPET_TIMER && (RTC=y || RTC=m || RTC_DRV_CMOS=m || RTC_DRV_CMOS=y)
config APB_TIMER
- def_bool y if MRST
- prompt "Langwell APB Timer Support" if X86_MRST
+ def_bool y if X86_INTEL_MID
+ prompt "Intel MID APB Timer Support" if X86_INTEL_MID
select DW_APB_TIMER
+ depends on X86_INTEL_MID && SFI
help
APB timer is the replacement for 8254, HPET on X86 MID platforms.
The APBT provides a stable time base on SMP
@@ -1489,6 +1512,13 @@
resultant kernel should continue to boot on existing non-EFI
platforms.
+config EFI_STUB
+ bool "EFI stub support"
+ depends on EFI
+ ---help---
+ This kernel feature allows a bzImage to be loaded directly
+ by EFI firmware without the use of a bootloader.
+
config SECCOMP
def_bool y
prompt "Enable seccomp to safely compute untrusted bytecode"
diff --git a/arch/x86/Kconfig.debug b/arch/x86/Kconfig.debug
index bf56e17..e46c214 100644
--- a/arch/x86/Kconfig.debug
+++ b/arch/x86/Kconfig.debug
@@ -43,9 +43,9 @@
with klogd/syslogd or the X server. You should normally N here,
unless you want to debug such a crash.
-config EARLY_PRINTK_MRST
- bool "Early printk for MRST platform support"
- depends on EARLY_PRINTK && X86_MRST
+config EARLY_PRINTK_INTEL_MID
+ bool "Early printk for Intel MID platform support"
+ depends on EARLY_PRINTK && X86_INTEL_MID
config EARLY_PRINTK_DBGP
bool "Early printk via EHCI debug port"
@@ -63,8 +63,11 @@
bool "Check for stack overflows"
depends on DEBUG_KERNEL
---help---
- This option will cause messages to be printed if free stack space
- drops below a certain limit.
+ Say Y here if you want to check the overflows of kernel, IRQ
+ and exception stacks. This option will cause messages of the
+ stacks in detail when free stack space drops below a certain
+ limit.
+ If in doubt, say "N".
config X86_PTDUMP
bool "Export kernel pagetable layout to userspace via debugfs"
@@ -284,4 +287,16 @@
If unsure, or if you run an older (pre 4.4) gcc, say N.
+config DEBUG_NMI_SELFTEST
+ bool "NMI Selftest"
+ depends on DEBUG_KERNEL && X86_LOCAL_APIC
+ ---help---
+ Enabling this option turns on a quick NMI selftest to verify
+ that the NMI behaves correctly.
+
+ This might help diagnose strange hangs that rely on NMI to
+ function properly.
+
+ If unsure, say N.
+
endmenu
diff --git a/arch/x86/boot/compressed/Makefile b/arch/x86/boot/compressed/Makefile
index 09664ef..b123b9a 100644
--- a/arch/x86/boot/compressed/Makefile
+++ b/arch/x86/boot/compressed/Makefile
@@ -23,7 +23,15 @@
hostprogs-y := mkpiggy
-$(obj)/vmlinux: $(obj)/vmlinux.lds $(obj)/head_$(BITS).o $(obj)/misc.o $(obj)/string.o $(obj)/cmdline.o $(obj)/early_serial_console.o $(obj)/piggy.o FORCE
+VMLINUX_OBJS = $(obj)/vmlinux.lds $(obj)/head_$(BITS).o $(obj)/misc.o \
+ $(obj)/string.o $(obj)/cmdline.o $(obj)/early_serial_console.o \
+ $(obj)/piggy.o
+
+ifeq ($(CONFIG_EFI_STUB), y)
+ VMLINUX_OBJS += $(obj)/eboot.o $(obj)/efi_stub_$(BITS).o
+endif
+
+$(obj)/vmlinux: $(VMLINUX_OBJS) FORCE
$(call if_changed,ld)
@:
diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c
new file mode 100644
index 0000000..fec216f
--- /dev/null
+++ b/arch/x86/boot/compressed/eboot.c
@@ -0,0 +1,1022 @@
+/* -----------------------------------------------------------------------
+ *
+ * Copyright 2011 Intel Corporation; author Matt Fleming
+ *
+ * This file is part of the Linux kernel, and is made available under
+ * the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+#include <linux/efi.h>
+#include <asm/efi.h>
+#include <asm/setup.h>
+#include <asm/desc.h>
+
+#include "eboot.h"
+
+static efi_system_table_t *sys_table;
+
+static efi_status_t __get_map(efi_memory_desc_t **map, unsigned long *map_size,
+ unsigned long *desc_size)
+{
+ efi_memory_desc_t *m = NULL;
+ efi_status_t status;
+ unsigned long key;
+ u32 desc_version;
+
+ *map_size = sizeof(*m) * 32;
+again:
+ /*
+ * Add an additional efi_memory_desc_t because we're doing an
+ * allocation which may be in a new descriptor region.
+ */
+ *map_size += sizeof(*m);
+ status = efi_call_phys3(sys_table->boottime->allocate_pool,
+ EFI_LOADER_DATA, *map_size, (void **)&m);
+ if (status != EFI_SUCCESS)
+ goto fail;
+
+ status = efi_call_phys5(sys_table->boottime->get_memory_map, map_size,
+ m, &key, desc_size, &desc_version);
+ if (status == EFI_BUFFER_TOO_SMALL) {
+ efi_call_phys1(sys_table->boottime->free_pool, m);
+ goto again;
+ }
+
+ if (status != EFI_SUCCESS)
+ efi_call_phys1(sys_table->boottime->free_pool, m);
+
+fail:
+ *map = m;
+ return status;
+}
+
+/*
+ * Allocate at the highest possible address that is not above 'max'.
+ */
+static efi_status_t high_alloc(unsigned long size, unsigned long align,
+ unsigned long *addr, unsigned long max)
+{
+ unsigned long map_size, desc_size;
+ efi_memory_desc_t *map;
+ efi_status_t status;
+ unsigned long nr_pages;
+ u64 max_addr = 0;
+ int i;
+
+ status = __get_map(&map, &map_size, &desc_size);
+ if (status != EFI_SUCCESS)
+ goto fail;
+
+ nr_pages = round_up(size, EFI_PAGE_SIZE) / EFI_PAGE_SIZE;
+again:
+ for (i = 0; i < map_size / desc_size; i++) {
+ efi_memory_desc_t *desc;
+ unsigned long m = (unsigned long)map;
+ u64 start, end;
+
+ desc = (efi_memory_desc_t *)(m + (i * desc_size));
+ if (desc->type != EFI_CONVENTIONAL_MEMORY)
+ continue;
+
+ if (desc->num_pages < nr_pages)
+ continue;
+
+ start = desc->phys_addr;
+ end = start + desc->num_pages * (1UL << EFI_PAGE_SHIFT);
+
+ if ((start + size) > end || (start + size) > max)
+ continue;
+
+ if (end - size > max)
+ end = max;
+
+ if (round_down(end - size, align) < start)
+ continue;
+
+ start = round_down(end - size, align);
+
+ /*
+ * Don't allocate at 0x0. It will confuse code that
+ * checks pointers against NULL.
+ */
+ if (start == 0x0)
+ continue;
+
+ if (start > max_addr)
+ max_addr = start;
+ }
+
+ if (!max_addr)
+ status = EFI_NOT_FOUND;
+ else {
+ status = efi_call_phys4(sys_table->boottime->allocate_pages,
+ EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA,
+ nr_pages, &max_addr);
+ if (status != EFI_SUCCESS) {
+ max = max_addr;
+ max_addr = 0;
+ goto again;
+ }
+
+ *addr = max_addr;
+ }
+
+free_pool:
+ efi_call_phys1(sys_table->boottime->free_pool, map);
+
+fail:
+ return status;
+}
+
+/*
+ * Allocate at the lowest possible address.
+ */
+static efi_status_t low_alloc(unsigned long size, unsigned long align,
+ unsigned long *addr)
+{
+ unsigned long map_size, desc_size;
+ efi_memory_desc_t *map;
+ efi_status_t status;
+ unsigned long nr_pages;
+ int i;
+
+ status = __get_map(&map, &map_size, &desc_size);
+ if (status != EFI_SUCCESS)
+ goto fail;
+
+ nr_pages = round_up(size, EFI_PAGE_SIZE) / EFI_PAGE_SIZE;
+ for (i = 0; i < map_size / desc_size; i++) {
+ efi_memory_desc_t *desc;
+ unsigned long m = (unsigned long)map;
+ u64 start, end;
+
+ desc = (efi_memory_desc_t *)(m + (i * desc_size));
+
+ if (desc->type != EFI_CONVENTIONAL_MEMORY)
+ continue;
+
+ if (desc->num_pages < nr_pages)
+ continue;
+
+ start = desc->phys_addr;
+ end = start + desc->num_pages * (1UL << EFI_PAGE_SHIFT);
+
+ /*
+ * Don't allocate at 0x0. It will confuse code that
+ * checks pointers against NULL. Skip the first 8
+ * bytes so we start at a nice even number.
+ */
+ if (start == 0x0)
+ start += 8;
+
+ start = round_up(start, align);
+ if ((start + size) > end)
+ continue;
+
+ status = efi_call_phys4(sys_table->boottime->allocate_pages,
+ EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA,
+ nr_pages, &start);
+ if (status == EFI_SUCCESS) {
+ *addr = start;
+ break;
+ }
+ }
+
+ if (i == map_size / desc_size)
+ status = EFI_NOT_FOUND;
+
+free_pool:
+ efi_call_phys1(sys_table->boottime->free_pool, map);
+fail:
+ return status;
+}
+
+static void low_free(unsigned long size, unsigned long addr)
+{
+ unsigned long nr_pages;
+
+ nr_pages = round_up(size, EFI_PAGE_SIZE) / EFI_PAGE_SIZE;
+ efi_call_phys2(sys_table->boottime->free_pages, addr, size);
+}
+
+static void find_bits(unsigned long mask, u8 *pos, u8 *size)
+{
+ u8 first, len;
+
+ first = 0;
+ len = 0;
+
+ if (mask) {
+ while (!(mask & 0x1)) {
+ mask = mask >> 1;
+ first++;
+ }
+
+ while (mask & 0x1) {
+ mask = mask >> 1;
+ len++;
+ }
+ }
+
+ *pos = first;
+ *size = len;
+}
+
+/*
+ * See if we have Graphics Output Protocol
+ */
+static efi_status_t setup_gop(struct screen_info *si, efi_guid_t *proto,
+ unsigned long size)
+{
+ struct efi_graphics_output_protocol *gop, *first_gop;
+ struct efi_pixel_bitmask pixel_info;
+ unsigned long nr_gops;
+ efi_status_t status;
+ void **gop_handle;
+ u16 width, height;
+ u32 fb_base, fb_size;
+ u32 pixels_per_scan_line;
+ int pixel_format;
+ int i;
+
+ status = efi_call_phys3(sys_table->boottime->allocate_pool,
+ EFI_LOADER_DATA, size, &gop_handle);
+ if (status != EFI_SUCCESS)
+ return status;
+
+ status = efi_call_phys5(sys_table->boottime->locate_handle,
+ EFI_LOCATE_BY_PROTOCOL, proto,
+ NULL, &size, gop_handle);
+ if (status != EFI_SUCCESS)
+ goto free_handle;
+
+ first_gop = NULL;
+
+ nr_gops = size / sizeof(void *);
+ for (i = 0; i < nr_gops; i++) {
+ struct efi_graphics_output_mode_info *info;
+ efi_guid_t pciio_proto = EFI_PCI_IO_PROTOCOL_GUID;
+ void *pciio;
+ void *h = gop_handle[i];
+
+ status = efi_call_phys3(sys_table->boottime->handle_protocol,
+ h, proto, &gop);
+ if (status != EFI_SUCCESS)
+ continue;
+
+ efi_call_phys3(sys_table->boottime->handle_protocol,
+ h, &pciio_proto, &pciio);
+
+ status = efi_call_phys4(gop->query_mode, gop,
+ gop->mode->mode, &size, &info);
+ if (status == EFI_SUCCESS && (!first_gop || pciio)) {
+ /*
+ * Apple provide GOPs that are not backed by
+ * real hardware (they're used to handle
+ * multiple displays). The workaround is to
+ * search for a GOP implementing the PCIIO
+ * protocol, and if one isn't found, to just
+ * fallback to the first GOP.
+ */
+ width = info->horizontal_resolution;
+ height = info->vertical_resolution;
+ fb_base = gop->mode->frame_buffer_base;
+ fb_size = gop->mode->frame_buffer_size;
+ pixel_format = info->pixel_format;
+ pixel_info = info->pixel_information;
+ pixels_per_scan_line = info->pixels_per_scan_line;
+
+ /*
+ * Once we've found a GOP supporting PCIIO,
+ * don't bother looking any further.
+ */
+ if (pciio)
+ break;
+
+ first_gop = gop;
+ }
+ }
+
+ /* Did we find any GOPs? */
+ if (!first_gop)
+ goto free_handle;
+
+ /* EFI framebuffer */
+ si->orig_video_isVGA = VIDEO_TYPE_EFI;
+
+ si->lfb_width = width;
+ si->lfb_height = height;
+ si->lfb_base = fb_base;
+ si->lfb_size = fb_size;
+ si->pages = 1;
+
+ if (pixel_format == PIXEL_RGB_RESERVED_8BIT_PER_COLOR) {
+ si->lfb_depth = 32;
+ si->lfb_linelength = pixels_per_scan_line * 4;
+ si->red_size = 8;
+ si->red_pos = 0;
+ si->green_size = 8;
+ si->green_pos = 8;
+ si->blue_size = 8;
+ si->blue_pos = 16;
+ si->rsvd_size = 8;
+ si->rsvd_pos = 24;
+ } else if (pixel_format == PIXEL_BGR_RESERVED_8BIT_PER_COLOR) {
+ si->lfb_depth = 32;
+ si->lfb_linelength = pixels_per_scan_line * 4;
+ si->red_size = 8;
+ si->red_pos = 16;
+ si->green_size = 8;
+ si->green_pos = 8;
+ si->blue_size = 8;
+ si->blue_pos = 0;
+ si->rsvd_size = 8;
+ si->rsvd_pos = 24;
+ } else if (pixel_format == PIXEL_BIT_MASK) {
+ find_bits(pixel_info.red_mask, &si->red_pos, &si->red_size);
+ find_bits(pixel_info.green_mask, &si->green_pos,
+ &si->green_size);
+ find_bits(pixel_info.blue_mask, &si->blue_pos, &si->blue_size);
+ find_bits(pixel_info.reserved_mask, &si->rsvd_pos,
+ &si->rsvd_size);
+ si->lfb_depth = si->red_size + si->green_size +
+ si->blue_size + si->rsvd_size;
+ si->lfb_linelength = (pixels_per_scan_line * si->lfb_depth) / 8;
+ } else {
+ si->lfb_depth = 4;
+ si->lfb_linelength = si->lfb_width / 2;
+ si->red_size = 0;
+ si->red_pos = 0;
+ si->green_size = 0;
+ si->green_pos = 0;
+ si->blue_size = 0;
+ si->blue_pos = 0;
+ si->rsvd_size = 0;
+ si->rsvd_pos = 0;
+ }
+
+free_handle:
+ efi_call_phys1(sys_table->boottime->free_pool, gop_handle);
+ return status;
+}
+
+/*
+ * See if we have Universal Graphics Adapter (UGA) protocol
+ */
+static efi_status_t setup_uga(struct screen_info *si, efi_guid_t *uga_proto,
+ unsigned long size)
+{
+ struct efi_uga_draw_protocol *uga, *first_uga;
+ unsigned long nr_ugas;
+ efi_status_t status;
+ u32 width, height;
+ void **uga_handle = NULL;
+ int i;
+
+ status = efi_call_phys3(sys_table->boottime->allocate_pool,
+ EFI_LOADER_DATA, size, &uga_handle);
+ if (status != EFI_SUCCESS)
+ return status;
+
+ status = efi_call_phys5(sys_table->boottime->locate_handle,
+ EFI_LOCATE_BY_PROTOCOL, uga_proto,
+ NULL, &size, uga_handle);
+ if (status != EFI_SUCCESS)
+ goto free_handle;
+
+ first_uga = NULL;
+
+ nr_ugas = size / sizeof(void *);
+ for (i = 0; i < nr_ugas; i++) {
+ efi_guid_t pciio_proto = EFI_PCI_IO_PROTOCOL_GUID;
+ void *handle = uga_handle[i];
+ u32 w, h, depth, refresh;
+ void *pciio;
+
+ status = efi_call_phys3(sys_table->boottime->handle_protocol,
+ handle, uga_proto, &uga);
+ if (status != EFI_SUCCESS)
+ continue;
+
+ efi_call_phys3(sys_table->boottime->handle_protocol,
+ handle, &pciio_proto, &pciio);
+
+ status = efi_call_phys5(uga->get_mode, uga, &w, &h,
+ &depth, &refresh);
+ if (status == EFI_SUCCESS && (!first_uga || pciio)) {
+ width = w;
+ height = h;
+
+ /*
+ * Once we've found a UGA supporting PCIIO,
+ * don't bother looking any further.
+ */
+ if (pciio)
+ break;
+
+ first_uga = uga;
+ }
+ }
+
+ if (!first_uga)
+ goto free_handle;
+
+ /* EFI framebuffer */
+ si->orig_video_isVGA = VIDEO_TYPE_EFI;
+
+ si->lfb_depth = 32;
+ si->lfb_width = width;
+ si->lfb_height = height;
+
+ si->red_size = 8;
+ si->red_pos = 16;
+ si->green_size = 8;
+ si->green_pos = 8;
+ si->blue_size = 8;
+ si->blue_pos = 0;
+ si->rsvd_size = 8;
+ si->rsvd_pos = 24;
+
+
+free_handle:
+ efi_call_phys1(sys_table->boottime->free_pool, uga_handle);
+ return status;
+}
+
+void setup_graphics(struct boot_params *boot_params)
+{
+ efi_guid_t graphics_proto = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
+ struct screen_info *si;
+ efi_guid_t uga_proto = EFI_UGA_PROTOCOL_GUID;
+ efi_status_t status;
+ unsigned long size;
+ void **gop_handle = NULL;
+ void **uga_handle = NULL;
+
+ si = &boot_params->screen_info;
+ memset(si, 0, sizeof(*si));
+
+ size = 0;
+ status = efi_call_phys5(sys_table->boottime->locate_handle,
+ EFI_LOCATE_BY_PROTOCOL, &graphics_proto,
+ NULL, &size, gop_handle);
+ if (status == EFI_BUFFER_TOO_SMALL)
+ status = setup_gop(si, &graphics_proto, size);
+
+ if (status != EFI_SUCCESS) {
+ size = 0;
+ status = efi_call_phys5(sys_table->boottime->locate_handle,
+ EFI_LOCATE_BY_PROTOCOL, &uga_proto,
+ NULL, &size, uga_handle);
+ if (status == EFI_BUFFER_TOO_SMALL)
+ setup_uga(si, &uga_proto, size);
+ }
+}
+
+struct initrd {
+ efi_file_handle_t *handle;
+ u64 size;
+};
+
+/*
+ * Check the cmdline for a LILO-style initrd= arguments.
+ *
+ * We only support loading an initrd from the same filesystem as the
+ * kernel image.
+ */
+static efi_status_t handle_ramdisks(efi_loaded_image_t *image,
+ struct setup_header *hdr)
+{
+ struct initrd *initrds;
+ unsigned long initrd_addr;
+ efi_guid_t fs_proto = EFI_FILE_SYSTEM_GUID;
+ u64 initrd_total;
+ efi_file_io_interface_t *io;
+ efi_file_handle_t *fh;
+ efi_status_t status;
+ int nr_initrds;
+ char *str;
+ int i, j, k;
+
+ initrd_addr = 0;
+ initrd_total = 0;
+
+ str = (char *)(unsigned long)hdr->cmd_line_ptr;
+
+ j = 0; /* See close_handles */
+
+ if (!str || !*str)
+ return EFI_SUCCESS;
+
+ for (nr_initrds = 0; *str; nr_initrds++) {
+ str = strstr(str, "initrd=");
+ if (!str)
+ break;
+
+ str += 7;
+
+ /* Skip any leading slashes */
+ while (*str == '/' || *str == '\\')
+ str++;
+
+ while (*str && *str != ' ' && *str != '\n')
+ str++;
+ }
+
+ if (!nr_initrds)
+ return EFI_SUCCESS;
+
+ status = efi_call_phys3(sys_table->boottime->allocate_pool,
+ EFI_LOADER_DATA,
+ nr_initrds * sizeof(*initrds),
+ &initrds);
+ if (status != EFI_SUCCESS)
+ goto fail;
+
+ str = (char *)(unsigned long)hdr->cmd_line_ptr;
+ for (i = 0; i < nr_initrds; i++) {
+ struct initrd *initrd;
+ efi_file_handle_t *h;
+ efi_file_info_t *info;
+ efi_char16_t filename[256];
+ unsigned long info_sz;
+ efi_guid_t info_guid = EFI_FILE_INFO_ID;
+ efi_char16_t *p;
+ u64 file_sz;
+
+ str = strstr(str, "initrd=");
+ if (!str)
+ break;
+
+ str += 7;
+
+ initrd = &initrds[i];
+ p = filename;
+
+ /* Skip any leading slashes */
+ while (*str == '/' || *str == '\\')
+ str++;
+
+ while (*str && *str != ' ' && *str != '\n') {
+ if (p >= filename + sizeof(filename))
+ break;
+
+ *p++ = *str++;
+ }
+
+ *p = '\0';
+
+ /* Only open the volume once. */
+ if (!i) {
+ efi_boot_services_t *boottime;
+
+ boottime = sys_table->boottime;
+
+ status = efi_call_phys3(boottime->handle_protocol,
+ image->device_handle, &fs_proto, &io);
+ if (status != EFI_SUCCESS)
+ goto free_initrds;
+
+ status = efi_call_phys2(io->open_volume, io, &fh);
+ if (status != EFI_SUCCESS)
+ goto free_initrds;
+ }
+
+ status = efi_call_phys5(fh->open, fh, &h, filename,
+ EFI_FILE_MODE_READ, (u64)0);
+ if (status != EFI_SUCCESS)
+ goto close_handles;
+
+ initrd->handle = h;
+
+ info_sz = 0;
+ status = efi_call_phys4(h->get_info, h, &info_guid,
+ &info_sz, NULL);
+ if (status != EFI_BUFFER_TOO_SMALL)
+ goto close_handles;
+
+grow:
+ status = efi_call_phys3(sys_table->boottime->allocate_pool,
+ EFI_LOADER_DATA, info_sz, &info);
+ if (status != EFI_SUCCESS)
+ goto close_handles;
+
+ status = efi_call_phys4(h->get_info, h, &info_guid,
+ &info_sz, info);
+ if (status == EFI_BUFFER_TOO_SMALL) {
+ efi_call_phys1(sys_table->boottime->free_pool, info);
+ goto grow;
+ }
+
+ file_sz = info->file_size;
+ efi_call_phys1(sys_table->boottime->free_pool, info);
+
+ if (status != EFI_SUCCESS)
+ goto close_handles;
+
+ initrd->size = file_sz;
+ initrd_total += file_sz;
+ }
+
+ if (initrd_total) {
+ unsigned long addr;
+
+ /*
+ * Multiple initrd's need to be at consecutive
+ * addresses in memory, so allocate enough memory for
+ * all the initrd's.
+ */
+ status = high_alloc(initrd_total, 0x1000,
+ &initrd_addr, hdr->initrd_addr_max);
+ if (status != EFI_SUCCESS)
+ goto close_handles;
+
+ /* We've run out of free low memory. */
+ if (initrd_addr > hdr->initrd_addr_max) {
+ status = EFI_INVALID_PARAMETER;
+ goto free_initrd_total;
+ }
+
+ addr = initrd_addr;
+ for (j = 0; j < nr_initrds; j++) {
+ u64 size;
+
+ size = initrds[j].size;
+ while (size) {
+ u64 chunksize;
+ if (size > EFI_READ_CHUNK_SIZE)
+ chunksize = EFI_READ_CHUNK_SIZE;
+ else
+ chunksize = size;
+ status = efi_call_phys3(fh->read,
+ initrds[j].handle,
+ &chunksize, addr);
+ if (status != EFI_SUCCESS)
+ goto free_initrd_total;
+ addr += chunksize;
+ size -= chunksize;
+ }
+
+ efi_call_phys1(fh->close, initrds[j].handle);
+ }
+
+ }
+
+ efi_call_phys1(sys_table->boottime->free_pool, initrds);
+
+ hdr->ramdisk_image = initrd_addr;
+ hdr->ramdisk_size = initrd_total;
+
+ return status;
+
+free_initrd_total:
+ low_free(initrd_total, initrd_addr);
+
+close_handles:
+ for (k = j; k < nr_initrds; k++)
+ efi_call_phys1(fh->close, initrds[k].handle);
+free_initrds:
+ efi_call_phys1(sys_table->boottime->free_pool, initrds);
+fail:
+ hdr->ramdisk_image = 0;
+ hdr->ramdisk_size = 0;
+
+ return status;
+}
+
+/*
+ * Because the x86 boot code expects to be passed a boot_params we
+ * need to create one ourselves (usually the bootloader would create
+ * one for us).
+ */
+static efi_status_t make_boot_params(struct boot_params *boot_params,
+ efi_loaded_image_t *image,
+ void *handle)
+{
+ struct efi_info *efi = &boot_params->efi_info;
+ struct apm_bios_info *bi = &boot_params->apm_bios_info;
+ struct sys_desc_table *sdt = &boot_params->sys_desc_table;
+ struct e820entry *e820_map = &boot_params->e820_map[0];
+ struct e820entry *prev = NULL;
+ struct setup_header *hdr = &boot_params->hdr;
+ unsigned long size, key, desc_size, _size;
+ efi_memory_desc_t *mem_map;
+ void *options = image->load_options;
+ u32 load_options_size = image->load_options_size / 2; /* ASCII */
+ int options_size = 0;
+ efi_status_t status;
+ __u32 desc_version;
+ unsigned long cmdline;
+ u8 nr_entries;
+ u16 *s2;
+ u8 *s1;
+ int i;
+
+ hdr->type_of_loader = 0x21;
+
+ /* Convert unicode cmdline to ascii */
+ cmdline = 0;
+ s2 = (u16 *)options;
+
+ if (s2) {
+ while (*s2 && *s2 != '\n' && options_size < load_options_size) {
+ s2++;
+ options_size++;
+ }
+
+ if (options_size) {
+ if (options_size > hdr->cmdline_size)
+ options_size = hdr->cmdline_size;
+
+ options_size++; /* NUL termination */
+
+ status = low_alloc(options_size, 1, &cmdline);
+ if (status != EFI_SUCCESS)
+ goto fail;
+
+ s1 = (u8 *)(unsigned long)cmdline;
+ s2 = (u16 *)options;
+
+ for (i = 0; i < options_size - 1; i++)
+ *s1++ = *s2++;
+
+ *s1 = '\0';
+ }
+ }
+
+ hdr->cmd_line_ptr = cmdline;
+
+ hdr->ramdisk_image = 0;
+ hdr->ramdisk_size = 0;
+
+ status = handle_ramdisks(image, hdr);
+ if (status != EFI_SUCCESS)
+ goto free_cmdline;
+
+ setup_graphics(boot_params);
+
+ /* Clear APM BIOS info */
+ memset(bi, 0, sizeof(*bi));
+
+ memset(sdt, 0, sizeof(*sdt));
+
+ memcpy(&efi->efi_loader_signature, EFI_LOADER_SIGNATURE, sizeof(__u32));
+
+ size = sizeof(*mem_map) * 32;
+
+again:
+ size += sizeof(*mem_map);
+ _size = size;
+ status = low_alloc(size, 1, (unsigned long *)&mem_map);
+ if (status != EFI_SUCCESS)
+ goto free_cmdline;
+
+ status = efi_call_phys5(sys_table->boottime->get_memory_map, &size,
+ mem_map, &key, &desc_size, &desc_version);
+ if (status == EFI_BUFFER_TOO_SMALL) {
+ low_free(_size, (unsigned long)mem_map);
+ goto again;
+ }
+
+ if (status != EFI_SUCCESS)
+ goto free_mem_map;
+
+ efi->efi_systab = (unsigned long)sys_table;
+ efi->efi_memdesc_size = desc_size;
+ efi->efi_memdesc_version = desc_version;
+ efi->efi_memmap = (unsigned long)mem_map;
+ efi->efi_memmap_size = size;
+
+#ifdef CONFIG_X86_64
+ efi->efi_systab_hi = (unsigned long)sys_table >> 32;
+ efi->efi_memmap_hi = (unsigned long)mem_map >> 32;
+#endif
+
+ /* Might as well exit boot services now */
+ status = efi_call_phys2(sys_table->boottime->exit_boot_services,
+ handle, key);
+ if (status != EFI_SUCCESS)
+ goto free_mem_map;
+
+ /* Historic? */
+ boot_params->alt_mem_k = 32 * 1024;
+
+ /*
+ * Convert the EFI memory map to E820.
+ */
+ nr_entries = 0;
+ for (i = 0; i < size / desc_size; i++) {
+ efi_memory_desc_t *d;
+ unsigned int e820_type = 0;
+ unsigned long m = (unsigned long)mem_map;
+
+ d = (efi_memory_desc_t *)(m + (i * desc_size));
+ switch (d->type) {
+ case EFI_RESERVED_TYPE:
+ case EFI_RUNTIME_SERVICES_CODE:
+ case EFI_RUNTIME_SERVICES_DATA:
+ case EFI_MEMORY_MAPPED_IO:
+ case EFI_MEMORY_MAPPED_IO_PORT_SPACE:
+ case EFI_PAL_CODE:
+ e820_type = E820_RESERVED;
+ break;
+
+ case EFI_UNUSABLE_MEMORY:
+ e820_type = E820_UNUSABLE;
+ break;
+
+ case EFI_ACPI_RECLAIM_MEMORY:
+ e820_type = E820_ACPI;
+ break;
+
+ case EFI_LOADER_CODE:
+ case EFI_LOADER_DATA:
+ case EFI_BOOT_SERVICES_CODE:
+ case EFI_BOOT_SERVICES_DATA:
+ case EFI_CONVENTIONAL_MEMORY:
+ e820_type = E820_RAM;
+ break;
+
+ case EFI_ACPI_MEMORY_NVS:
+ e820_type = E820_NVS;
+ break;
+
+ default:
+ continue;
+ }
+
+ /* Merge adjacent mappings */
+ if (prev && prev->type == e820_type &&
+ (prev->addr + prev->size) == d->phys_addr)
+ prev->size += d->num_pages << 12;
+ else {
+ e820_map->addr = d->phys_addr;
+ e820_map->size = d->num_pages << 12;
+ e820_map->type = e820_type;
+ prev = e820_map++;
+ nr_entries++;
+ }
+ }
+
+ boot_params->e820_entries = nr_entries;
+
+ return EFI_SUCCESS;
+
+free_mem_map:
+ low_free(_size, (unsigned long)mem_map);
+free_cmdline:
+ if (options_size)
+ low_free(options_size, hdr->cmd_line_ptr);
+fail:
+ return status;
+}
+
+/*
+ * On success we return a pointer to a boot_params structure, and NULL
+ * on failure.
+ */
+struct boot_params *efi_main(void *handle, efi_system_table_t *_table)
+{
+ struct boot_params *boot_params;
+ unsigned long start, nr_pages;
+ struct desc_ptr *gdt, *idt;
+ efi_loaded_image_t *image;
+ struct setup_header *hdr;
+ efi_status_t status;
+ efi_guid_t proto = LOADED_IMAGE_PROTOCOL_GUID;
+ struct desc_struct *desc;
+
+ sys_table = _table;
+
+ /* Check if we were booted by the EFI firmware */
+ if (sys_table->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE)
+ goto fail;
+
+ status = efi_call_phys3(sys_table->boottime->handle_protocol,
+ handle, &proto, (void *)&image);
+ if (status != EFI_SUCCESS)
+ goto fail;
+
+ status = low_alloc(0x4000, 1, (unsigned long *)&boot_params);
+ if (status != EFI_SUCCESS)
+ goto fail;
+
+ memset(boot_params, 0x0, 0x4000);
+
+ /* Copy first two sectors to boot_params */
+ memcpy(boot_params, image->image_base, 1024);
+
+ hdr = &boot_params->hdr;
+
+ /*
+ * The EFI firmware loader could have placed the kernel image
+ * anywhere in memory, but the kernel has various restrictions
+ * on the max physical address it can run at. Attempt to move
+ * the kernel to boot_params.pref_address, or as low as
+ * possible.
+ */
+ start = hdr->pref_address;
+ nr_pages = round_up(hdr->init_size, EFI_PAGE_SIZE) / EFI_PAGE_SIZE;
+
+ status = efi_call_phys4(sys_table->boottime->allocate_pages,
+ EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA,
+ nr_pages, &start);
+ if (status != EFI_SUCCESS) {
+ status = low_alloc(hdr->init_size, hdr->kernel_alignment,
+ &start);
+ if (status != EFI_SUCCESS)
+ goto fail;
+ }
+
+ hdr->code32_start = (__u32)start;
+ hdr->pref_address = (__u64)(unsigned long)image->image_base;
+
+ memcpy((void *)start, image->image_base, image->image_size);
+
+ status = efi_call_phys3(sys_table->boottime->allocate_pool,
+ EFI_LOADER_DATA, sizeof(*gdt),
+ (void **)&gdt);
+ if (status != EFI_SUCCESS)
+ goto fail;
+
+ gdt->size = 0x800;
+ status = low_alloc(gdt->size, 8, (unsigned long *)&gdt->address);
+ if (status != EFI_SUCCESS)
+ goto fail;
+
+ status = efi_call_phys3(sys_table->boottime->allocate_pool,
+ EFI_LOADER_DATA, sizeof(*idt),
+ (void **)&idt);
+ if (status != EFI_SUCCESS)
+ goto fail;
+
+ idt->size = 0;
+ idt->address = 0;
+
+ status = make_boot_params(boot_params, image, handle);
+ if (status != EFI_SUCCESS)
+ goto fail;
+
+ memset((char *)gdt->address, 0x0, gdt->size);
+ desc = (struct desc_struct *)gdt->address;
+
+ /* The first GDT is a dummy and the second is unused. */
+ desc += 2;
+
+ desc->limit0 = 0xffff;
+ desc->base0 = 0x0000;
+ desc->base1 = 0x0000;
+ desc->type = SEG_TYPE_CODE | SEG_TYPE_EXEC_READ;
+ desc->s = DESC_TYPE_CODE_DATA;
+ desc->dpl = 0;
+ desc->p = 1;
+ desc->limit = 0xf;
+ desc->avl = 0;
+ desc->l = 0;
+ desc->d = SEG_OP_SIZE_32BIT;
+ desc->g = SEG_GRANULARITY_4KB;
+ desc->base2 = 0x00;
+
+ desc++;
+ desc->limit0 = 0xffff;
+ desc->base0 = 0x0000;
+ desc->base1 = 0x0000;
+ desc->type = SEG_TYPE_DATA | SEG_TYPE_READ_WRITE;
+ desc->s = DESC_TYPE_CODE_DATA;
+ desc->dpl = 0;
+ desc->p = 1;
+ desc->limit = 0xf;
+ desc->avl = 0;
+ desc->l = 0;
+ desc->d = SEG_OP_SIZE_32BIT;
+ desc->g = SEG_GRANULARITY_4KB;
+ desc->base2 = 0x00;
+
+#ifdef CONFIG_X86_64
+ /* Task segment value */
+ desc++;
+ desc->limit0 = 0x0000;
+ desc->base0 = 0x0000;
+ desc->base1 = 0x0000;
+ desc->type = SEG_TYPE_TSS;
+ desc->s = 0;
+ desc->dpl = 0;
+ desc->p = 1;
+ desc->limit = 0x0;
+ desc->avl = 0;
+ desc->l = 0;
+ desc->d = 0;
+ desc->g = SEG_GRANULARITY_4KB;
+ desc->base2 = 0x00;
+#endif /* CONFIG_X86_64 */
+
+ asm volatile ("lidt %0" : : "m" (*idt));
+ asm volatile ("lgdt %0" : : "m" (*gdt));
+
+ asm volatile("cli");
+
+ return boot_params;
+fail:
+ return NULL;
+}
diff --git a/arch/x86/boot/compressed/eboot.h b/arch/x86/boot/compressed/eboot.h
new file mode 100644
index 0000000..3925166
--- /dev/null
+++ b/arch/x86/boot/compressed/eboot.h
@@ -0,0 +1,61 @@
+#ifndef BOOT_COMPRESSED_EBOOT_H
+#define BOOT_COMPRESSED_EBOOT_H
+
+#define SEG_TYPE_DATA (0 << 3)
+#define SEG_TYPE_READ_WRITE (1 << 1)
+#define SEG_TYPE_CODE (1 << 3)
+#define SEG_TYPE_EXEC_READ (1 << 1)
+#define SEG_TYPE_TSS ((1 << 3) | (1 << 0))
+#define SEG_OP_SIZE_32BIT (1 << 0)
+#define SEG_GRANULARITY_4KB (1 << 0)
+
+#define DESC_TYPE_CODE_DATA (1 << 0)
+
+#define EFI_PAGE_SIZE (1UL << EFI_PAGE_SHIFT)
+#define EFI_READ_CHUNK_SIZE (1024 * 1024)
+
+#define PIXEL_RGB_RESERVED_8BIT_PER_COLOR 0
+#define PIXEL_BGR_RESERVED_8BIT_PER_COLOR 1
+#define PIXEL_BIT_MASK 2
+#define PIXEL_BLT_ONLY 3
+#define PIXEL_FORMAT_MAX 4
+
+struct efi_pixel_bitmask {
+ u32 red_mask;
+ u32 green_mask;
+ u32 blue_mask;
+ u32 reserved_mask;
+};
+
+struct efi_graphics_output_mode_info {
+ u32 version;
+ u32 horizontal_resolution;
+ u32 vertical_resolution;
+ int pixel_format;
+ struct efi_pixel_bitmask pixel_information;
+ u32 pixels_per_scan_line;
+} __packed;
+
+struct efi_graphics_output_protocol_mode {
+ u32 max_mode;
+ u32 mode;
+ unsigned long info;
+ unsigned long size_of_info;
+ u64 frame_buffer_base;
+ unsigned long frame_buffer_size;
+} __packed;
+
+struct efi_graphics_output_protocol {
+ void *query_mode;
+ unsigned long set_mode;
+ unsigned long blt;
+ struct efi_graphics_output_protocol_mode *mode;
+};
+
+struct efi_uga_draw_protocol {
+ void *get_mode;
+ void *set_mode;
+ void *blt;
+};
+
+#endif /* BOOT_COMPRESSED_EBOOT_H */
diff --git a/arch/x86/boot/compressed/efi_stub_32.S b/arch/x86/boot/compressed/efi_stub_32.S
new file mode 100644
index 0000000..a53440e
--- /dev/null
+++ b/arch/x86/boot/compressed/efi_stub_32.S
@@ -0,0 +1,86 @@
+/*
+ * EFI call stub for IA32.
+ *
+ * This stub allows us to make EFI calls in physical mode with interrupts
+ * turned off. Note that this implementation is different from the one in
+ * arch/x86/platform/efi/efi_stub_32.S because we're _already_ in physical
+ * mode at this point.
+ */
+
+#include <linux/linkage.h>
+#include <asm/page_types.h>
+
+/*
+ * efi_call_phys(void *, ...) is a function with variable parameters.
+ * All the callers of this function assure that all the parameters are 4-bytes.
+ */
+
+/*
+ * In gcc calling convention, EBX, ESP, EBP, ESI and EDI are all callee save.
+ * So we'd better save all of them at the beginning of this function and restore
+ * at the end no matter how many we use, because we can not assure EFI runtime
+ * service functions will comply with gcc calling convention, too.
+ */
+
+.text
+ENTRY(efi_call_phys)
+ /*
+ * 0. The function can only be called in Linux kernel. So CS has been
+ * set to 0x0010, DS and SS have been set to 0x0018. In EFI, I found
+ * the values of these registers are the same. And, the corresponding
+ * GDT entries are identical. So I will do nothing about segment reg
+ * and GDT, but change GDT base register in prelog and epilog.
+ */
+
+ /*
+ * 1. Because we haven't been relocated by this point we need to
+ * use relative addressing.
+ */
+ call 1f
+1: popl %edx
+ subl $1b, %edx
+
+ /*
+ * 2. Now on the top of stack is the return
+ * address in the caller of efi_call_phys(), then parameter 1,
+ * parameter 2, ..., param n. To make things easy, we save the return
+ * address of efi_call_phys in a global variable.
+ */
+ popl %ecx
+ movl %ecx, saved_return_addr(%edx)
+ /* get the function pointer into ECX*/
+ popl %ecx
+ movl %ecx, efi_rt_function_ptr(%edx)
+
+ /*
+ * 3. Call the physical function.
+ */
+ call *%ecx
+
+ /*
+ * 4. Balance the stack. And because EAX contain the return value,
+ * we'd better not clobber it. We need to calculate our address
+ * again because %ecx and %edx are not preserved across EFI function
+ * calls.
+ */
+ call 1f
+1: popl %edx
+ subl $1b, %edx
+
+ movl efi_rt_function_ptr(%edx), %ecx
+ pushl %ecx
+
+ /*
+ * 10. Push the saved return address onto the stack and return.
+ */
+ movl saved_return_addr(%edx), %ecx
+ pushl %ecx
+ ret
+ENDPROC(efi_call_phys)
+.previous
+
+.data
+saved_return_addr:
+ .long 0
+efi_rt_function_ptr:
+ .long 0
diff --git a/arch/x86/boot/compressed/efi_stub_64.S b/arch/x86/boot/compressed/efi_stub_64.S
new file mode 100644
index 0000000..cedc60d
--- /dev/null
+++ b/arch/x86/boot/compressed/efi_stub_64.S
@@ -0,0 +1 @@
+#include "../../platform/efi/efi_stub_64.S"
diff --git a/arch/x86/boot/compressed/head_32.S b/arch/x86/boot/compressed/head_32.S
index 67a655a..a055993 100644
--- a/arch/x86/boot/compressed/head_32.S
+++ b/arch/x86/boot/compressed/head_32.S
@@ -32,6 +32,28 @@
__HEAD
ENTRY(startup_32)
+#ifdef CONFIG_EFI_STUB
+ /*
+ * We don't need the return address, so set up the stack so
+ * efi_main() can find its arugments.
+ */
+ add $0x4, %esp
+
+ call efi_main
+ cmpl $0, %eax
+ je preferred_addr
+ movl %eax, %esi
+ call 1f
+1:
+ popl %eax
+ subl $1b, %eax
+ subl BP_pref_address(%esi), %eax
+ add BP_code32_start(%esi), %eax
+ leal preferred_addr(%eax), %eax
+ jmp *%eax
+
+preferred_addr:
+#endif
cld
/*
* Test KEEP_SEGMENTS flag to see if the bootloader is asking
diff --git a/arch/x86/boot/compressed/head_64.S b/arch/x86/boot/compressed/head_64.S
index 35af09d..558d76c 100644
--- a/arch/x86/boot/compressed/head_64.S
+++ b/arch/x86/boot/compressed/head_64.S
@@ -199,6 +199,26 @@
* an identity mapped page table being provied that maps our
* entire text+data+bss and hopefully all of memory.
*/
+#ifdef CONFIG_EFI_STUB
+ pushq %rsi
+ mov %rcx, %rdi
+ mov %rdx, %rsi
+ call efi_main
+ popq %rsi
+ cmpq $0,%rax
+ je preferred_addr
+ movq %rax,%rsi
+ call 1f
+1:
+ popq %rax
+ subq $1b, %rax
+ subq BP_pref_address(%rsi), %rax
+ add BP_code32_start(%esi), %eax
+ leaq preferred_addr(%rax), %rax
+ jmp *%rax
+
+preferred_addr:
+#endif
/* Setup data segments. */
xorl %eax, %eax
diff --git a/arch/x86/boot/compressed/string.c b/arch/x86/boot/compressed/string.c
index 19b3e69..ffb9c5c 100644
--- a/arch/x86/boot/compressed/string.c
+++ b/arch/x86/boot/compressed/string.c
@@ -1,2 +1,11 @@
#include "misc.h"
+
+int memcmp(const void *s1, const void *s2, size_t len)
+{
+ u8 diff;
+ asm("repe; cmpsb; setnz %0"
+ : "=qm" (diff), "+D" (s1), "+S" (s2), "+c" (len));
+ return diff;
+}
+
#include "../string.c"
diff --git a/arch/x86/boot/header.S b/arch/x86/boot/header.S
index bdb4d45..f1bbeeb 100644
--- a/arch/x86/boot/header.S
+++ b/arch/x86/boot/header.S
@@ -45,6 +45,11 @@
.global bootsect_start
bootsect_start:
+#ifdef CONFIG_EFI_STUB
+ # "MZ", MS-DOS header
+ .byte 0x4d
+ .byte 0x5a
+#endif
# Normalize the start address
ljmp $BOOTSEG, $start2
@@ -79,6 +84,14 @@
# invoke the BIOS reset code...
ljmp $0xf000,$0xfff0
+#ifdef CONFIG_EFI_STUB
+ .org 0x3c
+ #
+ # Offset to the PE header.
+ #
+ .long pe_header
+#endif /* CONFIG_EFI_STUB */
+
.section ".bsdata", "a"
bugger_off_msg:
.ascii "Direct booting from floppy is no longer supported.\r\n"
@@ -87,6 +100,141 @@
.ascii "Remove disk and press any key to reboot . . .\r\n"
.byte 0
+#ifdef CONFIG_EFI_STUB
+pe_header:
+ .ascii "PE"
+ .word 0
+
+coff_header:
+#ifdef CONFIG_X86_32
+ .word 0x14c # i386
+#else
+ .word 0x8664 # x86-64
+#endif
+ .word 2 # nr_sections
+ .long 0 # TimeDateStamp
+ .long 0 # PointerToSymbolTable
+ .long 1 # NumberOfSymbols
+ .word section_table - optional_header # SizeOfOptionalHeader
+#ifdef CONFIG_X86_32
+ .word 0x306 # Characteristics.
+ # IMAGE_FILE_32BIT_MACHINE |
+ # IMAGE_FILE_DEBUG_STRIPPED |
+ # IMAGE_FILE_EXECUTABLE_IMAGE |
+ # IMAGE_FILE_LINE_NUMS_STRIPPED
+#else
+ .word 0x206 # Characteristics
+ # IMAGE_FILE_DEBUG_STRIPPED |
+ # IMAGE_FILE_EXECUTABLE_IMAGE |
+ # IMAGE_FILE_LINE_NUMS_STRIPPED
+#endif
+
+optional_header:
+#ifdef CONFIG_X86_32
+ .word 0x10b # PE32 format
+#else
+ .word 0x20b # PE32+ format
+#endif
+ .byte 0x02 # MajorLinkerVersion
+ .byte 0x14 # MinorLinkerVersion
+
+ # Filled in by build.c
+ .long 0 # SizeOfCode
+
+ .long 0 # SizeOfInitializedData
+ .long 0 # SizeOfUninitializedData
+
+ # Filled in by build.c
+ .long 0x0000 # AddressOfEntryPoint
+
+ .long 0x0000 # BaseOfCode
+#ifdef CONFIG_X86_32
+ .long 0 # data
+#endif
+
+extra_header_fields:
+#ifdef CONFIG_X86_32
+ .long 0 # ImageBase
+#else
+ .quad 0 # ImageBase
+#endif
+ .long 0x1000 # SectionAlignment
+ .long 0x200 # FileAlignment
+ .word 0 # MajorOperatingSystemVersion
+ .word 0 # MinorOperatingSystemVersion
+ .word 0 # MajorImageVersion
+ .word 0 # MinorImageVersion
+ .word 0 # MajorSubsystemVersion
+ .word 0 # MinorSubsystemVersion
+ .long 0 # Win32VersionValue
+
+ #
+ # The size of the bzImage is written in tools/build.c
+ #
+ .long 0 # SizeOfImage
+
+ .long 0x200 # SizeOfHeaders
+ .long 0 # CheckSum
+ .word 0xa # Subsystem (EFI application)
+ .word 0 # DllCharacteristics
+#ifdef CONFIG_X86_32
+ .long 0 # SizeOfStackReserve
+ .long 0 # SizeOfStackCommit
+ .long 0 # SizeOfHeapReserve
+ .long 0 # SizeOfHeapCommit
+#else
+ .quad 0 # SizeOfStackReserve
+ .quad 0 # SizeOfStackCommit
+ .quad 0 # SizeOfHeapReserve
+ .quad 0 # SizeOfHeapCommit
+#endif
+ .long 0 # LoaderFlags
+ .long 0x1 # NumberOfRvaAndSizes
+
+ .quad 0 # ExportTable
+ .quad 0 # ImportTable
+ .quad 0 # ResourceTable
+ .quad 0 # ExceptionTable
+ .quad 0 # CertificationTable
+ .quad 0 # BaseRelocationTable
+
+ # Section table
+section_table:
+ .ascii ".text"
+ .byte 0
+ .byte 0
+ .byte 0
+ .long 0
+ .long 0x0 # startup_{32,64}
+ .long 0 # Size of initialized data
+ # on disk
+ .long 0x0 # startup_{32,64}
+ .long 0 # PointerToRelocations
+ .long 0 # PointerToLineNumbers
+ .word 0 # NumberOfRelocations
+ .word 0 # NumberOfLineNumbers
+ .long 0x60500020 # Characteristics (section flags)
+
+ #
+ # The EFI application loader requires a relocation section
+ # because EFI applications are relocatable and not having
+ # this section seems to confuse it. But since we don't need
+ # the loader to fixup any relocs for us just fill it with a
+ # single dummy reloc.
+ #
+ .ascii ".reloc"
+ .byte 0
+ .byte 0
+ .long reloc_end - reloc_start
+ .long reloc_start
+ .long reloc_end - reloc_start # SizeOfRawData
+ .long reloc_start # PointerToRawData
+ .long 0 # PointerToRelocations
+ .long 0 # PointerToLineNumbers
+ .word 0 # NumberOfRelocations
+ .word 0 # NumberOfLineNumbers
+ .long 0x42100040 # Characteristics (section flags)
+#endif /* CONFIG_EFI_STUB */
# Kernel attributes; used by setup. This is part 1 of the
# header, from the old boot sector.
@@ -318,3 +466,13 @@
setup_corrupt:
.byte 7
.string "No setup signature found...\n"
+
+ .data
+dummy: .long 0
+
+ .section .reloc
+reloc_start:
+ .long dummy - reloc_start
+ .long 10
+ .word 0
+reloc_end:
diff --git a/arch/x86/boot/string.c b/arch/x86/boot/string.c
index 3cbc405..574dedf 100644
--- a/arch/x86/boot/string.c
+++ b/arch/x86/boot/string.c
@@ -111,3 +111,38 @@
return result;
}
+
+/**
+ * strlen - Find the length of a string
+ * @s: The string to be sized
+ */
+size_t strlen(const char *s)
+{
+ const char *sc;
+
+ for (sc = s; *sc != '\0'; ++sc)
+ /* nothing */;
+ return sc - s;
+}
+
+/**
+ * strstr - Find the first substring in a %NUL terminated string
+ * @s1: The string to be searched
+ * @s2: The string to search for
+ */
+char *strstr(const char *s1, const char *s2)
+{
+ size_t l1, l2;
+
+ l2 = strlen(s2);
+ if (!l2)
+ return (char *)s1;
+ l1 = strlen(s1);
+ while (l1 >= l2) {
+ l1--;
+ if (!memcmp(s1, s2, l2))
+ return (char *)s1;
+ s1++;
+ }
+ return NULL;
+}
diff --git a/arch/x86/boot/tools/build.c b/arch/x86/boot/tools/build.c
index fdc60a0..4e9bd6b 100644
--- a/arch/x86/boot/tools/build.c
+++ b/arch/x86/boot/tools/build.c
@@ -135,6 +135,9 @@
int main(int argc, char ** argv)
{
+#ifdef CONFIG_EFI_STUB
+ unsigned int file_sz, pe_header;
+#endif
unsigned int i, sz, setup_sectors;
int c;
u32 sys_size;
@@ -194,6 +197,42 @@
buf[0x1f6] = sys_size >> 16;
buf[0x1f7] = sys_size >> 24;
+#ifdef CONFIG_EFI_STUB
+ file_sz = sz + i + ((sys_size * 16) - sz);
+
+ pe_header = *(unsigned int *)&buf[0x3c];
+
+ /* Size of code */
+ *(unsigned int *)&buf[pe_header + 0x1c] = file_sz;
+
+ /* Size of image */
+ *(unsigned int *)&buf[pe_header + 0x50] = file_sz;
+
+#ifdef CONFIG_X86_32
+ /* Address of entry point */
+ *(unsigned int *)&buf[pe_header + 0x28] = i;
+
+ /* .text size */
+ *(unsigned int *)&buf[pe_header + 0xb0] = file_sz;
+
+ /* .text size of initialised data */
+ *(unsigned int *)&buf[pe_header + 0xb8] = file_sz;
+#else
+ /*
+ * Address of entry point. startup_32 is at the beginning and
+ * the 64-bit entry point (startup_64) is always 512 bytes
+ * after.
+ */
+ *(unsigned int *)&buf[pe_header + 0x28] = i + 512;
+
+ /* .text size */
+ *(unsigned int *)&buf[pe_header + 0xc0] = file_sz;
+
+ /* .text size of initialised data */
+ *(unsigned int *)&buf[pe_header + 0xc8] = file_sz;
+#endif /* CONFIG_X86_32 */
+#endif /* CONFIG_EFI_STUB */
+
crc = partial_crc32(buf, i, crc);
if (fwrite(buf, 1, i, stdout) != i)
die("Writing setup failed");
diff --git a/arch/x86/crypto/Makefile b/arch/x86/crypto/Makefile
index 3537d4b..2b0b963 100644
--- a/arch/x86/crypto/Makefile
+++ b/arch/x86/crypto/Makefile
@@ -5,12 +5,14 @@
obj-$(CONFIG_CRYPTO_AES_586) += aes-i586.o
obj-$(CONFIG_CRYPTO_TWOFISH_586) += twofish-i586.o
obj-$(CONFIG_CRYPTO_SALSA20_586) += salsa20-i586.o
+obj-$(CONFIG_CRYPTO_SERPENT_SSE2_586) += serpent-sse2-i586.o
obj-$(CONFIG_CRYPTO_AES_X86_64) += aes-x86_64.o
obj-$(CONFIG_CRYPTO_BLOWFISH_X86_64) += blowfish-x86_64.o
obj-$(CONFIG_CRYPTO_TWOFISH_X86_64) += twofish-x86_64.o
obj-$(CONFIG_CRYPTO_TWOFISH_X86_64_3WAY) += twofish-x86_64-3way.o
obj-$(CONFIG_CRYPTO_SALSA20_X86_64) += salsa20-x86_64.o
+obj-$(CONFIG_CRYPTO_SERPENT_SSE2_X86_64) += serpent-sse2-x86_64.o
obj-$(CONFIG_CRYPTO_AES_NI_INTEL) += aesni-intel.o
obj-$(CONFIG_CRYPTO_GHASH_CLMUL_NI_INTEL) += ghash-clmulni-intel.o
@@ -20,12 +22,14 @@
aes-i586-y := aes-i586-asm_32.o aes_glue.o
twofish-i586-y := twofish-i586-asm_32.o twofish_glue.o
salsa20-i586-y := salsa20-i586-asm_32.o salsa20_glue.o
+serpent-sse2-i586-y := serpent-sse2-i586-asm_32.o serpent_sse2_glue.o
aes-x86_64-y := aes-x86_64-asm_64.o aes_glue.o
blowfish-x86_64-y := blowfish-x86_64-asm_64.o blowfish_glue.o
twofish-x86_64-y := twofish-x86_64-asm_64.o twofish_glue.o
twofish-x86_64-3way-y := twofish-x86_64-asm_64-3way.o twofish_glue_3way.o
salsa20-x86_64-y := salsa20-x86_64-asm_64.o salsa20_glue.o
+serpent-sse2-x86_64-y := serpent-sse2-x86_64-asm_64.o serpent_sse2_glue.o
aesni-intel-y := aesni-intel_asm.o aesni-intel_glue.o fpu.o
diff --git a/arch/x86/crypto/serpent-sse2-i586-asm_32.S b/arch/x86/crypto/serpent-sse2-i586-asm_32.S
new file mode 100644
index 0000000..4e37677
--- /dev/null
+++ b/arch/x86/crypto/serpent-sse2-i586-asm_32.S
@@ -0,0 +1,638 @@
+/*
+ * Serpent Cipher 4-way parallel algorithm (i586/SSE2)
+ *
+ * Copyright (C) 2011 Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
+ *
+ * Based on crypto/serpent.c by
+ * Copyright (C) 2002 Dag Arne Osvik <osvik@ii.uib.no>
+ * 2003 Herbert Valerio Riedel <hvr@gnu.org>
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA
+ *
+ */
+
+.file "serpent-sse2-i586-asm_32.S"
+.text
+
+#define arg_ctx 4
+#define arg_dst 8
+#define arg_src 12
+#define arg_xor 16
+
+/**********************************************************************
+ 4-way SSE2 serpent
+ **********************************************************************/
+#define CTX %edx
+
+#define RA %xmm0
+#define RB %xmm1
+#define RC %xmm2
+#define RD %xmm3
+#define RE %xmm4
+
+#define RT0 %xmm5
+#define RT1 %xmm6
+
+#define RNOT %xmm7
+
+#define get_key(i, j, t) \
+ movd (4*(i)+(j))*4(CTX), t; \
+ pshufd $0, t, t;
+
+#define K(x0, x1, x2, x3, x4, i) \
+ get_key(i, 0, x4); \
+ get_key(i, 1, RT0); \
+ get_key(i, 2, RT1); \
+ pxor x4, x0; \
+ pxor RT0, x1; \
+ pxor RT1, x2; \
+ get_key(i, 3, x4); \
+ pxor x4, x3;
+
+#define LK(x0, x1, x2, x3, x4, i) \
+ movdqa x0, x4; \
+ pslld $13, x0; \
+ psrld $(32 - 13), x4; \
+ por x4, x0; \
+ pxor x0, x1; \
+ movdqa x2, x4; \
+ pslld $3, x2; \
+ psrld $(32 - 3), x4; \
+ por x4, x2; \
+ pxor x2, x1; \
+ movdqa x1, x4; \
+ pslld $1, x1; \
+ psrld $(32 - 1), x4; \
+ por x4, x1; \
+ movdqa x0, x4; \
+ pslld $3, x4; \
+ pxor x2, x3; \
+ pxor x4, x3; \
+ movdqa x3, x4; \
+ pslld $7, x3; \
+ psrld $(32 - 7), x4; \
+ por x4, x3; \
+ movdqa x1, x4; \
+ pslld $7, x4; \
+ pxor x1, x0; \
+ pxor x3, x0; \
+ pxor x3, x2; \
+ pxor x4, x2; \
+ movdqa x0, x4; \
+ get_key(i, 1, RT0); \
+ pxor RT0, x1; \
+ get_key(i, 3, RT0); \
+ pxor RT0, x3; \
+ pslld $5, x0; \
+ psrld $(32 - 5), x4; \
+ por x4, x0; \
+ movdqa x2, x4; \
+ pslld $22, x2; \
+ psrld $(32 - 22), x4; \
+ por x4, x2; \
+ get_key(i, 0, RT0); \
+ pxor RT0, x0; \
+ get_key(i, 2, RT0); \
+ pxor RT0, x2;
+
+#define KL(x0, x1, x2, x3, x4, i) \
+ K(x0, x1, x2, x3, x4, i); \
+ movdqa x0, x4; \
+ psrld $5, x0; \
+ pslld $(32 - 5), x4; \
+ por x4, x0; \
+ movdqa x2, x4; \
+ psrld $22, x2; \
+ pslld $(32 - 22), x4; \
+ por x4, x2; \
+ pxor x3, x2; \
+ pxor x3, x0; \
+ movdqa x1, x4; \
+ pslld $7, x4; \
+ pxor x1, x0; \
+ pxor x4, x2; \
+ movdqa x1, x4; \
+ psrld $1, x1; \
+ pslld $(32 - 1), x4; \
+ por x4, x1; \
+ movdqa x3, x4; \
+ psrld $7, x3; \
+ pslld $(32 - 7), x4; \
+ por x4, x3; \
+ pxor x0, x1; \
+ movdqa x0, x4; \
+ pslld $3, x4; \
+ pxor x4, x3; \
+ movdqa x0, x4; \
+ psrld $13, x0; \
+ pslld $(32 - 13), x4; \
+ por x4, x0; \
+ pxor x2, x1; \
+ pxor x2, x3; \
+ movdqa x2, x4; \
+ psrld $3, x2; \
+ pslld $(32 - 3), x4; \
+ por x4, x2;
+
+#define S0(x0, x1, x2, x3, x4) \
+ movdqa x3, x4; \
+ por x0, x3; \
+ pxor x4, x0; \
+ pxor x2, x4; \
+ pxor RNOT, x4; \
+ pxor x1, x3; \
+ pand x0, x1; \
+ pxor x4, x1; \
+ pxor x0, x2; \
+ pxor x3, x0; \
+ por x0, x4; \
+ pxor x2, x0; \
+ pand x1, x2; \
+ pxor x2, x3; \
+ pxor RNOT, x1; \
+ pxor x4, x2; \
+ pxor x2, x1;
+
+#define S1(x0, x1, x2, x3, x4) \
+ movdqa x1, x4; \
+ pxor x0, x1; \
+ pxor x3, x0; \
+ pxor RNOT, x3; \
+ pand x1, x4; \
+ por x1, x0; \
+ pxor x2, x3; \
+ pxor x3, x0; \
+ pxor x3, x1; \
+ pxor x4, x3; \
+ por x4, x1; \
+ pxor x2, x4; \
+ pand x0, x2; \
+ pxor x1, x2; \
+ por x0, x1; \
+ pxor RNOT, x0; \
+ pxor x2, x0; \
+ pxor x1, x4;
+
+#define S2(x0, x1, x2, x3, x4) \
+ pxor RNOT, x3; \
+ pxor x0, x1; \
+ movdqa x0, x4; \
+ pand x2, x0; \
+ pxor x3, x0; \
+ por x4, x3; \
+ pxor x1, x2; \
+ pxor x1, x3; \
+ pand x0, x1; \
+ pxor x2, x0; \
+ pand x3, x2; \
+ por x1, x3; \
+ pxor RNOT, x0; \
+ pxor x0, x3; \
+ pxor x0, x4; \
+ pxor x2, x0; \
+ por x2, x1;
+
+#define S3(x0, x1, x2, x3, x4) \
+ movdqa x1, x4; \
+ pxor x3, x1; \
+ por x0, x3; \
+ pand x0, x4; \
+ pxor x2, x0; \
+ pxor x1, x2; \
+ pand x3, x1; \
+ pxor x3, x2; \
+ por x4, x0; \
+ pxor x3, x4; \
+ pxor x0, x1; \
+ pand x3, x0; \
+ pand x4, x3; \
+ pxor x2, x3; \
+ por x1, x4; \
+ pand x1, x2; \
+ pxor x3, x4; \
+ pxor x3, x0; \
+ pxor x2, x3;
+
+#define S4(x0, x1, x2, x3, x4) \
+ movdqa x3, x4; \
+ pand x0, x3; \
+ pxor x4, x0; \
+ pxor x2, x3; \
+ por x4, x2; \
+ pxor x1, x0; \
+ pxor x3, x4; \
+ por x0, x2; \
+ pxor x1, x2; \
+ pand x0, x1; \
+ pxor x4, x1; \
+ pand x2, x4; \
+ pxor x3, x2; \
+ pxor x0, x4; \
+ por x1, x3; \
+ pxor RNOT, x1; \
+ pxor x0, x3;
+
+#define S5(x0, x1, x2, x3, x4) \
+ movdqa x1, x4; \
+ por x0, x1; \
+ pxor x1, x2; \
+ pxor RNOT, x3; \
+ pxor x0, x4; \
+ pxor x2, x0; \
+ pand x4, x1; \
+ por x3, x4; \
+ pxor x0, x4; \
+ pand x3, x0; \
+ pxor x3, x1; \
+ pxor x2, x3; \
+ pxor x1, x0; \
+ pand x4, x2; \
+ pxor x2, x1; \
+ pand x0, x2; \
+ pxor x2, x3;
+
+#define S6(x0, x1, x2, x3, x4) \
+ movdqa x1, x4; \
+ pxor x0, x3; \
+ pxor x2, x1; \
+ pxor x0, x2; \
+ pand x3, x0; \
+ por x3, x1; \
+ pxor RNOT, x4; \
+ pxor x1, x0; \
+ pxor x2, x1; \
+ pxor x4, x3; \
+ pxor x0, x4; \
+ pand x0, x2; \
+ pxor x1, x4; \
+ pxor x3, x2; \
+ pand x1, x3; \
+ pxor x0, x3; \
+ pxor x2, x1;
+
+#define S7(x0, x1, x2, x3, x4) \
+ pxor RNOT, x1; \
+ movdqa x1, x4; \
+ pxor RNOT, x0; \
+ pand x2, x1; \
+ pxor x3, x1; \
+ por x4, x3; \
+ pxor x2, x4; \
+ pxor x3, x2; \
+ pxor x0, x3; \
+ por x1, x0; \
+ pand x0, x2; \
+ pxor x4, x0; \
+ pxor x3, x4; \
+ pand x0, x3; \
+ pxor x1, x4; \
+ pxor x4, x2; \
+ pxor x1, x3; \
+ por x0, x4; \
+ pxor x1, x4;
+
+#define SI0(x0, x1, x2, x3, x4) \
+ movdqa x3, x4; \
+ pxor x0, x1; \
+ por x1, x3; \
+ pxor x1, x4; \
+ pxor RNOT, x0; \
+ pxor x3, x2; \
+ pxor x0, x3; \
+ pand x1, x0; \
+ pxor x2, x0; \
+ pand x3, x2; \
+ pxor x4, x3; \
+ pxor x3, x2; \
+ pxor x3, x1; \
+ pand x0, x3; \
+ pxor x0, x1; \
+ pxor x2, x0; \
+ pxor x3, x4;
+
+#define SI1(x0, x1, x2, x3, x4) \
+ pxor x3, x1; \
+ movdqa x0, x4; \
+ pxor x2, x0; \
+ pxor RNOT, x2; \
+ por x1, x4; \
+ pxor x3, x4; \
+ pand x1, x3; \
+ pxor x2, x1; \
+ pand x4, x2; \
+ pxor x1, x4; \
+ por x3, x1; \
+ pxor x0, x3; \
+ pxor x0, x2; \
+ por x4, x0; \
+ pxor x4, x2; \
+ pxor x0, x1; \
+ pxor x1, x4;
+
+#define SI2(x0, x1, x2, x3, x4) \
+ pxor x1, x2; \
+ movdqa x3, x4; \
+ pxor RNOT, x3; \
+ por x2, x3; \
+ pxor x4, x2; \
+ pxor x0, x4; \
+ pxor x1, x3; \
+ por x2, x1; \
+ pxor x0, x2; \
+ pxor x4, x1; \
+ por x3, x4; \
+ pxor x3, x2; \
+ pxor x2, x4; \
+ pand x1, x2; \
+ pxor x3, x2; \
+ pxor x4, x3; \
+ pxor x0, x4;
+
+#define SI3(x0, x1, x2, x3, x4) \
+ pxor x1, x2; \
+ movdqa x1, x4; \
+ pand x2, x1; \
+ pxor x0, x1; \
+ por x4, x0; \
+ pxor x3, x4; \
+ pxor x3, x0; \
+ por x1, x3; \
+ pxor x2, x1; \
+ pxor x3, x1; \
+ pxor x2, x0; \
+ pxor x3, x2; \
+ pand x1, x3; \
+ pxor x0, x1; \
+ pand x2, x0; \
+ pxor x3, x4; \
+ pxor x0, x3; \
+ pxor x1, x0;
+
+#define SI4(x0, x1, x2, x3, x4) \
+ pxor x3, x2; \
+ movdqa x0, x4; \
+ pand x1, x0; \
+ pxor x2, x0; \
+ por x3, x2; \
+ pxor RNOT, x4; \
+ pxor x0, x1; \
+ pxor x2, x0; \
+ pand x4, x2; \
+ pxor x0, x2; \
+ por x4, x0; \
+ pxor x3, x0; \
+ pand x2, x3; \
+ pxor x3, x4; \
+ pxor x1, x3; \
+ pand x0, x1; \
+ pxor x1, x4; \
+ pxor x3, x0;
+
+#define SI5(x0, x1, x2, x3, x4) \
+ movdqa x1, x4; \
+ por x2, x1; \
+ pxor x4, x2; \
+ pxor x3, x1; \
+ pand x4, x3; \
+ pxor x3, x2; \
+ por x0, x3; \
+ pxor RNOT, x0; \
+ pxor x2, x3; \
+ por x0, x2; \
+ pxor x1, x4; \
+ pxor x4, x2; \
+ pand x0, x4; \
+ pxor x1, x0; \
+ pxor x3, x1; \
+ pand x2, x0; \
+ pxor x3, x2; \
+ pxor x2, x0; \
+ pxor x4, x2; \
+ pxor x3, x4;
+
+#define SI6(x0, x1, x2, x3, x4) \
+ pxor x2, x0; \
+ movdqa x0, x4; \
+ pand x3, x0; \
+ pxor x3, x2; \
+ pxor x2, x0; \
+ pxor x1, x3; \
+ por x4, x2; \
+ pxor x3, x2; \
+ pand x0, x3; \
+ pxor RNOT, x0; \
+ pxor x1, x3; \
+ pand x2, x1; \
+ pxor x0, x4; \
+ pxor x4, x3; \
+ pxor x2, x4; \
+ pxor x1, x0; \
+ pxor x0, x2;
+
+#define SI7(x0, x1, x2, x3, x4) \
+ movdqa x3, x4; \
+ pand x0, x3; \
+ pxor x2, x0; \
+ por x4, x2; \
+ pxor x1, x4; \
+ pxor RNOT, x0; \
+ por x3, x1; \
+ pxor x0, x4; \
+ pand x2, x0; \
+ pxor x1, x0; \
+ pand x2, x1; \
+ pxor x2, x3; \
+ pxor x3, x4; \
+ pand x3, x2; \
+ por x0, x3; \
+ pxor x4, x1; \
+ pxor x4, x3; \
+ pand x0, x4; \
+ pxor x2, x4;
+
+#define transpose_4x4(x0, x1, x2, x3, t1, t2, t3) \
+ movdqa x2, t3; \
+ movdqa x0, t1; \
+ unpcklps x3, t3; \
+ movdqa x0, t2; \
+ unpcklps x1, t1; \
+ unpckhps x1, t2; \
+ movdqa t3, x1; \
+ unpckhps x3, x2; \
+ movdqa t1, x0; \
+ movhlps t1, x1; \
+ movdqa t2, t1; \
+ movlhps t3, x0; \
+ movlhps x2, t1; \
+ movhlps t2, x2; \
+ movdqa x2, x3; \
+ movdqa t1, x2;
+
+#define read_blocks(in, x0, x1, x2, x3, t0, t1, t2) \
+ movdqu (0*4*4)(in), x0; \
+ movdqu (1*4*4)(in), x1; \
+ movdqu (2*4*4)(in), x2; \
+ movdqu (3*4*4)(in), x3; \
+ \
+ transpose_4x4(x0, x1, x2, x3, t0, t1, t2)
+
+#define write_blocks(out, x0, x1, x2, x3, t0, t1, t2) \
+ transpose_4x4(x0, x1, x2, x3, t0, t1, t2) \
+ \
+ movdqu x0, (0*4*4)(out); \
+ movdqu x1, (1*4*4)(out); \
+ movdqu x2, (2*4*4)(out); \
+ movdqu x3, (3*4*4)(out);
+
+#define xor_blocks(out, x0, x1, x2, x3, t0, t1, t2) \
+ transpose_4x4(x0, x1, x2, x3, t0, t1, t2) \
+ \
+ movdqu (0*4*4)(out), t0; \
+ pxor t0, x0; \
+ movdqu x0, (0*4*4)(out); \
+ movdqu (1*4*4)(out), t0; \
+ pxor t0, x1; \
+ movdqu x1, (1*4*4)(out); \
+ movdqu (2*4*4)(out), t0; \
+ pxor t0, x2; \
+ movdqu x2, (2*4*4)(out); \
+ movdqu (3*4*4)(out), t0; \
+ pxor t0, x3; \
+ movdqu x3, (3*4*4)(out);
+
+.align 8
+.global __serpent_enc_blk_4way
+.type __serpent_enc_blk_4way,@function;
+
+__serpent_enc_blk_4way:
+ /* input:
+ * arg_ctx(%esp): ctx, CTX
+ * arg_dst(%esp): dst
+ * arg_src(%esp): src
+ * arg_xor(%esp): bool, if true: xor output
+ */
+
+ pcmpeqd RNOT, RNOT;
+
+ movl arg_ctx(%esp), CTX;
+
+ movl arg_src(%esp), %eax;
+ read_blocks(%eax, RA, RB, RC, RD, RT0, RT1, RE);
+
+ K(RA, RB, RC, RD, RE, 0);
+ S0(RA, RB, RC, RD, RE); LK(RC, RB, RD, RA, RE, 1);
+ S1(RC, RB, RD, RA, RE); LK(RE, RD, RA, RC, RB, 2);
+ S2(RE, RD, RA, RC, RB); LK(RB, RD, RE, RC, RA, 3);
+ S3(RB, RD, RE, RC, RA); LK(RC, RA, RD, RB, RE, 4);
+ S4(RC, RA, RD, RB, RE); LK(RA, RD, RB, RE, RC, 5);
+ S5(RA, RD, RB, RE, RC); LK(RC, RA, RD, RE, RB, 6);
+ S6(RC, RA, RD, RE, RB); LK(RD, RB, RA, RE, RC, 7);
+ S7(RD, RB, RA, RE, RC); LK(RC, RA, RE, RD, RB, 8);
+ S0(RC, RA, RE, RD, RB); LK(RE, RA, RD, RC, RB, 9);
+ S1(RE, RA, RD, RC, RB); LK(RB, RD, RC, RE, RA, 10);
+ S2(RB, RD, RC, RE, RA); LK(RA, RD, RB, RE, RC, 11);
+ S3(RA, RD, RB, RE, RC); LK(RE, RC, RD, RA, RB, 12);
+ S4(RE, RC, RD, RA, RB); LK(RC, RD, RA, RB, RE, 13);
+ S5(RC, RD, RA, RB, RE); LK(RE, RC, RD, RB, RA, 14);
+ S6(RE, RC, RD, RB, RA); LK(RD, RA, RC, RB, RE, 15);
+ S7(RD, RA, RC, RB, RE); LK(RE, RC, RB, RD, RA, 16);
+ S0(RE, RC, RB, RD, RA); LK(RB, RC, RD, RE, RA, 17);
+ S1(RB, RC, RD, RE, RA); LK(RA, RD, RE, RB, RC, 18);
+ S2(RA, RD, RE, RB, RC); LK(RC, RD, RA, RB, RE, 19);
+ S3(RC, RD, RA, RB, RE); LK(RB, RE, RD, RC, RA, 20);
+ S4(RB, RE, RD, RC, RA); LK(RE, RD, RC, RA, RB, 21);
+ S5(RE, RD, RC, RA, RB); LK(RB, RE, RD, RA, RC, 22);
+ S6(RB, RE, RD, RA, RC); LK(RD, RC, RE, RA, RB, 23);
+ S7(RD, RC, RE, RA, RB); LK(RB, RE, RA, RD, RC, 24);
+ S0(RB, RE, RA, RD, RC); LK(RA, RE, RD, RB, RC, 25);
+ S1(RA, RE, RD, RB, RC); LK(RC, RD, RB, RA, RE, 26);
+ S2(RC, RD, RB, RA, RE); LK(RE, RD, RC, RA, RB, 27);
+ S3(RE, RD, RC, RA, RB); LK(RA, RB, RD, RE, RC, 28);
+ S4(RA, RB, RD, RE, RC); LK(RB, RD, RE, RC, RA, 29);
+ S5(RB, RD, RE, RC, RA); LK(RA, RB, RD, RC, RE, 30);
+ S6(RA, RB, RD, RC, RE); LK(RD, RE, RB, RC, RA, 31);
+ S7(RD, RE, RB, RC, RA); K(RA, RB, RC, RD, RE, 32);
+
+ movl arg_dst(%esp), %eax;
+
+ cmpb $0, arg_xor(%esp);
+ jnz __enc_xor4;
+
+ write_blocks(%eax, RA, RB, RC, RD, RT0, RT1, RE);
+
+ ret;
+
+__enc_xor4:
+ xor_blocks(%eax, RA, RB, RC, RD, RT0, RT1, RE);
+
+ ret;
+
+.align 8
+.global serpent_dec_blk_4way
+.type serpent_dec_blk_4way,@function;
+
+serpent_dec_blk_4way:
+ /* input:
+ * arg_ctx(%esp): ctx, CTX
+ * arg_dst(%esp): dst
+ * arg_src(%esp): src
+ */
+
+ pcmpeqd RNOT, RNOT;
+
+ movl arg_ctx(%esp), CTX;
+
+ movl arg_src(%esp), %eax;
+ read_blocks(%eax, RA, RB, RC, RD, RT0, RT1, RE);
+
+ K(RA, RB, RC, RD, RE, 32);
+ SI7(RA, RB, RC, RD, RE); KL(RB, RD, RA, RE, RC, 31);
+ SI6(RB, RD, RA, RE, RC); KL(RA, RC, RE, RB, RD, 30);
+ SI5(RA, RC, RE, RB, RD); KL(RC, RD, RA, RE, RB, 29);
+ SI4(RC, RD, RA, RE, RB); KL(RC, RA, RB, RE, RD, 28);
+ SI3(RC, RA, RB, RE, RD); KL(RB, RC, RD, RE, RA, 27);
+ SI2(RB, RC, RD, RE, RA); KL(RC, RA, RE, RD, RB, 26);
+ SI1(RC, RA, RE, RD, RB); KL(RB, RA, RE, RD, RC, 25);
+ SI0(RB, RA, RE, RD, RC); KL(RE, RC, RA, RB, RD, 24);
+ SI7(RE, RC, RA, RB, RD); KL(RC, RB, RE, RD, RA, 23);
+ SI6(RC, RB, RE, RD, RA); KL(RE, RA, RD, RC, RB, 22);
+ SI5(RE, RA, RD, RC, RB); KL(RA, RB, RE, RD, RC, 21);
+ SI4(RA, RB, RE, RD, RC); KL(RA, RE, RC, RD, RB, 20);
+ SI3(RA, RE, RC, RD, RB); KL(RC, RA, RB, RD, RE, 19);
+ SI2(RC, RA, RB, RD, RE); KL(RA, RE, RD, RB, RC, 18);
+ SI1(RA, RE, RD, RB, RC); KL(RC, RE, RD, RB, RA, 17);
+ SI0(RC, RE, RD, RB, RA); KL(RD, RA, RE, RC, RB, 16);
+ SI7(RD, RA, RE, RC, RB); KL(RA, RC, RD, RB, RE, 15);
+ SI6(RA, RC, RD, RB, RE); KL(RD, RE, RB, RA, RC, 14);
+ SI5(RD, RE, RB, RA, RC); KL(RE, RC, RD, RB, RA, 13);
+ SI4(RE, RC, RD, RB, RA); KL(RE, RD, RA, RB, RC, 12);
+ SI3(RE, RD, RA, RB, RC); KL(RA, RE, RC, RB, RD, 11);
+ SI2(RA, RE, RC, RB, RD); KL(RE, RD, RB, RC, RA, 10);
+ SI1(RE, RD, RB, RC, RA); KL(RA, RD, RB, RC, RE, 9);
+ SI0(RA, RD, RB, RC, RE); KL(RB, RE, RD, RA, RC, 8);
+ SI7(RB, RE, RD, RA, RC); KL(RE, RA, RB, RC, RD, 7);
+ SI6(RE, RA, RB, RC, RD); KL(RB, RD, RC, RE, RA, 6);
+ SI5(RB, RD, RC, RE, RA); KL(RD, RA, RB, RC, RE, 5);
+ SI4(RD, RA, RB, RC, RE); KL(RD, RB, RE, RC, RA, 4);
+ SI3(RD, RB, RE, RC, RA); KL(RE, RD, RA, RC, RB, 3);
+ SI2(RE, RD, RA, RC, RB); KL(RD, RB, RC, RA, RE, 2);
+ SI1(RD, RB, RC, RA, RE); KL(RE, RB, RC, RA, RD, 1);
+ SI0(RE, RB, RC, RA, RD); K(RC, RD, RB, RE, RA, 0);
+
+ movl arg_dst(%esp), %eax;
+ write_blocks(%eax, RC, RD, RB, RE, RT0, RT1, RA);
+
+ ret;
diff --git a/arch/x86/crypto/serpent-sse2-x86_64-asm_64.S b/arch/x86/crypto/serpent-sse2-x86_64-asm_64.S
new file mode 100644
index 0000000..7f24a15
--- /dev/null
+++ b/arch/x86/crypto/serpent-sse2-x86_64-asm_64.S
@@ -0,0 +1,761 @@
+/*
+ * Serpent Cipher 8-way parallel algorithm (x86_64/SSE2)
+ *
+ * Copyright (C) 2011 Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
+ *
+ * Based on crypto/serpent.c by
+ * Copyright (C) 2002 Dag Arne Osvik <osvik@ii.uib.no>
+ * 2003 Herbert Valerio Riedel <hvr@gnu.org>
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA
+ *
+ */
+
+.file "serpent-sse2-x86_64-asm_64.S"
+.text
+
+#define CTX %rdi
+
+/**********************************************************************
+ 8-way SSE2 serpent
+ **********************************************************************/
+#define RA1 %xmm0
+#define RB1 %xmm1
+#define RC1 %xmm2
+#define RD1 %xmm3
+#define RE1 %xmm4
+
+#define RA2 %xmm5
+#define RB2 %xmm6
+#define RC2 %xmm7
+#define RD2 %xmm8
+#define RE2 %xmm9
+
+#define RNOT %xmm10
+
+#define RK0 %xmm11
+#define RK1 %xmm12
+#define RK2 %xmm13
+#define RK3 %xmm14
+
+#define S0_1(x0, x1, x2, x3, x4) \
+ movdqa x3, x4; \
+ por x0, x3; \
+ pxor x4, x0; \
+ pxor x2, x4; \
+ pxor RNOT, x4; \
+ pxor x1, x3; \
+ pand x0, x1; \
+ pxor x4, x1; \
+ pxor x0, x2;
+#define S0_2(x0, x1, x2, x3, x4) \
+ pxor x3, x0; \
+ por x0, x4; \
+ pxor x2, x0; \
+ pand x1, x2; \
+ pxor x2, x3; \
+ pxor RNOT, x1; \
+ pxor x4, x2; \
+ pxor x2, x1;
+
+#define S1_1(x0, x1, x2, x3, x4) \
+ movdqa x1, x4; \
+ pxor x0, x1; \
+ pxor x3, x0; \
+ pxor RNOT, x3; \
+ pand x1, x4; \
+ por x1, x0; \
+ pxor x2, x3; \
+ pxor x3, x0; \
+ pxor x3, x1;
+#define S1_2(x0, x1, x2, x3, x4) \
+ pxor x4, x3; \
+ por x4, x1; \
+ pxor x2, x4; \
+ pand x0, x2; \
+ pxor x1, x2; \
+ por x0, x1; \
+ pxor RNOT, x0; \
+ pxor x2, x0; \
+ pxor x1, x4;
+
+#define S2_1(x0, x1, x2, x3, x4) \
+ pxor RNOT, x3; \
+ pxor x0, x1; \
+ movdqa x0, x4; \
+ pand x2, x0; \
+ pxor x3, x0; \
+ por x4, x3; \
+ pxor x1, x2; \
+ pxor x1, x3; \
+ pand x0, x1;
+#define S2_2(x0, x1, x2, x3, x4) \
+ pxor x2, x0; \
+ pand x3, x2; \
+ por x1, x3; \
+ pxor RNOT, x0; \
+ pxor x0, x3; \
+ pxor x0, x4; \
+ pxor x2, x0; \
+ por x2, x1;
+
+#define S3_1(x0, x1, x2, x3, x4) \
+ movdqa x1, x4; \
+ pxor x3, x1; \
+ por x0, x3; \
+ pand x0, x4; \
+ pxor x2, x0; \
+ pxor x1, x2; \
+ pand x3, x1; \
+ pxor x3, x2; \
+ por x4, x0; \
+ pxor x3, x4;
+#define S3_2(x0, x1, x2, x3, x4) \
+ pxor x0, x1; \
+ pand x3, x0; \
+ pand x4, x3; \
+ pxor x2, x3; \
+ por x1, x4; \
+ pand x1, x2; \
+ pxor x3, x4; \
+ pxor x3, x0; \
+ pxor x2, x3;
+
+#define S4_1(x0, x1, x2, x3, x4) \
+ movdqa x3, x4; \
+ pand x0, x3; \
+ pxor x4, x0; \
+ pxor x2, x3; \
+ por x4, x2; \
+ pxor x1, x0; \
+ pxor x3, x4; \
+ por x0, x2; \
+ pxor x1, x2;
+#define S4_2(x0, x1, x2, x3, x4) \
+ pand x0, x1; \
+ pxor x4, x1; \
+ pand x2, x4; \
+ pxor x3, x2; \
+ pxor x0, x4; \
+ por x1, x3; \
+ pxor RNOT, x1; \
+ pxor x0, x3;
+
+#define S5_1(x0, x1, x2, x3, x4) \
+ movdqa x1, x4; \
+ por x0, x1; \
+ pxor x1, x2; \
+ pxor RNOT, x3; \
+ pxor x0, x4; \
+ pxor x2, x0; \
+ pand x4, x1; \
+ por x3, x4; \
+ pxor x0, x4;
+#define S5_2(x0, x1, x2, x3, x4) \
+ pand x3, x0; \
+ pxor x3, x1; \
+ pxor x2, x3; \
+ pxor x1, x0; \
+ pand x4, x2; \
+ pxor x2, x1; \
+ pand x0, x2; \
+ pxor x2, x3;
+
+#define S6_1(x0, x1, x2, x3, x4) \
+ movdqa x1, x4; \
+ pxor x0, x3; \
+ pxor x2, x1; \
+ pxor x0, x2; \
+ pand x3, x0; \
+ por x3, x1; \
+ pxor RNOT, x4; \
+ pxor x1, x0; \
+ pxor x2, x1;
+#define S6_2(x0, x1, x2, x3, x4) \
+ pxor x4, x3; \
+ pxor x0, x4; \
+ pand x0, x2; \
+ pxor x1, x4; \
+ pxor x3, x2; \
+ pand x1, x3; \
+ pxor x0, x3; \
+ pxor x2, x1;
+
+#define S7_1(x0, x1, x2, x3, x4) \
+ pxor RNOT, x1; \
+ movdqa x1, x4; \
+ pxor RNOT, x0; \
+ pand x2, x1; \
+ pxor x3, x1; \
+ por x4, x3; \
+ pxor x2, x4; \
+ pxor x3, x2; \
+ pxor x0, x3; \
+ por x1, x0;
+#define S7_2(x0, x1, x2, x3, x4) \
+ pand x0, x2; \
+ pxor x4, x0; \
+ pxor x3, x4; \
+ pand x0, x3; \
+ pxor x1, x4; \
+ pxor x4, x2; \
+ pxor x1, x3; \
+ por x0, x4; \
+ pxor x1, x4;
+
+#define SI0_1(x0, x1, x2, x3, x4) \
+ movdqa x3, x4; \
+ pxor x0, x1; \
+ por x1, x3; \
+ pxor x1, x4; \
+ pxor RNOT, x0; \
+ pxor x3, x2; \
+ pxor x0, x3; \
+ pand x1, x0; \
+ pxor x2, x0;
+#define SI0_2(x0, x1, x2, x3, x4) \
+ pand x3, x2; \
+ pxor x4, x3; \
+ pxor x3, x2; \
+ pxor x3, x1; \
+ pand x0, x3; \
+ pxor x0, x1; \
+ pxor x2, x0; \
+ pxor x3, x4;
+
+#define SI1_1(x0, x1, x2, x3, x4) \
+ pxor x3, x1; \
+ movdqa x0, x4; \
+ pxor x2, x0; \
+ pxor RNOT, x2; \
+ por x1, x4; \
+ pxor x3, x4; \
+ pand x1, x3; \
+ pxor x2, x1; \
+ pand x4, x2;
+#define SI1_2(x0, x1, x2, x3, x4) \
+ pxor x1, x4; \
+ por x3, x1; \
+ pxor x0, x3; \
+ pxor x0, x2; \
+ por x4, x0; \
+ pxor x4, x2; \
+ pxor x0, x1; \
+ pxor x1, x4;
+
+#define SI2_1(x0, x1, x2, x3, x4) \
+ pxor x1, x2; \
+ movdqa x3, x4; \
+ pxor RNOT, x3; \
+ por x2, x3; \
+ pxor x4, x2; \
+ pxor x0, x4; \
+ pxor x1, x3; \
+ por x2, x1; \
+ pxor x0, x2;
+#define SI2_2(x0, x1, x2, x3, x4) \
+ pxor x4, x1; \
+ por x3, x4; \
+ pxor x3, x2; \
+ pxor x2, x4; \
+ pand x1, x2; \
+ pxor x3, x2; \
+ pxor x4, x3; \
+ pxor x0, x4;
+
+#define SI3_1(x0, x1, x2, x3, x4) \
+ pxor x1, x2; \
+ movdqa x1, x4; \
+ pand x2, x1; \
+ pxor x0, x1; \
+ por x4, x0; \
+ pxor x3, x4; \
+ pxor x3, x0; \
+ por x1, x3; \
+ pxor x2, x1;
+#define SI3_2(x0, x1, x2, x3, x4) \
+ pxor x3, x1; \
+ pxor x2, x0; \
+ pxor x3, x2; \
+ pand x1, x3; \
+ pxor x0, x1; \
+ pand x2, x0; \
+ pxor x3, x4; \
+ pxor x0, x3; \
+ pxor x1, x0;
+
+#define SI4_1(x0, x1, x2, x3, x4) \
+ pxor x3, x2; \
+ movdqa x0, x4; \
+ pand x1, x0; \
+ pxor x2, x0; \
+ por x3, x2; \
+ pxor RNOT, x4; \
+ pxor x0, x1; \
+ pxor x2, x0; \
+ pand x4, x2;
+#define SI4_2(x0, x1, x2, x3, x4) \
+ pxor x0, x2; \
+ por x4, x0; \
+ pxor x3, x0; \
+ pand x2, x3; \
+ pxor x3, x4; \
+ pxor x1, x3; \
+ pand x0, x1; \
+ pxor x1, x4; \
+ pxor x3, x0;
+
+#define SI5_1(x0, x1, x2, x3, x4) \
+ movdqa x1, x4; \
+ por x2, x1; \
+ pxor x4, x2; \
+ pxor x3, x1; \
+ pand x4, x3; \
+ pxor x3, x2; \
+ por x0, x3; \
+ pxor RNOT, x0; \
+ pxor x2, x3; \
+ por x0, x2;
+#define SI5_2(x0, x1, x2, x3, x4) \
+ pxor x1, x4; \
+ pxor x4, x2; \
+ pand x0, x4; \
+ pxor x1, x0; \
+ pxor x3, x1; \
+ pand x2, x0; \
+ pxor x3, x2; \
+ pxor x2, x0; \
+ pxor x4, x2; \
+ pxor x3, x4;
+
+#define SI6_1(x0, x1, x2, x3, x4) \
+ pxor x2, x0; \
+ movdqa x0, x4; \
+ pand x3, x0; \
+ pxor x3, x2; \
+ pxor x2, x0; \
+ pxor x1, x3; \
+ por x4, x2; \
+ pxor x3, x2; \
+ pand x0, x3;
+#define SI6_2(x0, x1, x2, x3, x4) \
+ pxor RNOT, x0; \
+ pxor x1, x3; \
+ pand x2, x1; \
+ pxor x0, x4; \
+ pxor x4, x3; \
+ pxor x2, x4; \
+ pxor x1, x0; \
+ pxor x0, x2;
+
+#define SI7_1(x0, x1, x2, x3, x4) \
+ movdqa x3, x4; \
+ pand x0, x3; \
+ pxor x2, x0; \
+ por x4, x2; \
+ pxor x1, x4; \
+ pxor RNOT, x0; \
+ por x3, x1; \
+ pxor x0, x4; \
+ pand x2, x0; \
+ pxor x1, x0;
+#define SI7_2(x0, x1, x2, x3, x4) \
+ pand x2, x1; \
+ pxor x2, x3; \
+ pxor x3, x4; \
+ pand x3, x2; \
+ por x0, x3; \
+ pxor x4, x1; \
+ pxor x4, x3; \
+ pand x0, x4; \
+ pxor x2, x4;
+
+#define get_key(i, j, t) \
+ movd (4*(i)+(j))*4(CTX), t; \
+ pshufd $0, t, t;
+
+#define K2(x0, x1, x2, x3, x4, i) \
+ get_key(i, 0, RK0); \
+ get_key(i, 1, RK1); \
+ get_key(i, 2, RK2); \
+ get_key(i, 3, RK3); \
+ pxor RK0, x0 ## 1; \
+ pxor RK1, x1 ## 1; \
+ pxor RK2, x2 ## 1; \
+ pxor RK3, x3 ## 1; \
+ pxor RK0, x0 ## 2; \
+ pxor RK1, x1 ## 2; \
+ pxor RK2, x2 ## 2; \
+ pxor RK3, x3 ## 2;
+
+#define LK2(x0, x1, x2, x3, x4, i) \
+ movdqa x0 ## 1, x4 ## 1; \
+ pslld $13, x0 ## 1; \
+ psrld $(32 - 13), x4 ## 1; \
+ por x4 ## 1, x0 ## 1; \
+ pxor x0 ## 1, x1 ## 1; \
+ movdqa x2 ## 1, x4 ## 1; \
+ pslld $3, x2 ## 1; \
+ psrld $(32 - 3), x4 ## 1; \
+ por x4 ## 1, x2 ## 1; \
+ pxor x2 ## 1, x1 ## 1; \
+ movdqa x0 ## 2, x4 ## 2; \
+ pslld $13, x0 ## 2; \
+ psrld $(32 - 13), x4 ## 2; \
+ por x4 ## 2, x0 ## 2; \
+ pxor x0 ## 2, x1 ## 2; \
+ movdqa x2 ## 2, x4 ## 2; \
+ pslld $3, x2 ## 2; \
+ psrld $(32 - 3), x4 ## 2; \
+ por x4 ## 2, x2 ## 2; \
+ pxor x2 ## 2, x1 ## 2; \
+ movdqa x1 ## 1, x4 ## 1; \
+ pslld $1, x1 ## 1; \
+ psrld $(32 - 1), x4 ## 1; \
+ por x4 ## 1, x1 ## 1; \
+ movdqa x0 ## 1, x4 ## 1; \
+ pslld $3, x4 ## 1; \
+ pxor x2 ## 1, x3 ## 1; \
+ pxor x4 ## 1, x3 ## 1; \
+ movdqa x3 ## 1, x4 ## 1; \
+ get_key(i, 1, RK1); \
+ movdqa x1 ## 2, x4 ## 2; \
+ pslld $1, x1 ## 2; \
+ psrld $(32 - 1), x4 ## 2; \
+ por x4 ## 2, x1 ## 2; \
+ movdqa x0 ## 2, x4 ## 2; \
+ pslld $3, x4 ## 2; \
+ pxor x2 ## 2, x3 ## 2; \
+ pxor x4 ## 2, x3 ## 2; \
+ movdqa x3 ## 2, x4 ## 2; \
+ get_key(i, 3, RK3); \
+ pslld $7, x3 ## 1; \
+ psrld $(32 - 7), x4 ## 1; \
+ por x4 ## 1, x3 ## 1; \
+ movdqa x1 ## 1, x4 ## 1; \
+ pslld $7, x4 ## 1; \
+ pxor x1 ## 1, x0 ## 1; \
+ pxor x3 ## 1, x0 ## 1; \
+ pxor x3 ## 1, x2 ## 1; \
+ pxor x4 ## 1, x2 ## 1; \
+ get_key(i, 0, RK0); \
+ pslld $7, x3 ## 2; \
+ psrld $(32 - 7), x4 ## 2; \
+ por x4 ## 2, x3 ## 2; \
+ movdqa x1 ## 2, x4 ## 2; \
+ pslld $7, x4 ## 2; \
+ pxor x1 ## 2, x0 ## 2; \
+ pxor x3 ## 2, x0 ## 2; \
+ pxor x3 ## 2, x2 ## 2; \
+ pxor x4 ## 2, x2 ## 2; \
+ get_key(i, 2, RK2); \
+ pxor RK1, x1 ## 1; \
+ pxor RK3, x3 ## 1; \
+ movdqa x0 ## 1, x4 ## 1; \
+ pslld $5, x0 ## 1; \
+ psrld $(32 - 5), x4 ## 1; \
+ por x4 ## 1, x0 ## 1; \
+ movdqa x2 ## 1, x4 ## 1; \
+ pslld $22, x2 ## 1; \
+ psrld $(32 - 22), x4 ## 1; \
+ por x4 ## 1, x2 ## 1; \
+ pxor RK0, x0 ## 1; \
+ pxor RK2, x2 ## 1; \
+ pxor RK1, x1 ## 2; \
+ pxor RK3, x3 ## 2; \
+ movdqa x0 ## 2, x4 ## 2; \
+ pslld $5, x0 ## 2; \
+ psrld $(32 - 5), x4 ## 2; \
+ por x4 ## 2, x0 ## 2; \
+ movdqa x2 ## 2, x4 ## 2; \
+ pslld $22, x2 ## 2; \
+ psrld $(32 - 22), x4 ## 2; \
+ por x4 ## 2, x2 ## 2; \
+ pxor RK0, x0 ## 2; \
+ pxor RK2, x2 ## 2;
+
+#define KL2(x0, x1, x2, x3, x4, i) \
+ pxor RK0, x0 ## 1; \
+ pxor RK2, x2 ## 1; \
+ movdqa x0 ## 1, x4 ## 1; \
+ psrld $5, x0 ## 1; \
+ pslld $(32 - 5), x4 ## 1; \
+ por x4 ## 1, x0 ## 1; \
+ pxor RK3, x3 ## 1; \
+ pxor RK1, x1 ## 1; \
+ movdqa x2 ## 1, x4 ## 1; \
+ psrld $22, x2 ## 1; \
+ pslld $(32 - 22), x4 ## 1; \
+ por x4 ## 1, x2 ## 1; \
+ pxor x3 ## 1, x2 ## 1; \
+ pxor RK0, x0 ## 2; \
+ pxor RK2, x2 ## 2; \
+ movdqa x0 ## 2, x4 ## 2; \
+ psrld $5, x0 ## 2; \
+ pslld $(32 - 5), x4 ## 2; \
+ por x4 ## 2, x0 ## 2; \
+ pxor RK3, x3 ## 2; \
+ pxor RK1, x1 ## 2; \
+ movdqa x2 ## 2, x4 ## 2; \
+ psrld $22, x2 ## 2; \
+ pslld $(32 - 22), x4 ## 2; \
+ por x4 ## 2, x2 ## 2; \
+ pxor x3 ## 2, x2 ## 2; \
+ pxor x3 ## 1, x0 ## 1; \
+ movdqa x1 ## 1, x4 ## 1; \
+ pslld $7, x4 ## 1; \
+ pxor x1 ## 1, x0 ## 1; \
+ pxor x4 ## 1, x2 ## 1; \
+ movdqa x1 ## 1, x4 ## 1; \
+ psrld $1, x1 ## 1; \
+ pslld $(32 - 1), x4 ## 1; \
+ por x4 ## 1, x1 ## 1; \
+ pxor x3 ## 2, x0 ## 2; \
+ movdqa x1 ## 2, x4 ## 2; \
+ pslld $7, x4 ## 2; \
+ pxor x1 ## 2, x0 ## 2; \
+ pxor x4 ## 2, x2 ## 2; \
+ movdqa x1 ## 2, x4 ## 2; \
+ psrld $1, x1 ## 2; \
+ pslld $(32 - 1), x4 ## 2; \
+ por x4 ## 2, x1 ## 2; \
+ movdqa x3 ## 1, x4 ## 1; \
+ psrld $7, x3 ## 1; \
+ pslld $(32 - 7), x4 ## 1; \
+ por x4 ## 1, x3 ## 1; \
+ pxor x0 ## 1, x1 ## 1; \
+ movdqa x0 ## 1, x4 ## 1; \
+ pslld $3, x4 ## 1; \
+ pxor x4 ## 1, x3 ## 1; \
+ movdqa x0 ## 1, x4 ## 1; \
+ movdqa x3 ## 2, x4 ## 2; \
+ psrld $7, x3 ## 2; \
+ pslld $(32 - 7), x4 ## 2; \
+ por x4 ## 2, x3 ## 2; \
+ pxor x0 ## 2, x1 ## 2; \
+ movdqa x0 ## 2, x4 ## 2; \
+ pslld $3, x4 ## 2; \
+ pxor x4 ## 2, x3 ## 2; \
+ movdqa x0 ## 2, x4 ## 2; \
+ psrld $13, x0 ## 1; \
+ pslld $(32 - 13), x4 ## 1; \
+ por x4 ## 1, x0 ## 1; \
+ pxor x2 ## 1, x1 ## 1; \
+ pxor x2 ## 1, x3 ## 1; \
+ movdqa x2 ## 1, x4 ## 1; \
+ psrld $3, x2 ## 1; \
+ pslld $(32 - 3), x4 ## 1; \
+ por x4 ## 1, x2 ## 1; \
+ psrld $13, x0 ## 2; \
+ pslld $(32 - 13), x4 ## 2; \
+ por x4 ## 2, x0 ## 2; \
+ pxor x2 ## 2, x1 ## 2; \
+ pxor x2 ## 2, x3 ## 2; \
+ movdqa x2 ## 2, x4 ## 2; \
+ psrld $3, x2 ## 2; \
+ pslld $(32 - 3), x4 ## 2; \
+ por x4 ## 2, x2 ## 2;
+
+#define S(SBOX, x0, x1, x2, x3, x4) \
+ SBOX ## _1(x0 ## 1, x1 ## 1, x2 ## 1, x3 ## 1, x4 ## 1); \
+ SBOX ## _2(x0 ## 1, x1 ## 1, x2 ## 1, x3 ## 1, x4 ## 1); \
+ SBOX ## _1(x0 ## 2, x1 ## 2, x2 ## 2, x3 ## 2, x4 ## 2); \
+ SBOX ## _2(x0 ## 2, x1 ## 2, x2 ## 2, x3 ## 2, x4 ## 2);
+
+#define SP(SBOX, x0, x1, x2, x3, x4, i) \
+ get_key(i, 0, RK0); \
+ SBOX ## _1(x0 ## 1, x1 ## 1, x2 ## 1, x3 ## 1, x4 ## 1); \
+ get_key(i, 2, RK2); \
+ SBOX ## _1(x0 ## 2, x1 ## 2, x2 ## 2, x3 ## 2, x4 ## 2); \
+ get_key(i, 3, RK3); \
+ SBOX ## _2(x0 ## 1, x1 ## 1, x2 ## 1, x3 ## 1, x4 ## 1); \
+ get_key(i, 1, RK1); \
+ SBOX ## _2(x0 ## 2, x1 ## 2, x2 ## 2, x3 ## 2, x4 ## 2); \
+
+#define transpose_4x4(x0, x1, x2, x3, t1, t2, t3) \
+ movdqa x2, t3; \
+ movdqa x0, t1; \
+ unpcklps x3, t3; \
+ movdqa x0, t2; \
+ unpcklps x1, t1; \
+ unpckhps x1, t2; \
+ movdqa t3, x1; \
+ unpckhps x3, x2; \
+ movdqa t1, x0; \
+ movhlps t1, x1; \
+ movdqa t2, t1; \
+ movlhps t3, x0; \
+ movlhps x2, t1; \
+ movhlps t2, x2; \
+ movdqa x2, x3; \
+ movdqa t1, x2;
+
+#define read_blocks(in, x0, x1, x2, x3, t0, t1, t2) \
+ movdqu (0*4*4)(in), x0; \
+ movdqu (1*4*4)(in), x1; \
+ movdqu (2*4*4)(in), x2; \
+ movdqu (3*4*4)(in), x3; \
+ \
+ transpose_4x4(x0, x1, x2, x3, t0, t1, t2)
+
+#define write_blocks(out, x0, x1, x2, x3, t0, t1, t2) \
+ transpose_4x4(x0, x1, x2, x3, t0, t1, t2) \
+ \
+ movdqu x0, (0*4*4)(out); \
+ movdqu x1, (1*4*4)(out); \
+ movdqu x2, (2*4*4)(out); \
+ movdqu x3, (3*4*4)(out);
+
+#define xor_blocks(out, x0, x1, x2, x3, t0, t1, t2) \
+ transpose_4x4(x0, x1, x2, x3, t0, t1, t2) \
+ \
+ movdqu (0*4*4)(out), t0; \
+ pxor t0, x0; \
+ movdqu x0, (0*4*4)(out); \
+ movdqu (1*4*4)(out), t0; \
+ pxor t0, x1; \
+ movdqu x1, (1*4*4)(out); \
+ movdqu (2*4*4)(out), t0; \
+ pxor t0, x2; \
+ movdqu x2, (2*4*4)(out); \
+ movdqu (3*4*4)(out), t0; \
+ pxor t0, x3; \
+ movdqu x3, (3*4*4)(out);
+
+.align 8
+.global __serpent_enc_blk_8way
+.type __serpent_enc_blk_8way,@function;
+
+__serpent_enc_blk_8way:
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: dst
+ * %rdx: src
+ * %rcx: bool, if true: xor output
+ */
+
+ pcmpeqd RNOT, RNOT;
+
+ leaq (4*4*4)(%rdx), %rax;
+ read_blocks(%rdx, RA1, RB1, RC1, RD1, RK0, RK1, RK2);
+ read_blocks(%rax, RA2, RB2, RC2, RD2, RK0, RK1, RK2);
+
+ K2(RA, RB, RC, RD, RE, 0);
+ S(S0, RA, RB, RC, RD, RE); LK2(RC, RB, RD, RA, RE, 1);
+ S(S1, RC, RB, RD, RA, RE); LK2(RE, RD, RA, RC, RB, 2);
+ S(S2, RE, RD, RA, RC, RB); LK2(RB, RD, RE, RC, RA, 3);
+ S(S3, RB, RD, RE, RC, RA); LK2(RC, RA, RD, RB, RE, 4);
+ S(S4, RC, RA, RD, RB, RE); LK2(RA, RD, RB, RE, RC, 5);
+ S(S5, RA, RD, RB, RE, RC); LK2(RC, RA, RD, RE, RB, 6);
+ S(S6, RC, RA, RD, RE, RB); LK2(RD, RB, RA, RE, RC, 7);
+ S(S7, RD, RB, RA, RE, RC); LK2(RC, RA, RE, RD, RB, 8);
+ S(S0, RC, RA, RE, RD, RB); LK2(RE, RA, RD, RC, RB, 9);
+ S(S1, RE, RA, RD, RC, RB); LK2(RB, RD, RC, RE, RA, 10);
+ S(S2, RB, RD, RC, RE, RA); LK2(RA, RD, RB, RE, RC, 11);
+ S(S3, RA, RD, RB, RE, RC); LK2(RE, RC, RD, RA, RB, 12);
+ S(S4, RE, RC, RD, RA, RB); LK2(RC, RD, RA, RB, RE, 13);
+ S(S5, RC, RD, RA, RB, RE); LK2(RE, RC, RD, RB, RA, 14);
+ S(S6, RE, RC, RD, RB, RA); LK2(RD, RA, RC, RB, RE, 15);
+ S(S7, RD, RA, RC, RB, RE); LK2(RE, RC, RB, RD, RA, 16);
+ S(S0, RE, RC, RB, RD, RA); LK2(RB, RC, RD, RE, RA, 17);
+ S(S1, RB, RC, RD, RE, RA); LK2(RA, RD, RE, RB, RC, 18);
+ S(S2, RA, RD, RE, RB, RC); LK2(RC, RD, RA, RB, RE, 19);
+ S(S3, RC, RD, RA, RB, RE); LK2(RB, RE, RD, RC, RA, 20);
+ S(S4, RB, RE, RD, RC, RA); LK2(RE, RD, RC, RA, RB, 21);
+ S(S5, RE, RD, RC, RA, RB); LK2(RB, RE, RD, RA, RC, 22);
+ S(S6, RB, RE, RD, RA, RC); LK2(RD, RC, RE, RA, RB, 23);
+ S(S7, RD, RC, RE, RA, RB); LK2(RB, RE, RA, RD, RC, 24);
+ S(S0, RB, RE, RA, RD, RC); LK2(RA, RE, RD, RB, RC, 25);
+ S(S1, RA, RE, RD, RB, RC); LK2(RC, RD, RB, RA, RE, 26);
+ S(S2, RC, RD, RB, RA, RE); LK2(RE, RD, RC, RA, RB, 27);
+ S(S3, RE, RD, RC, RA, RB); LK2(RA, RB, RD, RE, RC, 28);
+ S(S4, RA, RB, RD, RE, RC); LK2(RB, RD, RE, RC, RA, 29);
+ S(S5, RB, RD, RE, RC, RA); LK2(RA, RB, RD, RC, RE, 30);
+ S(S6, RA, RB, RD, RC, RE); LK2(RD, RE, RB, RC, RA, 31);
+ S(S7, RD, RE, RB, RC, RA); K2(RA, RB, RC, RD, RE, 32);
+
+ leaq (4*4*4)(%rsi), %rax;
+
+ testb %cl, %cl;
+ jnz __enc_xor8;
+
+ write_blocks(%rsi, RA1, RB1, RC1, RD1, RK0, RK1, RK2);
+ write_blocks(%rax, RA2, RB2, RC2, RD2, RK0, RK1, RK2);
+
+ ret;
+
+__enc_xor8:
+ xor_blocks(%rsi, RA1, RB1, RC1, RD1, RK0, RK1, RK2);
+ xor_blocks(%rax, RA2, RB2, RC2, RD2, RK0, RK1, RK2);
+
+ ret;
+
+.align 8
+.global serpent_dec_blk_8way
+.type serpent_dec_blk_8way,@function;
+
+serpent_dec_blk_8way:
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: dst
+ * %rdx: src
+ */
+
+ pcmpeqd RNOT, RNOT;
+
+ leaq (4*4*4)(%rdx), %rax;
+ read_blocks(%rdx, RA1, RB1, RC1, RD1, RK0, RK1, RK2);
+ read_blocks(%rax, RA2, RB2, RC2, RD2, RK0, RK1, RK2);
+
+ K2(RA, RB, RC, RD, RE, 32);
+ SP(SI7, RA, RB, RC, RD, RE, 31); KL2(RB, RD, RA, RE, RC, 31);
+ SP(SI6, RB, RD, RA, RE, RC, 30); KL2(RA, RC, RE, RB, RD, 30);
+ SP(SI5, RA, RC, RE, RB, RD, 29); KL2(RC, RD, RA, RE, RB, 29);
+ SP(SI4, RC, RD, RA, RE, RB, 28); KL2(RC, RA, RB, RE, RD, 28);
+ SP(SI3, RC, RA, RB, RE, RD, 27); KL2(RB, RC, RD, RE, RA, 27);
+ SP(SI2, RB, RC, RD, RE, RA, 26); KL2(RC, RA, RE, RD, RB, 26);
+ SP(SI1, RC, RA, RE, RD, RB, 25); KL2(RB, RA, RE, RD, RC, 25);
+ SP(SI0, RB, RA, RE, RD, RC, 24); KL2(RE, RC, RA, RB, RD, 24);
+ SP(SI7, RE, RC, RA, RB, RD, 23); KL2(RC, RB, RE, RD, RA, 23);
+ SP(SI6, RC, RB, RE, RD, RA, 22); KL2(RE, RA, RD, RC, RB, 22);
+ SP(SI5, RE, RA, RD, RC, RB, 21); KL2(RA, RB, RE, RD, RC, 21);
+ SP(SI4, RA, RB, RE, RD, RC, 20); KL2(RA, RE, RC, RD, RB, 20);
+ SP(SI3, RA, RE, RC, RD, RB, 19); KL2(RC, RA, RB, RD, RE, 19);
+ SP(SI2, RC, RA, RB, RD, RE, 18); KL2(RA, RE, RD, RB, RC, 18);
+ SP(SI1, RA, RE, RD, RB, RC, 17); KL2(RC, RE, RD, RB, RA, 17);
+ SP(SI0, RC, RE, RD, RB, RA, 16); KL2(RD, RA, RE, RC, RB, 16);
+ SP(SI7, RD, RA, RE, RC, RB, 15); KL2(RA, RC, RD, RB, RE, 15);
+ SP(SI6, RA, RC, RD, RB, RE, 14); KL2(RD, RE, RB, RA, RC, 14);
+ SP(SI5, RD, RE, RB, RA, RC, 13); KL2(RE, RC, RD, RB, RA, 13);
+ SP(SI4, RE, RC, RD, RB, RA, 12); KL2(RE, RD, RA, RB, RC, 12);
+ SP(SI3, RE, RD, RA, RB, RC, 11); KL2(RA, RE, RC, RB, RD, 11);
+ SP(SI2, RA, RE, RC, RB, RD, 10); KL2(RE, RD, RB, RC, RA, 10);
+ SP(SI1, RE, RD, RB, RC, RA, 9); KL2(RA, RD, RB, RC, RE, 9);
+ SP(SI0, RA, RD, RB, RC, RE, 8); KL2(RB, RE, RD, RA, RC, 8);
+ SP(SI7, RB, RE, RD, RA, RC, 7); KL2(RE, RA, RB, RC, RD, 7);
+ SP(SI6, RE, RA, RB, RC, RD, 6); KL2(RB, RD, RC, RE, RA, 6);
+ SP(SI5, RB, RD, RC, RE, RA, 5); KL2(RD, RA, RB, RC, RE, 5);
+ SP(SI4, RD, RA, RB, RC, RE, 4); KL2(RD, RB, RE, RC, RA, 4);
+ SP(SI3, RD, RB, RE, RC, RA, 3); KL2(RE, RD, RA, RC, RB, 3);
+ SP(SI2, RE, RD, RA, RC, RB, 2); KL2(RD, RB, RC, RA, RE, 2);
+ SP(SI1, RD, RB, RC, RA, RE, 1); KL2(RE, RB, RC, RA, RD, 1);
+ S(SI0, RE, RB, RC, RA, RD); K2(RC, RD, RB, RE, RA, 0);
+
+ leaq (4*4*4)(%rsi), %rax;
+ write_blocks(%rsi, RC1, RD1, RB1, RE1, RK0, RK1, RK2);
+ write_blocks(%rax, RC2, RD2, RB2, RE2, RK0, RK1, RK2);
+
+ ret;
diff --git a/arch/x86/crypto/serpent_sse2_glue.c b/arch/x86/crypto/serpent_sse2_glue.c
new file mode 100644
index 0000000..7955a9b
--- /dev/null
+++ b/arch/x86/crypto/serpent_sse2_glue.c
@@ -0,0 +1,1070 @@
+/*
+ * Glue Code for SSE2 assembler versions of Serpent Cipher
+ *
+ * Copyright (c) 2011 Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
+ *
+ * Glue code based on aesni-intel_glue.c by:
+ * Copyright (C) 2008, Intel Corp.
+ * Author: Huang Ying <ying.huang@intel.com>
+ *
+ * CBC & ECB parts based on code (crypto/cbc.c,ecb.c) by:
+ * Copyright (c) 2006 Herbert Xu <herbert@gondor.apana.org.au>
+ * CTR part based on code (crypto/ctr.c) by:
+ * (C) Copyright IBM Corp. 2007 - Joy Latten <latten@us.ibm.com>
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/hardirq.h>
+#include <linux/types.h>
+#include <linux/crypto.h>
+#include <linux/err.h>
+#include <crypto/algapi.h>
+#include <crypto/serpent.h>
+#include <crypto/cryptd.h>
+#include <crypto/b128ops.h>
+#include <crypto/ctr.h>
+#include <crypto/lrw.h>
+#include <crypto/xts.h>
+#include <asm/i387.h>
+#include <asm/serpent.h>
+#include <crypto/scatterwalk.h>
+#include <linux/workqueue.h>
+#include <linux/spinlock.h>
+
+struct async_serpent_ctx {
+ struct cryptd_ablkcipher *cryptd_tfm;
+};
+
+static inline bool serpent_fpu_begin(bool fpu_enabled, unsigned int nbytes)
+{
+ if (fpu_enabled)
+ return true;
+
+ /* SSE2 is only used when chunk to be processed is large enough, so
+ * do not enable FPU until it is necessary.
+ */
+ if (nbytes < SERPENT_BLOCK_SIZE * SERPENT_PARALLEL_BLOCKS)
+ return false;
+
+ kernel_fpu_begin();
+ return true;
+}
+
+static inline void serpent_fpu_end(bool fpu_enabled)
+{
+ if (fpu_enabled)
+ kernel_fpu_end();
+}
+
+static int ecb_crypt(struct blkcipher_desc *desc, struct blkcipher_walk *walk,
+ bool enc)
+{
+ bool fpu_enabled = false;
+ struct serpent_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
+ const unsigned int bsize = SERPENT_BLOCK_SIZE;
+ unsigned int nbytes;
+ int err;
+
+ err = blkcipher_walk_virt(desc, walk);
+ desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
+
+ while ((nbytes = walk->nbytes)) {
+ u8 *wsrc = walk->src.virt.addr;
+ u8 *wdst = walk->dst.virt.addr;
+
+ fpu_enabled = serpent_fpu_begin(fpu_enabled, nbytes);
+
+ /* Process multi-block batch */
+ if (nbytes >= bsize * SERPENT_PARALLEL_BLOCKS) {
+ do {
+ if (enc)
+ serpent_enc_blk_xway(ctx, wdst, wsrc);
+ else
+ serpent_dec_blk_xway(ctx, wdst, wsrc);
+
+ wsrc += bsize * SERPENT_PARALLEL_BLOCKS;
+ wdst += bsize * SERPENT_PARALLEL_BLOCKS;
+ nbytes -= bsize * SERPENT_PARALLEL_BLOCKS;
+ } while (nbytes >= bsize * SERPENT_PARALLEL_BLOCKS);
+
+ if (nbytes < bsize)
+ goto done;
+ }
+
+ /* Handle leftovers */
+ do {
+ if (enc)
+ __serpent_encrypt(ctx, wdst, wsrc);
+ else
+ __serpent_decrypt(ctx, wdst, wsrc);
+
+ wsrc += bsize;
+ wdst += bsize;
+ nbytes -= bsize;
+ } while (nbytes >= bsize);
+
+done:
+ err = blkcipher_walk_done(desc, walk, nbytes);
+ }
+
+ serpent_fpu_end(fpu_enabled);
+ return err;
+}
+
+static int ecb_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
+ struct scatterlist *src, unsigned int nbytes)
+{
+ struct blkcipher_walk walk;
+
+ blkcipher_walk_init(&walk, dst, src, nbytes);
+ return ecb_crypt(desc, &walk, true);
+}
+
+static int ecb_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
+ struct scatterlist *src, unsigned int nbytes)
+{
+ struct blkcipher_walk walk;
+
+ blkcipher_walk_init(&walk, dst, src, nbytes);
+ return ecb_crypt(desc, &walk, false);
+}
+
+static struct crypto_alg blk_ecb_alg = {
+ .cra_name = "__ecb-serpent-sse2",
+ .cra_driver_name = "__driver-ecb-serpent-sse2",
+ .cra_priority = 0,
+ .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
+ .cra_blocksize = SERPENT_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct serpent_ctx),
+ .cra_alignmask = 0,
+ .cra_type = &crypto_blkcipher_type,
+ .cra_module = THIS_MODULE,
+ .cra_list = LIST_HEAD_INIT(blk_ecb_alg.cra_list),
+ .cra_u = {
+ .blkcipher = {
+ .min_keysize = SERPENT_MIN_KEY_SIZE,
+ .max_keysize = SERPENT_MAX_KEY_SIZE,
+ .setkey = serpent_setkey,
+ .encrypt = ecb_encrypt,
+ .decrypt = ecb_decrypt,
+ },
+ },
+};
+
+static unsigned int __cbc_encrypt(struct blkcipher_desc *desc,
+ struct blkcipher_walk *walk)
+{
+ struct serpent_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
+ const unsigned int bsize = SERPENT_BLOCK_SIZE;
+ unsigned int nbytes = walk->nbytes;
+ u128 *src = (u128 *)walk->src.virt.addr;
+ u128 *dst = (u128 *)walk->dst.virt.addr;
+ u128 *iv = (u128 *)walk->iv;
+
+ do {
+ u128_xor(dst, src, iv);
+ __serpent_encrypt(ctx, (u8 *)dst, (u8 *)dst);
+ iv = dst;
+
+ src += 1;
+ dst += 1;
+ nbytes -= bsize;
+ } while (nbytes >= bsize);
+
+ u128_xor((u128 *)walk->iv, (u128 *)walk->iv, iv);
+ return nbytes;
+}
+
+static int cbc_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
+ struct scatterlist *src, unsigned int nbytes)
+{
+ struct blkcipher_walk walk;
+ int err;
+
+ blkcipher_walk_init(&walk, dst, src, nbytes);
+ err = blkcipher_walk_virt(desc, &walk);
+
+ while ((nbytes = walk.nbytes)) {
+ nbytes = __cbc_encrypt(desc, &walk);
+ err = blkcipher_walk_done(desc, &walk, nbytes);
+ }
+
+ return err;
+}
+
+static unsigned int __cbc_decrypt(struct blkcipher_desc *desc,
+ struct blkcipher_walk *walk)
+{
+ struct serpent_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
+ const unsigned int bsize = SERPENT_BLOCK_SIZE;
+ unsigned int nbytes = walk->nbytes;
+ u128 *src = (u128 *)walk->src.virt.addr;
+ u128 *dst = (u128 *)walk->dst.virt.addr;
+ u128 ivs[SERPENT_PARALLEL_BLOCKS - 1];
+ u128 last_iv;
+ int i;
+
+ /* Start of the last block. */
+ src += nbytes / bsize - 1;
+ dst += nbytes / bsize - 1;
+
+ last_iv = *src;
+
+ /* Process multi-block batch */
+ if (nbytes >= bsize * SERPENT_PARALLEL_BLOCKS) {
+ do {
+ nbytes -= bsize * (SERPENT_PARALLEL_BLOCKS - 1);
+ src -= SERPENT_PARALLEL_BLOCKS - 1;
+ dst -= SERPENT_PARALLEL_BLOCKS - 1;
+
+ for (i = 0; i < SERPENT_PARALLEL_BLOCKS - 1; i++)
+ ivs[i] = src[i];
+
+ serpent_dec_blk_xway(ctx, (u8 *)dst, (u8 *)src);
+
+ for (i = 0; i < SERPENT_PARALLEL_BLOCKS - 1; i++)
+ u128_xor(dst + (i + 1), dst + (i + 1), ivs + i);
+
+ nbytes -= bsize;
+ if (nbytes < bsize)
+ goto done;
+
+ u128_xor(dst, dst, src - 1);
+ src -= 1;
+ dst -= 1;
+ } while (nbytes >= bsize * SERPENT_PARALLEL_BLOCKS);
+
+ if (nbytes < bsize)
+ goto done;
+ }
+
+ /* Handle leftovers */
+ for (;;) {
+ __serpent_decrypt(ctx, (u8 *)dst, (u8 *)src);
+
+ nbytes -= bsize;
+ if (nbytes < bsize)
+ break;
+
+ u128_xor(dst, dst, src - 1);
+ src -= 1;
+ dst -= 1;
+ }
+
+done:
+ u128_xor(dst, dst, (u128 *)walk->iv);
+ *(u128 *)walk->iv = last_iv;
+
+ return nbytes;
+}
+
+static int cbc_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
+ struct scatterlist *src, unsigned int nbytes)
+{
+ bool fpu_enabled = false;
+ struct blkcipher_walk walk;
+ int err;
+
+ blkcipher_walk_init(&walk, dst, src, nbytes);
+ err = blkcipher_walk_virt(desc, &walk);
+ desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
+
+ while ((nbytes = walk.nbytes)) {
+ fpu_enabled = serpent_fpu_begin(fpu_enabled, nbytes);
+ nbytes = __cbc_decrypt(desc, &walk);
+ err = blkcipher_walk_done(desc, &walk, nbytes);
+ }
+
+ serpent_fpu_end(fpu_enabled);
+ return err;
+}
+
+static struct crypto_alg blk_cbc_alg = {
+ .cra_name = "__cbc-serpent-sse2",
+ .cra_driver_name = "__driver-cbc-serpent-sse2",
+ .cra_priority = 0,
+ .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
+ .cra_blocksize = SERPENT_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct serpent_ctx),
+ .cra_alignmask = 0,
+ .cra_type = &crypto_blkcipher_type,
+ .cra_module = THIS_MODULE,
+ .cra_list = LIST_HEAD_INIT(blk_cbc_alg.cra_list),
+ .cra_u = {
+ .blkcipher = {
+ .min_keysize = SERPENT_MIN_KEY_SIZE,
+ .max_keysize = SERPENT_MAX_KEY_SIZE,
+ .setkey = serpent_setkey,
+ .encrypt = cbc_encrypt,
+ .decrypt = cbc_decrypt,
+ },
+ },
+};
+
+static inline void u128_to_be128(be128 *dst, const u128 *src)
+{
+ dst->a = cpu_to_be64(src->a);
+ dst->b = cpu_to_be64(src->b);
+}
+
+static inline void be128_to_u128(u128 *dst, const be128 *src)
+{
+ dst->a = be64_to_cpu(src->a);
+ dst->b = be64_to_cpu(src->b);
+}
+
+static inline void u128_inc(u128 *i)
+{
+ i->b++;
+ if (!i->b)
+ i->a++;
+}
+
+static void ctr_crypt_final(struct blkcipher_desc *desc,
+ struct blkcipher_walk *walk)
+{
+ struct serpent_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
+ u8 *ctrblk = walk->iv;
+ u8 keystream[SERPENT_BLOCK_SIZE];
+ u8 *src = walk->src.virt.addr;
+ u8 *dst = walk->dst.virt.addr;
+ unsigned int nbytes = walk->nbytes;
+
+ __serpent_encrypt(ctx, keystream, ctrblk);
+ crypto_xor(keystream, src, nbytes);
+ memcpy(dst, keystream, nbytes);
+
+ crypto_inc(ctrblk, SERPENT_BLOCK_SIZE);
+}
+
+static unsigned int __ctr_crypt(struct blkcipher_desc *desc,
+ struct blkcipher_walk *walk)
+{
+ struct serpent_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
+ const unsigned int bsize = SERPENT_BLOCK_SIZE;
+ unsigned int nbytes = walk->nbytes;
+ u128 *src = (u128 *)walk->src.virt.addr;
+ u128 *dst = (u128 *)walk->dst.virt.addr;
+ u128 ctrblk;
+ be128 ctrblocks[SERPENT_PARALLEL_BLOCKS];
+ int i;
+
+ be128_to_u128(&ctrblk, (be128 *)walk->iv);
+
+ /* Process multi-block batch */
+ if (nbytes >= bsize * SERPENT_PARALLEL_BLOCKS) {
+ do {
+ /* create ctrblks for parallel encrypt */
+ for (i = 0; i < SERPENT_PARALLEL_BLOCKS; i++) {
+ if (dst != src)
+ dst[i] = src[i];
+
+ u128_to_be128(&ctrblocks[i], &ctrblk);
+ u128_inc(&ctrblk);
+ }
+
+ serpent_enc_blk_xway_xor(ctx, (u8 *)dst,
+ (u8 *)ctrblocks);
+
+ src += SERPENT_PARALLEL_BLOCKS;
+ dst += SERPENT_PARALLEL_BLOCKS;
+ nbytes -= bsize * SERPENT_PARALLEL_BLOCKS;
+ } while (nbytes >= bsize * SERPENT_PARALLEL_BLOCKS);
+
+ if (nbytes < bsize)
+ goto done;
+ }
+
+ /* Handle leftovers */
+ do {
+ if (dst != src)
+ *dst = *src;
+
+ u128_to_be128(&ctrblocks[0], &ctrblk);
+ u128_inc(&ctrblk);
+
+ __serpent_encrypt(ctx, (u8 *)ctrblocks, (u8 *)ctrblocks);
+ u128_xor(dst, dst, (u128 *)ctrblocks);
+
+ src += 1;
+ dst += 1;
+ nbytes -= bsize;
+ } while (nbytes >= bsize);
+
+done:
+ u128_to_be128((be128 *)walk->iv, &ctrblk);
+ return nbytes;
+}
+
+static int ctr_crypt(struct blkcipher_desc *desc, struct scatterlist *dst,
+ struct scatterlist *src, unsigned int nbytes)
+{
+ bool fpu_enabled = false;
+ struct blkcipher_walk walk;
+ int err;
+
+ blkcipher_walk_init(&walk, dst, src, nbytes);
+ err = blkcipher_walk_virt_block(desc, &walk, SERPENT_BLOCK_SIZE);
+ desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
+
+ while ((nbytes = walk.nbytes) >= SERPENT_BLOCK_SIZE) {
+ fpu_enabled = serpent_fpu_begin(fpu_enabled, nbytes);
+ nbytes = __ctr_crypt(desc, &walk);
+ err = blkcipher_walk_done(desc, &walk, nbytes);
+ }
+
+ serpent_fpu_end(fpu_enabled);
+
+ if (walk.nbytes) {
+ ctr_crypt_final(desc, &walk);
+ err = blkcipher_walk_done(desc, &walk, 0);
+ }
+
+ return err;
+}
+
+static struct crypto_alg blk_ctr_alg = {
+ .cra_name = "__ctr-serpent-sse2",
+ .cra_driver_name = "__driver-ctr-serpent-sse2",
+ .cra_priority = 0,
+ .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
+ .cra_blocksize = 1,
+ .cra_ctxsize = sizeof(struct serpent_ctx),
+ .cra_alignmask = 0,
+ .cra_type = &crypto_blkcipher_type,
+ .cra_module = THIS_MODULE,
+ .cra_list = LIST_HEAD_INIT(blk_ctr_alg.cra_list),
+ .cra_u = {
+ .blkcipher = {
+ .min_keysize = SERPENT_MIN_KEY_SIZE,
+ .max_keysize = SERPENT_MAX_KEY_SIZE,
+ .ivsize = SERPENT_BLOCK_SIZE,
+ .setkey = serpent_setkey,
+ .encrypt = ctr_crypt,
+ .decrypt = ctr_crypt,
+ },
+ },
+};
+
+struct crypt_priv {
+ struct serpent_ctx *ctx;
+ bool fpu_enabled;
+};
+
+static void encrypt_callback(void *priv, u8 *srcdst, unsigned int nbytes)
+{
+ const unsigned int bsize = SERPENT_BLOCK_SIZE;
+ struct crypt_priv *ctx = priv;
+ int i;
+
+ ctx->fpu_enabled = serpent_fpu_begin(ctx->fpu_enabled, nbytes);
+
+ if (nbytes == bsize * SERPENT_PARALLEL_BLOCKS) {
+ serpent_enc_blk_xway(ctx->ctx, srcdst, srcdst);
+ return;
+ }
+
+ for (i = 0; i < nbytes / bsize; i++, srcdst += bsize)
+ __serpent_encrypt(ctx->ctx, srcdst, srcdst);
+}
+
+static void decrypt_callback(void *priv, u8 *srcdst, unsigned int nbytes)
+{
+ const unsigned int bsize = SERPENT_BLOCK_SIZE;
+ struct crypt_priv *ctx = priv;
+ int i;
+
+ ctx->fpu_enabled = serpent_fpu_begin(ctx->fpu_enabled, nbytes);
+
+ if (nbytes == bsize * SERPENT_PARALLEL_BLOCKS) {
+ serpent_dec_blk_xway(ctx->ctx, srcdst, srcdst);
+ return;
+ }
+
+ for (i = 0; i < nbytes / bsize; i++, srcdst += bsize)
+ __serpent_decrypt(ctx->ctx, srcdst, srcdst);
+}
+
+struct serpent_lrw_ctx {
+ struct lrw_table_ctx lrw_table;
+ struct serpent_ctx serpent_ctx;
+};
+
+static int lrw_serpent_setkey(struct crypto_tfm *tfm, const u8 *key,
+ unsigned int keylen)
+{
+ struct serpent_lrw_ctx *ctx = crypto_tfm_ctx(tfm);
+ int err;
+
+ err = __serpent_setkey(&ctx->serpent_ctx, key, keylen -
+ SERPENT_BLOCK_SIZE);
+ if (err)
+ return err;
+
+ return lrw_init_table(&ctx->lrw_table, key + keylen -
+ SERPENT_BLOCK_SIZE);
+}
+
+static int lrw_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
+ struct scatterlist *src, unsigned int nbytes)
+{
+ struct serpent_lrw_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
+ be128 buf[SERPENT_PARALLEL_BLOCKS];
+ struct crypt_priv crypt_ctx = {
+ .ctx = &ctx->serpent_ctx,
+ .fpu_enabled = false,
+ };
+ struct lrw_crypt_req req = {
+ .tbuf = buf,
+ .tbuflen = sizeof(buf),
+
+ .table_ctx = &ctx->lrw_table,
+ .crypt_ctx = &crypt_ctx,
+ .crypt_fn = encrypt_callback,
+ };
+ int ret;
+
+ desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
+ ret = lrw_crypt(desc, dst, src, nbytes, &req);
+ serpent_fpu_end(crypt_ctx.fpu_enabled);
+
+ return ret;
+}
+
+static int lrw_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
+ struct scatterlist *src, unsigned int nbytes)
+{
+ struct serpent_lrw_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
+ be128 buf[SERPENT_PARALLEL_BLOCKS];
+ struct crypt_priv crypt_ctx = {
+ .ctx = &ctx->serpent_ctx,
+ .fpu_enabled = false,
+ };
+ struct lrw_crypt_req req = {
+ .tbuf = buf,
+ .tbuflen = sizeof(buf),
+
+ .table_ctx = &ctx->lrw_table,
+ .crypt_ctx = &crypt_ctx,
+ .crypt_fn = decrypt_callback,
+ };
+ int ret;
+
+ desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
+ ret = lrw_crypt(desc, dst, src, nbytes, &req);
+ serpent_fpu_end(crypt_ctx.fpu_enabled);
+
+ return ret;
+}
+
+static void lrw_exit_tfm(struct crypto_tfm *tfm)
+{
+ struct serpent_lrw_ctx *ctx = crypto_tfm_ctx(tfm);
+
+ lrw_free_table(&ctx->lrw_table);
+}
+
+static struct crypto_alg blk_lrw_alg = {
+ .cra_name = "__lrw-serpent-sse2",
+ .cra_driver_name = "__driver-lrw-serpent-sse2",
+ .cra_priority = 0,
+ .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
+ .cra_blocksize = SERPENT_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct serpent_lrw_ctx),
+ .cra_alignmask = 0,
+ .cra_type = &crypto_blkcipher_type,
+ .cra_module = THIS_MODULE,
+ .cra_list = LIST_HEAD_INIT(blk_lrw_alg.cra_list),
+ .cra_exit = lrw_exit_tfm,
+ .cra_u = {
+ .blkcipher = {
+ .min_keysize = SERPENT_MIN_KEY_SIZE +
+ SERPENT_BLOCK_SIZE,
+ .max_keysize = SERPENT_MAX_KEY_SIZE +
+ SERPENT_BLOCK_SIZE,
+ .ivsize = SERPENT_BLOCK_SIZE,
+ .setkey = lrw_serpent_setkey,
+ .encrypt = lrw_encrypt,
+ .decrypt = lrw_decrypt,
+ },
+ },
+};
+
+struct serpent_xts_ctx {
+ struct serpent_ctx tweak_ctx;
+ struct serpent_ctx crypt_ctx;
+};
+
+static int xts_serpent_setkey(struct crypto_tfm *tfm, const u8 *key,
+ unsigned int keylen)
+{
+ struct serpent_xts_ctx *ctx = crypto_tfm_ctx(tfm);
+ u32 *flags = &tfm->crt_flags;
+ int err;
+
+ /* key consists of keys of equal size concatenated, therefore
+ * the length must be even
+ */
+ if (keylen % 2) {
+ *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
+ return -EINVAL;
+ }
+
+ /* first half of xts-key is for crypt */
+ err = __serpent_setkey(&ctx->crypt_ctx, key, keylen / 2);
+ if (err)
+ return err;
+
+ /* second half of xts-key is for tweak */
+ return __serpent_setkey(&ctx->tweak_ctx, key + keylen / 2, keylen / 2);
+}
+
+static int xts_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
+ struct scatterlist *src, unsigned int nbytes)
+{
+ struct serpent_xts_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
+ be128 buf[SERPENT_PARALLEL_BLOCKS];
+ struct crypt_priv crypt_ctx = {
+ .ctx = &ctx->crypt_ctx,
+ .fpu_enabled = false,
+ };
+ struct xts_crypt_req req = {
+ .tbuf = buf,
+ .tbuflen = sizeof(buf),
+
+ .tweak_ctx = &ctx->tweak_ctx,
+ .tweak_fn = XTS_TWEAK_CAST(__serpent_encrypt),
+ .crypt_ctx = &crypt_ctx,
+ .crypt_fn = encrypt_callback,
+ };
+ int ret;
+
+ desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
+ ret = xts_crypt(desc, dst, src, nbytes, &req);
+ serpent_fpu_end(crypt_ctx.fpu_enabled);
+
+ return ret;
+}
+
+static int xts_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
+ struct scatterlist *src, unsigned int nbytes)
+{
+ struct serpent_xts_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
+ be128 buf[SERPENT_PARALLEL_BLOCKS];
+ struct crypt_priv crypt_ctx = {
+ .ctx = &ctx->crypt_ctx,
+ .fpu_enabled = false,
+ };
+ struct xts_crypt_req req = {
+ .tbuf = buf,
+ .tbuflen = sizeof(buf),
+
+ .tweak_ctx = &ctx->tweak_ctx,
+ .tweak_fn = XTS_TWEAK_CAST(__serpent_encrypt),
+ .crypt_ctx = &crypt_ctx,
+ .crypt_fn = decrypt_callback,
+ };
+ int ret;
+
+ desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
+ ret = xts_crypt(desc, dst, src, nbytes, &req);
+ serpent_fpu_end(crypt_ctx.fpu_enabled);
+
+ return ret;
+}
+
+static struct crypto_alg blk_xts_alg = {
+ .cra_name = "__xts-serpent-sse2",
+ .cra_driver_name = "__driver-xts-serpent-sse2",
+ .cra_priority = 0,
+ .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
+ .cra_blocksize = SERPENT_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct serpent_xts_ctx),
+ .cra_alignmask = 0,
+ .cra_type = &crypto_blkcipher_type,
+ .cra_module = THIS_MODULE,
+ .cra_list = LIST_HEAD_INIT(blk_xts_alg.cra_list),
+ .cra_u = {
+ .blkcipher = {
+ .min_keysize = SERPENT_MIN_KEY_SIZE * 2,
+ .max_keysize = SERPENT_MAX_KEY_SIZE * 2,
+ .ivsize = SERPENT_BLOCK_SIZE,
+ .setkey = xts_serpent_setkey,
+ .encrypt = xts_encrypt,
+ .decrypt = xts_decrypt,
+ },
+ },
+};
+
+static int ablk_set_key(struct crypto_ablkcipher *tfm, const u8 *key,
+ unsigned int key_len)
+{
+ struct async_serpent_ctx *ctx = crypto_ablkcipher_ctx(tfm);
+ struct crypto_ablkcipher *child = &ctx->cryptd_tfm->base;
+ int err;
+
+ crypto_ablkcipher_clear_flags(child, CRYPTO_TFM_REQ_MASK);
+ crypto_ablkcipher_set_flags(child, crypto_ablkcipher_get_flags(tfm)
+ & CRYPTO_TFM_REQ_MASK);
+ err = crypto_ablkcipher_setkey(child, key, key_len);
+ crypto_ablkcipher_set_flags(tfm, crypto_ablkcipher_get_flags(child)
+ & CRYPTO_TFM_RES_MASK);
+ return err;
+}
+
+static int __ablk_encrypt(struct ablkcipher_request *req)
+{
+ struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req);
+ struct async_serpent_ctx *ctx = crypto_ablkcipher_ctx(tfm);
+ struct blkcipher_desc desc;
+
+ desc.tfm = cryptd_ablkcipher_child(ctx->cryptd_tfm);
+ desc.info = req->info;
+ desc.flags = 0;
+
+ return crypto_blkcipher_crt(desc.tfm)->encrypt(
+ &desc, req->dst, req->src, req->nbytes);
+}
+
+static int ablk_encrypt(struct ablkcipher_request *req)
+{
+ struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req);
+ struct async_serpent_ctx *ctx = crypto_ablkcipher_ctx(tfm);
+
+ if (!irq_fpu_usable()) {
+ struct ablkcipher_request *cryptd_req =
+ ablkcipher_request_ctx(req);
+
+ memcpy(cryptd_req, req, sizeof(*req));
+ ablkcipher_request_set_tfm(cryptd_req, &ctx->cryptd_tfm->base);
+
+ return crypto_ablkcipher_encrypt(cryptd_req);
+ } else {
+ return __ablk_encrypt(req);
+ }
+}
+
+static int ablk_decrypt(struct ablkcipher_request *req)
+{
+ struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req);
+ struct async_serpent_ctx *ctx = crypto_ablkcipher_ctx(tfm);
+
+ if (!irq_fpu_usable()) {
+ struct ablkcipher_request *cryptd_req =
+ ablkcipher_request_ctx(req);
+
+ memcpy(cryptd_req, req, sizeof(*req));
+ ablkcipher_request_set_tfm(cryptd_req, &ctx->cryptd_tfm->base);
+
+ return crypto_ablkcipher_decrypt(cryptd_req);
+ } else {
+ struct blkcipher_desc desc;
+
+ desc.tfm = cryptd_ablkcipher_child(ctx->cryptd_tfm);
+ desc.info = req->info;
+ desc.flags = 0;
+
+ return crypto_blkcipher_crt(desc.tfm)->decrypt(
+ &desc, req->dst, req->src, req->nbytes);
+ }
+}
+
+static void ablk_exit(struct crypto_tfm *tfm)
+{
+ struct async_serpent_ctx *ctx = crypto_tfm_ctx(tfm);
+
+ cryptd_free_ablkcipher(ctx->cryptd_tfm);
+}
+
+static void ablk_init_common(struct crypto_tfm *tfm,
+ struct cryptd_ablkcipher *cryptd_tfm)
+{
+ struct async_serpent_ctx *ctx = crypto_tfm_ctx(tfm);
+
+ ctx->cryptd_tfm = cryptd_tfm;
+ tfm->crt_ablkcipher.reqsize = sizeof(struct ablkcipher_request) +
+ crypto_ablkcipher_reqsize(&cryptd_tfm->base);
+}
+
+static int ablk_ecb_init(struct crypto_tfm *tfm)
+{
+ struct cryptd_ablkcipher *cryptd_tfm;
+
+ cryptd_tfm = cryptd_alloc_ablkcipher("__driver-ecb-serpent-sse2", 0, 0);
+ if (IS_ERR(cryptd_tfm))
+ return PTR_ERR(cryptd_tfm);
+ ablk_init_common(tfm, cryptd_tfm);
+ return 0;
+}
+
+static struct crypto_alg ablk_ecb_alg = {
+ .cra_name = "ecb(serpent)",
+ .cra_driver_name = "ecb-serpent-sse2",
+ .cra_priority = 400,
+ .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
+ .cra_blocksize = SERPENT_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct async_serpent_ctx),
+ .cra_alignmask = 0,
+ .cra_type = &crypto_ablkcipher_type,
+ .cra_module = THIS_MODULE,
+ .cra_list = LIST_HEAD_INIT(ablk_ecb_alg.cra_list),
+ .cra_init = ablk_ecb_init,
+ .cra_exit = ablk_exit,
+ .cra_u = {
+ .ablkcipher = {
+ .min_keysize = SERPENT_MIN_KEY_SIZE,
+ .max_keysize = SERPENT_MAX_KEY_SIZE,
+ .setkey = ablk_set_key,
+ .encrypt = ablk_encrypt,
+ .decrypt = ablk_decrypt,
+ },
+ },
+};
+
+static int ablk_cbc_init(struct crypto_tfm *tfm)
+{
+ struct cryptd_ablkcipher *cryptd_tfm;
+
+ cryptd_tfm = cryptd_alloc_ablkcipher("__driver-cbc-serpent-sse2", 0, 0);
+ if (IS_ERR(cryptd_tfm))
+ return PTR_ERR(cryptd_tfm);
+ ablk_init_common(tfm, cryptd_tfm);
+ return 0;
+}
+
+static struct crypto_alg ablk_cbc_alg = {
+ .cra_name = "cbc(serpent)",
+ .cra_driver_name = "cbc-serpent-sse2",
+ .cra_priority = 400,
+ .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
+ .cra_blocksize = SERPENT_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct async_serpent_ctx),
+ .cra_alignmask = 0,
+ .cra_type = &crypto_ablkcipher_type,
+ .cra_module = THIS_MODULE,
+ .cra_list = LIST_HEAD_INIT(ablk_cbc_alg.cra_list),
+ .cra_init = ablk_cbc_init,
+ .cra_exit = ablk_exit,
+ .cra_u = {
+ .ablkcipher = {
+ .min_keysize = SERPENT_MIN_KEY_SIZE,
+ .max_keysize = SERPENT_MAX_KEY_SIZE,
+ .ivsize = SERPENT_BLOCK_SIZE,
+ .setkey = ablk_set_key,
+ .encrypt = __ablk_encrypt,
+ .decrypt = ablk_decrypt,
+ },
+ },
+};
+
+static int ablk_ctr_init(struct crypto_tfm *tfm)
+{
+ struct cryptd_ablkcipher *cryptd_tfm;
+
+ cryptd_tfm = cryptd_alloc_ablkcipher("__driver-ctr-serpent-sse2", 0, 0);
+ if (IS_ERR(cryptd_tfm))
+ return PTR_ERR(cryptd_tfm);
+ ablk_init_common(tfm, cryptd_tfm);
+ return 0;
+}
+
+static struct crypto_alg ablk_ctr_alg = {
+ .cra_name = "ctr(serpent)",
+ .cra_driver_name = "ctr-serpent-sse2",
+ .cra_priority = 400,
+ .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
+ .cra_blocksize = 1,
+ .cra_ctxsize = sizeof(struct async_serpent_ctx),
+ .cra_alignmask = 0,
+ .cra_type = &crypto_ablkcipher_type,
+ .cra_module = THIS_MODULE,
+ .cra_list = LIST_HEAD_INIT(ablk_ctr_alg.cra_list),
+ .cra_init = ablk_ctr_init,
+ .cra_exit = ablk_exit,
+ .cra_u = {
+ .ablkcipher = {
+ .min_keysize = SERPENT_MIN_KEY_SIZE,
+ .max_keysize = SERPENT_MAX_KEY_SIZE,
+ .ivsize = SERPENT_BLOCK_SIZE,
+ .setkey = ablk_set_key,
+ .encrypt = ablk_encrypt,
+ .decrypt = ablk_encrypt,
+ .geniv = "chainiv",
+ },
+ },
+};
+
+static int ablk_lrw_init(struct crypto_tfm *tfm)
+{
+ struct cryptd_ablkcipher *cryptd_tfm;
+
+ cryptd_tfm = cryptd_alloc_ablkcipher("__driver-lrw-serpent-sse2", 0, 0);
+ if (IS_ERR(cryptd_tfm))
+ return PTR_ERR(cryptd_tfm);
+ ablk_init_common(tfm, cryptd_tfm);
+ return 0;
+}
+
+static struct crypto_alg ablk_lrw_alg = {
+ .cra_name = "lrw(serpent)",
+ .cra_driver_name = "lrw-serpent-sse2",
+ .cra_priority = 400,
+ .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
+ .cra_blocksize = SERPENT_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct async_serpent_ctx),
+ .cra_alignmask = 0,
+ .cra_type = &crypto_ablkcipher_type,
+ .cra_module = THIS_MODULE,
+ .cra_list = LIST_HEAD_INIT(ablk_lrw_alg.cra_list),
+ .cra_init = ablk_lrw_init,
+ .cra_exit = ablk_exit,
+ .cra_u = {
+ .ablkcipher = {
+ .min_keysize = SERPENT_MIN_KEY_SIZE +
+ SERPENT_BLOCK_SIZE,
+ .max_keysize = SERPENT_MAX_KEY_SIZE +
+ SERPENT_BLOCK_SIZE,
+ .ivsize = SERPENT_BLOCK_SIZE,
+ .setkey = ablk_set_key,
+ .encrypt = ablk_encrypt,
+ .decrypt = ablk_decrypt,
+ },
+ },
+};
+
+static int ablk_xts_init(struct crypto_tfm *tfm)
+{
+ struct cryptd_ablkcipher *cryptd_tfm;
+
+ cryptd_tfm = cryptd_alloc_ablkcipher("__driver-xts-serpent-sse2", 0, 0);
+ if (IS_ERR(cryptd_tfm))
+ return PTR_ERR(cryptd_tfm);
+ ablk_init_common(tfm, cryptd_tfm);
+ return 0;
+}
+
+static struct crypto_alg ablk_xts_alg = {
+ .cra_name = "xts(serpent)",
+ .cra_driver_name = "xts-serpent-sse2",
+ .cra_priority = 400,
+ .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
+ .cra_blocksize = SERPENT_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct async_serpent_ctx),
+ .cra_alignmask = 0,
+ .cra_type = &crypto_ablkcipher_type,
+ .cra_module = THIS_MODULE,
+ .cra_list = LIST_HEAD_INIT(ablk_xts_alg.cra_list),
+ .cra_init = ablk_xts_init,
+ .cra_exit = ablk_exit,
+ .cra_u = {
+ .ablkcipher = {
+ .min_keysize = SERPENT_MIN_KEY_SIZE * 2,
+ .max_keysize = SERPENT_MAX_KEY_SIZE * 2,
+ .ivsize = SERPENT_BLOCK_SIZE,
+ .setkey = ablk_set_key,
+ .encrypt = ablk_encrypt,
+ .decrypt = ablk_decrypt,
+ },
+ },
+};
+
+static int __init serpent_sse2_init(void)
+{
+ int err;
+
+ if (!cpu_has_xmm2) {
+ printk(KERN_INFO "SSE2 instructions are not detected.\n");
+ return -ENODEV;
+ }
+
+ err = crypto_register_alg(&blk_ecb_alg);
+ if (err)
+ goto blk_ecb_err;
+ err = crypto_register_alg(&blk_cbc_alg);
+ if (err)
+ goto blk_cbc_err;
+ err = crypto_register_alg(&blk_ctr_alg);
+ if (err)
+ goto blk_ctr_err;
+ err = crypto_register_alg(&ablk_ecb_alg);
+ if (err)
+ goto ablk_ecb_err;
+ err = crypto_register_alg(&ablk_cbc_alg);
+ if (err)
+ goto ablk_cbc_err;
+ err = crypto_register_alg(&ablk_ctr_alg);
+ if (err)
+ goto ablk_ctr_err;
+ err = crypto_register_alg(&blk_lrw_alg);
+ if (err)
+ goto blk_lrw_err;
+ err = crypto_register_alg(&ablk_lrw_alg);
+ if (err)
+ goto ablk_lrw_err;
+ err = crypto_register_alg(&blk_xts_alg);
+ if (err)
+ goto blk_xts_err;
+ err = crypto_register_alg(&ablk_xts_alg);
+ if (err)
+ goto ablk_xts_err;
+ return err;
+
+ crypto_unregister_alg(&ablk_xts_alg);
+ablk_xts_err:
+ crypto_unregister_alg(&blk_xts_alg);
+blk_xts_err:
+ crypto_unregister_alg(&ablk_lrw_alg);
+ablk_lrw_err:
+ crypto_unregister_alg(&blk_lrw_alg);
+blk_lrw_err:
+ crypto_unregister_alg(&ablk_ctr_alg);
+ablk_ctr_err:
+ crypto_unregister_alg(&ablk_cbc_alg);
+ablk_cbc_err:
+ crypto_unregister_alg(&ablk_ecb_alg);
+ablk_ecb_err:
+ crypto_unregister_alg(&blk_ctr_alg);
+blk_ctr_err:
+ crypto_unregister_alg(&blk_cbc_alg);
+blk_cbc_err:
+ crypto_unregister_alg(&blk_ecb_alg);
+blk_ecb_err:
+ return err;
+}
+
+static void __exit serpent_sse2_exit(void)
+{
+ crypto_unregister_alg(&ablk_xts_alg);
+ crypto_unregister_alg(&blk_xts_alg);
+ crypto_unregister_alg(&ablk_lrw_alg);
+ crypto_unregister_alg(&blk_lrw_alg);
+ crypto_unregister_alg(&ablk_ctr_alg);
+ crypto_unregister_alg(&ablk_cbc_alg);
+ crypto_unregister_alg(&ablk_ecb_alg);
+ crypto_unregister_alg(&blk_ctr_alg);
+ crypto_unregister_alg(&blk_cbc_alg);
+ crypto_unregister_alg(&blk_ecb_alg);
+}
+
+module_init(serpent_sse2_init);
+module_exit(serpent_sse2_exit);
+
+MODULE_DESCRIPTION("Serpent Cipher Algorithm, SSE2 optimized");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("serpent");
diff --git a/arch/x86/crypto/twofish_glue_3way.c b/arch/x86/crypto/twofish_glue_3way.c
index 5ede9c4..7fee8c1 100644
--- a/arch/x86/crypto/twofish_glue_3way.c
+++ b/arch/x86/crypto/twofish_glue_3way.c
@@ -32,6 +32,8 @@
#include <crypto/algapi.h>
#include <crypto/twofish.h>
#include <crypto/b128ops.h>
+#include <crypto/lrw.h>
+#include <crypto/xts.h>
/* regular block cipher functions from twofish_x86_64 module */
asmlinkage void twofish_enc_blk(struct twofish_ctx *ctx, u8 *dst,
@@ -432,6 +434,209 @@
},
};
+static void encrypt_callback(void *priv, u8 *srcdst, unsigned int nbytes)
+{
+ const unsigned int bsize = TF_BLOCK_SIZE;
+ struct twofish_ctx *ctx = priv;
+ int i;
+
+ if (nbytes == 3 * bsize) {
+ twofish_enc_blk_3way(ctx, srcdst, srcdst);
+ return;
+ }
+
+ for (i = 0; i < nbytes / bsize; i++, srcdst += bsize)
+ twofish_enc_blk(ctx, srcdst, srcdst);
+}
+
+static void decrypt_callback(void *priv, u8 *srcdst, unsigned int nbytes)
+{
+ const unsigned int bsize = TF_BLOCK_SIZE;
+ struct twofish_ctx *ctx = priv;
+ int i;
+
+ if (nbytes == 3 * bsize) {
+ twofish_dec_blk_3way(ctx, srcdst, srcdst);
+ return;
+ }
+
+ for (i = 0; i < nbytes / bsize; i++, srcdst += bsize)
+ twofish_dec_blk(ctx, srcdst, srcdst);
+}
+
+struct twofish_lrw_ctx {
+ struct lrw_table_ctx lrw_table;
+ struct twofish_ctx twofish_ctx;
+};
+
+static int lrw_twofish_setkey(struct crypto_tfm *tfm, const u8 *key,
+ unsigned int keylen)
+{
+ struct twofish_lrw_ctx *ctx = crypto_tfm_ctx(tfm);
+ int err;
+
+ err = __twofish_setkey(&ctx->twofish_ctx, key, keylen - TF_BLOCK_SIZE,
+ &tfm->crt_flags);
+ if (err)
+ return err;
+
+ return lrw_init_table(&ctx->lrw_table, key + keylen - TF_BLOCK_SIZE);
+}
+
+static int lrw_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
+ struct scatterlist *src, unsigned int nbytes)
+{
+ struct twofish_lrw_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
+ be128 buf[3];
+ struct lrw_crypt_req req = {
+ .tbuf = buf,
+ .tbuflen = sizeof(buf),
+
+ .table_ctx = &ctx->lrw_table,
+ .crypt_ctx = &ctx->twofish_ctx,
+ .crypt_fn = encrypt_callback,
+ };
+
+ return lrw_crypt(desc, dst, src, nbytes, &req);
+}
+
+static int lrw_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
+ struct scatterlist *src, unsigned int nbytes)
+{
+ struct twofish_lrw_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
+ be128 buf[3];
+ struct lrw_crypt_req req = {
+ .tbuf = buf,
+ .tbuflen = sizeof(buf),
+
+ .table_ctx = &ctx->lrw_table,
+ .crypt_ctx = &ctx->twofish_ctx,
+ .crypt_fn = decrypt_callback,
+ };
+
+ return lrw_crypt(desc, dst, src, nbytes, &req);
+}
+
+static void lrw_exit_tfm(struct crypto_tfm *tfm)
+{
+ struct twofish_lrw_ctx *ctx = crypto_tfm_ctx(tfm);
+
+ lrw_free_table(&ctx->lrw_table);
+}
+
+static struct crypto_alg blk_lrw_alg = {
+ .cra_name = "lrw(twofish)",
+ .cra_driver_name = "lrw-twofish-3way",
+ .cra_priority = 300,
+ .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
+ .cra_blocksize = TF_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct twofish_lrw_ctx),
+ .cra_alignmask = 0,
+ .cra_type = &crypto_blkcipher_type,
+ .cra_module = THIS_MODULE,
+ .cra_list = LIST_HEAD_INIT(blk_lrw_alg.cra_list),
+ .cra_exit = lrw_exit_tfm,
+ .cra_u = {
+ .blkcipher = {
+ .min_keysize = TF_MIN_KEY_SIZE + TF_BLOCK_SIZE,
+ .max_keysize = TF_MAX_KEY_SIZE + TF_BLOCK_SIZE,
+ .ivsize = TF_BLOCK_SIZE,
+ .setkey = lrw_twofish_setkey,
+ .encrypt = lrw_encrypt,
+ .decrypt = lrw_decrypt,
+ },
+ },
+};
+
+struct twofish_xts_ctx {
+ struct twofish_ctx tweak_ctx;
+ struct twofish_ctx crypt_ctx;
+};
+
+static int xts_twofish_setkey(struct crypto_tfm *tfm, const u8 *key,
+ unsigned int keylen)
+{
+ struct twofish_xts_ctx *ctx = crypto_tfm_ctx(tfm);
+ u32 *flags = &tfm->crt_flags;
+ int err;
+
+ /* key consists of keys of equal size concatenated, therefore
+ * the length must be even
+ */
+ if (keylen % 2) {
+ *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
+ return -EINVAL;
+ }
+
+ /* first half of xts-key is for crypt */
+ err = __twofish_setkey(&ctx->crypt_ctx, key, keylen / 2, flags);
+ if (err)
+ return err;
+
+ /* second half of xts-key is for tweak */
+ return __twofish_setkey(&ctx->tweak_ctx, key + keylen / 2, keylen / 2,
+ flags);
+}
+
+static int xts_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
+ struct scatterlist *src, unsigned int nbytes)
+{
+ struct twofish_xts_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
+ be128 buf[3];
+ struct xts_crypt_req req = {
+ .tbuf = buf,
+ .tbuflen = sizeof(buf),
+
+ .tweak_ctx = &ctx->tweak_ctx,
+ .tweak_fn = XTS_TWEAK_CAST(twofish_enc_blk),
+ .crypt_ctx = &ctx->crypt_ctx,
+ .crypt_fn = encrypt_callback,
+ };
+
+ return xts_crypt(desc, dst, src, nbytes, &req);
+}
+
+static int xts_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
+ struct scatterlist *src, unsigned int nbytes)
+{
+ struct twofish_xts_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
+ be128 buf[3];
+ struct xts_crypt_req req = {
+ .tbuf = buf,
+ .tbuflen = sizeof(buf),
+
+ .tweak_ctx = &ctx->tweak_ctx,
+ .tweak_fn = XTS_TWEAK_CAST(twofish_enc_blk),
+ .crypt_ctx = &ctx->crypt_ctx,
+ .crypt_fn = decrypt_callback,
+ };
+
+ return xts_crypt(desc, dst, src, nbytes, &req);
+}
+
+static struct crypto_alg blk_xts_alg = {
+ .cra_name = "xts(twofish)",
+ .cra_driver_name = "xts-twofish-3way",
+ .cra_priority = 300,
+ .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
+ .cra_blocksize = TF_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct twofish_xts_ctx),
+ .cra_alignmask = 0,
+ .cra_type = &crypto_blkcipher_type,
+ .cra_module = THIS_MODULE,
+ .cra_list = LIST_HEAD_INIT(blk_xts_alg.cra_list),
+ .cra_u = {
+ .blkcipher = {
+ .min_keysize = TF_MIN_KEY_SIZE * 2,
+ .max_keysize = TF_MAX_KEY_SIZE * 2,
+ .ivsize = TF_BLOCK_SIZE,
+ .setkey = xts_twofish_setkey,
+ .encrypt = xts_encrypt,
+ .decrypt = xts_decrypt,
+ },
+ },
+};
+
int __init init(void)
{
int err;
@@ -445,9 +650,20 @@
err = crypto_register_alg(&blk_ctr_alg);
if (err)
goto ctr_err;
+ err = crypto_register_alg(&blk_lrw_alg);
+ if (err)
+ goto blk_lrw_err;
+ err = crypto_register_alg(&blk_xts_alg);
+ if (err)
+ goto blk_xts_err;
return 0;
+ crypto_unregister_alg(&blk_xts_alg);
+blk_xts_err:
+ crypto_unregister_alg(&blk_lrw_alg);
+blk_lrw_err:
+ crypto_unregister_alg(&blk_ctr_alg);
ctr_err:
crypto_unregister_alg(&blk_cbc_alg);
cbc_err:
@@ -458,6 +674,8 @@
void __exit fini(void)
{
+ crypto_unregister_alg(&blk_xts_alg);
+ crypto_unregister_alg(&blk_lrw_alg);
crypto_unregister_alg(&blk_ctr_alg);
crypto_unregister_alg(&blk_cbc_alg);
crypto_unregister_alg(&blk_ecb_alg);
diff --git a/arch/x86/include/asm/amd_nb.h b/arch/x86/include/asm/amd_nb.h
index 8e41071..49ad773 100644
--- a/arch/x86/include/asm/amd_nb.h
+++ b/arch/x86/include/asm/amd_nb.h
@@ -1,6 +1,7 @@
#ifndef _ASM_X86_AMD_NB_H
#define _ASM_X86_AMD_NB_H
+#include <linux/ioport.h>
#include <linux/pci.h>
struct amd_nb_bus_dev_range {
@@ -13,6 +14,7 @@
extern const struct amd_nb_bus_dev_range amd_nb_bus_dev_ranges[];
extern bool early_is_amd_nb(u32 value);
+extern struct resource *amd_get_mmconfig_range(struct resource *res);
extern int amd_cache_northbridges(void);
extern void amd_flush_garts(void);
extern int amd_numa_init(void);
diff --git a/arch/x86/include/asm/bootparam.h b/arch/x86/include/asm/bootparam.h
index e020d88..2f90c51 100644
--- a/arch/x86/include/asm/bootparam.h
+++ b/arch/x86/include/asm/bootparam.h
@@ -64,6 +64,8 @@
__u32 payload_offset;
__u32 payload_length;
__u64 setup_data;
+ __u64 pref_address;
+ __u32 init_size;
} __attribute__((packed));
struct sys_desc_table {
diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h
index 7093e4a..844f735 100644
--- a/arch/x86/include/asm/efi.h
+++ b/arch/x86/include/asm/efi.h
@@ -3,6 +3,8 @@
#ifdef CONFIG_X86_32
+#define EFI_LOADER_SIGNATURE "EL32"
+
extern unsigned long asmlinkage efi_call_phys(void *, ...);
#define efi_call_phys0(f) efi_call_phys(f)
@@ -37,6 +39,8 @@
#else /* !CONFIG_X86_32 */
+#define EFI_LOADER_SIGNATURE "EL64"
+
extern u64 efi_call0(void *fp);
extern u64 efi_call1(void *fp, u64 arg1);
extern u64 efi_call2(void *fp, u64 arg1, u64 arg2);
diff --git a/arch/x86/include/asm/fixmap.h b/arch/x86/include/asm/fixmap.h
index 460c74e..4da3c0c 100644
--- a/arch/x86/include/asm/fixmap.h
+++ b/arch/x86/include/asm/fixmap.h
@@ -117,7 +117,7 @@
#endif
FIX_TEXT_POKE1, /* reserve 2 pages for text_poke() */
FIX_TEXT_POKE0, /* first page is last, because allocation is backward */
-#ifdef CONFIG_X86_MRST
+#ifdef CONFIG_X86_INTEL_MID
FIX_LNW_VRTC,
#endif
__end_of_permanent_fixed_addresses,
diff --git a/arch/x86/include/asm/init.h b/arch/x86/include/asm/init.h
index 8dbe353..adcc0ae 100644
--- a/arch/x86/include/asm/init.h
+++ b/arch/x86/include/asm/init.h
@@ -5,6 +5,8 @@
extern void __init early_ioremap_page_table_range_init(void);
#endif
+extern void __init zone_sizes_init(void);
+
extern unsigned long __init
kernel_physical_mapping_init(unsigned long start,
unsigned long end,
diff --git a/arch/x86/include/asm/pci.h b/arch/x86/include/asm/pci.h
index d498943..df75d07 100644
--- a/arch/x86/include/asm/pci.h
+++ b/arch/x86/include/asm/pci.h
@@ -112,19 +112,28 @@
{
x86_msi.teardown_msi_irq(irq);
}
+static inline void x86_restore_msi_irqs(struct pci_dev *dev, int irq)
+{
+ x86_msi.restore_msi_irqs(dev, irq);
+}
#define arch_setup_msi_irqs x86_setup_msi_irqs
#define arch_teardown_msi_irqs x86_teardown_msi_irqs
#define arch_teardown_msi_irq x86_teardown_msi_irq
+#define arch_restore_msi_irqs x86_restore_msi_irqs
/* implemented in arch/x86/kernel/apic/io_apic. */
int native_setup_msi_irqs(struct pci_dev *dev, int nvec, int type);
void native_teardown_msi_irq(unsigned int irq);
+void native_restore_msi_irqs(struct pci_dev *dev, int irq);
/* default to the implementation in drivers/lib/msi.c */
#define HAVE_DEFAULT_MSI_TEARDOWN_IRQS
+#define HAVE_DEFAULT_MSI_RESTORE_IRQS
void default_teardown_msi_irqs(struct pci_dev *dev);
+void default_restore_msi_irqs(struct pci_dev *dev, int irq);
#else
#define native_setup_msi_irqs NULL
#define native_teardown_msi_irq NULL
#define default_teardown_msi_irqs NULL
+#define default_restore_msi_irqs NULL
#endif
#define PCI_DMA_BUS_IS_PHYS (dma_ops->is_phys)
diff --git a/arch/x86/include/asm/pci_x86.h b/arch/x86/include/asm/pci_x86.h
index e381978..b3a5317 100644
--- a/arch/x86/include/asm/pci_x86.h
+++ b/arch/x86/include/asm/pci_x86.h
@@ -44,8 +44,6 @@
/* pci-i386.c */
-extern unsigned int pcibios_max_latency;
-
void pcibios_resource_survey(void);
void pcibios_set_cache_line_size(void);
diff --git a/arch/x86/include/asm/serpent.h b/arch/x86/include/asm/serpent.h
new file mode 100644
index 0000000..d3ef63f
--- /dev/null
+++ b/arch/x86/include/asm/serpent.h
@@ -0,0 +1,63 @@
+#ifndef ASM_X86_SERPENT_H
+#define ASM_X86_SERPENT_H
+
+#include <linux/crypto.h>
+#include <crypto/serpent.h>
+
+#ifdef CONFIG_X86_32
+
+#define SERPENT_PARALLEL_BLOCKS 4
+
+asmlinkage void __serpent_enc_blk_4way(struct serpent_ctx *ctx, u8 *dst,
+ const u8 *src, bool xor);
+asmlinkage void serpent_dec_blk_4way(struct serpent_ctx *ctx, u8 *dst,
+ const u8 *src);
+
+static inline void serpent_enc_blk_xway(struct serpent_ctx *ctx, u8 *dst,
+ const u8 *src)
+{
+ __serpent_enc_blk_4way(ctx, dst, src, false);
+}
+
+static inline void serpent_enc_blk_xway_xor(struct serpent_ctx *ctx, u8 *dst,
+ const u8 *src)
+{
+ __serpent_enc_blk_4way(ctx, dst, src, true);
+}
+
+static inline void serpent_dec_blk_xway(struct serpent_ctx *ctx, u8 *dst,
+ const u8 *src)
+{
+ serpent_dec_blk_4way(ctx, dst, src);
+}
+
+#else
+
+#define SERPENT_PARALLEL_BLOCKS 8
+
+asmlinkage void __serpent_enc_blk_8way(struct serpent_ctx *ctx, u8 *dst,
+ const u8 *src, bool xor);
+asmlinkage void serpent_dec_blk_8way(struct serpent_ctx *ctx, u8 *dst,
+ const u8 *src);
+
+static inline void serpent_enc_blk_xway(struct serpent_ctx *ctx, u8 *dst,
+ const u8 *src)
+{
+ __serpent_enc_blk_8way(ctx, dst, src, false);
+}
+
+static inline void serpent_enc_blk_xway_xor(struct serpent_ctx *ctx, u8 *dst,
+ const u8 *src)
+{
+ __serpent_enc_blk_8way(ctx, dst, src, true);
+}
+
+static inline void serpent_dec_blk_xway(struct serpent_ctx *ctx, u8 *dst,
+ const u8 *src)
+{
+ serpent_dec_blk_8way(ctx, dst, src);
+}
+
+#endif
+
+#endif
diff --git a/arch/x86/include/asm/setup.h b/arch/x86/include/asm/setup.h
index 9756551..d0f19f9 100644
--- a/arch/x86/include/asm/setup.h
+++ b/arch/x86/include/asm/setup.h
@@ -47,7 +47,7 @@
extern void i386_reserve_resources(void);
extern void setup_default_timer_irq(void);
-#ifdef CONFIG_X86_MRST
+#ifdef CONFIG_X86_INTEL_MID
extern void x86_mrst_early_setup(void);
#else
static inline void x86_mrst_early_setup(void) { }
diff --git a/arch/x86/include/asm/smp.h b/arch/x86/include/asm/smp.h
index 73b11bc..0434c40 100644
--- a/arch/x86/include/asm/smp.h
+++ b/arch/x86/include/asm/smp.h
@@ -225,5 +225,11 @@
#endif /* CONFIG_X86_LOCAL_APIC */
+#ifdef CONFIG_DEBUG_NMI_SELFTEST
+extern void nmi_selftest(void);
+#else
+#define nmi_selftest() do { } while (0)
+#endif
+
#endif /* __ASSEMBLY__ */
#endif /* _ASM_X86_SMP_H */
diff --git a/arch/x86/include/asm/thread_info.h b/arch/x86/include/asm/thread_info.h
index 7404715..bc817cd 100644
--- a/arch/x86/include/asm/thread_info.h
+++ b/arch/x86/include/asm/thread_info.h
@@ -40,8 +40,8 @@
*/
__u8 supervisor_stack[0];
#endif
- int sig_on_uaccess_error:1;
- int uaccess_err:1; /* uaccess failed */
+ unsigned int sig_on_uaccess_error:1;
+ unsigned int uaccess_err:1; /* uaccess failed */
};
#define INIT_THREAD_INFO(tsk) \
diff --git a/arch/x86/include/asm/topology.h b/arch/x86/include/asm/topology.h
index 800f77c..b9676ae 100644
--- a/arch/x86/include/asm/topology.h
+++ b/arch/x86/include/asm/topology.h
@@ -172,7 +172,7 @@
}
struct pci_bus;
-void x86_pci_root_bus_res_quirks(struct pci_bus *b);
+void x86_pci_root_bus_resources(int bus, struct list_head *resources);
#ifdef CONFIG_SMP
#define mc_capable() ((boot_cpu_data.x86_max_cores > 1) && \
diff --git a/arch/x86/include/asm/x86_init.h b/arch/x86/include/asm/x86_init.h
index 1ac860a..517d476 100644
--- a/arch/x86/include/asm/x86_init.h
+++ b/arch/x86/include/asm/x86_init.h
@@ -179,6 +179,7 @@
int (*setup_msi_irqs)(struct pci_dev *dev, int nvec, int type);
void (*teardown_msi_irq)(unsigned int irq);
void (*teardown_msi_irqs)(struct pci_dev *dev);
+ void (*restore_msi_irqs)(struct pci_dev *dev, int irq);
};
extern struct x86_init_ops x86_init;
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
index 8baca3c..02b2f05 100644
--- a/arch/x86/kernel/Makefile
+++ b/arch/x86/kernel/Makefile
@@ -80,6 +80,7 @@
obj-$(CONFIG_AMD_NB) += amd_nb.o
obj-$(CONFIG_DEBUG_RODATA_TEST) += test_rodata.o
obj-$(CONFIG_DEBUG_NX_TEST) += test_nx.o
+obj-$(CONFIG_DEBUG_NMI_SELFTEST) += nmi_selftest.o
obj-$(CONFIG_KVM_GUEST) += kvm.o
obj-$(CONFIG_KVM_CLOCK) += kvmclock.o
diff --git a/arch/x86/kernel/amd_nb.c b/arch/x86/kernel/amd_nb.c
index 013c181..be16854 100644
--- a/arch/x86/kernel/amd_nb.c
+++ b/arch/x86/kernel/amd_nb.c
@@ -119,6 +119,37 @@
return false;
}
+struct resource *amd_get_mmconfig_range(struct resource *res)
+{
+ u32 address;
+ u64 base, msr;
+ unsigned segn_busn_bits;
+
+ if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD)
+ return NULL;
+
+ /* assume all cpus from fam10h have mmconfig */
+ if (boot_cpu_data.x86 < 0x10)
+ return NULL;
+
+ address = MSR_FAM10H_MMIO_CONF_BASE;
+ rdmsrl(address, msr);
+
+ /* mmconfig is not enabled */
+ if (!(msr & FAM10H_MMIO_CONF_ENABLE))
+ return NULL;
+
+ base = msr & (FAM10H_MMIO_CONF_BASE_MASK<<FAM10H_MMIO_CONF_BASE_SHIFT);
+
+ segn_busn_bits = (msr >> FAM10H_MMIO_CONF_BUSRANGE_SHIFT) &
+ FAM10H_MMIO_CONF_BUSRANGE_MASK;
+
+ res->flags = IORESOURCE_MEM;
+ res->start = base;
+ res->end = base + (1ULL<<(segn_busn_bits + 20)) - 1;
+ return res;
+}
+
int amd_get_subcaches(int cpu)
{
struct pci_dev *link = node_to_amd_nb(amd_get_nb_id(cpu))->link;
diff --git a/arch/x86/kernel/asm-offsets.c b/arch/x86/kernel/asm-offsets.c
index 4f13faf..68de2dc 100644
--- a/arch/x86/kernel/asm-offsets.c
+++ b/arch/x86/kernel/asm-offsets.c
@@ -67,4 +67,6 @@
OFFSET(BP_hardware_subarch, boot_params, hdr.hardware_subarch);
OFFSET(BP_version, boot_params, hdr.version);
OFFSET(BP_kernel_alignment, boot_params, hdr.kernel_alignment);
+ OFFSET(BP_pref_address, boot_params, hdr.pref_address);
+ OFFSET(BP_code32_start, boot_params, hdr.code32_start);
}
diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c
index 8071e2f..174d938 100644
--- a/arch/x86/kernel/e820.c
+++ b/arch/x86/kernel/e820.c
@@ -19,6 +19,7 @@
#include <linux/acpi.h>
#include <linux/firmware-map.h>
#include <linux/memblock.h>
+#include <linux/sort.h>
#include <asm/e820.h>
#include <asm/proto.h>
@@ -227,22 +228,38 @@
* ____________________33__
* ______________________4_
*/
+struct change_member {
+ struct e820entry *pbios; /* pointer to original bios entry */
+ unsigned long long addr; /* address for this change point */
+};
+
+static int __init cpcompare(const void *a, const void *b)
+{
+ struct change_member * const *app = a, * const *bpp = b;
+ const struct change_member *ap = *app, *bp = *bpp;
+
+ /*
+ * Inputs are pointers to two elements of change_point[]. If their
+ * addresses are unequal, their difference dominates. If the addresses
+ * are equal, then consider one that represents the end of its region
+ * to be greater than one that does not.
+ */
+ if (ap->addr != bp->addr)
+ return ap->addr > bp->addr ? 1 : -1;
+
+ return (ap->addr != ap->pbios->addr) - (bp->addr != bp->pbios->addr);
+}
int __init sanitize_e820_map(struct e820entry *biosmap, int max_nr_map,
u32 *pnr_map)
{
- struct change_member {
- struct e820entry *pbios; /* pointer to original bios entry */
- unsigned long long addr; /* address for this change point */
- };
static struct change_member change_point_list[2*E820_X_MAX] __initdata;
static struct change_member *change_point[2*E820_X_MAX] __initdata;
static struct e820entry *overlap_list[E820_X_MAX] __initdata;
static struct e820entry new_bios[E820_X_MAX] __initdata;
- struct change_member *change_tmp;
unsigned long current_type, last_type;
unsigned long long last_addr;
- int chgidx, still_changing;
+ int chgidx;
int overlap_entries;
int new_bios_entry;
int old_nr, new_nr, chg_nr;
@@ -279,35 +296,7 @@
chg_nr = chgidx;
/* sort change-point list by memory addresses (low -> high) */
- still_changing = 1;
- while (still_changing) {
- still_changing = 0;
- for (i = 1; i < chg_nr; i++) {
- unsigned long long curaddr, lastaddr;
- unsigned long long curpbaddr, lastpbaddr;
-
- curaddr = change_point[i]->addr;
- lastaddr = change_point[i - 1]->addr;
- curpbaddr = change_point[i]->pbios->addr;
- lastpbaddr = change_point[i - 1]->pbios->addr;
-
- /*
- * swap entries, when:
- *
- * curaddr > lastaddr or
- * curaddr == lastaddr and curaddr == curpbaddr and
- * lastaddr != lastpbaddr
- */
- if (curaddr < lastaddr ||
- (curaddr == lastaddr && curaddr == curpbaddr &&
- lastaddr != lastpbaddr)) {
- change_tmp = change_point[i];
- change_point[i] = change_point[i-1];
- change_point[i-1] = change_tmp;
- still_changing = 1;
- }
- }
- }
+ sort(change_point, chg_nr, sizeof *change_point, cpcompare, NULL);
/* create a new bios memory map, removing overlaps */
overlap_entries = 0; /* number of entries in the overlap table */
diff --git a/arch/x86/kernel/early_printk.c b/arch/x86/kernel/early_printk.c
index 9d42a52..9b9f18b 100644
--- a/arch/x86/kernel/early_printk.c
+++ b/arch/x86/kernel/early_printk.c
@@ -240,7 +240,7 @@
if (!strncmp(buf, "xen", 3))
early_console_register(&xenboot_console, keep);
#endif
-#ifdef CONFIG_EARLY_PRINTK_MRST
+#ifdef CONFIG_EARLY_PRINTK_INTEL_MID
if (!strncmp(buf, "mrst", 4)) {
mrst_early_console_init();
early_console_register(&early_mrst_console, keep);
diff --git a/arch/x86/kernel/irq_32.c b/arch/x86/kernel/irq_32.c
index 7209070..40fc861 100644
--- a/arch/x86/kernel/irq_32.c
+++ b/arch/x86/kernel/irq_32.c
@@ -28,6 +28,9 @@
EXPORT_PER_CPU_SYMBOL(irq_regs);
#ifdef CONFIG_DEBUG_STACKOVERFLOW
+
+int sysctl_panic_on_stackoverflow __read_mostly;
+
/* Debugging check for stack overflow: is there less than 1KB free? */
static int check_stack_overflow(void)
{
@@ -43,6 +46,8 @@
{
printk(KERN_WARNING "low stack detected by irq handler\n");
dump_stack();
+ if (sysctl_panic_on_stackoverflow)
+ panic("low stack detected by irq handler - check messages\n");
}
#else
diff --git a/arch/x86/kernel/irq_64.c b/arch/x86/kernel/irq_64.c
index 69bca46..d04d3ecd 100644
--- a/arch/x86/kernel/irq_64.c
+++ b/arch/x86/kernel/irq_64.c
@@ -26,6 +26,8 @@
DEFINE_PER_CPU(struct pt_regs *, irq_regs);
EXPORT_PER_CPU_SYMBOL(irq_regs);
+int sysctl_panic_on_stackoverflow;
+
/*
* Probabilistic stack overflow check:
*
@@ -36,18 +38,39 @@
static inline void stack_overflow_check(struct pt_regs *regs)
{
#ifdef CONFIG_DEBUG_STACKOVERFLOW
+#define STACK_TOP_MARGIN 128
+ struct orig_ist *oist;
+ u64 irq_stack_top, irq_stack_bottom;
+ u64 estack_top, estack_bottom;
u64 curbase = (u64)task_stack_page(current);
if (user_mode_vm(regs))
return;
- WARN_ONCE(regs->sp >= curbase &&
- regs->sp <= curbase + THREAD_SIZE &&
- regs->sp < curbase + sizeof(struct thread_info) +
- sizeof(struct pt_regs) + 128,
+ if (regs->sp >= curbase + sizeof(struct thread_info) +
+ sizeof(struct pt_regs) + STACK_TOP_MARGIN &&
+ regs->sp <= curbase + THREAD_SIZE)
+ return;
- "do_IRQ: %s near stack overflow (cur:%Lx,sp:%lx)\n",
- current->comm, curbase, regs->sp);
+ irq_stack_top = (u64)__get_cpu_var(irq_stack_union.irq_stack) +
+ STACK_TOP_MARGIN;
+ irq_stack_bottom = (u64)__get_cpu_var(irq_stack_ptr);
+ if (regs->sp >= irq_stack_top && regs->sp <= irq_stack_bottom)
+ return;
+
+ oist = &__get_cpu_var(orig_ist);
+ estack_top = (u64)oist->ist[0] - EXCEPTION_STKSZ + STACK_TOP_MARGIN;
+ estack_bottom = (u64)oist->ist[N_EXCEPTION_STACKS - 1];
+ if (regs->sp >= estack_top && regs->sp <= estack_bottom)
+ return;
+
+ WARN_ONCE(1, "do_IRQ(): %s has overflown the kernel stack (cur:%Lx,sp:%lx,irq stk top-bottom:%Lx-%Lx,exception stk top-bottom:%Lx-%Lx)\n",
+ current->comm, curbase, regs->sp,
+ irq_stack_top, irq_stack_bottom,
+ estack_top, estack_bottom);
+
+ if (sysctl_panic_on_stackoverflow)
+ panic("low stack detected by irq handler - check messages\n");
#endif
}
diff --git a/arch/x86/kernel/nmi_selftest.c b/arch/x86/kernel/nmi_selftest.c
new file mode 100644
index 0000000..0d01a8e
--- /dev/null
+++ b/arch/x86/kernel/nmi_selftest.c
@@ -0,0 +1,180 @@
+/*
+ * arch/x86/kernel/nmi-selftest.c
+ *
+ * Testsuite for NMI: IPIs
+ *
+ * Started by Don Zickus:
+ * (using lib/locking-selftest.c as a guide)
+ *
+ * Copyright (C) 2011 Red Hat, Inc., Don Zickus <dzickus@redhat.com>
+ */
+
+#include <linux/smp.h>
+#include <linux/cpumask.h>
+#include <linux/delay.h>
+
+#include <asm/apic.h>
+#include <asm/nmi.h>
+
+#define SUCCESS 0
+#define FAILURE 1
+#define TIMEOUT 2
+
+static int nmi_fail;
+
+/* check to see if NMI IPIs work on this machine */
+static DECLARE_BITMAP(nmi_ipi_mask, NR_CPUS) __read_mostly;
+
+static int testcase_total;
+static int testcase_successes;
+static int expected_testcase_failures;
+static int unexpected_testcase_failures;
+static int unexpected_testcase_unknowns;
+
+static int nmi_unk_cb(unsigned int val, struct pt_regs *regs)
+{
+ unexpected_testcase_unknowns++;
+ return NMI_HANDLED;
+}
+
+static void init_nmi_testsuite(void)
+{
+ /* trap all the unknown NMIs we may generate */
+ register_nmi_handler(NMI_UNKNOWN, nmi_unk_cb, 0, "nmi_selftest_unk");
+}
+
+static void cleanup_nmi_testsuite(void)
+{
+ unregister_nmi_handler(NMI_UNKNOWN, "nmi_selftest_unk");
+}
+
+static int test_nmi_ipi_callback(unsigned int val, struct pt_regs *regs)
+{
+ int cpu = raw_smp_processor_id();
+
+ if (cpumask_test_and_clear_cpu(cpu, to_cpumask(nmi_ipi_mask)))
+ return NMI_HANDLED;
+
+ return NMI_DONE;
+}
+
+static void test_nmi_ipi(struct cpumask *mask)
+{
+ unsigned long timeout;
+
+ if (register_nmi_handler(NMI_LOCAL, test_nmi_ipi_callback,
+ NMI_FLAG_FIRST, "nmi_selftest")) {
+ nmi_fail = FAILURE;
+ return;
+ }
+
+ /* sync above data before sending NMI */
+ wmb();
+
+ apic->send_IPI_mask(mask, NMI_VECTOR);
+
+ /* Don't wait longer than a second */
+ timeout = USEC_PER_SEC;
+ while (!cpumask_empty(mask) && timeout--)
+ udelay(1);
+
+ /* What happens if we timeout, do we still unregister?? */
+ unregister_nmi_handler(NMI_LOCAL, "nmi_selftest");
+
+ if (!timeout)
+ nmi_fail = TIMEOUT;
+ return;
+}
+
+static void remote_ipi(void)
+{
+ cpumask_copy(to_cpumask(nmi_ipi_mask), cpu_online_mask);
+ cpumask_clear_cpu(smp_processor_id(), to_cpumask(nmi_ipi_mask));
+ if (!cpumask_empty(to_cpumask(nmi_ipi_mask)))
+ test_nmi_ipi(to_cpumask(nmi_ipi_mask));
+}
+
+static void local_ipi(void)
+{
+ cpumask_clear(to_cpumask(nmi_ipi_mask));
+ cpumask_set_cpu(smp_processor_id(), to_cpumask(nmi_ipi_mask));
+ test_nmi_ipi(to_cpumask(nmi_ipi_mask));
+}
+
+static void reset_nmi(void)
+{
+ nmi_fail = 0;
+}
+
+static void dotest(void (*testcase_fn)(void), int expected)
+{
+ testcase_fn();
+ /*
+ * Filter out expected failures:
+ */
+ if (nmi_fail != expected) {
+ unexpected_testcase_failures++;
+
+ if (nmi_fail == FAILURE)
+ printk("FAILED |");
+ else if (nmi_fail == TIMEOUT)
+ printk("TIMEOUT|");
+ else
+ printk("ERROR |");
+ dump_stack();
+ } else {
+ testcase_successes++;
+ printk(" ok |");
+ }
+ testcase_total++;
+
+ reset_nmi();
+}
+
+static inline void print_testname(const char *testname)
+{
+ printk("%12s:", testname);
+}
+
+void nmi_selftest(void)
+{
+ init_nmi_testsuite();
+
+ /*
+ * Run the testsuite:
+ */
+ printk("----------------\n");
+ printk("| NMI testsuite:\n");
+ printk("--------------------\n");
+
+ print_testname("remote IPI");
+ dotest(remote_ipi, SUCCESS);
+ printk("\n");
+ print_testname("local IPI");
+ dotest(local_ipi, SUCCESS);
+ printk("\n");
+
+ cleanup_nmi_testsuite();
+
+ if (unexpected_testcase_failures) {
+ printk("--------------------\n");
+ printk("BUG: %3d unexpected failures (out of %3d) - debugging disabled! |\n",
+ unexpected_testcase_failures, testcase_total);
+ printk("-----------------------------------------------------------------\n");
+ } else if (expected_testcase_failures && testcase_successes) {
+ printk("--------------------\n");
+ printk("%3d out of %3d testcases failed, as expected. |\n",
+ expected_testcase_failures, testcase_total);
+ printk("----------------------------------------------------\n");
+ } else if (expected_testcase_failures && !testcase_successes) {
+ printk("--------------------\n");
+ printk("All %3d testcases failed, as expected. |\n",
+ expected_testcase_failures);
+ printk("----------------------------------------\n");
+ } else {
+ printk("--------------------\n");
+ printk("Good, all %3d testcases passed! |\n",
+ testcase_successes);
+ printk("---------------------------------\n");
+ }
+}
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index d05444a..d7d5099 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -749,12 +749,7 @@
#endif
#ifdef CONFIG_EFI
if (!strncmp((char *)&boot_params.efi_info.efi_loader_signature,
-#ifdef CONFIG_X86_32
- "EL32",
-#else
- "EL64",
-#endif
- 4)) {
+ EFI_LOADER_SIGNATURE, 4)) {
efi_enabled = 1;
efi_memblock_x86_reserve_range();
}
diff --git a/arch/x86/kernel/smp.c b/arch/x86/kernel/smp.c
index 16204dc..66c74f4 100644
--- a/arch/x86/kernel/smp.c
+++ b/arch/x86/kernel/smp.c
@@ -29,6 +29,7 @@
#include <asm/mmu_context.h>
#include <asm/proto.h>
#include <asm/apic.h>
+#include <asm/nmi.h>
/*
* Some notes on x86 processor bugs affecting SMP operation:
*
@@ -148,6 +149,60 @@
free_cpumask_var(allbutself);
}
+static atomic_t stopping_cpu = ATOMIC_INIT(-1);
+
+static int smp_stop_nmi_callback(unsigned int val, struct pt_regs *regs)
+{
+ /* We are registered on stopping cpu too, avoid spurious NMI */
+ if (raw_smp_processor_id() == atomic_read(&stopping_cpu))
+ return NMI_HANDLED;
+
+ stop_this_cpu(NULL);
+
+ return NMI_HANDLED;
+}
+
+static void native_nmi_stop_other_cpus(int wait)
+{
+ unsigned long flags;
+ unsigned long timeout;
+
+ if (reboot_force)
+ return;
+
+ /*
+ * Use an own vector here because smp_call_function
+ * does lots of things not suitable in a panic situation.
+ */
+ if (num_online_cpus() > 1) {
+ /* did someone beat us here? */
+ if (atomic_cmpxchg(&stopping_cpu, -1, safe_smp_processor_id()) != -1)
+ return;
+
+ if (register_nmi_handler(NMI_LOCAL, smp_stop_nmi_callback,
+ NMI_FLAG_FIRST, "smp_stop"))
+ /* Note: we ignore failures here */
+ return;
+
+ /* sync above data before sending NMI */
+ wmb();
+
+ apic->send_IPI_allbutself(NMI_VECTOR);
+
+ /*
+ * Don't wait longer than a second if the caller
+ * didn't ask us to wait.
+ */
+ timeout = USEC_PER_SEC;
+ while (num_online_cpus() > 1 && (wait || timeout--))
+ udelay(1);
+ }
+
+ local_irq_save(flags);
+ disable_local_APIC();
+ local_irq_restore(flags);
+}
+
/*
* this function calls the 'stop' function on all other CPUs in the system.
*/
@@ -160,7 +215,7 @@
irq_exit();
}
-static void native_stop_other_cpus(int wait)
+static void native_irq_stop_other_cpus(int wait)
{
unsigned long flags;
unsigned long timeout;
@@ -194,6 +249,11 @@
local_irq_restore(flags);
}
+static void native_smp_disable_nmi_ipi(void)
+{
+ smp_ops.stop_other_cpus = native_irq_stop_other_cpus;
+}
+
/*
* Reschedule call back.
*/
@@ -225,12 +285,20 @@
irq_exit();
}
+static int __init nonmi_ipi_setup(char *str)
+{
+ native_smp_disable_nmi_ipi();
+ return 1;
+}
+
+__setup("nonmi_ipi", nonmi_ipi_setup);
+
struct smp_ops smp_ops = {
.smp_prepare_boot_cpu = native_smp_prepare_boot_cpu,
.smp_prepare_cpus = native_smp_prepare_cpus,
.smp_cpus_done = native_smp_cpus_done,
- .stop_other_cpus = native_stop_other_cpus,
+ .stop_other_cpus = native_nmi_stop_other_cpus,
.smp_send_reschedule = native_smp_send_reschedule,
.cpu_up = native_cpu_up,
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index e38e217..66d250c 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -207,23 +207,29 @@
* Need to setup vector mappings before we enable interrupts.
*/
setup_vector_irq(smp_processor_id());
+
+ /*
+ * Save our processor parameters. Note: this information
+ * is needed for clock calibration.
+ */
+ smp_store_cpu_info(cpuid);
+
/*
* Get our bogomips.
+ * Update loops_per_jiffy in cpu_data. Previous call to
+ * smp_store_cpu_info() stored a value that is close but not as
+ * accurate as the value just calculated.
*
* Need to enable IRQs because it can take longer and then
* the NMI watchdog might kill us.
*/
local_irq_enable();
calibrate_delay();
+ cpu_data(cpuid).loops_per_jiffy = loops_per_jiffy;
local_irq_disable();
pr_debug("Stack at about %p\n", &cpuid);
/*
- * Save our processor parameters
- */
- smp_store_cpu_info(cpuid);
-
- /*
* This must be done before setting cpu_online_mask
* or calling notify_cpu_starting.
*/
@@ -1143,6 +1149,7 @@
{
pr_debug("Boot done.\n");
+ nmi_selftest();
impress_friends();
#ifdef CONFIG_X86_IO_APIC
setup_ioapic_dest();
diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c
index 2c9cf0f..c0dd5b6 100644
--- a/arch/x86/kernel/tsc.c
+++ b/arch/x86/kernel/tsc.c
@@ -995,3 +995,23 @@
check_system_tsc_reliable();
}
+#ifdef CONFIG_SMP
+/*
+ * If we have a constant TSC and are using the TSC for the delay loop,
+ * we can skip clock calibration if another cpu in the same socket has already
+ * been calibrated. This assumes that CONSTANT_TSC applies to all
+ * cpus in the socket - this should be a safe assumption.
+ */
+unsigned long __cpuinit calibrate_delay_is_known(void)
+{
+ int i, cpu = smp_processor_id();
+
+ if (!tsc_disabled && !cpu_has(&cpu_data(cpu), X86_FEATURE_CONSTANT_TSC))
+ return 0;
+
+ for_each_online_cpu(i)
+ if (cpu_data(i).phys_proc_id == cpu_data(cpu).phys_proc_id)
+ return cpu_data(i).loops_per_jiffy;
+ return 0;
+}
+#endif
diff --git a/arch/x86/kernel/x86_init.c b/arch/x86/kernel/x86_init.c
index 91f83e2..947a06c 100644
--- a/arch/x86/kernel/x86_init.c
+++ b/arch/x86/kernel/x86_init.c
@@ -115,4 +115,5 @@
.setup_msi_irqs = native_setup_msi_irqs,
.teardown_msi_irq = native_teardown_msi_irq,
.teardown_msi_irqs = default_teardown_msi_irqs,
+ .restore_msi_irqs = default_restore_msi_irqs,
};
diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c
index a298914..6cabf65 100644
--- a/arch/x86/mm/init.c
+++ b/arch/x86/mm/init.c
@@ -3,6 +3,7 @@
#include <linux/ioport.h>
#include <linux/swap.h>
#include <linux/memblock.h>
+#include <linux/bootmem.h> /* for max_low_pfn */
#include <asm/cacheflush.h>
#include <asm/e820.h>
@@ -15,6 +16,7 @@
#include <asm/tlbflush.h>
#include <asm/tlb.h>
#include <asm/proto.h>
+#include <asm/dma.h> /* for MAX_DMA_PFN */
unsigned long __initdata pgt_buf_start;
unsigned long __meminitdata pgt_buf_end;
@@ -392,3 +394,24 @@
free_init_pages("initrd memory", start, PAGE_ALIGN(end));
}
#endif
+
+void __init zone_sizes_init(void)
+{
+ unsigned long max_zone_pfns[MAX_NR_ZONES];
+
+ memset(max_zone_pfns, 0, sizeof(max_zone_pfns));
+
+#ifdef CONFIG_ZONE_DMA
+ max_zone_pfns[ZONE_DMA] = MAX_DMA_PFN;
+#endif
+#ifdef CONFIG_ZONE_DMA32
+ max_zone_pfns[ZONE_DMA32] = MAX_DMA32_PFN;
+#endif
+ max_zone_pfns[ZONE_NORMAL] = max_low_pfn;
+#ifdef CONFIG_HIGHMEM
+ max_zone_pfns[ZONE_HIGHMEM] = max_pfn;
+#endif
+
+ free_area_init_nodes(max_zone_pfns);
+}
+
diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c
index 0c1da39..8663f6c 100644
--- a/arch/x86/mm/init_32.c
+++ b/arch/x86/mm/init_32.c
@@ -668,22 +668,6 @@
}
#endif /* !CONFIG_NEED_MULTIPLE_NODES */
-static void __init zone_sizes_init(void)
-{
- unsigned long max_zone_pfns[MAX_NR_ZONES];
- memset(max_zone_pfns, 0, sizeof(max_zone_pfns));
-#ifdef CONFIG_ZONE_DMA
- max_zone_pfns[ZONE_DMA] =
- virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT;
-#endif
- max_zone_pfns[ZONE_NORMAL] = max_low_pfn;
-#ifdef CONFIG_HIGHMEM
- max_zone_pfns[ZONE_HIGHMEM] = highend_pfn;
-#endif
-
- free_area_init_nodes(max_zone_pfns);
-}
-
void __init setup_bootmem_allocator(void)
{
printk(KERN_INFO " mapped low ram: 0 - %08lx\n",
@@ -754,6 +738,17 @@
#ifdef CONFIG_FLATMEM
BUG_ON(!mem_map);
#endif
+ /*
+ * With CONFIG_DEBUG_PAGEALLOC initialization of highmem pages has to
+ * be done before free_all_bootmem(). Memblock use free low memory for
+ * temporary data (see find_range_array()) and for this purpose can use
+ * pages that was already passed to the buddy allocator, hence marked as
+ * not accessible in the page tables when compiled with
+ * CONFIG_DEBUG_PAGEALLOC. Otherwise order of initialization is not
+ * important here.
+ */
+ set_highmem_pages_init();
+
/* this will put all low memory onto the freelists */
totalram_pages += free_all_bootmem();
@@ -765,8 +760,6 @@
if (page_is_ram(tmp) && PageReserved(pfn_to_page(tmp)))
reservedpages++;
- set_highmem_pages_init();
-
codesize = (unsigned long) &_etext - (unsigned long) &_text;
datasize = (unsigned long) &_edata - (unsigned long) &_etext;
initsize = (unsigned long) &__init_end - (unsigned long) &__init_begin;
diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
index a8a56ce..436a030 100644
--- a/arch/x86/mm/init_64.c
+++ b/arch/x86/mm/init_64.c
@@ -614,15 +614,6 @@
void __init paging_init(void)
{
- unsigned long max_zone_pfns[MAX_NR_ZONES];
-
- memset(max_zone_pfns, 0, sizeof(max_zone_pfns));
-#ifdef CONFIG_ZONE_DMA
- max_zone_pfns[ZONE_DMA] = MAX_DMA_PFN;
-#endif
- max_zone_pfns[ZONE_DMA32] = MAX_DMA32_PFN;
- max_zone_pfns[ZONE_NORMAL] = max_pfn;
-
sparse_memory_present_with_active_regions(MAX_NUMNODES);
sparse_init();
@@ -634,7 +625,7 @@
*/
node_clear_state(0, N_NORMAL_MEMORY);
- free_area_init_nodes(max_zone_pfns);
+ zone_sizes_init();
}
/*
diff --git a/arch/x86/mm/mmap.c b/arch/x86/mm/mmap.c
index 4b5ba85..845df68 100644
--- a/arch/x86/mm/mmap.c
+++ b/arch/x86/mm/mmap.c
@@ -75,9 +75,9 @@
*/
if (current->flags & PF_RANDOMIZE) {
if (mmap_is_ia32())
- rnd = (long)get_random_int() % (1<<8);
+ rnd = get_random_int() % (1<<8);
else
- rnd = (long)(get_random_int() % (1<<28));
+ rnd = get_random_int() % (1<<28);
}
return rnd << PAGE_SHIFT;
}
diff --git a/arch/x86/mm/numa.c b/arch/x86/mm/numa.c
index 496f494..020cd2e 100644
--- a/arch/x86/mm/numa.c
+++ b/arch/x86/mm/numa.c
@@ -422,8 +422,9 @@
* calls are ignored until the distance table is reset with
* numa_reset_distance().
*
- * If @from or @to is higher than the highest known node at the time of
- * table creation or @distance doesn't make sense, the call is ignored.
+ * If @from or @to is higher than the highest known node or lower than zero
+ * at the time of table creation or @distance doesn't make sense, the call
+ * is ignored.
* This is to allow simplification of specific NUMA config implementations.
*/
void __init numa_set_distance(int from, int to, int distance)
@@ -431,8 +432,9 @@
if (!numa_distance && numa_alloc_distance() < 0)
return;
- if (from >= numa_distance_cnt || to >= numa_distance_cnt) {
- printk_once(KERN_DEBUG "NUMA: Debug: distance out of bound, from=%d to=%d distance=%d\n",
+ if (from >= numa_distance_cnt || to >= numa_distance_cnt ||
+ from < 0 || to < 0) {
+ pr_warn_once("NUMA: Warning: node ids are out of bound, from=%d to=%d distance=%d\n",
from, to, distance);
return;
}
diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c
index eda2acb..e1ebde3 100644
--- a/arch/x86/mm/pageattr.c
+++ b/arch/x86/mm/pageattr.c
@@ -1334,12 +1334,6 @@
}
/*
- * If page allocator is not up yet then do not call c_p_a():
- */
- if (!debug_pagealloc_enabled)
- return;
-
- /*
* The return value is ignored as the calls cannot fail.
* Large pages for identity mappings are not used at boot time
* and hence no memory allocations during large page split.
diff --git a/arch/x86/pci/Makefile b/arch/x86/pci/Makefile
index 6b8759f..e76e18c 100644
--- a/arch/x86/pci/Makefile
+++ b/arch/x86/pci/Makefile
@@ -15,11 +15,12 @@
obj-$(CONFIG_X86_NUMAQ) += numaq_32.o
-obj-$(CONFIG_X86_MRST) += mrst.o
+obj-$(CONFIG_X86_INTEL_MID) += mrst.o
obj-y += common.o early.o
-obj-y += amd_bus.o bus_numa.o
+obj-y += bus_numa.o
+obj-$(CONFIG_AMD_NB) += amd_bus.o
obj-$(CONFIG_PCI_CNB20LE_QUIRK) += broadcom_bus.o
ifeq ($(CONFIG_PCI_DEBUG),y)
diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c
index 404f21a..a312e76 100644
--- a/arch/x86/pci/acpi.c
+++ b/arch/x86/pci/acpi.c
@@ -12,7 +12,7 @@
char *name;
unsigned int res_num;
struct resource *res;
- struct pci_bus *bus;
+ struct list_head *resources;
int busnum;
};
@@ -24,6 +24,12 @@
return 0;
}
+static int __init set_nouse_crs(const struct dmi_system_id *id)
+{
+ pci_use_crs = false;
+ return 0;
+}
+
static const struct dmi_system_id pci_use_crs_table[] __initconst = {
/* http://bugzilla.kernel.org/show_bug.cgi?id=14183 */
{
@@ -54,6 +60,29 @@
DMI_MATCH(DMI_BIOS_VENDOR, "American Megatrends Inc."),
},
},
+
+ /* Now for the blacklist.. */
+
+ /* https://bugzilla.redhat.com/show_bug.cgi?id=769657 */
+ {
+ .callback = set_nouse_crs,
+ .ident = "Dell Studio 1557",
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "Dell Inc."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Studio 1557"),
+ DMI_MATCH(DMI_BIOS_VERSION, "A09"),
+ },
+ },
+ /* https://bugzilla.redhat.com/show_bug.cgi?id=769657 */
+ {
+ .callback = set_nouse_crs,
+ .ident = "Thinkpad SL510",
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
+ DMI_MATCH(DMI_BOARD_NAME, "2847DFG"),
+ DMI_MATCH(DMI_BIOS_VERSION, "6JET85WW (1.43 )"),
+ },
+ },
{}
};
@@ -149,7 +178,7 @@
struct acpi_resource_address64 addr;
acpi_status status;
unsigned long flags;
- u64 start, end;
+ u64 start, orig_end, end;
status = resource_to_addr(acpi_res, &addr);
if (!ACPI_SUCCESS(status))
@@ -165,7 +194,21 @@
return AE_OK;
start = addr.minimum + addr.translation_offset;
- end = addr.maximum + addr.translation_offset;
+ orig_end = end = addr.maximum + addr.translation_offset;
+
+ /* Exclude non-addressable range or non-addressable portion of range */
+ end = min(end, (u64)iomem_resource.end);
+ if (end <= start) {
+ dev_info(&info->bridge->dev,
+ "host bridge window [%#llx-%#llx] "
+ "(ignored, not CPU addressable)\n", start, orig_end);
+ return AE_OK;
+ } else if (orig_end != end) {
+ dev_info(&info->bridge->dev,
+ "host bridge window [%#llx-%#llx] "
+ "([%#llx-%#llx] ignored, not CPU addressable)\n",
+ start, orig_end, end + 1, orig_end);
+ }
res = &info->res[info->res_num];
res->name = info->name;
@@ -261,23 +304,20 @@
"ignoring host bridge window %pR (conflicts with %s %pR)\n",
res, conflict->name, conflict);
else
- pci_bus_add_resource(info->bus, res, 0);
+ pci_add_resource(info->resources, res);
}
}
static void
get_current_resources(struct acpi_device *device, int busnum,
- int domain, struct pci_bus *bus)
+ int domain, struct list_head *resources)
{
struct pci_root_info info;
size_t size;
- if (pci_use_crs)
- pci_bus_remove_resources(bus);
-
info.bridge = device;
- info.bus = bus;
info.res_num = 0;
+ info.resources = resources;
acpi_walk_resources(device->handle, METHOD_NAME__CRS, count_resource,
&info);
if (!info.res_num)
@@ -286,7 +326,7 @@
size = sizeof(*info.res) * info.res_num;
info.res = kmalloc(size, GFP_KERNEL);
if (!info.res)
- goto res_alloc_fail;
+ return;
info.name = kasprintf(GFP_KERNEL, "PCI Bus %04x:%02x", domain, busnum);
if (!info.name)
@@ -301,8 +341,6 @@
name_alloc_fail:
kfree(info.res);
-res_alloc_fail:
- return;
}
struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_pci_root *root)
@@ -310,6 +348,7 @@
struct acpi_device *device = root->device;
int domain = root->segment;
int busnum = root->secondary.start;
+ LIST_HEAD(resources);
struct pci_bus *bus;
struct pci_sysdata *sd;
int node;
@@ -364,11 +403,15 @@
memcpy(bus->sysdata, sd, sizeof(*sd));
kfree(sd);
} else {
- bus = pci_create_bus(NULL, busnum, &pci_root_ops, sd);
- if (bus) {
- get_current_resources(device, busnum, domain, bus);
+ get_current_resources(device, busnum, domain, &resources);
+ if (list_empty(&resources))
+ x86_pci_root_bus_resources(busnum, &resources);
+ bus = pci_create_root_bus(NULL, busnum, &pci_root_ops, sd,
+ &resources);
+ if (bus)
bus->subordinate = pci_scan_child_bus(bus);
- }
+ else
+ pci_free_resource_list(&resources);
}
/* After the PCI-E bus has been walked and all devices discovered,
diff --git a/arch/x86/pci/amd_bus.c b/arch/x86/pci/amd_bus.c
index 026e493..0567df3 100644
--- a/arch/x86/pci/amd_bus.c
+++ b/arch/x86/pci/amd_bus.c
@@ -30,34 +30,6 @@
{ 0, 0x18, PCI_VENDOR_ID_AMD, 0x1300 },
};
-static u64 __initdata fam10h_mmconf_start;
-static u64 __initdata fam10h_mmconf_end;
-static void __init get_pci_mmcfg_amd_fam10h_range(void)
-{
- u32 address;
- u64 base, msr;
- unsigned segn_busn_bits;
-
- /* assume all cpus from fam10h have mmconf */
- if (boot_cpu_data.x86 < 0x10)
- return;
-
- address = MSR_FAM10H_MMIO_CONF_BASE;
- rdmsrl(address, msr);
-
- /* mmconfig is not enable */
- if (!(msr & FAM10H_MMIO_CONF_ENABLE))
- return;
-
- base = msr & (FAM10H_MMIO_CONF_BASE_MASK<<FAM10H_MMIO_CONF_BASE_SHIFT);
-
- segn_busn_bits = (msr >> FAM10H_MMIO_CONF_BUSRANGE_SHIFT) &
- FAM10H_MMIO_CONF_BUSRANGE_MASK;
-
- fam10h_mmconf_start = base;
- fam10h_mmconf_end = base + (1ULL<<(segn_busn_bits + 20)) - 1;
-}
-
#define RANGE_NUM 16
/**
@@ -85,6 +57,9 @@
u64 val;
u32 address;
bool found;
+ struct resource fam10h_mmconf_res, *fam10h_mmconf;
+ u64 fam10h_mmconf_start;
+ u64 fam10h_mmconf_end;
if (!early_pci_allowed())
return -1;
@@ -211,12 +186,17 @@
subtract_range(range, RANGE_NUM, 0, end);
/* get mmconfig */
- get_pci_mmcfg_amd_fam10h_range();
+ fam10h_mmconf = amd_get_mmconfig_range(&fam10h_mmconf_res);
/* need to take out mmconf range */
- if (fam10h_mmconf_end) {
- printk(KERN_DEBUG "Fam 10h mmconf [%llx, %llx]\n", fam10h_mmconf_start, fam10h_mmconf_end);
+ if (fam10h_mmconf) {
+ printk(KERN_DEBUG "Fam 10h mmconf %pR\n", fam10h_mmconf);
+ fam10h_mmconf_start = fam10h_mmconf->start;
+ fam10h_mmconf_end = fam10h_mmconf->end;
subtract_range(range, RANGE_NUM, fam10h_mmconf_start,
fam10h_mmconf_end + 1);
+ } else {
+ fam10h_mmconf_start = 0;
+ fam10h_mmconf_end = 0;
}
/* mmio resource */
@@ -403,7 +383,6 @@
++n;
}
}
- pr_info("Extended Config Space enabled on %u nodes\n", n);
#endif
}
diff --git a/arch/x86/pci/broadcom_bus.c b/arch/x86/pci/broadcom_bus.c
index ab8269b..f3a7c56 100644
--- a/arch/x86/pci/broadcom_bus.c
+++ b/arch/x86/pci/broadcom_bus.c
@@ -15,10 +15,11 @@
#include <linux/pci.h>
#include <linux/init.h>
#include <asm/pci_x86.h>
+#include <asm/pci-direct.h>
#include "bus_numa.h"
-static void __devinit cnb20le_res(struct pci_dev *dev)
+static void __init cnb20le_res(u8 bus, u8 slot, u8 func)
{
struct pci_root_info *info;
struct resource res;
@@ -26,21 +27,12 @@
u8 fbus, lbus;
int i;
-#ifdef CONFIG_ACPI
- /*
- * We should get host bridge information from ACPI unless the BIOS
- * doesn't support it.
- */
- if (acpi_os_get_root_pointer())
- return;
-#endif
-
info = &pci_root_info[pci_root_num];
pci_root_num++;
/* read the PCI bus numbers */
- pci_read_config_byte(dev, 0x44, &fbus);
- pci_read_config_byte(dev, 0x45, &lbus);
+ fbus = read_pci_config_byte(bus, slot, func, 0x44);
+ lbus = read_pci_config_byte(bus, slot, func, 0x45);
info->bus_min = fbus;
info->bus_max = lbus;
@@ -59,8 +51,8 @@
}
/* read the non-prefetchable memory window */
- pci_read_config_word(dev, 0xc0, &word1);
- pci_read_config_word(dev, 0xc2, &word2);
+ word1 = read_pci_config_16(bus, slot, func, 0xc0);
+ word2 = read_pci_config_16(bus, slot, func, 0xc2);
if (word1 != word2) {
res.start = (word1 << 16) | 0x0000;
res.end = (word2 << 16) | 0xffff;
@@ -69,8 +61,8 @@
}
/* read the prefetchable memory window */
- pci_read_config_word(dev, 0xc4, &word1);
- pci_read_config_word(dev, 0xc6, &word2);
+ word1 = read_pci_config_16(bus, slot, func, 0xc4);
+ word2 = read_pci_config_16(bus, slot, func, 0xc6);
if (word1 != word2) {
res.start = (word1 << 16) | 0x0000;
res.end = (word2 << 16) | 0xffff;
@@ -79,8 +71,8 @@
}
/* read the IO port window */
- pci_read_config_word(dev, 0xd0, &word1);
- pci_read_config_word(dev, 0xd2, &word2);
+ word1 = read_pci_config_16(bus, slot, func, 0xd0);
+ word2 = read_pci_config_16(bus, slot, func, 0xd2);
if (word1 != word2) {
res.start = word1;
res.end = word2;
@@ -92,13 +84,37 @@
res.start = fbus;
res.end = lbus;
res.flags = IORESOURCE_BUS;
- dev_info(&dev->dev, "CNB20LE PCI Host Bridge (domain %04x %pR)\n",
- pci_domain_nr(dev->bus), &res);
+ printk(KERN_INFO "CNB20LE PCI Host Bridge (domain 0000 %pR)\n", &res);
for (i = 0; i < info->res_num; i++)
- dev_info(&dev->dev, "host bridge window %pR\n", &info->res[i]);
+ printk(KERN_INFO "host bridge window %pR\n", &info->res[i]);
}
-DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_LE,
- cnb20le_res);
+static int __init broadcom_postcore_init(void)
+{
+ u8 bus = 0, slot = 0;
+ u32 id;
+ u16 vendor, device;
+#ifdef CONFIG_ACPI
+ /*
+ * We should get host bridge information from ACPI unless the BIOS
+ * doesn't support it.
+ */
+ if (acpi_os_get_root_pointer())
+ return 0;
+#endif
+
+ id = read_pci_config(bus, slot, 0, PCI_VENDOR_ID);
+ vendor = id & 0xffff;
+ device = (id >> 16) & 0xffff;
+
+ if (vendor == PCI_VENDOR_ID_SERVERWORKS &&
+ device == PCI_DEVICE_ID_SERVERWORKS_LE) {
+ cnb20le_res(bus, slot, 0);
+ cnb20le_res(bus, slot, 1);
+ }
+ return 0;
+}
+
+postcore_initcall(broadcom_postcore_init);
diff --git a/arch/x86/pci/bus_numa.c b/arch/x86/pci/bus_numa.c
index 64a1228..fd3f655 100644
--- a/arch/x86/pci/bus_numa.c
+++ b/arch/x86/pci/bus_numa.c
@@ -7,45 +7,50 @@
int pci_root_num;
struct pci_root_info pci_root_info[PCI_ROOT_NR];
-void x86_pci_root_bus_res_quirks(struct pci_bus *b)
+void x86_pci_root_bus_resources(int bus, struct list_head *resources)
{
int i;
int j;
struct pci_root_info *info;
- /* don't go for it if _CRS is used already */
- if (b->resource[0] != &ioport_resource ||
- b->resource[1] != &iomem_resource)
- return;
-
if (!pci_root_num)
- return;
+ goto default_resources;
for (i = 0; i < pci_root_num; i++) {
- if (pci_root_info[i].bus_min == b->number)
+ if (pci_root_info[i].bus_min == bus)
break;
}
if (i == pci_root_num)
- return;
+ goto default_resources;
- printk(KERN_DEBUG "PCI: peer root bus %02x res updated from pci conf\n",
- b->number);
+ printk(KERN_DEBUG "PCI: root bus %02x: hardware-probed resources\n",
+ bus);
- pci_bus_remove_resources(b);
info = &pci_root_info[i];
for (j = 0; j < info->res_num; j++) {
struct resource *res;
struct resource *root;
res = &info->res[j];
- pci_bus_add_resource(b, res, 0);
+ pci_add_resource(resources, res);
if (res->flags & IORESOURCE_IO)
root = &ioport_resource;
else
root = &iomem_resource;
insert_resource(root, res);
}
+ return;
+
+default_resources:
+ /*
+ * We don't have any host bridge aperture information from the
+ * "native host bridge drivers," e.g., amd_bus or broadcom_bus,
+ * so fall back to the defaults historically used by pci_create_bus().
+ */
+ printk(KERN_DEBUG "PCI: root bus %02x: using default resources\n", bus);
+ pci_add_resource(resources, &ioport_resource);
+ pci_add_resource(resources, &iomem_resource);
}
void __devinit update_res(struct pci_root_info *info, resource_size_t start,
diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c
index 7962ccb..323481e 100644
--- a/arch/x86/pci/common.c
+++ b/arch/x86/pci/common.c
@@ -164,9 +164,6 @@
{
struct pci_dev *dev;
- /* root bus? */
- if (!b->parent)
- x86_pci_root_bus_res_quirks(b);
pci_read_bridge_bases(b);
list_for_each_entry(dev, &b->devices, bus_list)
pcibios_fixup_device_resources(dev);
@@ -433,6 +430,7 @@
struct pci_bus * __devinit pcibios_scan_root(int busnum)
{
+ LIST_HEAD(resources);
struct pci_bus *bus = NULL;
struct pci_sysdata *sd;
@@ -456,9 +454,12 @@
sd->node = get_mp_bus_to_node(busnum);
printk(KERN_DEBUG "PCI: Probing PCI hardware (bus %02x)\n", busnum);
- bus = pci_scan_bus_parented(NULL, busnum, &pci_root_ops, sd);
- if (!bus)
+ x86_pci_root_bus_resources(busnum, &resources);
+ bus = pci_scan_root_bus(NULL, busnum, &pci_root_ops, sd, &resources);
+ if (!bus) {
+ pci_free_resource_list(&resources);
kfree(sd);
+ }
return bus;
}
@@ -639,6 +640,7 @@
struct pci_bus * __devinit pci_scan_bus_on_node(int busno, struct pci_ops *ops, int node)
{
+ LIST_HEAD(resources);
struct pci_bus *bus = NULL;
struct pci_sysdata *sd;
@@ -653,9 +655,12 @@
return NULL;
}
sd->node = node;
- bus = pci_scan_bus(busno, ops, sd);
- if (!bus)
+ x86_pci_root_bus_resources(busno, &resources);
+ bus = pci_scan_root_bus(NULL, busno, ops, sd, &resources);
+ if (!bus) {
+ pci_free_resource_list(&resources);
kfree(sd);
+ }
return bus;
}
diff --git a/arch/x86/pci/i386.c b/arch/x86/pci/i386.c
index 794b092..91821a1 100644
--- a/arch/x86/pci/i386.c
+++ b/arch/x86/pci/i386.c
@@ -254,26 +254,6 @@
*/
fs_initcall(pcibios_assign_resources);
-/*
- * If we set up a device for bus mastering, we need to check the latency
- * timer as certain crappy BIOSes forget to set it properly.
- */
-unsigned int pcibios_max_latency = 255;
-
-void pcibios_set_master(struct pci_dev *dev)
-{
- u8 lat;
- pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
- if (lat < 16)
- lat = (64 <= pcibios_max_latency) ? 64 : pcibios_max_latency;
- else if (lat > pcibios_max_latency)
- lat = pcibios_max_latency;
- else
- return;
- dev_printk(KERN_DEBUG, &dev->dev, "setting latency timer to %d\n", lat);
- pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat);
-}
-
static const struct vm_operations_struct pci_mmap_ops = {
.access = generic_access_phys,
};
diff --git a/arch/x86/pci/legacy.c b/arch/x86/pci/legacy.c
index 2c2aeab..a1df191 100644
--- a/arch/x86/pci/legacy.c
+++ b/arch/x86/pci/legacy.c
@@ -31,9 +31,6 @@
printk("PCI: Probing PCI hardware\n");
pci_root_bus = pcibios_scan_root(0);
- if (pci_root_bus)
- pci_bus_add_devices(pci_root_bus);
-
return 0;
}
diff --git a/arch/x86/pci/numaq_32.c b/arch/x86/pci/numaq_32.c
index 51abf02..83e125b 100644
--- a/arch/x86/pci/numaq_32.c
+++ b/arch/x86/pci/numaq_32.c
@@ -153,8 +153,6 @@
raw_pci_ops = &pci_direct_conf1_mq;
pci_root_bus = pcibios_scan_root(0);
- if (pci_root_bus)
- pci_bus_add_devices(pci_root_bus);
if (num_online_nodes() > 1)
for_each_online_node(quad) {
if (quad == 0)
diff --git a/arch/x86/platform/mrst/Makefile b/arch/x86/platform/mrst/Makefile
index 1ea3877..7baed51 100644
--- a/arch/x86/platform/mrst/Makefile
+++ b/arch/x86/platform/mrst/Makefile
@@ -1,4 +1,4 @@
-obj-$(CONFIG_X86_MRST) += mrst.o
-obj-$(CONFIG_X86_MRST) += vrtc.o
-obj-$(CONFIG_EARLY_PRINTK_MRST) += early_printk_mrst.o
+obj-$(CONFIG_X86_INTEL_MID) += mrst.o
+obj-$(CONFIG_X86_INTEL_MID) += vrtc.o
+obj-$(CONFIG_EARLY_PRINTK_INTEL_MID) += early_printk_mrst.o
obj-$(CONFIG_X86_MRST) += pmu.o
diff --git a/arch/x86/platform/mrst/mrst.c b/arch/x86/platform/mrst/mrst.c
index ad4ec1c..475e2cd 100644
--- a/arch/x86/platform/mrst/mrst.c
+++ b/arch/x86/platform/mrst/mrst.c
@@ -848,8 +848,7 @@
if (mrst_has_msic())
return;
- /* ID as IRQ is a hack that will go away */
- pdev = platform_device_alloc(entry->name, entry->irq);
+ pdev = platform_device_alloc(entry->name, 0);
if (pdev == NULL) {
pr_err("out of memory for SFI platform device '%s'.\n",
entry->name);
@@ -1030,6 +1029,7 @@
num = sizeof(gpio_button) / sizeof(struct gpio_keys_button);
for (i = 0; i < num; i++) {
gb[i].gpio = get_gpio_by_name(gb[i].desc);
+ pr_debug("info[%2d]: name = %s, gpio = %d\n", i, gb[i].desc, gb[i].gpio);
if (gb[i].gpio == -1)
continue;
diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig
index c346ccd..8a3f835 100644
--- a/arch/xtensa/Kconfig
+++ b/arch/xtensa/Kconfig
@@ -9,6 +9,7 @@
select HAVE_IDE
select HAVE_GENERIC_HARDIRQS
select GENERIC_IRQ_SHOW
+ select GENERIC_CPU_DEVICES
help
Xtensa processors are 32-bit RISC machines designed by Tensilica
primarily for embedded systems. These processors are both
diff --git a/arch/xtensa/include/asm/pci.h b/arch/xtensa/include/asm/pci.h
index 4609b0f..05244f0 100644
--- a/arch/xtensa/include/asm/pci.h
+++ b/arch/xtensa/include/asm/pci.h
@@ -22,11 +22,6 @@
extern struct pci_controller* pcibios_alloc_controller(void);
-static inline void pcibios_set_master(struct pci_dev *dev)
-{
- /* No special bus mastering setup handling */
-}
-
static inline void pcibios_penalize_isa_irq(int irq)
{
/* We don't do dynamic PCI IRQ allocation */
diff --git a/arch/xtensa/kernel/pci.c b/arch/xtensa/kernel/pci.c
index cd10269..61045c1 100644
--- a/arch/xtensa/kernel/pci.c
+++ b/arch/xtensa/kernel/pci.c
@@ -134,9 +134,46 @@
return pci_ctrl;
}
+static void __init pci_controller_apertures(struct pci_controller *pci_ctrl,
+ struct list_head *resources)
+{
+ struct resource *res;
+ unsigned long io_offset;
+ int i;
+
+ io_offset = (unsigned long)pci_ctrl->io_space.base;
+ res = &pci_ctrl->io_resource;
+ if (!res->flags) {
+ if (io_offset)
+ printk (KERN_ERR "I/O resource not set for host"
+ " bridge %d\n", pci_ctrl->index);
+ res->start = 0;
+ res->end = IO_SPACE_LIMIT;
+ res->flags = IORESOURCE_IO;
+ }
+ res->start += io_offset;
+ res->end += io_offset;
+ pci_add_resource(resources, res);
+
+ for (i = 0; i < 3; i++) {
+ res = &pci_ctrl->mem_resources[i];
+ if (!res->flags) {
+ if (i > 0)
+ continue;
+ printk(KERN_ERR "Memory resource not set for "
+ "host bridge %d\n", pci_ctrl->index);
+ res->start = 0;
+ res->end = ~0U;
+ res->flags = IORESOURCE_MEM;
+ }
+ pci_add_resource(resources, res);
+ }
+}
+
static int __init pcibios_init(void)
{
struct pci_controller *pci_ctrl;
+ struct list_head resources;
struct pci_bus *bus;
int next_busno = 0, i;
@@ -145,19 +182,10 @@
/* Scan all of the recorded PCI controllers. */
for (pci_ctrl = pci_ctrl_head; pci_ctrl; pci_ctrl = pci_ctrl->next) {
pci_ctrl->last_busno = 0xff;
- bus = pci_scan_bus(pci_ctrl->first_busno, pci_ctrl->ops,
- pci_ctrl);
- if (pci_ctrl->io_resource.flags) {
- unsigned long offs;
-
- offs = (unsigned long)pci_ctrl->io_space.base;
- pci_ctrl->io_resource.start += offs;
- pci_ctrl->io_resource.end += offs;
- bus->resource[0] = &pci_ctrl->io_resource;
- }
- for (i = 0; i < 3; ++i)
- if (pci_ctrl->mem_resources[i].flags)
- bus->resource[i+1] =&pci_ctrl->mem_resources[i];
+ INIT_LIST_HEAD(&resources);
+ pci_controller_apertures(pci_ctrl, &resources);
+ bus = pci_scan_root_bus(NULL, pci_ctrl->first_busno,
+ pci_ctrl->ops, pci_ctrl, &resources);
pci_ctrl->bus = bus;
pci_ctrl->last_busno = bus->subordinate;
if (next_busno <= pci_ctrl->last_busno)
@@ -178,36 +206,7 @@
int i;
io_offset = (unsigned long)pci_ctrl->io_space.base;
- if (bus->parent == NULL) {
- /* this is a host bridge - fill in its resources */
- pci_ctrl->bus = bus;
-
- bus->resource[0] = res = &pci_ctrl->io_resource;
- if (!res->flags) {
- if (io_offset)
- printk (KERN_ERR "I/O resource not set for host"
- " bridge %d\n", pci_ctrl->index);
- res->start = 0;
- res->end = IO_SPACE_LIMIT;
- res->flags = IORESOURCE_IO;
- }
- res->start += io_offset;
- res->end += io_offset;
-
- for (i = 0; i < 3; i++) {
- res = &pci_ctrl->mem_resources[i];
- if (!res->flags) {
- if (i > 0)
- continue;
- printk(KERN_ERR "Memory resource not set for "
- "host bridge %d\n", pci_ctrl->index);
- res->start = 0;
- res->end = ~0U;
- res->flags = IORESOURCE_MEM;
- }
- bus->resource[i+1] = res;
- }
- } else {
+ if (bus->parent) {
/* This is a subordinate bridge */
pci_read_bridge_bases(bus);
@@ -227,6 +226,11 @@
return str;
}
+void pcibios_set_master(struct pci_dev *dev)
+{
+ /* No special bus mastering setup handling */
+}
+
/* the next one is stolen from the alpha port... */
void __init
diff --git a/crypto/Kconfig b/crypto/Kconfig
index ae9c3ce..e6cfe1a 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -105,7 +105,7 @@
depends on NET
select CRYPTO_MANAGER
help
- Userapace configuration for cryptographic instantiations such as
+ Userspace configuration for cryptographic instantiations such as
cbc(aes).
config CRYPTO_MANAGER_DISABLE_TESTS
@@ -117,7 +117,7 @@
algorithm registration.
config CRYPTO_GF128MUL
- tristate "GF(2^128) multiplication functions (EXPERIMENTAL)"
+ tristate "GF(2^128) multiplication functions"
help
Efficient table driven implementation of multiplications in the
field GF(2^128). This is needed by some cypher modes. This
@@ -241,8 +241,7 @@
the input block by block.
config CRYPTO_LRW
- tristate "LRW support (EXPERIMENTAL)"
- depends on EXPERIMENTAL
+ tristate "LRW support"
select CRYPTO_BLKCIPHER
select CRYPTO_MANAGER
select CRYPTO_GF128MUL
@@ -262,8 +261,7 @@
This block cipher algorithm is required for RxRPC.
config CRYPTO_XTS
- tristate "XTS support (EXPERIMENTAL)"
- depends on EXPERIMENTAL
+ tristate "XTS support"
select CRYPTO_BLKCIPHER
select CRYPTO_MANAGER
select CRYPTO_GF128MUL
@@ -764,6 +762,46 @@
See also:
<http://www.cl.cam.ac.uk/~rja14/serpent.html>
+config CRYPTO_SERPENT_SSE2_X86_64
+ tristate "Serpent cipher algorithm (x86_64/SSE2)"
+ depends on X86 && 64BIT
+ select CRYPTO_ALGAPI
+ select CRYPTO_CRYPTD
+ select CRYPTO_SERPENT
+ select CRYPTO_LRW
+ select CRYPTO_XTS
+ help
+ Serpent cipher algorithm, by Anderson, Biham & Knudsen.
+
+ Keys are allowed to be from 0 to 256 bits in length, in steps
+ of 8 bits.
+
+ This module provides Serpent cipher algorithm that processes eigth
+ blocks parallel using SSE2 instruction set.
+
+ See also:
+ <http://www.cl.cam.ac.uk/~rja14/serpent.html>
+
+config CRYPTO_SERPENT_SSE2_586
+ tristate "Serpent cipher algorithm (i586/SSE2)"
+ depends on X86 && !64BIT
+ select CRYPTO_ALGAPI
+ select CRYPTO_CRYPTD
+ select CRYPTO_SERPENT
+ select CRYPTO_LRW
+ select CRYPTO_XTS
+ help
+ Serpent cipher algorithm, by Anderson, Biham & Knudsen.
+
+ Keys are allowed to be from 0 to 256 bits in length, in steps
+ of 8 bits.
+
+ This module provides Serpent cipher algorithm that processes four
+ blocks parallel using SSE2 instruction set.
+
+ See also:
+ <http://www.cl.cam.ac.uk/~rja14/serpent.html>
+
config CRYPTO_TEA
tristate "TEA, XTEA and XETA cipher algorithms"
select CRYPTO_ALGAPI
@@ -840,6 +878,8 @@
select CRYPTO_ALGAPI
select CRYPTO_TWOFISH_COMMON
select CRYPTO_TWOFISH_X86_64
+ select CRYPTO_LRW
+ select CRYPTO_XTS
help
Twofish cipher algorithm (x86_64, 3-way parallel).
diff --git a/crypto/Makefile b/crypto/Makefile
index 9e6eee2..f638063 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -65,7 +65,7 @@
obj-$(CONFIG_CRYPTO_BLOWFISH_COMMON) += blowfish_common.o
obj-$(CONFIG_CRYPTO_TWOFISH) += twofish_generic.o
obj-$(CONFIG_CRYPTO_TWOFISH_COMMON) += twofish_common.o
-obj-$(CONFIG_CRYPTO_SERPENT) += serpent.o
+obj-$(CONFIG_CRYPTO_SERPENT) += serpent_generic.o
obj-$(CONFIG_CRYPTO_AES) += aes_generic.o
obj-$(CONFIG_CRYPTO_CAMELLIA) += camellia.o
obj-$(CONFIG_CRYPTO_CAST5) += cast5.o
diff --git a/crypto/algapi.c b/crypto/algapi.c
index 54dd4e3..9d4a9fe 100644
--- a/crypto/algapi.c
+++ b/crypto/algapi.c
@@ -518,6 +518,35 @@
}
EXPORT_SYMBOL_GPL(crypto_register_instance);
+int crypto_unregister_instance(struct crypto_alg *alg)
+{
+ int err;
+ struct crypto_instance *inst = (void *)alg;
+ struct crypto_template *tmpl = inst->tmpl;
+ LIST_HEAD(users);
+
+ if (!(alg->cra_flags & CRYPTO_ALG_INSTANCE))
+ return -EINVAL;
+
+ BUG_ON(atomic_read(&alg->cra_refcnt) != 1);
+
+ down_write(&crypto_alg_sem);
+
+ hlist_del_init(&inst->list);
+ err = crypto_remove_alg(alg, &users);
+
+ up_write(&crypto_alg_sem);
+
+ if (err)
+ return err;
+
+ tmpl->free(inst);
+ crypto_remove_final(&users);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(crypto_unregister_instance);
+
int crypto_init_spawn(struct crypto_spawn *spawn, struct crypto_alg *alg,
struct crypto_instance *inst, u32 mask)
{
diff --git a/crypto/ansi_cprng.c b/crypto/ansi_cprng.c
index ffa0245..6ddd99e 100644
--- a/crypto/ansi_cprng.c
+++ b/crypto/ansi_cprng.c
@@ -414,10 +414,18 @@
static int fips_cprng_reset(struct crypto_rng *tfm, u8 *seed, unsigned int slen)
{
u8 rdata[DEFAULT_BLK_SZ];
+ u8 *key = seed + DEFAULT_BLK_SZ;
int rc;
struct prng_context *prng = crypto_rng_ctx(tfm);
+ if (slen < DEFAULT_PRNG_KSZ + DEFAULT_BLK_SZ)
+ return -EINVAL;
+
+ /* fips strictly requires seed != key */
+ if (!memcmp(seed, key, DEFAULT_PRNG_KSZ))
+ return -EINVAL;
+
rc = cprng_reset(tfm, seed, slen);
if (!rc)
diff --git a/crypto/crypto_user.c b/crypto/crypto_user.c
index 0605a2b..3ba6ef50 100644
--- a/crypto/crypto_user.c
+++ b/crypto/crypto_user.c
@@ -298,7 +298,7 @@
if (atomic_read(&alg->cra_refcnt) != 1)
return -EBUSY;
- return crypto_unregister_alg(alg);
+ return crypto_unregister_instance(alg);
}
static int crypto_add_alg(struct sk_buff *skb, struct nlmsghdr *nlh,
diff --git a/crypto/lrw.c b/crypto/lrw.c
index 358f80b..ba42acc 100644
--- a/crypto/lrw.c
+++ b/crypto/lrw.c
@@ -3,7 +3,7 @@
*
* Copyright (c) 2006 Rik Snel <rsnel@cube.dyndns.org>
*
- * Based om ecb.c
+ * Based on ecb.c
* Copyright (c) 2006 Herbert Xu <herbert@gondor.apana.org.au>
*
* This program is free software; you can redistribute it and/or modify it
@@ -16,6 +16,7 @@
* http://www.mail-archive.com/stds-p1619@listserv.ieee.org/msg00173.html
*
* The test vectors are included in the testing module tcrypt.[ch] */
+
#include <crypto/algapi.h>
#include <linux/err.h>
#include <linux/init.h>
@@ -26,21 +27,11 @@
#include <crypto/b128ops.h>
#include <crypto/gf128mul.h>
+#include <crypto/lrw.h>
struct priv {
struct crypto_cipher *child;
- /* optimizes multiplying a random (non incrementing, as at the
- * start of a new sector) value with key2, we could also have
- * used 4k optimization tables or no optimization at all. In the
- * latter case we would have to store key2 here */
- struct gf128mul_64k *table;
- /* stores:
- * key2*{ 0,0,...0,0,0,0,1 }, key2*{ 0,0,...0,0,0,1,1 },
- * key2*{ 0,0,...0,0,1,1,1 }, key2*{ 0,0,...0,1,1,1,1 }
- * key2*{ 0,0,...1,1,1,1,1 }, etc
- * needed for optimized multiplication of incrementing values
- * with key2 */
- be128 mulinc[128];
+ struct lrw_table_ctx table;
};
static inline void setbit128_bbe(void *b, int bit)
@@ -54,28 +45,16 @@
), b);
}
-static int setkey(struct crypto_tfm *parent, const u8 *key,
- unsigned int keylen)
+int lrw_init_table(struct lrw_table_ctx *ctx, const u8 *tweak)
{
- struct priv *ctx = crypto_tfm_ctx(parent);
- struct crypto_cipher *child = ctx->child;
- int err, i;
be128 tmp = { 0 };
- int bsize = crypto_cipher_blocksize(child);
-
- crypto_cipher_clear_flags(child, CRYPTO_TFM_REQ_MASK);
- crypto_cipher_set_flags(child, crypto_tfm_get_flags(parent) &
- CRYPTO_TFM_REQ_MASK);
- if ((err = crypto_cipher_setkey(child, key, keylen - bsize)))
- return err;
- crypto_tfm_set_flags(parent, crypto_cipher_get_flags(child) &
- CRYPTO_TFM_RES_MASK);
+ int i;
if (ctx->table)
gf128mul_free_64k(ctx->table);
/* initialize multiplication table for Key2 */
- ctx->table = gf128mul_init_64k_bbe((be128 *)(key + keylen - bsize));
+ ctx->table = gf128mul_init_64k_bbe((be128 *)tweak);
if (!ctx->table)
return -ENOMEM;
@@ -88,6 +67,34 @@
return 0;
}
+EXPORT_SYMBOL_GPL(lrw_init_table);
+
+void lrw_free_table(struct lrw_table_ctx *ctx)
+{
+ if (ctx->table)
+ gf128mul_free_64k(ctx->table);
+}
+EXPORT_SYMBOL_GPL(lrw_free_table);
+
+static int setkey(struct crypto_tfm *parent, const u8 *key,
+ unsigned int keylen)
+{
+ struct priv *ctx = crypto_tfm_ctx(parent);
+ struct crypto_cipher *child = ctx->child;
+ int err, bsize = LRW_BLOCK_SIZE;
+ const u8 *tweak = key + keylen - bsize;
+
+ crypto_cipher_clear_flags(child, CRYPTO_TFM_REQ_MASK);
+ crypto_cipher_set_flags(child, crypto_tfm_get_flags(parent) &
+ CRYPTO_TFM_REQ_MASK);
+ err = crypto_cipher_setkey(child, key, keylen - bsize);
+ if (err)
+ return err;
+ crypto_tfm_set_flags(parent, crypto_cipher_get_flags(child) &
+ CRYPTO_TFM_RES_MASK);
+
+ return lrw_init_table(&ctx->table, tweak);
+}
struct sinfo {
be128 t;
@@ -134,7 +141,7 @@
{
int err;
unsigned int avail;
- const int bs = crypto_cipher_blocksize(ctx->child);
+ const int bs = LRW_BLOCK_SIZE;
struct sinfo s = {
.tfm = crypto_cipher_tfm(ctx->child),
.fn = fn
@@ -155,7 +162,7 @@
s.t = *iv;
/* T <- I*Key2 */
- gf128mul_64k_bbe(&s.t, ctx->table);
+ gf128mul_64k_bbe(&s.t, ctx->table.table);
goto first;
@@ -163,7 +170,8 @@
do {
/* T <- I*Key2, using the optimization
* discussed in the specification */
- be128_xor(&s.t, &s.t, &ctx->mulinc[get_index128(iv)]);
+ be128_xor(&s.t, &s.t,
+ &ctx->table.mulinc[get_index128(iv)]);
inc(iv);
first:
@@ -206,6 +214,85 @@
crypto_cipher_alg(ctx->child)->cia_decrypt);
}
+int lrw_crypt(struct blkcipher_desc *desc, struct scatterlist *sdst,
+ struct scatterlist *ssrc, unsigned int nbytes,
+ struct lrw_crypt_req *req)
+{
+ const unsigned int bsize = LRW_BLOCK_SIZE;
+ const unsigned int max_blks = req->tbuflen / bsize;
+ struct lrw_table_ctx *ctx = req->table_ctx;
+ struct blkcipher_walk walk;
+ unsigned int nblocks;
+ be128 *iv, *src, *dst, *t;
+ be128 *t_buf = req->tbuf;
+ int err, i;
+
+ BUG_ON(max_blks < 1);
+
+ blkcipher_walk_init(&walk, sdst, ssrc, nbytes);
+
+ err = blkcipher_walk_virt(desc, &walk);
+ nbytes = walk.nbytes;
+ if (!nbytes)
+ return err;
+
+ nblocks = min(walk.nbytes / bsize, max_blks);
+ src = (be128 *)walk.src.virt.addr;
+ dst = (be128 *)walk.dst.virt.addr;
+
+ /* calculate first value of T */
+ iv = (be128 *)walk.iv;
+ t_buf[0] = *iv;
+
+ /* T <- I*Key2 */
+ gf128mul_64k_bbe(&t_buf[0], ctx->table);
+
+ i = 0;
+ goto first;
+
+ for (;;) {
+ do {
+ for (i = 0; i < nblocks; i++) {
+ /* T <- I*Key2, using the optimization
+ * discussed in the specification */
+ be128_xor(&t_buf[i], t,
+ &ctx->mulinc[get_index128(iv)]);
+ inc(iv);
+first:
+ t = &t_buf[i];
+
+ /* PP <- T xor P */
+ be128_xor(dst + i, t, src + i);
+ }
+
+ /* CC <- E(Key2,PP) */
+ req->crypt_fn(req->crypt_ctx, (u8 *)dst,
+ nblocks * bsize);
+
+ /* C <- T xor CC */
+ for (i = 0; i < nblocks; i++)
+ be128_xor(dst + i, dst + i, &t_buf[i]);
+
+ src += nblocks;
+ dst += nblocks;
+ nbytes -= nblocks * bsize;
+ nblocks = min(nbytes / bsize, max_blks);
+ } while (nblocks > 0);
+
+ err = blkcipher_walk_done(desc, &walk, nbytes);
+ nbytes = walk.nbytes;
+ if (!nbytes)
+ break;
+
+ nblocks = min(nbytes / bsize, max_blks);
+ src = (be128 *)walk.src.virt.addr;
+ dst = (be128 *)walk.dst.virt.addr;
+ }
+
+ return err;
+}
+EXPORT_SYMBOL_GPL(lrw_crypt);
+
static int init_tfm(struct crypto_tfm *tfm)
{
struct crypto_cipher *cipher;
@@ -218,8 +305,9 @@
if (IS_ERR(cipher))
return PTR_ERR(cipher);
- if (crypto_cipher_blocksize(cipher) != 16) {
+ if (crypto_cipher_blocksize(cipher) != LRW_BLOCK_SIZE) {
*flags |= CRYPTO_TFM_RES_BAD_BLOCK_LEN;
+ crypto_free_cipher(cipher);
return -EINVAL;
}
@@ -230,8 +318,8 @@
static void exit_tfm(struct crypto_tfm *tfm)
{
struct priv *ctx = crypto_tfm_ctx(tfm);
- if (ctx->table)
- gf128mul_free_64k(ctx->table);
+
+ lrw_free_table(&ctx->table);
crypto_free_cipher(ctx->child);
}
diff --git a/crypto/serpent.c b/crypto/serpent.c
deleted file mode 100644
index b651a55..0000000
--- a/crypto/serpent.c
+++ /dev/null
@@ -1,587 +0,0 @@
-/*
- * Cryptographic API.
- *
- * Serpent Cipher Algorithm.
- *
- * Copyright (C) 2002 Dag Arne Osvik <osvik@ii.uib.no>
- * 2003 Herbert Valerio Riedel <hvr@gnu.org>
- *
- * Added tnepres support: Ruben Jesus Garcia Hernandez <ruben@ugr.es>, 18.10.2004
- * Based on code by hvr
- *
- * 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.
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/errno.h>
-#include <asm/byteorder.h>
-#include <linux/crypto.h>
-#include <linux/types.h>
-
-/* Key is padded to the maximum of 256 bits before round key generation.
- * Any key length <= 256 bits (32 bytes) is allowed by the algorithm.
- */
-
-#define SERPENT_MIN_KEY_SIZE 0
-#define SERPENT_MAX_KEY_SIZE 32
-#define SERPENT_EXPKEY_WORDS 132
-#define SERPENT_BLOCK_SIZE 16
-
-#define PHI 0x9e3779b9UL
-
-#define keyiter(a,b,c,d,i,j) \
- b ^= d; b ^= c; b ^= a; b ^= PHI ^ i; b = rol32(b,11); k[j] = b;
-
-#define loadkeys(x0,x1,x2,x3,i) \
- x0=k[i]; x1=k[i+1]; x2=k[i+2]; x3=k[i+3];
-
-#define storekeys(x0,x1,x2,x3,i) \
- k[i]=x0; k[i+1]=x1; k[i+2]=x2; k[i+3]=x3;
-
-#define K(x0,x1,x2,x3,i) \
- x3 ^= k[4*(i)+3]; x2 ^= k[4*(i)+2]; \
- x1 ^= k[4*(i)+1]; x0 ^= k[4*(i)+0];
-
-#define LK(x0,x1,x2,x3,x4,i) \
- x0=rol32(x0,13);\
- x2=rol32(x2,3); x1 ^= x0; x4 = x0 << 3; \
- x3 ^= x2; x1 ^= x2; \
- x1=rol32(x1,1); x3 ^= x4; \
- x3=rol32(x3,7); x4 = x1; \
- x0 ^= x1; x4 <<= 7; x2 ^= x3; \
- x0 ^= x3; x2 ^= x4; x3 ^= k[4*i+3]; \
- x1 ^= k[4*i+1]; x0=rol32(x0,5); x2=rol32(x2,22);\
- x0 ^= k[4*i+0]; x2 ^= k[4*i+2];
-
-#define KL(x0,x1,x2,x3,x4,i) \
- x0 ^= k[4*i+0]; x1 ^= k[4*i+1]; x2 ^= k[4*i+2]; \
- x3 ^= k[4*i+3]; x0=ror32(x0,5); x2=ror32(x2,22);\
- x4 = x1; x2 ^= x3; x0 ^= x3; \
- x4 <<= 7; x0 ^= x1; x1=ror32(x1,1); \
- x2 ^= x4; x3=ror32(x3,7); x4 = x0 << 3; \
- x1 ^= x0; x3 ^= x4; x0=ror32(x0,13);\
- x1 ^= x2; x3 ^= x2; x2=ror32(x2,3);
-
-#define S0(x0,x1,x2,x3,x4) \
- x4 = x3; \
- x3 |= x0; x0 ^= x4; x4 ^= x2; \
- x4 =~ x4; x3 ^= x1; x1 &= x0; \
- x1 ^= x4; x2 ^= x0; x0 ^= x3; \
- x4 |= x0; x0 ^= x2; x2 &= x1; \
- x3 ^= x2; x1 =~ x1; x2 ^= x4; \
- x1 ^= x2;
-
-#define S1(x0,x1,x2,x3,x4) \
- x4 = x1; \
- x1 ^= x0; x0 ^= x3; x3 =~ x3; \
- x4 &= x1; x0 |= x1; x3 ^= x2; \
- x0 ^= x3; x1 ^= x3; x3 ^= x4; \
- x1 |= x4; x4 ^= x2; x2 &= x0; \
- x2 ^= x1; x1 |= x0; x0 =~ x0; \
- x0 ^= x2; x4 ^= x1;
-
-#define S2(x0,x1,x2,x3,x4) \
- x3 =~ x3; \
- x1 ^= x0; x4 = x0; x0 &= x2; \
- x0 ^= x3; x3 |= x4; x2 ^= x1; \
- x3 ^= x1; x1 &= x0; x0 ^= x2; \
- x2 &= x3; x3 |= x1; x0 =~ x0; \
- x3 ^= x0; x4 ^= x0; x0 ^= x2; \
- x1 |= x2;
-
-#define S3(x0,x1,x2,x3,x4) \
- x4 = x1; \
- x1 ^= x3; x3 |= x0; x4 &= x0; \
- x0 ^= x2; x2 ^= x1; x1 &= x3; \
- x2 ^= x3; x0 |= x4; x4 ^= x3; \
- x1 ^= x0; x0 &= x3; x3 &= x4; \
- x3 ^= x2; x4 |= x1; x2 &= x1; \
- x4 ^= x3; x0 ^= x3; x3 ^= x2;
-
-#define S4(x0,x1,x2,x3,x4) \
- x4 = x3; \
- x3 &= x0; x0 ^= x4; \
- x3 ^= x2; x2 |= x4; x0 ^= x1; \
- x4 ^= x3; x2 |= x0; \
- x2 ^= x1; x1 &= x0; \
- x1 ^= x4; x4 &= x2; x2 ^= x3; \
- x4 ^= x0; x3 |= x1; x1 =~ x1; \
- x3 ^= x0;
-
-#define S5(x0,x1,x2,x3,x4) \
- x4 = x1; x1 |= x0; \
- x2 ^= x1; x3 =~ x3; x4 ^= x0; \
- x0 ^= x2; x1 &= x4; x4 |= x3; \
- x4 ^= x0; x0 &= x3; x1 ^= x3; \
- x3 ^= x2; x0 ^= x1; x2 &= x4; \
- x1 ^= x2; x2 &= x0; \
- x3 ^= x2;
-
-#define S6(x0,x1,x2,x3,x4) \
- x4 = x1; \
- x3 ^= x0; x1 ^= x2; x2 ^= x0; \
- x0 &= x3; x1 |= x3; x4 =~ x4; \
- x0 ^= x1; x1 ^= x2; \
- x3 ^= x4; x4 ^= x0; x2 &= x0; \
- x4 ^= x1; x2 ^= x3; x3 &= x1; \
- x3 ^= x0; x1 ^= x2;
-
-#define S7(x0,x1,x2,x3,x4) \
- x1 =~ x1; \
- x4 = x1; x0 =~ x0; x1 &= x2; \
- x1 ^= x3; x3 |= x4; x4 ^= x2; \
- x2 ^= x3; x3 ^= x0; x0 |= x1; \
- x2 &= x0; x0 ^= x4; x4 ^= x3; \
- x3 &= x0; x4 ^= x1; \
- x2 ^= x4; x3 ^= x1; x4 |= x0; \
- x4 ^= x1;
-
-#define SI0(x0,x1,x2,x3,x4) \
- x4 = x3; x1 ^= x0; \
- x3 |= x1; x4 ^= x1; x0 =~ x0; \
- x2 ^= x3; x3 ^= x0; x0 &= x1; \
- x0 ^= x2; x2 &= x3; x3 ^= x4; \
- x2 ^= x3; x1 ^= x3; x3 &= x0; \
- x1 ^= x0; x0 ^= x2; x4 ^= x3;
-
-#define SI1(x0,x1,x2,x3,x4) \
- x1 ^= x3; x4 = x0; \
- x0 ^= x2; x2 =~ x2; x4 |= x1; \
- x4 ^= x3; x3 &= x1; x1 ^= x2; \
- x2 &= x4; x4 ^= x1; x1 |= x3; \
- x3 ^= x0; x2 ^= x0; x0 |= x4; \
- x2 ^= x4; x1 ^= x0; \
- x4 ^= x1;
-
-#define SI2(x0,x1,x2,x3,x4) \
- x2 ^= x1; x4 = x3; x3 =~ x3; \
- x3 |= x2; x2 ^= x4; x4 ^= x0; \
- x3 ^= x1; x1 |= x2; x2 ^= x0; \
- x1 ^= x4; x4 |= x3; x2 ^= x3; \
- x4 ^= x2; x2 &= x1; \
- x2 ^= x3; x3 ^= x4; x4 ^= x0;
-
-#define SI3(x0,x1,x2,x3,x4) \
- x2 ^= x1; \
- x4 = x1; x1 &= x2; \
- x1 ^= x0; x0 |= x4; x4 ^= x3; \
- x0 ^= x3; x3 |= x1; x1 ^= x2; \
- x1 ^= x3; x0 ^= x2; x2 ^= x3; \
- x3 &= x1; x1 ^= x0; x0 &= x2; \
- x4 ^= x3; x3 ^= x0; x0 ^= x1;
-
-#define SI4(x0,x1,x2,x3,x4) \
- x2 ^= x3; x4 = x0; x0 &= x1; \
- x0 ^= x2; x2 |= x3; x4 =~ x4; \
- x1 ^= x0; x0 ^= x2; x2 &= x4; \
- x2 ^= x0; x0 |= x4; \
- x0 ^= x3; x3 &= x2; \
- x4 ^= x3; x3 ^= x1; x1 &= x0; \
- x4 ^= x1; x0 ^= x3;
-
-#define SI5(x0,x1,x2,x3,x4) \
- x4 = x1; x1 |= x2; \
- x2 ^= x4; x1 ^= x3; x3 &= x4; \
- x2 ^= x3; x3 |= x0; x0 =~ x0; \
- x3 ^= x2; x2 |= x0; x4 ^= x1; \
- x2 ^= x4; x4 &= x0; x0 ^= x1; \
- x1 ^= x3; x0 &= x2; x2 ^= x3; \
- x0 ^= x2; x2 ^= x4; x4 ^= x3;
-
-#define SI6(x0,x1,x2,x3,x4) \
- x0 ^= x2; \
- x4 = x0; x0 &= x3; x2 ^= x3; \
- x0 ^= x2; x3 ^= x1; x2 |= x4; \
- x2 ^= x3; x3 &= x0; x0 =~ x0; \
- x3 ^= x1; x1 &= x2; x4 ^= x0; \
- x3 ^= x4; x4 ^= x2; x0 ^= x1; \
- x2 ^= x0;
-
-#define SI7(x0,x1,x2,x3,x4) \
- x4 = x3; x3 &= x0; x0 ^= x2; \
- x2 |= x4; x4 ^= x1; x0 =~ x0; \
- x1 |= x3; x4 ^= x0; x0 &= x2; \
- x0 ^= x1; x1 &= x2; x3 ^= x2; \
- x4 ^= x3; x2 &= x3; x3 |= x0; \
- x1 ^= x4; x3 ^= x4; x4 &= x0; \
- x4 ^= x2;
-
-struct serpent_ctx {
- u32 expkey[SERPENT_EXPKEY_WORDS];
-};
-
-
-static int serpent_setkey(struct crypto_tfm *tfm, const u8 *key,
- unsigned int keylen)
-{
- struct serpent_ctx *ctx = crypto_tfm_ctx(tfm);
- u32 *k = ctx->expkey;
- u8 *k8 = (u8 *)k;
- u32 r0,r1,r2,r3,r4;
- int i;
-
- /* Copy key, add padding */
-
- for (i = 0; i < keylen; ++i)
- k8[i] = key[i];
- if (i < SERPENT_MAX_KEY_SIZE)
- k8[i++] = 1;
- while (i < SERPENT_MAX_KEY_SIZE)
- k8[i++] = 0;
-
- /* Expand key using polynomial */
-
- r0 = le32_to_cpu(k[3]);
- r1 = le32_to_cpu(k[4]);
- r2 = le32_to_cpu(k[5]);
- r3 = le32_to_cpu(k[6]);
- r4 = le32_to_cpu(k[7]);
-
- keyiter(le32_to_cpu(k[0]),r0,r4,r2,0,0);
- keyiter(le32_to_cpu(k[1]),r1,r0,r3,1,1);
- keyiter(le32_to_cpu(k[2]),r2,r1,r4,2,2);
- keyiter(le32_to_cpu(k[3]),r3,r2,r0,3,3);
- keyiter(le32_to_cpu(k[4]),r4,r3,r1,4,4);
- keyiter(le32_to_cpu(k[5]),r0,r4,r2,5,5);
- keyiter(le32_to_cpu(k[6]),r1,r0,r3,6,6);
- keyiter(le32_to_cpu(k[7]),r2,r1,r4,7,7);
-
- keyiter(k[ 0],r3,r2,r0, 8, 8); keyiter(k[ 1],r4,r3,r1, 9, 9);
- keyiter(k[ 2],r0,r4,r2, 10, 10); keyiter(k[ 3],r1,r0,r3, 11, 11);
- keyiter(k[ 4],r2,r1,r4, 12, 12); keyiter(k[ 5],r3,r2,r0, 13, 13);
- keyiter(k[ 6],r4,r3,r1, 14, 14); keyiter(k[ 7],r0,r4,r2, 15, 15);
- keyiter(k[ 8],r1,r0,r3, 16, 16); keyiter(k[ 9],r2,r1,r4, 17, 17);
- keyiter(k[ 10],r3,r2,r0, 18, 18); keyiter(k[ 11],r4,r3,r1, 19, 19);
- keyiter(k[ 12],r0,r4,r2, 20, 20); keyiter(k[ 13],r1,r0,r3, 21, 21);
- keyiter(k[ 14],r2,r1,r4, 22, 22); keyiter(k[ 15],r3,r2,r0, 23, 23);
- keyiter(k[ 16],r4,r3,r1, 24, 24); keyiter(k[ 17],r0,r4,r2, 25, 25);
- keyiter(k[ 18],r1,r0,r3, 26, 26); keyiter(k[ 19],r2,r1,r4, 27, 27);
- keyiter(k[ 20],r3,r2,r0, 28, 28); keyiter(k[ 21],r4,r3,r1, 29, 29);
- keyiter(k[ 22],r0,r4,r2, 30, 30); keyiter(k[ 23],r1,r0,r3, 31, 31);
-
- k += 50;
-
- keyiter(k[-26],r2,r1,r4, 32,-18); keyiter(k[-25],r3,r2,r0, 33,-17);
- keyiter(k[-24],r4,r3,r1, 34,-16); keyiter(k[-23],r0,r4,r2, 35,-15);
- keyiter(k[-22],r1,r0,r3, 36,-14); keyiter(k[-21],r2,r1,r4, 37,-13);
- keyiter(k[-20],r3,r2,r0, 38,-12); keyiter(k[-19],r4,r3,r1, 39,-11);
- keyiter(k[-18],r0,r4,r2, 40,-10); keyiter(k[-17],r1,r0,r3, 41, -9);
- keyiter(k[-16],r2,r1,r4, 42, -8); keyiter(k[-15],r3,r2,r0, 43, -7);
- keyiter(k[-14],r4,r3,r1, 44, -6); keyiter(k[-13],r0,r4,r2, 45, -5);
- keyiter(k[-12],r1,r0,r3, 46, -4); keyiter(k[-11],r2,r1,r4, 47, -3);
- keyiter(k[-10],r3,r2,r0, 48, -2); keyiter(k[ -9],r4,r3,r1, 49, -1);
- keyiter(k[ -8],r0,r4,r2, 50, 0); keyiter(k[ -7],r1,r0,r3, 51, 1);
- keyiter(k[ -6],r2,r1,r4, 52, 2); keyiter(k[ -5],r3,r2,r0, 53, 3);
- keyiter(k[ -4],r4,r3,r1, 54, 4); keyiter(k[ -3],r0,r4,r2, 55, 5);
- keyiter(k[ -2],r1,r0,r3, 56, 6); keyiter(k[ -1],r2,r1,r4, 57, 7);
- keyiter(k[ 0],r3,r2,r0, 58, 8); keyiter(k[ 1],r4,r3,r1, 59, 9);
- keyiter(k[ 2],r0,r4,r2, 60, 10); keyiter(k[ 3],r1,r0,r3, 61, 11);
- keyiter(k[ 4],r2,r1,r4, 62, 12); keyiter(k[ 5],r3,r2,r0, 63, 13);
- keyiter(k[ 6],r4,r3,r1, 64, 14); keyiter(k[ 7],r0,r4,r2, 65, 15);
- keyiter(k[ 8],r1,r0,r3, 66, 16); keyiter(k[ 9],r2,r1,r4, 67, 17);
- keyiter(k[ 10],r3,r2,r0, 68, 18); keyiter(k[ 11],r4,r3,r1, 69, 19);
- keyiter(k[ 12],r0,r4,r2, 70, 20); keyiter(k[ 13],r1,r0,r3, 71, 21);
- keyiter(k[ 14],r2,r1,r4, 72, 22); keyiter(k[ 15],r3,r2,r0, 73, 23);
- keyiter(k[ 16],r4,r3,r1, 74, 24); keyiter(k[ 17],r0,r4,r2, 75, 25);
- keyiter(k[ 18],r1,r0,r3, 76, 26); keyiter(k[ 19],r2,r1,r4, 77, 27);
- keyiter(k[ 20],r3,r2,r0, 78, 28); keyiter(k[ 21],r4,r3,r1, 79, 29);
- keyiter(k[ 22],r0,r4,r2, 80, 30); keyiter(k[ 23],r1,r0,r3, 81, 31);
-
- k += 50;
-
- keyiter(k[-26],r2,r1,r4, 82,-18); keyiter(k[-25],r3,r2,r0, 83,-17);
- keyiter(k[-24],r4,r3,r1, 84,-16); keyiter(k[-23],r0,r4,r2, 85,-15);
- keyiter(k[-22],r1,r0,r3, 86,-14); keyiter(k[-21],r2,r1,r4, 87,-13);
- keyiter(k[-20],r3,r2,r0, 88,-12); keyiter(k[-19],r4,r3,r1, 89,-11);
- keyiter(k[-18],r0,r4,r2, 90,-10); keyiter(k[-17],r1,r0,r3, 91, -9);
- keyiter(k[-16],r2,r1,r4, 92, -8); keyiter(k[-15],r3,r2,r0, 93, -7);
- keyiter(k[-14],r4,r3,r1, 94, -6); keyiter(k[-13],r0,r4,r2, 95, -5);
- keyiter(k[-12],r1,r0,r3, 96, -4); keyiter(k[-11],r2,r1,r4, 97, -3);
- keyiter(k[-10],r3,r2,r0, 98, -2); keyiter(k[ -9],r4,r3,r1, 99, -1);
- keyiter(k[ -8],r0,r4,r2,100, 0); keyiter(k[ -7],r1,r0,r3,101, 1);
- keyiter(k[ -6],r2,r1,r4,102, 2); keyiter(k[ -5],r3,r2,r0,103, 3);
- keyiter(k[ -4],r4,r3,r1,104, 4); keyiter(k[ -3],r0,r4,r2,105, 5);
- keyiter(k[ -2],r1,r0,r3,106, 6); keyiter(k[ -1],r2,r1,r4,107, 7);
- keyiter(k[ 0],r3,r2,r0,108, 8); keyiter(k[ 1],r4,r3,r1,109, 9);
- keyiter(k[ 2],r0,r4,r2,110, 10); keyiter(k[ 3],r1,r0,r3,111, 11);
- keyiter(k[ 4],r2,r1,r4,112, 12); keyiter(k[ 5],r3,r2,r0,113, 13);
- keyiter(k[ 6],r4,r3,r1,114, 14); keyiter(k[ 7],r0,r4,r2,115, 15);
- keyiter(k[ 8],r1,r0,r3,116, 16); keyiter(k[ 9],r2,r1,r4,117, 17);
- keyiter(k[ 10],r3,r2,r0,118, 18); keyiter(k[ 11],r4,r3,r1,119, 19);
- keyiter(k[ 12],r0,r4,r2,120, 20); keyiter(k[ 13],r1,r0,r3,121, 21);
- keyiter(k[ 14],r2,r1,r4,122, 22); keyiter(k[ 15],r3,r2,r0,123, 23);
- keyiter(k[ 16],r4,r3,r1,124, 24); keyiter(k[ 17],r0,r4,r2,125, 25);
- keyiter(k[ 18],r1,r0,r3,126, 26); keyiter(k[ 19],r2,r1,r4,127, 27);
- keyiter(k[ 20],r3,r2,r0,128, 28); keyiter(k[ 21],r4,r3,r1,129, 29);
- keyiter(k[ 22],r0,r4,r2,130, 30); keyiter(k[ 23],r1,r0,r3,131, 31);
-
- /* Apply S-boxes */
-
- S3(r3,r4,r0,r1,r2); storekeys(r1,r2,r4,r3, 28); loadkeys(r1,r2,r4,r3, 24);
- S4(r1,r2,r4,r3,r0); storekeys(r2,r4,r3,r0, 24); loadkeys(r2,r4,r3,r0, 20);
- S5(r2,r4,r3,r0,r1); storekeys(r1,r2,r4,r0, 20); loadkeys(r1,r2,r4,r0, 16);
- S6(r1,r2,r4,r0,r3); storekeys(r4,r3,r2,r0, 16); loadkeys(r4,r3,r2,r0, 12);
- S7(r4,r3,r2,r0,r1); storekeys(r1,r2,r0,r4, 12); loadkeys(r1,r2,r0,r4, 8);
- S0(r1,r2,r0,r4,r3); storekeys(r0,r2,r4,r1, 8); loadkeys(r0,r2,r4,r1, 4);
- S1(r0,r2,r4,r1,r3); storekeys(r3,r4,r1,r0, 4); loadkeys(r3,r4,r1,r0, 0);
- S2(r3,r4,r1,r0,r2); storekeys(r2,r4,r3,r0, 0); loadkeys(r2,r4,r3,r0, -4);
- S3(r2,r4,r3,r0,r1); storekeys(r0,r1,r4,r2, -4); loadkeys(r0,r1,r4,r2, -8);
- S4(r0,r1,r4,r2,r3); storekeys(r1,r4,r2,r3, -8); loadkeys(r1,r4,r2,r3,-12);
- S5(r1,r4,r2,r3,r0); storekeys(r0,r1,r4,r3,-12); loadkeys(r0,r1,r4,r3,-16);
- S6(r0,r1,r4,r3,r2); storekeys(r4,r2,r1,r3,-16); loadkeys(r4,r2,r1,r3,-20);
- S7(r4,r2,r1,r3,r0); storekeys(r0,r1,r3,r4,-20); loadkeys(r0,r1,r3,r4,-24);
- S0(r0,r1,r3,r4,r2); storekeys(r3,r1,r4,r0,-24); loadkeys(r3,r1,r4,r0,-28);
- k -= 50;
- S1(r3,r1,r4,r0,r2); storekeys(r2,r4,r0,r3, 22); loadkeys(r2,r4,r0,r3, 18);
- S2(r2,r4,r0,r3,r1); storekeys(r1,r4,r2,r3, 18); loadkeys(r1,r4,r2,r3, 14);
- S3(r1,r4,r2,r3,r0); storekeys(r3,r0,r4,r1, 14); loadkeys(r3,r0,r4,r1, 10);
- S4(r3,r0,r4,r1,r2); storekeys(r0,r4,r1,r2, 10); loadkeys(r0,r4,r1,r2, 6);
- S5(r0,r4,r1,r2,r3); storekeys(r3,r0,r4,r2, 6); loadkeys(r3,r0,r4,r2, 2);
- S6(r3,r0,r4,r2,r1); storekeys(r4,r1,r0,r2, 2); loadkeys(r4,r1,r0,r2, -2);
- S7(r4,r1,r0,r2,r3); storekeys(r3,r0,r2,r4, -2); loadkeys(r3,r0,r2,r4, -6);
- S0(r3,r0,r2,r4,r1); storekeys(r2,r0,r4,r3, -6); loadkeys(r2,r0,r4,r3,-10);
- S1(r2,r0,r4,r3,r1); storekeys(r1,r4,r3,r2,-10); loadkeys(r1,r4,r3,r2,-14);
- S2(r1,r4,r3,r2,r0); storekeys(r0,r4,r1,r2,-14); loadkeys(r0,r4,r1,r2,-18);
- S3(r0,r4,r1,r2,r3); storekeys(r2,r3,r4,r0,-18); loadkeys(r2,r3,r4,r0,-22);
- k -= 50;
- S4(r2,r3,r4,r0,r1); storekeys(r3,r4,r0,r1, 28); loadkeys(r3,r4,r0,r1, 24);
- S5(r3,r4,r0,r1,r2); storekeys(r2,r3,r4,r1, 24); loadkeys(r2,r3,r4,r1, 20);
- S6(r2,r3,r4,r1,r0); storekeys(r4,r0,r3,r1, 20); loadkeys(r4,r0,r3,r1, 16);
- S7(r4,r0,r3,r1,r2); storekeys(r2,r3,r1,r4, 16); loadkeys(r2,r3,r1,r4, 12);
- S0(r2,r3,r1,r4,r0); storekeys(r1,r3,r4,r2, 12); loadkeys(r1,r3,r4,r2, 8);
- S1(r1,r3,r4,r2,r0); storekeys(r0,r4,r2,r1, 8); loadkeys(r0,r4,r2,r1, 4);
- S2(r0,r4,r2,r1,r3); storekeys(r3,r4,r0,r1, 4); loadkeys(r3,r4,r0,r1, 0);
- S3(r3,r4,r0,r1,r2); storekeys(r1,r2,r4,r3, 0);
-
- return 0;
-}
-
-static void serpent_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
-{
- struct serpent_ctx *ctx = crypto_tfm_ctx(tfm);
- const u32
- *k = ctx->expkey;
- const __le32 *s = (const __le32 *)src;
- __le32 *d = (__le32 *)dst;
- u32 r0, r1, r2, r3, r4;
-
-/*
- * Note: The conversions between u8* and u32* might cause trouble
- * on architectures with stricter alignment rules than x86
- */
-
- r0 = le32_to_cpu(s[0]);
- r1 = le32_to_cpu(s[1]);
- r2 = le32_to_cpu(s[2]);
- r3 = le32_to_cpu(s[3]);
-
- K(r0,r1,r2,r3,0);
- S0(r0,r1,r2,r3,r4); LK(r2,r1,r3,r0,r4,1);
- S1(r2,r1,r3,r0,r4); LK(r4,r3,r0,r2,r1,2);
- S2(r4,r3,r0,r2,r1); LK(r1,r3,r4,r2,r0,3);
- S3(r1,r3,r4,r2,r0); LK(r2,r0,r3,r1,r4,4);
- S4(r2,r0,r3,r1,r4); LK(r0,r3,r1,r4,r2,5);
- S5(r0,r3,r1,r4,r2); LK(r2,r0,r3,r4,r1,6);
- S6(r2,r0,r3,r4,r1); LK(r3,r1,r0,r4,r2,7);
- S7(r3,r1,r0,r4,r2); LK(r2,r0,r4,r3,r1,8);
- S0(r2,r0,r4,r3,r1); LK(r4,r0,r3,r2,r1,9);
- S1(r4,r0,r3,r2,r1); LK(r1,r3,r2,r4,r0,10);
- S2(r1,r3,r2,r4,r0); LK(r0,r3,r1,r4,r2,11);
- S3(r0,r3,r1,r4,r2); LK(r4,r2,r3,r0,r1,12);
- S4(r4,r2,r3,r0,r1); LK(r2,r3,r0,r1,r4,13);
- S5(r2,r3,r0,r1,r4); LK(r4,r2,r3,r1,r0,14);
- S6(r4,r2,r3,r1,r0); LK(r3,r0,r2,r1,r4,15);
- S7(r3,r0,r2,r1,r4); LK(r4,r2,r1,r3,r0,16);
- S0(r4,r2,r1,r3,r0); LK(r1,r2,r3,r4,r0,17);
- S1(r1,r2,r3,r4,r0); LK(r0,r3,r4,r1,r2,18);
- S2(r0,r3,r4,r1,r2); LK(r2,r3,r0,r1,r4,19);
- S3(r2,r3,r0,r1,r4); LK(r1,r4,r3,r2,r0,20);
- S4(r1,r4,r3,r2,r0); LK(r4,r3,r2,r0,r1,21);
- S5(r4,r3,r2,r0,r1); LK(r1,r4,r3,r0,r2,22);
- S6(r1,r4,r3,r0,r2); LK(r3,r2,r4,r0,r1,23);
- S7(r3,r2,r4,r0,r1); LK(r1,r4,r0,r3,r2,24);
- S0(r1,r4,r0,r3,r2); LK(r0,r4,r3,r1,r2,25);
- S1(r0,r4,r3,r1,r2); LK(r2,r3,r1,r0,r4,26);
- S2(r2,r3,r1,r0,r4); LK(r4,r3,r2,r0,r1,27);
- S3(r4,r3,r2,r0,r1); LK(r0,r1,r3,r4,r2,28);
- S4(r0,r1,r3,r4,r2); LK(r1,r3,r4,r2,r0,29);
- S5(r1,r3,r4,r2,r0); LK(r0,r1,r3,r2,r4,30);
- S6(r0,r1,r3,r2,r4); LK(r3,r4,r1,r2,r0,31);
- S7(r3,r4,r1,r2,r0); K(r0,r1,r2,r3,32);
-
- d[0] = cpu_to_le32(r0);
- d[1] = cpu_to_le32(r1);
- d[2] = cpu_to_le32(r2);
- d[3] = cpu_to_le32(r3);
-}
-
-static void serpent_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
-{
- struct serpent_ctx *ctx = crypto_tfm_ctx(tfm);
- const u32
- *k = ((struct serpent_ctx *)ctx)->expkey;
- const __le32 *s = (const __le32 *)src;
- __le32 *d = (__le32 *)dst;
- u32 r0, r1, r2, r3, r4;
-
- r0 = le32_to_cpu(s[0]);
- r1 = le32_to_cpu(s[1]);
- r2 = le32_to_cpu(s[2]);
- r3 = le32_to_cpu(s[3]);
-
- K(r0,r1,r2,r3,32);
- SI7(r0,r1,r2,r3,r4); KL(r1,r3,r0,r4,r2,31);
- SI6(r1,r3,r0,r4,r2); KL(r0,r2,r4,r1,r3,30);
- SI5(r0,r2,r4,r1,r3); KL(r2,r3,r0,r4,r1,29);
- SI4(r2,r3,r0,r4,r1); KL(r2,r0,r1,r4,r3,28);
- SI3(r2,r0,r1,r4,r3); KL(r1,r2,r3,r4,r0,27);
- SI2(r1,r2,r3,r4,r0); KL(r2,r0,r4,r3,r1,26);
- SI1(r2,r0,r4,r3,r1); KL(r1,r0,r4,r3,r2,25);
- SI0(r1,r0,r4,r3,r2); KL(r4,r2,r0,r1,r3,24);
- SI7(r4,r2,r0,r1,r3); KL(r2,r1,r4,r3,r0,23);
- SI6(r2,r1,r4,r3,r0); KL(r4,r0,r3,r2,r1,22);
- SI5(r4,r0,r3,r2,r1); KL(r0,r1,r4,r3,r2,21);
- SI4(r0,r1,r4,r3,r2); KL(r0,r4,r2,r3,r1,20);
- SI3(r0,r4,r2,r3,r1); KL(r2,r0,r1,r3,r4,19);
- SI2(r2,r0,r1,r3,r4); KL(r0,r4,r3,r1,r2,18);
- SI1(r0,r4,r3,r1,r2); KL(r2,r4,r3,r1,r0,17);
- SI0(r2,r4,r3,r1,r0); KL(r3,r0,r4,r2,r1,16);
- SI7(r3,r0,r4,r2,r1); KL(r0,r2,r3,r1,r4,15);
- SI6(r0,r2,r3,r1,r4); KL(r3,r4,r1,r0,r2,14);
- SI5(r3,r4,r1,r0,r2); KL(r4,r2,r3,r1,r0,13);
- SI4(r4,r2,r3,r1,r0); KL(r4,r3,r0,r1,r2,12);
- SI3(r4,r3,r0,r1,r2); KL(r0,r4,r2,r1,r3,11);
- SI2(r0,r4,r2,r1,r3); KL(r4,r3,r1,r2,r0,10);
- SI1(r4,r3,r1,r2,r0); KL(r0,r3,r1,r2,r4,9);
- SI0(r0,r3,r1,r2,r4); KL(r1,r4,r3,r0,r2,8);
- SI7(r1,r4,r3,r0,r2); KL(r4,r0,r1,r2,r3,7);
- SI6(r4,r0,r1,r2,r3); KL(r1,r3,r2,r4,r0,6);
- SI5(r1,r3,r2,r4,r0); KL(r3,r0,r1,r2,r4,5);
- SI4(r3,r0,r1,r2,r4); KL(r3,r1,r4,r2,r0,4);
- SI3(r3,r1,r4,r2,r0); KL(r4,r3,r0,r2,r1,3);
- SI2(r4,r3,r0,r2,r1); KL(r3,r1,r2,r0,r4,2);
- SI1(r3,r1,r2,r0,r4); KL(r4,r1,r2,r0,r3,1);
- SI0(r4,r1,r2,r0,r3); K(r2,r3,r1,r4,0);
-
- d[0] = cpu_to_le32(r2);
- d[1] = cpu_to_le32(r3);
- d[2] = cpu_to_le32(r1);
- d[3] = cpu_to_le32(r4);
-}
-
-static struct crypto_alg serpent_alg = {
- .cra_name = "serpent",
- .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
- .cra_blocksize = SERPENT_BLOCK_SIZE,
- .cra_ctxsize = sizeof(struct serpent_ctx),
- .cra_alignmask = 3,
- .cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(serpent_alg.cra_list),
- .cra_u = { .cipher = {
- .cia_min_keysize = SERPENT_MIN_KEY_SIZE,
- .cia_max_keysize = SERPENT_MAX_KEY_SIZE,
- .cia_setkey = serpent_setkey,
- .cia_encrypt = serpent_encrypt,
- .cia_decrypt = serpent_decrypt } }
-};
-
-static int tnepres_setkey(struct crypto_tfm *tfm, const u8 *key,
- unsigned int keylen)
-{
- u8 rev_key[SERPENT_MAX_KEY_SIZE];
- int i;
-
- for (i = 0; i < keylen; ++i)
- rev_key[keylen - i - 1] = key[i];
-
- return serpent_setkey(tfm, rev_key, keylen);
-}
-
-static void tnepres_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
-{
- const u32 * const s = (const u32 * const)src;
- u32 * const d = (u32 * const)dst;
-
- u32 rs[4], rd[4];
-
- rs[0] = swab32(s[3]);
- rs[1] = swab32(s[2]);
- rs[2] = swab32(s[1]);
- rs[3] = swab32(s[0]);
-
- serpent_encrypt(tfm, (u8 *)rd, (u8 *)rs);
-
- d[0] = swab32(rd[3]);
- d[1] = swab32(rd[2]);
- d[2] = swab32(rd[1]);
- d[3] = swab32(rd[0]);
-}
-
-static void tnepres_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
-{
- const u32 * const s = (const u32 * const)src;
- u32 * const d = (u32 * const)dst;
-
- u32 rs[4], rd[4];
-
- rs[0] = swab32(s[3]);
- rs[1] = swab32(s[2]);
- rs[2] = swab32(s[1]);
- rs[3] = swab32(s[0]);
-
- serpent_decrypt(tfm, (u8 *)rd, (u8 *)rs);
-
- d[0] = swab32(rd[3]);
- d[1] = swab32(rd[2]);
- d[2] = swab32(rd[1]);
- d[3] = swab32(rd[0]);
-}
-
-static struct crypto_alg tnepres_alg = {
- .cra_name = "tnepres",
- .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
- .cra_blocksize = SERPENT_BLOCK_SIZE,
- .cra_ctxsize = sizeof(struct serpent_ctx),
- .cra_alignmask = 3,
- .cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(serpent_alg.cra_list),
- .cra_u = { .cipher = {
- .cia_min_keysize = SERPENT_MIN_KEY_SIZE,
- .cia_max_keysize = SERPENT_MAX_KEY_SIZE,
- .cia_setkey = tnepres_setkey,
- .cia_encrypt = tnepres_encrypt,
- .cia_decrypt = tnepres_decrypt } }
-};
-
-static int __init serpent_mod_init(void)
-{
- int ret = crypto_register_alg(&serpent_alg);
-
- if (ret)
- return ret;
-
- ret = crypto_register_alg(&tnepres_alg);
-
- if (ret)
- crypto_unregister_alg(&serpent_alg);
-
- return ret;
-}
-
-static void __exit serpent_mod_fini(void)
-{
- crypto_unregister_alg(&tnepres_alg);
- crypto_unregister_alg(&serpent_alg);
-}
-
-module_init(serpent_mod_init);
-module_exit(serpent_mod_fini);
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("Serpent and tnepres (kerneli compatible serpent reversed) Cipher Algorithm");
-MODULE_AUTHOR("Dag Arne Osvik <osvik@ii.uib.no>");
-MODULE_ALIAS("tnepres");
diff --git a/crypto/serpent_generic.c b/crypto/serpent_generic.c
new file mode 100644
index 0000000..8f32cf3
--- /dev/null
+++ b/crypto/serpent_generic.c
@@ -0,0 +1,684 @@
+/*
+ * Cryptographic API.
+ *
+ * Serpent Cipher Algorithm.
+ *
+ * Copyright (C) 2002 Dag Arne Osvik <osvik@ii.uib.no>
+ * 2003 Herbert Valerio Riedel <hvr@gnu.org>
+ *
+ * Added tnepres support:
+ * Ruben Jesus Garcia Hernandez <ruben@ugr.es>, 18.10.2004
+ * Based on code by hvr
+ *
+ * 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.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <asm/byteorder.h>
+#include <linux/crypto.h>
+#include <linux/types.h>
+#include <crypto/serpent.h>
+
+/* Key is padded to the maximum of 256 bits before round key generation.
+ * Any key length <= 256 bits (32 bytes) is allowed by the algorithm.
+ */
+
+#define PHI 0x9e3779b9UL
+
+#define keyiter(a, b, c, d, i, j) \
+ ({ b ^= d; b ^= c; b ^= a; b ^= PHI ^ i; b = rol32(b, 11); k[j] = b; })
+
+#define loadkeys(x0, x1, x2, x3, i) \
+ ({ x0 = k[i]; x1 = k[i+1]; x2 = k[i+2]; x3 = k[i+3]; })
+
+#define storekeys(x0, x1, x2, x3, i) \
+ ({ k[i] = x0; k[i+1] = x1; k[i+2] = x2; k[i+3] = x3; })
+
+#define store_and_load_keys(x0, x1, x2, x3, s, l) \
+ ({ storekeys(x0, x1, x2, x3, s); loadkeys(x0, x1, x2, x3, l); })
+
+#define K(x0, x1, x2, x3, i) ({ \
+ x3 ^= k[4*(i)+3]; x2 ^= k[4*(i)+2]; \
+ x1 ^= k[4*(i)+1]; x0 ^= k[4*(i)+0]; \
+ })
+
+#define LK(x0, x1, x2, x3, x4, i) ({ \
+ x0 = rol32(x0, 13);\
+ x2 = rol32(x2, 3); x1 ^= x0; x4 = x0 << 3; \
+ x3 ^= x2; x1 ^= x2; \
+ x1 = rol32(x1, 1); x3 ^= x4; \
+ x3 = rol32(x3, 7); x4 = x1; \
+ x0 ^= x1; x4 <<= 7; x2 ^= x3; \
+ x0 ^= x3; x2 ^= x4; x3 ^= k[4*i+3]; \
+ x1 ^= k[4*i+1]; x0 = rol32(x0, 5); x2 = rol32(x2, 22);\
+ x0 ^= k[4*i+0]; x2 ^= k[4*i+2]; \
+ })
+
+#define KL(x0, x1, x2, x3, x4, i) ({ \
+ x0 ^= k[4*i+0]; x1 ^= k[4*i+1]; x2 ^= k[4*i+2]; \
+ x3 ^= k[4*i+3]; x0 = ror32(x0, 5); x2 = ror32(x2, 22);\
+ x4 = x1; x2 ^= x3; x0 ^= x3; \
+ x4 <<= 7; x0 ^= x1; x1 = ror32(x1, 1); \
+ x2 ^= x4; x3 = ror32(x3, 7); x4 = x0 << 3; \
+ x1 ^= x0; x3 ^= x4; x0 = ror32(x0, 13);\
+ x1 ^= x2; x3 ^= x2; x2 = ror32(x2, 3); \
+ })
+
+#define S0(x0, x1, x2, x3, x4) ({ \
+ x4 = x3; \
+ x3 |= x0; x0 ^= x4; x4 ^= x2; \
+ x4 = ~x4; x3 ^= x1; x1 &= x0; \
+ x1 ^= x4; x2 ^= x0; x0 ^= x3; \
+ x4 |= x0; x0 ^= x2; x2 &= x1; \
+ x3 ^= x2; x1 = ~x1; x2 ^= x4; \
+ x1 ^= x2; \
+ })
+
+#define S1(x0, x1, x2, x3, x4) ({ \
+ x4 = x1; \
+ x1 ^= x0; x0 ^= x3; x3 = ~x3; \
+ x4 &= x1; x0 |= x1; x3 ^= x2; \
+ x0 ^= x3; x1 ^= x3; x3 ^= x4; \
+ x1 |= x4; x4 ^= x2; x2 &= x0; \
+ x2 ^= x1; x1 |= x0; x0 = ~x0; \
+ x0 ^= x2; x4 ^= x1; \
+ })
+
+#define S2(x0, x1, x2, x3, x4) ({ \
+ x3 = ~x3; \
+ x1 ^= x0; x4 = x0; x0 &= x2; \
+ x0 ^= x3; x3 |= x4; x2 ^= x1; \
+ x3 ^= x1; x1 &= x0; x0 ^= x2; \
+ x2 &= x3; x3 |= x1; x0 = ~x0; \
+ x3 ^= x0; x4 ^= x0; x0 ^= x2; \
+ x1 |= x2; \
+ })
+
+#define S3(x0, x1, x2, x3, x4) ({ \
+ x4 = x1; \
+ x1 ^= x3; x3 |= x0; x4 &= x0; \
+ x0 ^= x2; x2 ^= x1; x1 &= x3; \
+ x2 ^= x3; x0 |= x4; x4 ^= x3; \
+ x1 ^= x0; x0 &= x3; x3 &= x4; \
+ x3 ^= x2; x4 |= x1; x2 &= x1; \
+ x4 ^= x3; x0 ^= x3; x3 ^= x2; \
+ })
+
+#define S4(x0, x1, x2, x3, x4) ({ \
+ x4 = x3; \
+ x3 &= x0; x0 ^= x4; \
+ x3 ^= x2; x2 |= x4; x0 ^= x1; \
+ x4 ^= x3; x2 |= x0; \
+ x2 ^= x1; x1 &= x0; \
+ x1 ^= x4; x4 &= x2; x2 ^= x3; \
+ x4 ^= x0; x3 |= x1; x1 = ~x1; \
+ x3 ^= x0; \
+ })
+
+#define S5(x0, x1, x2, x3, x4) ({ \
+ x4 = x1; x1 |= x0; \
+ x2 ^= x1; x3 = ~x3; x4 ^= x0; \
+ x0 ^= x2; x1 &= x4; x4 |= x3; \
+ x4 ^= x0; x0 &= x3; x1 ^= x3; \
+ x3 ^= x2; x0 ^= x1; x2 &= x4; \
+ x1 ^= x2; x2 &= x0; \
+ x3 ^= x2; \
+ })
+
+#define S6(x0, x1, x2, x3, x4) ({ \
+ x4 = x1; \
+ x3 ^= x0; x1 ^= x2; x2 ^= x0; \
+ x0 &= x3; x1 |= x3; x4 = ~x4; \
+ x0 ^= x1; x1 ^= x2; \
+ x3 ^= x4; x4 ^= x0; x2 &= x0; \
+ x4 ^= x1; x2 ^= x3; x3 &= x1; \
+ x3 ^= x0; x1 ^= x2; \
+ })
+
+#define S7(x0, x1, x2, x3, x4) ({ \
+ x1 = ~x1; \
+ x4 = x1; x0 = ~x0; x1 &= x2; \
+ x1 ^= x3; x3 |= x4; x4 ^= x2; \
+ x2 ^= x3; x3 ^= x0; x0 |= x1; \
+ x2 &= x0; x0 ^= x4; x4 ^= x3; \
+ x3 &= x0; x4 ^= x1; \
+ x2 ^= x4; x3 ^= x1; x4 |= x0; \
+ x4 ^= x1; \
+ })
+
+#define SI0(x0, x1, x2, x3, x4) ({ \
+ x4 = x3; x1 ^= x0; \
+ x3 |= x1; x4 ^= x1; x0 = ~x0; \
+ x2 ^= x3; x3 ^= x0; x0 &= x1; \
+ x0 ^= x2; x2 &= x3; x3 ^= x4; \
+ x2 ^= x3; x1 ^= x3; x3 &= x0; \
+ x1 ^= x0; x0 ^= x2; x4 ^= x3; \
+ })
+
+#define SI1(x0, x1, x2, x3, x4) ({ \
+ x1 ^= x3; x4 = x0; \
+ x0 ^= x2; x2 = ~x2; x4 |= x1; \
+ x4 ^= x3; x3 &= x1; x1 ^= x2; \
+ x2 &= x4; x4 ^= x1; x1 |= x3; \
+ x3 ^= x0; x2 ^= x0; x0 |= x4; \
+ x2 ^= x4; x1 ^= x0; \
+ x4 ^= x1; \
+ })
+
+#define SI2(x0, x1, x2, x3, x4) ({ \
+ x2 ^= x1; x4 = x3; x3 = ~x3; \
+ x3 |= x2; x2 ^= x4; x4 ^= x0; \
+ x3 ^= x1; x1 |= x2; x2 ^= x0; \
+ x1 ^= x4; x4 |= x3; x2 ^= x3; \
+ x4 ^= x2; x2 &= x1; \
+ x2 ^= x3; x3 ^= x4; x4 ^= x0; \
+ })
+
+#define SI3(x0, x1, x2, x3, x4) ({ \
+ x2 ^= x1; \
+ x4 = x1; x1 &= x2; \
+ x1 ^= x0; x0 |= x4; x4 ^= x3; \
+ x0 ^= x3; x3 |= x1; x1 ^= x2; \
+ x1 ^= x3; x0 ^= x2; x2 ^= x3; \
+ x3 &= x1; x1 ^= x0; x0 &= x2; \
+ x4 ^= x3; x3 ^= x0; x0 ^= x1; \
+ })
+
+#define SI4(x0, x1, x2, x3, x4) ({ \
+ x2 ^= x3; x4 = x0; x0 &= x1; \
+ x0 ^= x2; x2 |= x3; x4 = ~x4; \
+ x1 ^= x0; x0 ^= x2; x2 &= x4; \
+ x2 ^= x0; x0 |= x4; \
+ x0 ^= x3; x3 &= x2; \
+ x4 ^= x3; x3 ^= x1; x1 &= x0; \
+ x4 ^= x1; x0 ^= x3; \
+ })
+
+#define SI5(x0, x1, x2, x3, x4) ({ \
+ x4 = x1; x1 |= x2; \
+ x2 ^= x4; x1 ^= x3; x3 &= x4; \
+ x2 ^= x3; x3 |= x0; x0 = ~x0; \
+ x3 ^= x2; x2 |= x0; x4 ^= x1; \
+ x2 ^= x4; x4 &= x0; x0 ^= x1; \
+ x1 ^= x3; x0 &= x2; x2 ^= x3; \
+ x0 ^= x2; x2 ^= x4; x4 ^= x3; \
+ })
+
+#define SI6(x0, x1, x2, x3, x4) ({ \
+ x0 ^= x2; \
+ x4 = x0; x0 &= x3; x2 ^= x3; \
+ x0 ^= x2; x3 ^= x1; x2 |= x4; \
+ x2 ^= x3; x3 &= x0; x0 = ~x0; \
+ x3 ^= x1; x1 &= x2; x4 ^= x0; \
+ x3 ^= x4; x4 ^= x2; x0 ^= x1; \
+ x2 ^= x0; \
+ })
+
+#define SI7(x0, x1, x2, x3, x4) ({ \
+ x4 = x3; x3 &= x0; x0 ^= x2; \
+ x2 |= x4; x4 ^= x1; x0 = ~x0; \
+ x1 |= x3; x4 ^= x0; x0 &= x2; \
+ x0 ^= x1; x1 &= x2; x3 ^= x2; \
+ x4 ^= x3; x2 &= x3; x3 |= x0; \
+ x1 ^= x4; x3 ^= x4; x4 &= x0; \
+ x4 ^= x2; \
+ })
+
+int __serpent_setkey(struct serpent_ctx *ctx, const u8 *key,
+ unsigned int keylen)
+{
+ u32 *k = ctx->expkey;
+ u8 *k8 = (u8 *)k;
+ u32 r0, r1, r2, r3, r4;
+ int i;
+
+ /* Copy key, add padding */
+
+ for (i = 0; i < keylen; ++i)
+ k8[i] = key[i];
+ if (i < SERPENT_MAX_KEY_SIZE)
+ k8[i++] = 1;
+ while (i < SERPENT_MAX_KEY_SIZE)
+ k8[i++] = 0;
+
+ /* Expand key using polynomial */
+
+ r0 = le32_to_cpu(k[3]);
+ r1 = le32_to_cpu(k[4]);
+ r2 = le32_to_cpu(k[5]);
+ r3 = le32_to_cpu(k[6]);
+ r4 = le32_to_cpu(k[7]);
+
+ keyiter(le32_to_cpu(k[0]), r0, r4, r2, 0, 0);
+ keyiter(le32_to_cpu(k[1]), r1, r0, r3, 1, 1);
+ keyiter(le32_to_cpu(k[2]), r2, r1, r4, 2, 2);
+ keyiter(le32_to_cpu(k[3]), r3, r2, r0, 3, 3);
+ keyiter(le32_to_cpu(k[4]), r4, r3, r1, 4, 4);
+ keyiter(le32_to_cpu(k[5]), r0, r4, r2, 5, 5);
+ keyiter(le32_to_cpu(k[6]), r1, r0, r3, 6, 6);
+ keyiter(le32_to_cpu(k[7]), r2, r1, r4, 7, 7);
+
+ keyiter(k[0], r3, r2, r0, 8, 8);
+ keyiter(k[1], r4, r3, r1, 9, 9);
+ keyiter(k[2], r0, r4, r2, 10, 10);
+ keyiter(k[3], r1, r0, r3, 11, 11);
+ keyiter(k[4], r2, r1, r4, 12, 12);
+ keyiter(k[5], r3, r2, r0, 13, 13);
+ keyiter(k[6], r4, r3, r1, 14, 14);
+ keyiter(k[7], r0, r4, r2, 15, 15);
+ keyiter(k[8], r1, r0, r3, 16, 16);
+ keyiter(k[9], r2, r1, r4, 17, 17);
+ keyiter(k[10], r3, r2, r0, 18, 18);
+ keyiter(k[11], r4, r3, r1, 19, 19);
+ keyiter(k[12], r0, r4, r2, 20, 20);
+ keyiter(k[13], r1, r0, r3, 21, 21);
+ keyiter(k[14], r2, r1, r4, 22, 22);
+ keyiter(k[15], r3, r2, r0, 23, 23);
+ keyiter(k[16], r4, r3, r1, 24, 24);
+ keyiter(k[17], r0, r4, r2, 25, 25);
+ keyiter(k[18], r1, r0, r3, 26, 26);
+ keyiter(k[19], r2, r1, r4, 27, 27);
+ keyiter(k[20], r3, r2, r0, 28, 28);
+ keyiter(k[21], r4, r3, r1, 29, 29);
+ keyiter(k[22], r0, r4, r2, 30, 30);
+ keyiter(k[23], r1, r0, r3, 31, 31);
+
+ k += 50;
+
+ keyiter(k[-26], r2, r1, r4, 32, -18);
+ keyiter(k[-25], r3, r2, r0, 33, -17);
+ keyiter(k[-24], r4, r3, r1, 34, -16);
+ keyiter(k[-23], r0, r4, r2, 35, -15);
+ keyiter(k[-22], r1, r0, r3, 36, -14);
+ keyiter(k[-21], r2, r1, r4, 37, -13);
+ keyiter(k[-20], r3, r2, r0, 38, -12);
+ keyiter(k[-19], r4, r3, r1, 39, -11);
+ keyiter(k[-18], r0, r4, r2, 40, -10);
+ keyiter(k[-17], r1, r0, r3, 41, -9);
+ keyiter(k[-16], r2, r1, r4, 42, -8);
+ keyiter(k[-15], r3, r2, r0, 43, -7);
+ keyiter(k[-14], r4, r3, r1, 44, -6);
+ keyiter(k[-13], r0, r4, r2, 45, -5);
+ keyiter(k[-12], r1, r0, r3, 46, -4);
+ keyiter(k[-11], r2, r1, r4, 47, -3);
+ keyiter(k[-10], r3, r2, r0, 48, -2);
+ keyiter(k[-9], r4, r3, r1, 49, -1);
+ keyiter(k[-8], r0, r4, r2, 50, 0);
+ keyiter(k[-7], r1, r0, r3, 51, 1);
+ keyiter(k[-6], r2, r1, r4, 52, 2);
+ keyiter(k[-5], r3, r2, r0, 53, 3);
+ keyiter(k[-4], r4, r3, r1, 54, 4);
+ keyiter(k[-3], r0, r4, r2, 55, 5);
+ keyiter(k[-2], r1, r0, r3, 56, 6);
+ keyiter(k[-1], r2, r1, r4, 57, 7);
+ keyiter(k[0], r3, r2, r0, 58, 8);
+ keyiter(k[1], r4, r3, r1, 59, 9);
+ keyiter(k[2], r0, r4, r2, 60, 10);
+ keyiter(k[3], r1, r0, r3, 61, 11);
+ keyiter(k[4], r2, r1, r4, 62, 12);
+ keyiter(k[5], r3, r2, r0, 63, 13);
+ keyiter(k[6], r4, r3, r1, 64, 14);
+ keyiter(k[7], r0, r4, r2, 65, 15);
+ keyiter(k[8], r1, r0, r3, 66, 16);
+ keyiter(k[9], r2, r1, r4, 67, 17);
+ keyiter(k[10], r3, r2, r0, 68, 18);
+ keyiter(k[11], r4, r3, r1, 69, 19);
+ keyiter(k[12], r0, r4, r2, 70, 20);
+ keyiter(k[13], r1, r0, r3, 71, 21);
+ keyiter(k[14], r2, r1, r4, 72, 22);
+ keyiter(k[15], r3, r2, r0, 73, 23);
+ keyiter(k[16], r4, r3, r1, 74, 24);
+ keyiter(k[17], r0, r4, r2, 75, 25);
+ keyiter(k[18], r1, r0, r3, 76, 26);
+ keyiter(k[19], r2, r1, r4, 77, 27);
+ keyiter(k[20], r3, r2, r0, 78, 28);
+ keyiter(k[21], r4, r3, r1, 79, 29);
+ keyiter(k[22], r0, r4, r2, 80, 30);
+ keyiter(k[23], r1, r0, r3, 81, 31);
+
+ k += 50;
+
+ keyiter(k[-26], r2, r1, r4, 82, -18);
+ keyiter(k[-25], r3, r2, r0, 83, -17);
+ keyiter(k[-24], r4, r3, r1, 84, -16);
+ keyiter(k[-23], r0, r4, r2, 85, -15);
+ keyiter(k[-22], r1, r0, r3, 86, -14);
+ keyiter(k[-21], r2, r1, r4, 87, -13);
+ keyiter(k[-20], r3, r2, r0, 88, -12);
+ keyiter(k[-19], r4, r3, r1, 89, -11);
+ keyiter(k[-18], r0, r4, r2, 90, -10);
+ keyiter(k[-17], r1, r0, r3, 91, -9);
+ keyiter(k[-16], r2, r1, r4, 92, -8);
+ keyiter(k[-15], r3, r2, r0, 93, -7);
+ keyiter(k[-14], r4, r3, r1, 94, -6);
+ keyiter(k[-13], r0, r4, r2, 95, -5);
+ keyiter(k[-12], r1, r0, r3, 96, -4);
+ keyiter(k[-11], r2, r1, r4, 97, -3);
+ keyiter(k[-10], r3, r2, r0, 98, -2);
+ keyiter(k[-9], r4, r3, r1, 99, -1);
+ keyiter(k[-8], r0, r4, r2, 100, 0);
+ keyiter(k[-7], r1, r0, r3, 101, 1);
+ keyiter(k[-6], r2, r1, r4, 102, 2);
+ keyiter(k[-5], r3, r2, r0, 103, 3);
+ keyiter(k[-4], r4, r3, r1, 104, 4);
+ keyiter(k[-3], r0, r4, r2, 105, 5);
+ keyiter(k[-2], r1, r0, r3, 106, 6);
+ keyiter(k[-1], r2, r1, r4, 107, 7);
+ keyiter(k[0], r3, r2, r0, 108, 8);
+ keyiter(k[1], r4, r3, r1, 109, 9);
+ keyiter(k[2], r0, r4, r2, 110, 10);
+ keyiter(k[3], r1, r0, r3, 111, 11);
+ keyiter(k[4], r2, r1, r4, 112, 12);
+ keyiter(k[5], r3, r2, r0, 113, 13);
+ keyiter(k[6], r4, r3, r1, 114, 14);
+ keyiter(k[7], r0, r4, r2, 115, 15);
+ keyiter(k[8], r1, r0, r3, 116, 16);
+ keyiter(k[9], r2, r1, r4, 117, 17);
+ keyiter(k[10], r3, r2, r0, 118, 18);
+ keyiter(k[11], r4, r3, r1, 119, 19);
+ keyiter(k[12], r0, r4, r2, 120, 20);
+ keyiter(k[13], r1, r0, r3, 121, 21);
+ keyiter(k[14], r2, r1, r4, 122, 22);
+ keyiter(k[15], r3, r2, r0, 123, 23);
+ keyiter(k[16], r4, r3, r1, 124, 24);
+ keyiter(k[17], r0, r4, r2, 125, 25);
+ keyiter(k[18], r1, r0, r3, 126, 26);
+ keyiter(k[19], r2, r1, r4, 127, 27);
+ keyiter(k[20], r3, r2, r0, 128, 28);
+ keyiter(k[21], r4, r3, r1, 129, 29);
+ keyiter(k[22], r0, r4, r2, 130, 30);
+ keyiter(k[23], r1, r0, r3, 131, 31);
+
+ /* Apply S-boxes */
+
+ S3(r3, r4, r0, r1, r2); store_and_load_keys(r1, r2, r4, r3, 28, 24);
+ S4(r1, r2, r4, r3, r0); store_and_load_keys(r2, r4, r3, r0, 24, 20);
+ S5(r2, r4, r3, r0, r1); store_and_load_keys(r1, r2, r4, r0, 20, 16);
+ S6(r1, r2, r4, r0, r3); store_and_load_keys(r4, r3, r2, r0, 16, 12);
+ S7(r4, r3, r2, r0, r1); store_and_load_keys(r1, r2, r0, r4, 12, 8);
+ S0(r1, r2, r0, r4, r3); store_and_load_keys(r0, r2, r4, r1, 8, 4);
+ S1(r0, r2, r4, r1, r3); store_and_load_keys(r3, r4, r1, r0, 4, 0);
+ S2(r3, r4, r1, r0, r2); store_and_load_keys(r2, r4, r3, r0, 0, -4);
+ S3(r2, r4, r3, r0, r1); store_and_load_keys(r0, r1, r4, r2, -4, -8);
+ S4(r0, r1, r4, r2, r3); store_and_load_keys(r1, r4, r2, r3, -8, -12);
+ S5(r1, r4, r2, r3, r0); store_and_load_keys(r0, r1, r4, r3, -12, -16);
+ S6(r0, r1, r4, r3, r2); store_and_load_keys(r4, r2, r1, r3, -16, -20);
+ S7(r4, r2, r1, r3, r0); store_and_load_keys(r0, r1, r3, r4, -20, -24);
+ S0(r0, r1, r3, r4, r2); store_and_load_keys(r3, r1, r4, r0, -24, -28);
+ k -= 50;
+ S1(r3, r1, r4, r0, r2); store_and_load_keys(r2, r4, r0, r3, 22, 18);
+ S2(r2, r4, r0, r3, r1); store_and_load_keys(r1, r4, r2, r3, 18, 14);
+ S3(r1, r4, r2, r3, r0); store_and_load_keys(r3, r0, r4, r1, 14, 10);
+ S4(r3, r0, r4, r1, r2); store_and_load_keys(r0, r4, r1, r2, 10, 6);
+ S5(r0, r4, r1, r2, r3); store_and_load_keys(r3, r0, r4, r2, 6, 2);
+ S6(r3, r0, r4, r2, r1); store_and_load_keys(r4, r1, r0, r2, 2, -2);
+ S7(r4, r1, r0, r2, r3); store_and_load_keys(r3, r0, r2, r4, -2, -6);
+ S0(r3, r0, r2, r4, r1); store_and_load_keys(r2, r0, r4, r3, -6, -10);
+ S1(r2, r0, r4, r3, r1); store_and_load_keys(r1, r4, r3, r2, -10, -14);
+ S2(r1, r4, r3, r2, r0); store_and_load_keys(r0, r4, r1, r2, -14, -18);
+ S3(r0, r4, r1, r2, r3); store_and_load_keys(r2, r3, r4, r0, -18, -22);
+ k -= 50;
+ S4(r2, r3, r4, r0, r1); store_and_load_keys(r3, r4, r0, r1, 28, 24);
+ S5(r3, r4, r0, r1, r2); store_and_load_keys(r2, r3, r4, r1, 24, 20);
+ S6(r2, r3, r4, r1, r0); store_and_load_keys(r4, r0, r3, r1, 20, 16);
+ S7(r4, r0, r3, r1, r2); store_and_load_keys(r2, r3, r1, r4, 16, 12);
+ S0(r2, r3, r1, r4, r0); store_and_load_keys(r1, r3, r4, r2, 12, 8);
+ S1(r1, r3, r4, r2, r0); store_and_load_keys(r0, r4, r2, r1, 8, 4);
+ S2(r0, r4, r2, r1, r3); store_and_load_keys(r3, r4, r0, r1, 4, 0);
+ S3(r3, r4, r0, r1, r2); storekeys(r1, r2, r4, r3, 0);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(__serpent_setkey);
+
+int serpent_setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen)
+{
+ return __serpent_setkey(crypto_tfm_ctx(tfm), key, keylen);
+}
+EXPORT_SYMBOL_GPL(serpent_setkey);
+
+void __serpent_encrypt(struct serpent_ctx *ctx, u8 *dst, const u8 *src)
+{
+ const u32 *k = ctx->expkey;
+ const __le32 *s = (const __le32 *)src;
+ __le32 *d = (__le32 *)dst;
+ u32 r0, r1, r2, r3, r4;
+
+/*
+ * Note: The conversions between u8* and u32* might cause trouble
+ * on architectures with stricter alignment rules than x86
+ */
+
+ r0 = le32_to_cpu(s[0]);
+ r1 = le32_to_cpu(s[1]);
+ r2 = le32_to_cpu(s[2]);
+ r3 = le32_to_cpu(s[3]);
+
+ K(r0, r1, r2, r3, 0);
+ S0(r0, r1, r2, r3, r4); LK(r2, r1, r3, r0, r4, 1);
+ S1(r2, r1, r3, r0, r4); LK(r4, r3, r0, r2, r1, 2);
+ S2(r4, r3, r0, r2, r1); LK(r1, r3, r4, r2, r0, 3);
+ S3(r1, r3, r4, r2, r0); LK(r2, r0, r3, r1, r4, 4);
+ S4(r2, r0, r3, r1, r4); LK(r0, r3, r1, r4, r2, 5);
+ S5(r0, r3, r1, r4, r2); LK(r2, r0, r3, r4, r1, 6);
+ S6(r2, r0, r3, r4, r1); LK(r3, r1, r0, r4, r2, 7);
+ S7(r3, r1, r0, r4, r2); LK(r2, r0, r4, r3, r1, 8);
+ S0(r2, r0, r4, r3, r1); LK(r4, r0, r3, r2, r1, 9);
+ S1(r4, r0, r3, r2, r1); LK(r1, r3, r2, r4, r0, 10);
+ S2(r1, r3, r2, r4, r0); LK(r0, r3, r1, r4, r2, 11);
+ S3(r0, r3, r1, r4, r2); LK(r4, r2, r3, r0, r1, 12);
+ S4(r4, r2, r3, r0, r1); LK(r2, r3, r0, r1, r4, 13);
+ S5(r2, r3, r0, r1, r4); LK(r4, r2, r3, r1, r0, 14);
+ S6(r4, r2, r3, r1, r0); LK(r3, r0, r2, r1, r4, 15);
+ S7(r3, r0, r2, r1, r4); LK(r4, r2, r1, r3, r0, 16);
+ S0(r4, r2, r1, r3, r0); LK(r1, r2, r3, r4, r0, 17);
+ S1(r1, r2, r3, r4, r0); LK(r0, r3, r4, r1, r2, 18);
+ S2(r0, r3, r4, r1, r2); LK(r2, r3, r0, r1, r4, 19);
+ S3(r2, r3, r0, r1, r4); LK(r1, r4, r3, r2, r0, 20);
+ S4(r1, r4, r3, r2, r0); LK(r4, r3, r2, r0, r1, 21);
+ S5(r4, r3, r2, r0, r1); LK(r1, r4, r3, r0, r2, 22);
+ S6(r1, r4, r3, r0, r2); LK(r3, r2, r4, r0, r1, 23);
+ S7(r3, r2, r4, r0, r1); LK(r1, r4, r0, r3, r2, 24);
+ S0(r1, r4, r0, r3, r2); LK(r0, r4, r3, r1, r2, 25);
+ S1(r0, r4, r3, r1, r2); LK(r2, r3, r1, r0, r4, 26);
+ S2(r2, r3, r1, r0, r4); LK(r4, r3, r2, r0, r1, 27);
+ S3(r4, r3, r2, r0, r1); LK(r0, r1, r3, r4, r2, 28);
+ S4(r0, r1, r3, r4, r2); LK(r1, r3, r4, r2, r0, 29);
+ S5(r1, r3, r4, r2, r0); LK(r0, r1, r3, r2, r4, 30);
+ S6(r0, r1, r3, r2, r4); LK(r3, r4, r1, r2, r0, 31);
+ S7(r3, r4, r1, r2, r0); K(r0, r1, r2, r3, 32);
+
+ d[0] = cpu_to_le32(r0);
+ d[1] = cpu_to_le32(r1);
+ d[2] = cpu_to_le32(r2);
+ d[3] = cpu_to_le32(r3);
+}
+EXPORT_SYMBOL_GPL(__serpent_encrypt);
+
+static void serpent_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
+{
+ struct serpent_ctx *ctx = crypto_tfm_ctx(tfm);
+
+ __serpent_encrypt(ctx, dst, src);
+}
+
+void __serpent_decrypt(struct serpent_ctx *ctx, u8 *dst, const u8 *src)
+{
+ const u32 *k = ctx->expkey;
+ const __le32 *s = (const __le32 *)src;
+ __le32 *d = (__le32 *)dst;
+ u32 r0, r1, r2, r3, r4;
+
+ r0 = le32_to_cpu(s[0]);
+ r1 = le32_to_cpu(s[1]);
+ r2 = le32_to_cpu(s[2]);
+ r3 = le32_to_cpu(s[3]);
+
+ K(r0, r1, r2, r3, 32);
+ SI7(r0, r1, r2, r3, r4); KL(r1, r3, r0, r4, r2, 31);
+ SI6(r1, r3, r0, r4, r2); KL(r0, r2, r4, r1, r3, 30);
+ SI5(r0, r2, r4, r1, r3); KL(r2, r3, r0, r4, r1, 29);
+ SI4(r2, r3, r0, r4, r1); KL(r2, r0, r1, r4, r3, 28);
+ SI3(r2, r0, r1, r4, r3); KL(r1, r2, r3, r4, r0, 27);
+ SI2(r1, r2, r3, r4, r0); KL(r2, r0, r4, r3, r1, 26);
+ SI1(r2, r0, r4, r3, r1); KL(r1, r0, r4, r3, r2, 25);
+ SI0(r1, r0, r4, r3, r2); KL(r4, r2, r0, r1, r3, 24);
+ SI7(r4, r2, r0, r1, r3); KL(r2, r1, r4, r3, r0, 23);
+ SI6(r2, r1, r4, r3, r0); KL(r4, r0, r3, r2, r1, 22);
+ SI5(r4, r0, r3, r2, r1); KL(r0, r1, r4, r3, r2, 21);
+ SI4(r0, r1, r4, r3, r2); KL(r0, r4, r2, r3, r1, 20);
+ SI3(r0, r4, r2, r3, r1); KL(r2, r0, r1, r3, r4, 19);
+ SI2(r2, r0, r1, r3, r4); KL(r0, r4, r3, r1, r2, 18);
+ SI1(r0, r4, r3, r1, r2); KL(r2, r4, r3, r1, r0, 17);
+ SI0(r2, r4, r3, r1, r0); KL(r3, r0, r4, r2, r1, 16);
+ SI7(r3, r0, r4, r2, r1); KL(r0, r2, r3, r1, r4, 15);
+ SI6(r0, r2, r3, r1, r4); KL(r3, r4, r1, r0, r2, 14);
+ SI5(r3, r4, r1, r0, r2); KL(r4, r2, r3, r1, r0, 13);
+ SI4(r4, r2, r3, r1, r0); KL(r4, r3, r0, r1, r2, 12);
+ SI3(r4, r3, r0, r1, r2); KL(r0, r4, r2, r1, r3, 11);
+ SI2(r0, r4, r2, r1, r3); KL(r4, r3, r1, r2, r0, 10);
+ SI1(r4, r3, r1, r2, r0); KL(r0, r3, r1, r2, r4, 9);
+ SI0(r0, r3, r1, r2, r4); KL(r1, r4, r3, r0, r2, 8);
+ SI7(r1, r4, r3, r0, r2); KL(r4, r0, r1, r2, r3, 7);
+ SI6(r4, r0, r1, r2, r3); KL(r1, r3, r2, r4, r0, 6);
+ SI5(r1, r3, r2, r4, r0); KL(r3, r0, r1, r2, r4, 5);
+ SI4(r3, r0, r1, r2, r4); KL(r3, r1, r4, r2, r0, 4);
+ SI3(r3, r1, r4, r2, r0); KL(r4, r3, r0, r2, r1, 3);
+ SI2(r4, r3, r0, r2, r1); KL(r3, r1, r2, r0, r4, 2);
+ SI1(r3, r1, r2, r0, r4); KL(r4, r1, r2, r0, r3, 1);
+ SI0(r4, r1, r2, r0, r3); K(r2, r3, r1, r4, 0);
+
+ d[0] = cpu_to_le32(r2);
+ d[1] = cpu_to_le32(r3);
+ d[2] = cpu_to_le32(r1);
+ d[3] = cpu_to_le32(r4);
+}
+EXPORT_SYMBOL_GPL(__serpent_decrypt);
+
+static void serpent_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
+{
+ struct serpent_ctx *ctx = crypto_tfm_ctx(tfm);
+
+ __serpent_decrypt(ctx, dst, src);
+}
+
+static struct crypto_alg serpent_alg = {
+ .cra_name = "serpent",
+ .cra_driver_name = "serpent-generic",
+ .cra_priority = 100,
+ .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
+ .cra_blocksize = SERPENT_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct serpent_ctx),
+ .cra_alignmask = 3,
+ .cra_module = THIS_MODULE,
+ .cra_list = LIST_HEAD_INIT(serpent_alg.cra_list),
+ .cra_u = { .cipher = {
+ .cia_min_keysize = SERPENT_MIN_KEY_SIZE,
+ .cia_max_keysize = SERPENT_MAX_KEY_SIZE,
+ .cia_setkey = serpent_setkey,
+ .cia_encrypt = serpent_encrypt,
+ .cia_decrypt = serpent_decrypt } }
+};
+
+static int tnepres_setkey(struct crypto_tfm *tfm, const u8 *key,
+ unsigned int keylen)
+{
+ u8 rev_key[SERPENT_MAX_KEY_SIZE];
+ int i;
+
+ for (i = 0; i < keylen; ++i)
+ rev_key[keylen - i - 1] = key[i];
+
+ return serpent_setkey(tfm, rev_key, keylen);
+}
+
+static void tnepres_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
+{
+ const u32 * const s = (const u32 * const)src;
+ u32 * const d = (u32 * const)dst;
+
+ u32 rs[4], rd[4];
+
+ rs[0] = swab32(s[3]);
+ rs[1] = swab32(s[2]);
+ rs[2] = swab32(s[1]);
+ rs[3] = swab32(s[0]);
+
+ serpent_encrypt(tfm, (u8 *)rd, (u8 *)rs);
+
+ d[0] = swab32(rd[3]);
+ d[1] = swab32(rd[2]);
+ d[2] = swab32(rd[1]);
+ d[3] = swab32(rd[0]);
+}
+
+static void tnepres_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
+{
+ const u32 * const s = (const u32 * const)src;
+ u32 * const d = (u32 * const)dst;
+
+ u32 rs[4], rd[4];
+
+ rs[0] = swab32(s[3]);
+ rs[1] = swab32(s[2]);
+ rs[2] = swab32(s[1]);
+ rs[3] = swab32(s[0]);
+
+ serpent_decrypt(tfm, (u8 *)rd, (u8 *)rs);
+
+ d[0] = swab32(rd[3]);
+ d[1] = swab32(rd[2]);
+ d[2] = swab32(rd[1]);
+ d[3] = swab32(rd[0]);
+}
+
+static struct crypto_alg tnepres_alg = {
+ .cra_name = "tnepres",
+ .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
+ .cra_blocksize = SERPENT_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct serpent_ctx),
+ .cra_alignmask = 3,
+ .cra_module = THIS_MODULE,
+ .cra_list = LIST_HEAD_INIT(serpent_alg.cra_list),
+ .cra_u = { .cipher = {
+ .cia_min_keysize = SERPENT_MIN_KEY_SIZE,
+ .cia_max_keysize = SERPENT_MAX_KEY_SIZE,
+ .cia_setkey = tnepres_setkey,
+ .cia_encrypt = tnepres_encrypt,
+ .cia_decrypt = tnepres_decrypt } }
+};
+
+static int __init serpent_mod_init(void)
+{
+ int ret = crypto_register_alg(&serpent_alg);
+
+ if (ret)
+ return ret;
+
+ ret = crypto_register_alg(&tnepres_alg);
+
+ if (ret)
+ crypto_unregister_alg(&serpent_alg);
+
+ return ret;
+}
+
+static void __exit serpent_mod_fini(void)
+{
+ crypto_unregister_alg(&tnepres_alg);
+ crypto_unregister_alg(&serpent_alg);
+}
+
+module_init(serpent_mod_init);
+module_exit(serpent_mod_fini);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Serpent and tnepres (kerneli compatible serpent reversed) Cipher Algorithm");
+MODULE_AUTHOR("Dag Arne Osvik <osvik@ii.uib.no>");
+MODULE_ALIAS("tnepres");
+MODULE_ALIAS("serpent");
diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c
index 0c4e80f..7736a9f 100644
--- a/crypto/tcrypt.c
+++ b/crypto/tcrypt.c
@@ -719,6 +719,207 @@
crypto_free_ahash(tfm);
}
+static inline int do_one_acipher_op(struct ablkcipher_request *req, int ret)
+{
+ if (ret == -EINPROGRESS || ret == -EBUSY) {
+ struct tcrypt_result *tr = req->base.data;
+
+ ret = wait_for_completion_interruptible(&tr->completion);
+ if (!ret)
+ ret = tr->err;
+ INIT_COMPLETION(tr->completion);
+ }
+
+ return ret;
+}
+
+static int test_acipher_jiffies(struct ablkcipher_request *req, int enc,
+ int blen, int sec)
+{
+ unsigned long start, end;
+ int bcount;
+ int ret;
+
+ for (start = jiffies, end = start + sec * HZ, bcount = 0;
+ time_before(jiffies, end); bcount++) {
+ if (enc)
+ ret = do_one_acipher_op(req,
+ crypto_ablkcipher_encrypt(req));
+ else
+ ret = do_one_acipher_op(req,
+ crypto_ablkcipher_decrypt(req));
+
+ if (ret)
+ return ret;
+ }
+
+ pr_cont("%d operations in %d seconds (%ld bytes)\n",
+ bcount, sec, (long)bcount * blen);
+ return 0;
+}
+
+static int test_acipher_cycles(struct ablkcipher_request *req, int enc,
+ int blen)
+{
+ unsigned long cycles = 0;
+ int ret = 0;
+ int i;
+
+ /* Warm-up run. */
+ for (i = 0; i < 4; i++) {
+ if (enc)
+ ret = do_one_acipher_op(req,
+ crypto_ablkcipher_encrypt(req));
+ else
+ ret = do_one_acipher_op(req,
+ crypto_ablkcipher_decrypt(req));
+
+ if (ret)
+ goto out;
+ }
+
+ /* The real thing. */
+ for (i = 0; i < 8; i++) {
+ cycles_t start, end;
+
+ start = get_cycles();
+ if (enc)
+ ret = do_one_acipher_op(req,
+ crypto_ablkcipher_encrypt(req));
+ else
+ ret = do_one_acipher_op(req,
+ crypto_ablkcipher_decrypt(req));
+ end = get_cycles();
+
+ if (ret)
+ goto out;
+
+ cycles += end - start;
+ }
+
+out:
+ if (ret == 0)
+ pr_cont("1 operation in %lu cycles (%d bytes)\n",
+ (cycles + 4) / 8, blen);
+
+ return ret;
+}
+
+static void test_acipher_speed(const char *algo, int enc, unsigned int sec,
+ struct cipher_speed_template *template,
+ unsigned int tcount, u8 *keysize)
+{
+ unsigned int ret, i, j, iv_len;
+ struct tcrypt_result tresult;
+ const char *key;
+ char iv[128];
+ struct ablkcipher_request *req;
+ struct crypto_ablkcipher *tfm;
+ const char *e;
+ u32 *b_size;
+
+ if (enc == ENCRYPT)
+ e = "encryption";
+ else
+ e = "decryption";
+
+ pr_info("\ntesting speed of async %s %s\n", algo, e);
+
+ init_completion(&tresult.completion);
+
+ tfm = crypto_alloc_ablkcipher(algo, 0, 0);
+
+ if (IS_ERR(tfm)) {
+ pr_err("failed to load transform for %s: %ld\n", algo,
+ PTR_ERR(tfm));
+ return;
+ }
+
+ req = ablkcipher_request_alloc(tfm, GFP_KERNEL);
+ if (!req) {
+ pr_err("tcrypt: skcipher: Failed to allocate request for %s\n",
+ algo);
+ goto out;
+ }
+
+ ablkcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
+ tcrypt_complete, &tresult);
+
+ i = 0;
+ do {
+ b_size = block_sizes;
+
+ do {
+ struct scatterlist sg[TVMEMSIZE];
+
+ if ((*keysize + *b_size) > TVMEMSIZE * PAGE_SIZE) {
+ pr_err("template (%u) too big for "
+ "tvmem (%lu)\n", *keysize + *b_size,
+ TVMEMSIZE * PAGE_SIZE);
+ goto out_free_req;
+ }
+
+ pr_info("test %u (%d bit key, %d byte blocks): ", i,
+ *keysize * 8, *b_size);
+
+ memset(tvmem[0], 0xff, PAGE_SIZE);
+
+ /* set key, plain text and IV */
+ key = tvmem[0];
+ for (j = 0; j < tcount; j++) {
+ if (template[j].klen == *keysize) {
+ key = template[j].key;
+ break;
+ }
+ }
+
+ crypto_ablkcipher_clear_flags(tfm, ~0);
+
+ ret = crypto_ablkcipher_setkey(tfm, key, *keysize);
+ if (ret) {
+ pr_err("setkey() failed flags=%x\n",
+ crypto_ablkcipher_get_flags(tfm));
+ goto out_free_req;
+ }
+
+ sg_init_table(sg, TVMEMSIZE);
+ sg_set_buf(sg, tvmem[0] + *keysize,
+ PAGE_SIZE - *keysize);
+ for (j = 1; j < TVMEMSIZE; j++) {
+ sg_set_buf(sg + j, tvmem[j], PAGE_SIZE);
+ memset(tvmem[j], 0xff, PAGE_SIZE);
+ }
+
+ iv_len = crypto_ablkcipher_ivsize(tfm);
+ if (iv_len)
+ memset(&iv, 0xff, iv_len);
+
+ ablkcipher_request_set_crypt(req, sg, sg, *b_size, iv);
+
+ if (sec)
+ ret = test_acipher_jiffies(req, enc,
+ *b_size, sec);
+ else
+ ret = test_acipher_cycles(req, enc,
+ *b_size);
+
+ if (ret) {
+ pr_err("%s() failed flags=%x\n", e,
+ crypto_ablkcipher_get_flags(tfm));
+ break;
+ }
+ b_size++;
+ i++;
+ } while (*b_size);
+ keysize++;
+ } while (*keysize);
+
+out_free_req:
+ ablkcipher_request_free(req);
+out:
+ crypto_free_ablkcipher(tfm);
+}
+
static void test_available(void)
{
char **name = check;
@@ -789,10 +990,16 @@
ret += tcrypt_test("ecb(twofish)");
ret += tcrypt_test("cbc(twofish)");
ret += tcrypt_test("ctr(twofish)");
+ ret += tcrypt_test("lrw(twofish)");
+ ret += tcrypt_test("xts(twofish)");
break;
case 9:
ret += tcrypt_test("ecb(serpent)");
+ ret += tcrypt_test("cbc(serpent)");
+ ret += tcrypt_test("ctr(serpent)");
+ ret += tcrypt_test("lrw(serpent)");
+ ret += tcrypt_test("xts(serpent)");
break;
case 10:
@@ -1045,6 +1252,14 @@
speed_template_16_24_32);
test_cipher_speed("ctr(twofish)", DECRYPT, sec, NULL, 0,
speed_template_16_24_32);
+ test_cipher_speed("lrw(twofish)", ENCRYPT, sec, NULL, 0,
+ speed_template_32_40_48);
+ test_cipher_speed("lrw(twofish)", DECRYPT, sec, NULL, 0,
+ speed_template_32_40_48);
+ test_cipher_speed("xts(twofish)", ENCRYPT, sec, NULL, 0,
+ speed_template_32_48_64);
+ test_cipher_speed("xts(twofish)", DECRYPT, sec, NULL, 0,
+ speed_template_32_48_64);
break;
case 203:
@@ -1089,6 +1304,29 @@
speed_template_16_32);
break;
+ case 207:
+ test_cipher_speed("ecb(serpent)", ENCRYPT, sec, NULL, 0,
+ speed_template_16_32);
+ test_cipher_speed("ecb(serpent)", DECRYPT, sec, NULL, 0,
+ speed_template_16_32);
+ test_cipher_speed("cbc(serpent)", ENCRYPT, sec, NULL, 0,
+ speed_template_16_32);
+ test_cipher_speed("cbc(serpent)", DECRYPT, sec, NULL, 0,
+ speed_template_16_32);
+ test_cipher_speed("ctr(serpent)", ENCRYPT, sec, NULL, 0,
+ speed_template_16_32);
+ test_cipher_speed("ctr(serpent)", DECRYPT, sec, NULL, 0,
+ speed_template_16_32);
+ test_cipher_speed("lrw(serpent)", ENCRYPT, sec, NULL, 0,
+ speed_template_32_48);
+ test_cipher_speed("lrw(serpent)", DECRYPT, sec, NULL, 0,
+ speed_template_32_48);
+ test_cipher_speed("xts(serpent)", ENCRYPT, sec, NULL, 0,
+ speed_template_32_64);
+ test_cipher_speed("xts(serpent)", DECRYPT, sec, NULL, 0,
+ speed_template_32_64);
+ break;
+
case 300:
/* fall through */
@@ -1241,6 +1479,78 @@
case 499:
break;
+ case 500:
+ test_acipher_speed("ecb(aes)", ENCRYPT, sec, NULL, 0,
+ speed_template_16_24_32);
+ test_acipher_speed("ecb(aes)", DECRYPT, sec, NULL, 0,
+ speed_template_16_24_32);
+ test_acipher_speed("cbc(aes)", ENCRYPT, sec, NULL, 0,
+ speed_template_16_24_32);
+ test_acipher_speed("cbc(aes)", DECRYPT, sec, NULL, 0,
+ speed_template_16_24_32);
+ test_acipher_speed("lrw(aes)", ENCRYPT, sec, NULL, 0,
+ speed_template_32_40_48);
+ test_acipher_speed("lrw(aes)", DECRYPT, sec, NULL, 0,
+ speed_template_32_40_48);
+ test_acipher_speed("xts(aes)", ENCRYPT, sec, NULL, 0,
+ speed_template_32_48_64);
+ test_acipher_speed("xts(aes)", DECRYPT, sec, NULL, 0,
+ speed_template_32_48_64);
+ test_acipher_speed("ctr(aes)", ENCRYPT, sec, NULL, 0,
+ speed_template_16_24_32);
+ test_acipher_speed("ctr(aes)", DECRYPT, sec, NULL, 0,
+ speed_template_16_24_32);
+ break;
+
+ case 501:
+ test_acipher_speed("ecb(des3_ede)", ENCRYPT, sec,
+ des3_speed_template, DES3_SPEED_VECTORS,
+ speed_template_24);
+ test_acipher_speed("ecb(des3_ede)", DECRYPT, sec,
+ des3_speed_template, DES3_SPEED_VECTORS,
+ speed_template_24);
+ test_acipher_speed("cbc(des3_ede)", ENCRYPT, sec,
+ des3_speed_template, DES3_SPEED_VECTORS,
+ speed_template_24);
+ test_acipher_speed("cbc(des3_ede)", DECRYPT, sec,
+ des3_speed_template, DES3_SPEED_VECTORS,
+ speed_template_24);
+ break;
+
+ case 502:
+ test_acipher_speed("ecb(des)", ENCRYPT, sec, NULL, 0,
+ speed_template_8);
+ test_acipher_speed("ecb(des)", DECRYPT, sec, NULL, 0,
+ speed_template_8);
+ test_acipher_speed("cbc(des)", ENCRYPT, sec, NULL, 0,
+ speed_template_8);
+ test_acipher_speed("cbc(des)", DECRYPT, sec, NULL, 0,
+ speed_template_8);
+ break;
+
+ case 503:
+ test_acipher_speed("ecb(serpent)", ENCRYPT, sec, NULL, 0,
+ speed_template_16_32);
+ test_acipher_speed("ecb(serpent)", DECRYPT, sec, NULL, 0,
+ speed_template_16_32);
+ test_acipher_speed("cbc(serpent)", ENCRYPT, sec, NULL, 0,
+ speed_template_16_32);
+ test_acipher_speed("cbc(serpent)", DECRYPT, sec, NULL, 0,
+ speed_template_16_32);
+ test_acipher_speed("ctr(serpent)", ENCRYPT, sec, NULL, 0,
+ speed_template_16_32);
+ test_acipher_speed("ctr(serpent)", DECRYPT, sec, NULL, 0,
+ speed_template_16_32);
+ test_acipher_speed("lrw(serpent)", ENCRYPT, sec, NULL, 0,
+ speed_template_32_48);
+ test_acipher_speed("lrw(serpent)", DECRYPT, sec, NULL, 0,
+ speed_template_32_48);
+ test_acipher_speed("xts(serpent)", ENCRYPT, sec, NULL, 0,
+ speed_template_32_64);
+ test_acipher_speed("xts(serpent)", DECRYPT, sec, NULL, 0,
+ speed_template_32_64);
+ break;
+
case 1000:
test_available();
break;
diff --git a/crypto/tcrypt.h b/crypto/tcrypt.h
index 10cb925..5be1fc8 100644
--- a/crypto/tcrypt.h
+++ b/crypto/tcrypt.h
@@ -51,7 +51,9 @@
static u8 speed_template_16_32[] = {16, 32, 0};
static u8 speed_template_16_24_32[] = {16, 24, 32, 0};
static u8 speed_template_32_40_48[] = {32, 40, 48, 0};
+static u8 speed_template_32_48[] = {32, 48, 0};
static u8 speed_template_32_48_64[] = {32, 48, 64, 0};
+static u8 speed_template_32_64[] = {32, 64, 0};
/*
* Digest speed tests
diff --git a/crypto/testmgr.c b/crypto/testmgr.c
index e91c1eb..bb54b882 100644
--- a/crypto/testmgr.c
+++ b/crypto/testmgr.c
@@ -1534,6 +1534,21 @@
/* Please keep this list sorted by algorithm name. */
static const struct alg_test_desc alg_test_descs[] = {
{
+ .alg = "__cbc-serpent-sse2",
+ .test = alg_test_null,
+ .suite = {
+ .cipher = {
+ .enc = {
+ .vecs = NULL,
+ .count = 0
+ },
+ .dec = {
+ .vecs = NULL,
+ .count = 0
+ }
+ }
+ }
+ }, {
.alg = "__driver-cbc-aes-aesni",
.test = alg_test_null,
.suite = {
@@ -1549,6 +1564,21 @@
}
}
}, {
+ .alg = "__driver-cbc-serpent-sse2",
+ .test = alg_test_null,
+ .suite = {
+ .cipher = {
+ .enc = {
+ .vecs = NULL,
+ .count = 0
+ },
+ .dec = {
+ .vecs = NULL,
+ .count = 0
+ }
+ }
+ }
+ }, {
.alg = "__driver-ecb-aes-aesni",
.test = alg_test_null,
.suite = {
@@ -1564,6 +1594,21 @@
}
}
}, {
+ .alg = "__driver-ecb-serpent-sse2",
+ .test = alg_test_null,
+ .suite = {
+ .cipher = {
+ .enc = {
+ .vecs = NULL,
+ .count = 0
+ },
+ .dec = {
+ .vecs = NULL,
+ .count = 0
+ }
+ }
+ }
+ }, {
.alg = "__ghash-pclmulqdqni",
.test = alg_test_null,
.suite = {
@@ -1675,6 +1720,21 @@
}
}
}, {
+ .alg = "cbc(serpent)",
+ .test = alg_test_skcipher,
+ .suite = {
+ .cipher = {
+ .enc = {
+ .vecs = serpent_cbc_enc_tv_template,
+ .count = SERPENT_CBC_ENC_TEST_VECTORS
+ },
+ .dec = {
+ .vecs = serpent_cbc_dec_tv_template,
+ .count = SERPENT_CBC_DEC_TEST_VECTORS
+ }
+ }
+ }
+ }, {
.alg = "cbc(twofish)",
.test = alg_test_skcipher,
.suite = {
@@ -1731,6 +1791,21 @@
}
}
}, {
+ .alg = "cryptd(__driver-ecb-serpent-sse2)",
+ .test = alg_test_null,
+ .suite = {
+ .cipher = {
+ .enc = {
+ .vecs = NULL,
+ .count = 0
+ },
+ .dec = {
+ .vecs = NULL,
+ .count = 0
+ }
+ }
+ }
+ }, {
.alg = "cryptd(__ghash-pclmulqdqni)",
.test = alg_test_null,
.suite = {
@@ -1771,6 +1846,21 @@
}
}
}, {
+ .alg = "ctr(serpent)",
+ .test = alg_test_skcipher,
+ .suite = {
+ .cipher = {
+ .enc = {
+ .vecs = serpent_ctr_enc_tv_template,
+ .count = SERPENT_CTR_ENC_TEST_VECTORS
+ },
+ .dec = {
+ .vecs = serpent_ctr_dec_tv_template,
+ .count = SERPENT_CTR_DEC_TEST_VECTORS
+ }
+ }
+ }
+ }, {
.alg = "ctr(twofish)",
.test = alg_test_skcipher,
.suite = {
@@ -2207,6 +2297,36 @@
}
}
}, {
+ .alg = "lrw(serpent)",
+ .test = alg_test_skcipher,
+ .suite = {
+ .cipher = {
+ .enc = {
+ .vecs = serpent_lrw_enc_tv_template,
+ .count = SERPENT_LRW_ENC_TEST_VECTORS
+ },
+ .dec = {
+ .vecs = serpent_lrw_dec_tv_template,
+ .count = SERPENT_LRW_DEC_TEST_VECTORS
+ }
+ }
+ }
+ }, {
+ .alg = "lrw(twofish)",
+ .test = alg_test_skcipher,
+ .suite = {
+ .cipher = {
+ .enc = {
+ .vecs = tf_lrw_enc_tv_template,
+ .count = TF_LRW_ENC_TEST_VECTORS
+ },
+ .dec = {
+ .vecs = tf_lrw_dec_tv_template,
+ .count = TF_LRW_DEC_TEST_VECTORS
+ }
+ }
+ }
+ }, {
.alg = "lzo",
.test = alg_test_comp,
.suite = {
@@ -2514,6 +2634,36 @@
}
}
}, {
+ .alg = "xts(serpent)",
+ .test = alg_test_skcipher,
+ .suite = {
+ .cipher = {
+ .enc = {
+ .vecs = serpent_xts_enc_tv_template,
+ .count = SERPENT_XTS_ENC_TEST_VECTORS
+ },
+ .dec = {
+ .vecs = serpent_xts_dec_tv_template,
+ .count = SERPENT_XTS_DEC_TEST_VECTORS
+ }
+ }
+ }
+ }, {
+ .alg = "xts(twofish)",
+ .test = alg_test_skcipher,
+ .suite = {
+ .cipher = {
+ .enc = {
+ .vecs = tf_xts_enc_tv_template,
+ .count = TF_XTS_ENC_TEST_VECTORS
+ },
+ .dec = {
+ .vecs = tf_xts_dec_tv_template,
+ .count = TF_XTS_DEC_TEST_VECTORS
+ }
+ }
+ }
+ }, {
.alg = "zlib",
.test = alg_test_pcomp,
.suite = {
diff --git a/crypto/testmgr.h b/crypto/testmgr.h
index 37b4d8f..43e84d3 100644
--- a/crypto/testmgr.h
+++ b/crypto/testmgr.h
@@ -2717,6 +2717,10 @@
#define TF_CBC_DEC_TEST_VECTORS 5
#define TF_CTR_ENC_TEST_VECTORS 2
#define TF_CTR_DEC_TEST_VECTORS 2
+#define TF_LRW_ENC_TEST_VECTORS 8
+#define TF_LRW_DEC_TEST_VECTORS 8
+#define TF_XTS_ENC_TEST_VECTORS 5
+#define TF_XTS_DEC_TEST_VECTORS 5
static struct cipher_testvec tf_enc_tv_template[] = {
{
@@ -3092,16 +3096,1206 @@
},
};
+static struct cipher_testvec tf_lrw_enc_tv_template[] = {
+ /* Generated from AES-LRW test vectors */
+ {
+ .key = "\x45\x62\xac\x25\xf8\x28\x17\x6d"
+ "\x4c\x26\x84\x14\xb5\x68\x01\x85"
+ "\x25\x8e\x2a\x05\xe7\x3e\x9d\x03"
+ "\xee\x5a\x83\x0c\xcc\x09\x4c\x87",
+ .klen = 32,
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x01",
+ .input = "\x30\x31\x32\x33\x34\x35\x36\x37"
+ "\x38\x39\x41\x42\x43\x44\x45\x46",
+ .ilen = 16,
+ .result = "\xa1\x6c\x50\x69\x26\xa4\xef\x7b"
+ "\x7c\xc6\x91\xeb\x72\xdd\x9b\xee",
+ .rlen = 16,
+ }, {
+ .key = "\x59\x70\x47\x14\xf5\x57\x47\x8c"
+ "\xd7\x79\xe8\x0f\x54\x88\x79\x44"
+ "\x0d\x48\xf0\xb7\xb1\x5a\x53\xea"
+ "\x1c\xaa\x6b\x29\xc2\xca\xfb\xaf",
+ .klen = 32,
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x02",
+ .input = "\x30\x31\x32\x33\x34\x35\x36\x37"
+ "\x38\x39\x41\x42\x43\x44\x45\x46",
+ .ilen = 16,
+ .result = "\xab\x72\x0a\xad\x3b\x0c\xf0\xc9"
+ "\x42\x2f\xf1\xae\xf1\x3c\xb1\xbd",
+ .rlen = 16,
+ }, {
+ .key = "\xd8\x2a\x91\x34\xb2\x6a\x56\x50"
+ "\x30\xfe\x69\xe2\x37\x7f\x98\x47"
+ "\xcd\xf9\x0b\x16\x0c\x64\x8f\xb6"
+ "\xb0\x0d\x0d\x1b\xae\x85\x87\x1f",
+ .klen = 32,
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x02\x00\x00\x00\x00",
+ .input = "\x30\x31\x32\x33\x34\x35\x36\x37"
+ "\x38\x39\x41\x42\x43\x44\x45\x46",
+ .ilen = 16,
+ .result = "\x85\xa7\x56\x67\x08\xfa\x42\xe1"
+ "\x22\xe6\x82\xfc\xd9\xb4\xd7\xd4",
+ .rlen = 16,
+ }, {
+ .key = "\x0f\x6a\xef\xf8\xd3\xd2\xbb\x15"
+ "\x25\x83\xf7\x3c\x1f\x01\x28\x74"
+ "\xca\xc6\xbc\x35\x4d\x4a\x65\x54"
+ "\x90\xae\x61\xcf\x7b\xae\xbd\xcc"
+ "\xad\xe4\x94\xc5\x4a\x29\xae\x70",
+ .klen = 40,
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x01",
+ .input = "\x30\x31\x32\x33\x34\x35\x36\x37"
+ "\x38\x39\x41\x42\x43\x44\x45\x46",
+ .ilen = 16,
+ .result = "\xd2\xaf\x69\x35\x24\x1d\x0e\x1c"
+ "\x84\x8b\x05\xe4\xa2\x2f\x16\xf5",
+ .rlen = 16,
+ }, {
+ .key = "\x8a\xd4\xee\x10\x2f\xbd\x81\xff"
+ "\xf8\x86\xce\xac\x93\xc5\xad\xc6"
+ "\xa0\x19\x07\xc0\x9d\xf7\xbb\xdd"
+ "\x52\x13\xb2\xb7\xf0\xff\x11\xd8"
+ "\xd6\x08\xd0\xcd\x2e\xb1\x17\x6f",
+ .klen = 40,
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x02\x00\x00\x00\x00",
+ .input = "\x30\x31\x32\x33\x34\x35\x36\x37"
+ "\x38\x39\x41\x42\x43\x44\x45\x46",
+ .ilen = 16,
+ .result = "\x4a\x23\x56\xd7\xff\x90\xd0\x9a"
+ "\x0d\x7c\x26\xfc\xf0\xf0\xf6\xe4",
+ .rlen = 16,
+ }, {
+ .key = "\xf8\xd4\x76\xff\xd6\x46\xee\x6c"
+ "\x23\x84\xcb\x1c\x77\xd6\x19\x5d"
+ "\xfe\xf1\xa9\xf3\x7b\xbc\x8d\x21"
+ "\xa7\x9c\x21\xf8\xcb\x90\x02\x89"
+ "\xa8\x45\x34\x8e\xc8\xc5\xb5\xf1"
+ "\x26\xf5\x0e\x76\xfe\xfd\x1b\x1e",
+ .klen = 48,
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x01",
+ .input = "\x30\x31\x32\x33\x34\x35\x36\x37"
+ "\x38\x39\x41\x42\x43\x44\x45\x46",
+ .ilen = 16,
+ .result = "\x30\xaf\x26\x05\x9d\x5d\x0a\x58"
+ "\xe2\xe7\xce\x8a\xb2\x56\x6d\x76",
+ .rlen = 16,
+ }, {
+ .key = "\xfb\x76\x15\xb2\x3d\x80\x89\x1d"
+ "\xd4\x70\x98\x0b\xc7\x95\x84\xc8"
+ "\xb2\xfb\x64\xce\x60\x97\x87\x8d"
+ "\x17\xfc\xe4\x5a\x49\xe8\x30\xb7"
+ "\x6e\x78\x17\xe7\x2d\x5e\x12\xd4"
+ "\x60\x64\x04\x7a\xf1\x2f\x9e\x0c",
+ .klen = 48,
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x02\x00\x00\x00\x00",
+ .input = "\x30\x31\x32\x33\x34\x35\x36\x37"
+ "\x38\x39\x41\x42\x43\x44\x45\x46",
+ .ilen = 16,
+ .result = "\xdf\xcf\xdc\xd2\xe1\xcf\x86\x75"
+ "\x17\x66\x5e\x0c\x14\xa1\x3d\x40",
+ .rlen = 16,
+ }, {
+ .key = "\xf8\xd4\x76\xff\xd6\x46\xee\x6c"
+ "\x23\x84\xcb\x1c\x77\xd6\x19\x5d"
+ "\xfe\xf1\xa9\xf3\x7b\xbc\x8d\x21"
+ "\xa7\x9c\x21\xf8\xcb\x90\x02\x89"
+ "\xa8\x45\x34\x8e\xc8\xc5\xb5\xf1"
+ "\x26\xf5\x0e\x76\xfe\xfd\x1b\x1e",
+ .klen = 48,
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x01",
+ .input = "\x05\x11\xb7\x18\xab\xc6\x2d\xac"
+ "\x70\x5d\xf6\x22\x94\xcd\xe5\x6c"
+ "\x17\x6b\xf6\x1c\xf0\xf3\x6e\xf8"
+ "\x50\x38\x1f\x71\x49\xb6\x57\xd6"
+ "\x8f\xcb\x8d\x6b\xe3\xa6\x29\x90"
+ "\xfe\x2a\x62\x82\xae\x6d\x8b\xf6"
+ "\xad\x1e\x9e\x20\x5f\x38\xbe\x04"
+ "\xda\x10\x8e\xed\xa2\xa4\x87\xab"
+ "\xda\x6b\xb4\x0c\x75\xba\xd3\x7c"
+ "\xc9\xac\x42\x31\x95\x7c\xc9\x04"
+ "\xeb\xd5\x6e\x32\x69\x8a\xdb\xa6"
+ "\x15\xd7\x3f\x4f\x2f\x66\x69\x03"
+ "\x9c\x1f\x54\x0f\xde\x1f\xf3\x65"
+ "\x4c\x96\x12\xed\x7c\x92\x03\x01"
+ "\x6f\xbc\x35\x93\xac\xf1\x27\xf1"
+ "\xb4\x96\x82\x5a\x5f\xb0\xa0\x50"
+ "\x89\xa4\x8e\x66\x44\x85\xcc\xfd"
+ "\x33\x14\x70\xe3\x96\xb2\xc3\xd3"
+ "\xbb\x54\x5a\x1a\xf9\x74\xa2\xc5"
+ "\x2d\x64\x75\xdd\xb4\x54\xe6\x74"
+ "\x8c\xd3\x9d\x9e\x86\xab\x51\x53"
+ "\xb7\x93\x3e\x6f\xd0\x4e\x2c\x40"
+ "\xf6\xa8\x2e\x3e\x9d\xf4\x66\xa5"
+ "\x76\x12\x73\x44\x1a\x56\xd7\x72"
+ "\x88\xcd\x21\x8c\x4c\x0f\xfe\xda"
+ "\x95\xe0\x3a\xa6\xa5\x84\x46\xcd"
+ "\xd5\x3e\x9d\x3a\xe2\x67\xe6\x60"
+ "\x1a\xe2\x70\x85\x58\xc2\x1b\x09"
+ "\xe1\xd7\x2c\xca\xad\xa8\x8f\xf9"
+ "\xac\xb3\x0e\xdb\xca\x2e\xe2\xb8"
+ "\x51\x71\xd9\x3c\x6c\xf1\x56\xf8"
+ "\xea\x9c\xf1\xfb\x0c\xe6\xb7\x10"
+ "\x1c\xf8\xa9\x7c\xe8\x53\x35\xc1"
+ "\x90\x3e\x76\x4a\x74\xa4\x21\x2c"
+ "\xf6\x2c\x4e\x0f\x94\x3a\x88\x2e"
+ "\x41\x09\x6a\x33\x7d\xf6\xdd\x3f"
+ "\x8d\x23\x31\x74\x84\xeb\x88\x6e"
+ "\xcc\xb9\xbc\x22\x83\x19\x07\x22"
+ "\xa5\x2d\xdf\xa5\xf3\x80\x85\x78"
+ "\x84\x39\x6a\x6d\x6a\x99\x4f\xa5"
+ "\x15\xfe\x46\xb0\xe4\x6c\xa5\x41"
+ "\x3c\xce\x8f\x42\x60\x71\xa7\x75"
+ "\x08\x40\x65\x8a\x82\xbf\xf5\x43"
+ "\x71\x96\xa9\x4d\x44\x8a\x20\xbe"
+ "\xfa\x4d\xbb\xc0\x7d\x31\x96\x65"
+ "\xe7\x75\xe5\x3e\xfd\x92\x3b\xc9"
+ "\x55\xbb\x16\x7e\xf7\xc2\x8c\xa4"
+ "\x40\x1d\xe5\xef\x0e\xdf\xe4\x9a"
+ "\x62\x73\x65\xfd\x46\x63\x25\x3d"
+ "\x2b\xaf\xe5\x64\xfe\xa5\x5c\xcf"
+ "\x24\xf3\xb4\xac\x64\xba\xdf\x4b"
+ "\xc6\x96\x7d\x81\x2d\x8d\x97\xf7"
+ "\xc5\x68\x77\x84\x32\x2b\xcc\x85"
+ "\x74\x96\xf0\x12\x77\x61\xb9\xeb"
+ "\x71\xaa\x82\xcb\x1c\xdb\x89\xc8"
+ "\xc6\xb5\xe3\x5c\x7d\x39\x07\x24"
+ "\xda\x39\x87\x45\xc0\x2b\xbb\x01"
+ "\xac\xbc\x2a\x5c\x7f\xfc\xe8\xce"
+ "\x6d\x9c\x6f\xed\xd3\xc1\xa1\xd6"
+ "\xc5\x55\xa9\x66\x2f\xe1\xc8\x32"
+ "\xa6\x5d\xa4\x3a\x98\x73\xe8\x45"
+ "\xa4\xc7\xa8\xb4\xf6\x13\x03\xf6"
+ "\xe9\x2e\xc4\x29\x0f\x84\xdb\xc4"
+ "\x21\xc4\xc2\x75\x67\x89\x37\x0a",
+ .ilen = 512,
+ .result = "\x30\x38\xeb\xaf\x12\x43\x1a\x89"
+ "\x62\xa2\x36\xe5\xcf\x77\x1e\xd9"
+ "\x08\xc3\x0d\xdd\x95\xab\x19\x96"
+ "\x27\x52\x41\xc3\xca\xfb\xf6\xee"
+ "\x40\x2d\xdf\xdd\x00\x0c\xb9\x0a"
+ "\x3a\xf0\xc0\xd1\xda\x63\x9e\x45"
+ "\x42\xe9\x29\xc0\xb4\x07\xb4\x31"
+ "\x66\x77\x72\xb5\xb6\xb3\x57\x46"
+ "\x34\x9a\xfe\x03\xaf\x6b\x36\x07"
+ "\x63\x8e\xc2\x5d\xa6\x0f\xb6\x7d"
+ "\xfb\x6d\x82\x51\xb6\x98\xd0\x71"
+ "\xe7\x10\x7a\xdf\xb2\xbd\xf1\x1d"
+ "\x72\x2b\x54\x13\xe3\x6d\x79\x37"
+ "\xa9\x39\x2c\xdf\x21\xab\x87\xd5"
+ "\xee\xef\x9a\x12\x50\x39\x2e\x1b"
+ "\x7d\xe6\x6a\x27\x48\xb9\xe7\xac"
+ "\xaa\xcd\x79\x5f\xf2\xf3\xa0\x08"
+ "\x6f\x2c\xf4\x0e\xd1\xb8\x89\x25"
+ "\x31\x9d\xef\xb1\x1d\x27\x55\x04"
+ "\xc9\x8c\xb7\x68\xdc\xb6\x67\x8a"
+ "\xdb\xcf\x22\xf2\x3b\x6f\xce\xbb"
+ "\x26\xbe\x4f\x27\x04\x42\xd1\x44"
+ "\x4c\x08\xa3\x95\x4c\x7f\x1a\xaf"
+ "\x1d\x28\x14\xfd\xb1\x1a\x34\x18"
+ "\xf5\x1e\x28\x69\x95\x6a\x5a\xba"
+ "\x8e\xb2\x58\x1d\x28\x17\x13\x3d"
+ "\x38\x7d\x14\x8d\xab\x5d\xf9\xe8"
+ "\x3c\x0f\x2b\x0d\x2b\x08\xb4\x4b"
+ "\x6b\x0d\xc8\xa7\x84\xc2\x3a\x1a"
+ "\xb7\xbd\xda\x92\x29\xb8\x5b\x5a"
+ "\x63\xa5\x99\x82\x09\x72\x8f\xc6"
+ "\xa4\x62\x24\x69\x8c\x2d\x26\x00"
+ "\x99\x83\x91\xd6\xc6\xcf\x57\x67"
+ "\x38\xea\xf2\xfc\x29\xe0\x73\x39"
+ "\xf9\x13\x94\x6d\xe2\x58\x28\x75"
+ "\x3e\xae\x71\x90\x07\x70\x1c\x38"
+ "\x5b\x4c\x1e\xb5\xa5\x3b\x20\xef"
+ "\xb1\x4c\x3e\x1a\x72\x62\xbb\x22"
+ "\x82\x09\xe3\x18\x3f\x4f\x48\xfc"
+ "\xdd\xac\xfc\xb6\x09\xdb\xd2\x7b"
+ "\xd6\xb7\x7e\x41\x2f\x14\xf5\x0e"
+ "\xc3\xac\x4a\xed\xe7\x82\xef\x31"
+ "\x1f\x1a\x51\x1e\x29\x60\xc8\x98"
+ "\x93\x51\x1d\x3d\x62\x59\x83\x82"
+ "\x0c\xf1\xd7\x8d\xac\x33\x44\x81"
+ "\x3c\x59\xb7\xd4\x5b\x65\x82\xc4"
+ "\xec\xdc\x24\xfd\x0e\x1a\x79\x94"
+ "\x34\xb0\x62\xfa\x98\x49\x26\x1f"
+ "\xf4\x9e\x40\x44\x5b\x1f\xf8\xbe"
+ "\x36\xff\xc6\xc6\x9d\xf2\xd6\xcc"
+ "\x63\x93\x29\xb9\x0b\x6d\xd7\x6c"
+ "\xdb\xf6\x21\x80\xf7\x5a\x37\x15"
+ "\x0c\xe3\x36\xc8\x74\x75\x20\x91"
+ "\xdf\x52\x2d\x0c\xe7\x45\xff\x46"
+ "\xb3\xf4\xec\xc2\xbd\xd3\x37\xb6"
+ "\x26\xa2\x5d\x7d\x61\xbf\x10\x46"
+ "\x57\x8d\x05\x96\x70\x0b\xd6\x41"
+ "\x5c\xe9\xd3\x54\x81\x39\x3a\xdd"
+ "\x5f\x92\x81\x6e\x35\x03\xd4\x72"
+ "\x3d\x5a\xe7\xb9\x3b\x0c\x84\x23"
+ "\x45\x5d\xec\x72\xc1\x52\xef\x2e"
+ "\x81\x00\xd3\xfe\x4c\x3c\x05\x61"
+ "\x80\x18\xc4\x6c\x03\xd3\xb7\xba"
+ "\x11\xd7\xb8\x6e\xea\xe1\x80\x30",
+ .rlen = 512,
+ },
+};
+
+static struct cipher_testvec tf_lrw_dec_tv_template[] = {
+ /* Generated from AES-LRW test vectors */
+ /* same as enc vectors with input and result reversed */
+ {
+ .key = "\x45\x62\xac\x25\xf8\x28\x17\x6d"
+ "\x4c\x26\x84\x14\xb5\x68\x01\x85"
+ "\x25\x8e\x2a\x05\xe7\x3e\x9d\x03"
+ "\xee\x5a\x83\x0c\xcc\x09\x4c\x87",
+ .klen = 32,
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x01",
+ .input = "\xa1\x6c\x50\x69\x26\xa4\xef\x7b"
+ "\x7c\xc6\x91\xeb\x72\xdd\x9b\xee",
+ .ilen = 16,
+ .result = "\x30\x31\x32\x33\x34\x35\x36\x37"
+ "\x38\x39\x41\x42\x43\x44\x45\x46",
+ .rlen = 16,
+ }, {
+ .key = "\x59\x70\x47\x14\xf5\x57\x47\x8c"
+ "\xd7\x79\xe8\x0f\x54\x88\x79\x44"
+ "\x0d\x48\xf0\xb7\xb1\x5a\x53\xea"
+ "\x1c\xaa\x6b\x29\xc2\xca\xfb\xaf",
+ .klen = 32,
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x02",
+ .input = "\xab\x72\x0a\xad\x3b\x0c\xf0\xc9"
+ "\x42\x2f\xf1\xae\xf1\x3c\xb1\xbd",
+ .ilen = 16,
+ .result = "\x30\x31\x32\x33\x34\x35\x36\x37"
+ "\x38\x39\x41\x42\x43\x44\x45\x46",
+ .rlen = 16,
+ }, {
+ .key = "\xd8\x2a\x91\x34\xb2\x6a\x56\x50"
+ "\x30\xfe\x69\xe2\x37\x7f\x98\x47"
+ "\xcd\xf9\x0b\x16\x0c\x64\x8f\xb6"
+ "\xb0\x0d\x0d\x1b\xae\x85\x87\x1f",
+ .klen = 32,
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x02\x00\x00\x00\x00",
+ .input = "\x85\xa7\x56\x67\x08\xfa\x42\xe1"
+ "\x22\xe6\x82\xfc\xd9\xb4\xd7\xd4",
+ .ilen = 16,
+ .result = "\x30\x31\x32\x33\x34\x35\x36\x37"
+ "\x38\x39\x41\x42\x43\x44\x45\x46",
+ .rlen = 16,
+ }, {
+ .key = "\x0f\x6a\xef\xf8\xd3\xd2\xbb\x15"
+ "\x25\x83\xf7\x3c\x1f\x01\x28\x74"
+ "\xca\xc6\xbc\x35\x4d\x4a\x65\x54"
+ "\x90\xae\x61\xcf\x7b\xae\xbd\xcc"
+ "\xad\xe4\x94\xc5\x4a\x29\xae\x70",
+ .klen = 40,
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x01",
+ .input = "\xd2\xaf\x69\x35\x24\x1d\x0e\x1c"
+ "\x84\x8b\x05\xe4\xa2\x2f\x16\xf5",
+ .ilen = 16,
+ .result = "\x30\x31\x32\x33\x34\x35\x36\x37"
+ "\x38\x39\x41\x42\x43\x44\x45\x46",
+ .rlen = 16,
+ }, {
+ .key = "\x8a\xd4\xee\x10\x2f\xbd\x81\xff"
+ "\xf8\x86\xce\xac\x93\xc5\xad\xc6"
+ "\xa0\x19\x07\xc0\x9d\xf7\xbb\xdd"
+ "\x52\x13\xb2\xb7\xf0\xff\x11\xd8"
+ "\xd6\x08\xd0\xcd\x2e\xb1\x17\x6f",
+ .klen = 40,
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x02\x00\x00\x00\x00",
+ .input = "\x4a\x23\x56\xd7\xff\x90\xd0\x9a"
+ "\x0d\x7c\x26\xfc\xf0\xf0\xf6\xe4",
+ .ilen = 16,
+ .result = "\x30\x31\x32\x33\x34\x35\x36\x37"
+ "\x38\x39\x41\x42\x43\x44\x45\x46",
+ .rlen = 16,
+ }, {
+ .key = "\xf8\xd4\x76\xff\xd6\x46\xee\x6c"
+ "\x23\x84\xcb\x1c\x77\xd6\x19\x5d"
+ "\xfe\xf1\xa9\xf3\x7b\xbc\x8d\x21"
+ "\xa7\x9c\x21\xf8\xcb\x90\x02\x89"
+ "\xa8\x45\x34\x8e\xc8\xc5\xb5\xf1"
+ "\x26\xf5\x0e\x76\xfe\xfd\x1b\x1e",
+ .klen = 48,
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x01",
+ .input = "\x30\xaf\x26\x05\x9d\x5d\x0a\x58"
+ "\xe2\xe7\xce\x8a\xb2\x56\x6d\x76",
+ .ilen = 16,
+ .result = "\x30\x31\x32\x33\x34\x35\x36\x37"
+ "\x38\x39\x41\x42\x43\x44\x45\x46",
+ .rlen = 16,
+ }, {
+ .key = "\xfb\x76\x15\xb2\x3d\x80\x89\x1d"
+ "\xd4\x70\x98\x0b\xc7\x95\x84\xc8"
+ "\xb2\xfb\x64\xce\x60\x97\x87\x8d"
+ "\x17\xfc\xe4\x5a\x49\xe8\x30\xb7"
+ "\x6e\x78\x17\xe7\x2d\x5e\x12\xd4"
+ "\x60\x64\x04\x7a\xf1\x2f\x9e\x0c",
+ .klen = 48,
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x02\x00\x00\x00\x00",
+ .input = "\xdf\xcf\xdc\xd2\xe1\xcf\x86\x75"
+ "\x17\x66\x5e\x0c\x14\xa1\x3d\x40",
+ .ilen = 16,
+ .result = "\x30\x31\x32\x33\x34\x35\x36\x37"
+ "\x38\x39\x41\x42\x43\x44\x45\x46",
+ .rlen = 16,
+ }, {
+ .key = "\xf8\xd4\x76\xff\xd6\x46\xee\x6c"
+ "\x23\x84\xcb\x1c\x77\xd6\x19\x5d"
+ "\xfe\xf1\xa9\xf3\x7b\xbc\x8d\x21"
+ "\xa7\x9c\x21\xf8\xcb\x90\x02\x89"
+ "\xa8\x45\x34\x8e\xc8\xc5\xb5\xf1"
+ "\x26\xf5\x0e\x76\xfe\xfd\x1b\x1e",
+ .klen = 48,
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x01",
+ .input = "\x30\x38\xeb\xaf\x12\x43\x1a\x89"
+ "\x62\xa2\x36\xe5\xcf\x77\x1e\xd9"
+ "\x08\xc3\x0d\xdd\x95\xab\x19\x96"
+ "\x27\x52\x41\xc3\xca\xfb\xf6\xee"
+ "\x40\x2d\xdf\xdd\x00\x0c\xb9\x0a"
+ "\x3a\xf0\xc0\xd1\xda\x63\x9e\x45"
+ "\x42\xe9\x29\xc0\xb4\x07\xb4\x31"
+ "\x66\x77\x72\xb5\xb6\xb3\x57\x46"
+ "\x34\x9a\xfe\x03\xaf\x6b\x36\x07"
+ "\x63\x8e\xc2\x5d\xa6\x0f\xb6\x7d"
+ "\xfb\x6d\x82\x51\xb6\x98\xd0\x71"
+ "\xe7\x10\x7a\xdf\xb2\xbd\xf1\x1d"
+ "\x72\x2b\x54\x13\xe3\x6d\x79\x37"
+ "\xa9\x39\x2c\xdf\x21\xab\x87\xd5"
+ "\xee\xef\x9a\x12\x50\x39\x2e\x1b"
+ "\x7d\xe6\x6a\x27\x48\xb9\xe7\xac"
+ "\xaa\xcd\x79\x5f\xf2\xf3\xa0\x08"
+ "\x6f\x2c\xf4\x0e\xd1\xb8\x89\x25"
+ "\x31\x9d\xef\xb1\x1d\x27\x55\x04"
+ "\xc9\x8c\xb7\x68\xdc\xb6\x67\x8a"
+ "\xdb\xcf\x22\xf2\x3b\x6f\xce\xbb"
+ "\x26\xbe\x4f\x27\x04\x42\xd1\x44"
+ "\x4c\x08\xa3\x95\x4c\x7f\x1a\xaf"
+ "\x1d\x28\x14\xfd\xb1\x1a\x34\x18"
+ "\xf5\x1e\x28\x69\x95\x6a\x5a\xba"
+ "\x8e\xb2\x58\x1d\x28\x17\x13\x3d"
+ "\x38\x7d\x14\x8d\xab\x5d\xf9\xe8"
+ "\x3c\x0f\x2b\x0d\x2b\x08\xb4\x4b"
+ "\x6b\x0d\xc8\xa7\x84\xc2\x3a\x1a"
+ "\xb7\xbd\xda\x92\x29\xb8\x5b\x5a"
+ "\x63\xa5\x99\x82\x09\x72\x8f\xc6"
+ "\xa4\x62\x24\x69\x8c\x2d\x26\x00"
+ "\x99\x83\x91\xd6\xc6\xcf\x57\x67"
+ "\x38\xea\xf2\xfc\x29\xe0\x73\x39"
+ "\xf9\x13\x94\x6d\xe2\x58\x28\x75"
+ "\x3e\xae\x71\x90\x07\x70\x1c\x38"
+ "\x5b\x4c\x1e\xb5\xa5\x3b\x20\xef"
+ "\xb1\x4c\x3e\x1a\x72\x62\xbb\x22"
+ "\x82\x09\xe3\x18\x3f\x4f\x48\xfc"
+ "\xdd\xac\xfc\xb6\x09\xdb\xd2\x7b"
+ "\xd6\xb7\x7e\x41\x2f\x14\xf5\x0e"
+ "\xc3\xac\x4a\xed\xe7\x82\xef\x31"
+ "\x1f\x1a\x51\x1e\x29\x60\xc8\x98"
+ "\x93\x51\x1d\x3d\x62\x59\x83\x82"
+ "\x0c\xf1\xd7\x8d\xac\x33\x44\x81"
+ "\x3c\x59\xb7\xd4\x5b\x65\x82\xc4"
+ "\xec\xdc\x24\xfd\x0e\x1a\x79\x94"
+ "\x34\xb0\x62\xfa\x98\x49\x26\x1f"
+ "\xf4\x9e\x40\x44\x5b\x1f\xf8\xbe"
+ "\x36\xff\xc6\xc6\x9d\xf2\xd6\xcc"
+ "\x63\x93\x29\xb9\x0b\x6d\xd7\x6c"
+ "\xdb\xf6\x21\x80\xf7\x5a\x37\x15"
+ "\x0c\xe3\x36\xc8\x74\x75\x20\x91"
+ "\xdf\x52\x2d\x0c\xe7\x45\xff\x46"
+ "\xb3\xf4\xec\xc2\xbd\xd3\x37\xb6"
+ "\x26\xa2\x5d\x7d\x61\xbf\x10\x46"
+ "\x57\x8d\x05\x96\x70\x0b\xd6\x41"
+ "\x5c\xe9\xd3\x54\x81\x39\x3a\xdd"
+ "\x5f\x92\x81\x6e\x35\x03\xd4\x72"
+ "\x3d\x5a\xe7\xb9\x3b\x0c\x84\x23"
+ "\x45\x5d\xec\x72\xc1\x52\xef\x2e"
+ "\x81\x00\xd3\xfe\x4c\x3c\x05\x61"
+ "\x80\x18\xc4\x6c\x03\xd3\xb7\xba"
+ "\x11\xd7\xb8\x6e\xea\xe1\x80\x30",
+ .ilen = 512,
+ .result = "\x05\x11\xb7\x18\xab\xc6\x2d\xac"
+ "\x70\x5d\xf6\x22\x94\xcd\xe5\x6c"
+ "\x17\x6b\xf6\x1c\xf0\xf3\x6e\xf8"
+ "\x50\x38\x1f\x71\x49\xb6\x57\xd6"
+ "\x8f\xcb\x8d\x6b\xe3\xa6\x29\x90"
+ "\xfe\x2a\x62\x82\xae\x6d\x8b\xf6"
+ "\xad\x1e\x9e\x20\x5f\x38\xbe\x04"
+ "\xda\x10\x8e\xed\xa2\xa4\x87\xab"
+ "\xda\x6b\xb4\x0c\x75\xba\xd3\x7c"
+ "\xc9\xac\x42\x31\x95\x7c\xc9\x04"
+ "\xeb\xd5\x6e\x32\x69\x8a\xdb\xa6"
+ "\x15\xd7\x3f\x4f\x2f\x66\x69\x03"
+ "\x9c\x1f\x54\x0f\xde\x1f\xf3\x65"
+ "\x4c\x96\x12\xed\x7c\x92\x03\x01"
+ "\x6f\xbc\x35\x93\xac\xf1\x27\xf1"
+ "\xb4\x96\x82\x5a\x5f\xb0\xa0\x50"
+ "\x89\xa4\x8e\x66\x44\x85\xcc\xfd"
+ "\x33\x14\x70\xe3\x96\xb2\xc3\xd3"
+ "\xbb\x54\x5a\x1a\xf9\x74\xa2\xc5"
+ "\x2d\x64\x75\xdd\xb4\x54\xe6\x74"
+ "\x8c\xd3\x9d\x9e\x86\xab\x51\x53"
+ "\xb7\x93\x3e\x6f\xd0\x4e\x2c\x40"
+ "\xf6\xa8\x2e\x3e\x9d\xf4\x66\xa5"
+ "\x76\x12\x73\x44\x1a\x56\xd7\x72"
+ "\x88\xcd\x21\x8c\x4c\x0f\xfe\xda"
+ "\x95\xe0\x3a\xa6\xa5\x84\x46\xcd"
+ "\xd5\x3e\x9d\x3a\xe2\x67\xe6\x60"
+ "\x1a\xe2\x70\x85\x58\xc2\x1b\x09"
+ "\xe1\xd7\x2c\xca\xad\xa8\x8f\xf9"
+ "\xac\xb3\x0e\xdb\xca\x2e\xe2\xb8"
+ "\x51\x71\xd9\x3c\x6c\xf1\x56\xf8"
+ "\xea\x9c\xf1\xfb\x0c\xe6\xb7\x10"
+ "\x1c\xf8\xa9\x7c\xe8\x53\x35\xc1"
+ "\x90\x3e\x76\x4a\x74\xa4\x21\x2c"
+ "\xf6\x2c\x4e\x0f\x94\x3a\x88\x2e"
+ "\x41\x09\x6a\x33\x7d\xf6\xdd\x3f"
+ "\x8d\x23\x31\x74\x84\xeb\x88\x6e"
+ "\xcc\xb9\xbc\x22\x83\x19\x07\x22"
+ "\xa5\x2d\xdf\xa5\xf3\x80\x85\x78"
+ "\x84\x39\x6a\x6d\x6a\x99\x4f\xa5"
+ "\x15\xfe\x46\xb0\xe4\x6c\xa5\x41"
+ "\x3c\xce\x8f\x42\x60\x71\xa7\x75"
+ "\x08\x40\x65\x8a\x82\xbf\xf5\x43"
+ "\x71\x96\xa9\x4d\x44\x8a\x20\xbe"
+ "\xfa\x4d\xbb\xc0\x7d\x31\x96\x65"
+ "\xe7\x75\xe5\x3e\xfd\x92\x3b\xc9"
+ "\x55\xbb\x16\x7e\xf7\xc2\x8c\xa4"
+ "\x40\x1d\xe5\xef\x0e\xdf\xe4\x9a"
+ "\x62\x73\x65\xfd\x46\x63\x25\x3d"
+ "\x2b\xaf\xe5\x64\xfe\xa5\x5c\xcf"
+ "\x24\xf3\xb4\xac\x64\xba\xdf\x4b"
+ "\xc6\x96\x7d\x81\x2d\x8d\x97\xf7"
+ "\xc5\x68\x77\x84\x32\x2b\xcc\x85"
+ "\x74\x96\xf0\x12\x77\x61\xb9\xeb"
+ "\x71\xaa\x82\xcb\x1c\xdb\x89\xc8"
+ "\xc6\xb5\xe3\x5c\x7d\x39\x07\x24"
+ "\xda\x39\x87\x45\xc0\x2b\xbb\x01"
+ "\xac\xbc\x2a\x5c\x7f\xfc\xe8\xce"
+ "\x6d\x9c\x6f\xed\xd3\xc1\xa1\xd6"
+ "\xc5\x55\xa9\x66\x2f\xe1\xc8\x32"
+ "\xa6\x5d\xa4\x3a\x98\x73\xe8\x45"
+ "\xa4\xc7\xa8\xb4\xf6\x13\x03\xf6"
+ "\xe9\x2e\xc4\x29\x0f\x84\xdb\xc4"
+ "\x21\xc4\xc2\x75\x67\x89\x37\x0a",
+ .rlen = 512,
+ },
+};
+
+static struct cipher_testvec tf_xts_enc_tv_template[] = {
+ /* Generated from AES-XTS test vectors */
+{
+ .key = "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .klen = 32,
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .input = "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .ilen = 32,
+ .result = "\x4b\xc9\x44\x4a\x11\xa3\xef\xac"
+ "\x30\x74\xe4\x44\x52\x77\x97\x43"
+ "\xa7\x60\xb2\x45\x2e\xf9\x00\x90"
+ "\x9f\xaa\xfd\x89\x6e\x9d\x4a\xe0",
+ .rlen = 32,
+ }, {
+ .key = "\x11\x11\x11\x11\x11\x11\x11\x11"
+ "\x11\x11\x11\x11\x11\x11\x11\x11"
+ "\x22\x22\x22\x22\x22\x22\x22\x22"
+ "\x22\x22\x22\x22\x22\x22\x22\x22",
+ .klen = 32,
+ .iv = "\x33\x33\x33\x33\x33\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .input = "\x44\x44\x44\x44\x44\x44\x44\x44"
+ "\x44\x44\x44\x44\x44\x44\x44\x44"
+ "\x44\x44\x44\x44\x44\x44\x44\x44"
+ "\x44\x44\x44\x44\x44\x44\x44\x44",
+ .ilen = 32,
+ .result = "\x57\x0e\x8f\xe5\x2a\x35\x61\x4f"
+ "\x32\xd3\xbd\x36\x05\x15\x44\x2c"
+ "\x58\x06\xf7\xf8\x00\xa8\xb6\xd5"
+ "\xc6\x28\x92\xdb\xd8\x34\xa2\xe9",
+ .rlen = 32,
+ }, {
+ .key = "\xff\xfe\xfd\xfc\xfb\xfa\xf9\xf8"
+ "\xf7\xf6\xf5\xf4\xf3\xf2\xf1\xf0"
+ "\x22\x22\x22\x22\x22\x22\x22\x22"
+ "\x22\x22\x22\x22\x22\x22\x22\x22",
+ .klen = 32,
+ .iv = "\x33\x33\x33\x33\x33\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .input = "\x44\x44\x44\x44\x44\x44\x44\x44"
+ "\x44\x44\x44\x44\x44\x44\x44\x44"
+ "\x44\x44\x44\x44\x44\x44\x44\x44"
+ "\x44\x44\x44\x44\x44\x44\x44\x44",
+ .ilen = 32,
+ .result = "\x96\x45\x8f\x8d\x7a\x75\xb1\xde"
+ "\x40\x0c\x89\x56\xf6\x4d\xa7\x07"
+ "\x38\xbb\x5b\xe9\xcd\x84\xae\xb2"
+ "\x7b\x6a\x62\xf4\x8c\xb5\x37\xea",
+ .rlen = 32,
+ }, {
+ .key = "\x27\x18\x28\x18\x28\x45\x90\x45"
+ "\x23\x53\x60\x28\x74\x71\x35\x26"
+ "\x31\x41\x59\x26\x53\x58\x97\x93"
+ "\x23\x84\x62\x64\x33\x83\x27\x95",
+ .klen = 32,
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .input = "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+ "\x10\x11\x12\x13\x14\x15\x16\x17"
+ "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
+ "\x20\x21\x22\x23\x24\x25\x26\x27"
+ "\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f"
+ "\x30\x31\x32\x33\x34\x35\x36\x37"
+ "\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f"
+ "\x40\x41\x42\x43\x44\x45\x46\x47"
+ "\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f"
+ "\x50\x51\x52\x53\x54\x55\x56\x57"
+ "\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f"
+ "\x60\x61\x62\x63\x64\x65\x66\x67"
+ "\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f"
+ "\x70\x71\x72\x73\x74\x75\x76\x77"
+ "\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f"
+ "\x80\x81\x82\x83\x84\x85\x86\x87"
+ "\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
+ "\x90\x91\x92\x93\x94\x95\x96\x97"
+ "\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
+ "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7"
+ "\xa8\xa9\xaa\xab\xac\xad\xae\xaf"
+ "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7"
+ "\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
+ "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7"
+ "\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
+ "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7"
+ "\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf"
+ "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7"
+ "\xe8\xe9\xea\xeb\xec\xed\xee\xef"
+ "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7"
+ "\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"
+ "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+ "\x10\x11\x12\x13\x14\x15\x16\x17"
+ "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
+ "\x20\x21\x22\x23\x24\x25\x26\x27"
+ "\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f"
+ "\x30\x31\x32\x33\x34\x35\x36\x37"
+ "\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f"
+ "\x40\x41\x42\x43\x44\x45\x46\x47"
+ "\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f"
+ "\x50\x51\x52\x53\x54\x55\x56\x57"
+ "\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f"
+ "\x60\x61\x62\x63\x64\x65\x66\x67"
+ "\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f"
+ "\x70\x71\x72\x73\x74\x75\x76\x77"
+ "\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f"
+ "\x80\x81\x82\x83\x84\x85\x86\x87"
+ "\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
+ "\x90\x91\x92\x93\x94\x95\x96\x97"
+ "\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
+ "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7"
+ "\xa8\xa9\xaa\xab\xac\xad\xae\xaf"
+ "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7"
+ "\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
+ "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7"
+ "\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
+ "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7"
+ "\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf"
+ "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7"
+ "\xe8\xe9\xea\xeb\xec\xed\xee\xef"
+ "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7"
+ "\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff",
+ .ilen = 512,
+ .result = "\xa9\x78\xae\x1e\xea\xa2\x44\x4c"
+ "\xa2\x7a\x64\x1f\xaf\x46\xc1\xe0"
+ "\x6c\xb2\xf3\x92\x9a\xd6\x7d\x58"
+ "\xb8\x2d\xb9\x5d\x58\x07\x66\x50"
+ "\xea\x35\x35\x8c\xb2\x46\x61\x06"
+ "\x5d\x65\xfc\x57\x8f\x69\x74\xab"
+ "\x8a\x06\x69\xb5\x6c\xda\x66\xc7"
+ "\x52\x90\xbb\x8e\x6d\x8b\xb5\xa2"
+ "\x78\x1d\xc2\xa9\xc2\x73\x00\xc3"
+ "\x32\x36\x7c\x97\x6b\x4e\x8a\x50"
+ "\xe4\x91\x83\x96\x8f\xf4\x94\x1a"
+ "\xa6\x27\xe1\x33\xcb\x91\xc6\x5f"
+ "\x94\x75\xbc\xd7\x3e\x3e\x6f\x9e"
+ "\xa9\x31\x80\x5e\xe5\xdb\xc8\x53"
+ "\x01\x73\x68\x32\x25\x19\xfa\xfb"
+ "\xe4\xcf\xb9\x3e\xa2\xa0\x8f\x31"
+ "\xbf\x54\x06\x93\xa8\xb1\x0f\xb6"
+ "\x7c\x3c\xde\x6f\x0f\xfb\x0c\x11"
+ "\x39\x80\x39\x09\x97\x65\xf2\x83"
+ "\xae\xe6\xa1\x6f\x47\xb8\x49\xde"
+ "\x99\x36\x20\x7d\x97\x3b\xec\xfa"
+ "\xb4\x33\x6e\x7a\xc7\x46\x84\x49"
+ "\x91\xcd\xe1\x57\x0d\xed\x40\x08"
+ "\x13\xf1\x4e\x3e\xa4\xa4\x5c\xe6"
+ "\xd2\x0c\x20\x8f\x3e\xdf\x3f\x47"
+ "\x9a\x2f\xde\x6d\x66\xc9\x99\x4a"
+ "\x2d\x9e\x9d\x4b\x1a\x27\xa2\x12"
+ "\x99\xf0\xf8\xb1\xb6\xf6\x57\xc3"
+ "\xca\x1c\xa3\x8e\xed\x39\x28\xb5"
+ "\x10\x1b\x4b\x08\x42\x00\x4a\xd3"
+ "\xad\x5a\xc6\x8e\xc8\xbb\x95\xc4"
+ "\x4b\xaa\xfe\xd5\x42\xa8\xa3\x6d"
+ "\x3c\xf3\x34\x91\x2d\xb4\xdd\x20"
+ "\x0c\x90\x6d\xa3\x9b\x66\x9d\x24"
+ "\x02\xa6\xa9\x3f\x3f\x58\x5d\x47"
+ "\x24\x65\x63\x7e\xbd\x8c\xe6\x52"
+ "\x7d\xef\x33\x53\x63\xec\xaa\x0b"
+ "\x64\x15\xa9\xa6\x1f\x10\x00\x38"
+ "\x35\xa8\xe7\xbe\x23\x70\x22\xe0"
+ "\xd3\xb9\xe6\xfd\xe6\xaa\x03\x50"
+ "\xf3\x3c\x27\x36\x8b\xcc\xfe\x9c"
+ "\x9c\xa3\xb3\xe7\x68\x9b\xa2\x71"
+ "\xe0\x07\xd9\x1f\x68\x1f\xac\x5e"
+ "\x7a\x74\x85\xa9\x6a\x90\xab\x2c"
+ "\x38\x51\xbc\x1f\x43\x4a\x56\x1c"
+ "\xf8\x47\x03\x4e\x67\xa8\x1f\x99"
+ "\x04\x39\x73\x32\xb2\x86\x79\xe7"
+ "\x14\x28\x70\xb8\xe2\x7d\x69\x85"
+ "\xb6\x0f\xc5\xd0\xd0\x01\x5c\xe6"
+ "\x09\x0f\x75\xf7\xb6\x81\xd2\x11"
+ "\x20\x9c\xa1\xee\x11\x44\x79\xd0"
+ "\xb2\x34\x77\xda\x10\x9a\x6f\x6f"
+ "\xef\x7c\xd9\xdc\x35\xb7\x61\xdd"
+ "\xf1\xa4\xc6\x1c\xbf\x05\x22\xac"
+ "\xfe\x2f\x85\x00\x44\xdf\x33\x16"
+ "\x35\xb6\xa3\xd3\x70\xdf\x69\x35"
+ "\x6a\xc7\xb4\x99\x45\x27\xc8\x8e"
+ "\x5a\x14\x30\xd0\x55\x3e\x4f\x64"
+ "\x0d\x38\xe3\xdf\x8b\xa8\x93\x26"
+ "\x75\xae\xf6\xb5\x23\x0b\x17\x31"
+ "\xbf\x27\xb8\xb5\x94\x31\xa7\x8f"
+ "\x43\xc4\x46\x24\x22\x4f\x8f\x7e"
+ "\xe5\xf4\x6d\x1e\x0e\x18\x7a\xbb"
+ "\xa6\x8f\xfb\x49\x49\xd8\x7e\x5a",
+ .rlen = 512,
+ }, {
+ .key = "\x27\x18\x28\x18\x28\x45\x90\x45"
+ "\x23\x53\x60\x28\x74\x71\x35\x26"
+ "\x62\x49\x77\x57\x24\x70\x93\x69"
+ "\x99\x59\x57\x49\x66\x96\x76\x27"
+ "\x31\x41\x59\x26\x53\x58\x97\x93"
+ "\x23\x84\x62\x64\x33\x83\x27\x95"
+ "\x02\x88\x41\x97\x16\x93\x99\x37"
+ "\x51\x05\x82\x09\x74\x94\x45\x92",
+ .klen = 64,
+ .iv = "\xff\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .input = "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+ "\x10\x11\x12\x13\x14\x15\x16\x17"
+ "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
+ "\x20\x21\x22\x23\x24\x25\x26\x27"
+ "\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f"
+ "\x30\x31\x32\x33\x34\x35\x36\x37"
+ "\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f"
+ "\x40\x41\x42\x43\x44\x45\x46\x47"
+ "\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f"
+ "\x50\x51\x52\x53\x54\x55\x56\x57"
+ "\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f"
+ "\x60\x61\x62\x63\x64\x65\x66\x67"
+ "\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f"
+ "\x70\x71\x72\x73\x74\x75\x76\x77"
+ "\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f"
+ "\x80\x81\x82\x83\x84\x85\x86\x87"
+ "\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
+ "\x90\x91\x92\x93\x94\x95\x96\x97"
+ "\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
+ "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7"
+ "\xa8\xa9\xaa\xab\xac\xad\xae\xaf"
+ "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7"
+ "\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
+ "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7"
+ "\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
+ "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7"
+ "\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf"
+ "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7"
+ "\xe8\xe9\xea\xeb\xec\xed\xee\xef"
+ "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7"
+ "\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"
+ "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+ "\x10\x11\x12\x13\x14\x15\x16\x17"
+ "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
+ "\x20\x21\x22\x23\x24\x25\x26\x27"
+ "\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f"
+ "\x30\x31\x32\x33\x34\x35\x36\x37"
+ "\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f"
+ "\x40\x41\x42\x43\x44\x45\x46\x47"
+ "\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f"
+ "\x50\x51\x52\x53\x54\x55\x56\x57"
+ "\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f"
+ "\x60\x61\x62\x63\x64\x65\x66\x67"
+ "\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f"
+ "\x70\x71\x72\x73\x74\x75\x76\x77"
+ "\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f"
+ "\x80\x81\x82\x83\x84\x85\x86\x87"
+ "\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
+ "\x90\x91\x92\x93\x94\x95\x96\x97"
+ "\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
+ "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7"
+ "\xa8\xa9\xaa\xab\xac\xad\xae\xaf"
+ "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7"
+ "\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
+ "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7"
+ "\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
+ "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7"
+ "\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf"
+ "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7"
+ "\xe8\xe9\xea\xeb\xec\xed\xee\xef"
+ "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7"
+ "\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff",
+ .ilen = 512,
+ .result = "\xd7\x4b\x93\x7d\x13\xa2\xa2\xe1"
+ "\x35\x39\x71\x88\x76\x1e\xc9\xea"
+ "\x86\xad\xf3\x14\x48\x3d\x5e\xe9"
+ "\xe9\x2d\xb2\x56\x59\x35\x9d\xec"
+ "\x84\xfa\x7e\x9d\x6d\x33\x36\x8f"
+ "\xce\xf4\xa9\x21\x0b\x5f\x96\xec"
+ "\xcb\xf9\x57\x68\x33\x88\x39\xbf"
+ "\x2f\xbb\x59\x03\xbd\x66\x8b\x11"
+ "\x11\x65\x51\x2e\xb8\x67\x05\xd1"
+ "\x27\x11\x5c\xd4\xcc\x97\xc2\xb3"
+ "\xa9\x55\xaf\x07\x56\xd1\xdc\xf5"
+ "\x85\xdc\x46\xe6\xf0\x24\xeb\x93"
+ "\x4d\xf0\x9b\xf5\x73\x1c\xda\x03"
+ "\x22\xc8\x3a\x4f\xb4\x19\x91\x09"
+ "\x54\x0b\xf6\xfe\x17\x3d\x1a\x53"
+ "\x72\x60\x79\xcb\x0e\x32\x8a\x77"
+ "\xd5\xed\xdb\x33\xd7\x62\x16\x69"
+ "\x63\xe0\xab\xb5\xf6\x9c\x5f\x3d"
+ "\x69\x35\x61\x86\xf8\x86\xb9\x89"
+ "\x6e\x59\x35\xac\xf6\x6b\x33\xa0"
+ "\xea\xef\x96\x62\xd8\xa9\xcf\x56"
+ "\xbf\xdb\x8a\xfd\xa1\x82\x77\x73"
+ "\x3d\x94\x4a\x49\x42\x6d\x08\x60"
+ "\xa1\xea\xab\xb6\x88\x13\x94\xb8"
+ "\x51\x98\xdb\x35\x85\xdf\xf6\xb9"
+ "\x8f\xcd\xdf\x80\xd3\x40\x2d\x72"
+ "\xb8\xb2\x6c\x02\x43\x35\x22\x2a"
+ "\x31\xed\xcd\x16\x19\xdf\x62\x0f"
+ "\x29\xcf\x87\x04\xec\x02\x4f\xe4"
+ "\xa2\xed\x73\xc6\x69\xd3\x7e\x89"
+ "\x0b\x76\x10\x7c\xd6\xf9\x6a\x25"
+ "\xed\xcc\x60\x5d\x61\x20\xc1\x97"
+ "\x56\x91\x57\x28\xbe\x71\x0d\xcd"
+ "\xde\xc4\x9e\x55\x91\xbe\xd1\x28"
+ "\x9b\x90\xeb\x73\xf3\x68\x51\xc6"
+ "\xdf\x82\xcc\xd8\x1f\xce\x5b\x27"
+ "\xc0\x60\x5e\x33\xd6\xa7\x20\xea"
+ "\xb2\x54\xc7\x5d\x6a\x3b\x67\x47"
+ "\xcf\xa0\xe3\xab\x86\xaf\xc1\x42"
+ "\xe6\xb0\x23\x4a\xaf\x53\xdf\xa0"
+ "\xad\x12\x32\x31\x03\xf7\x21\xbe"
+ "\x2d\xd5\x82\x42\xb6\x4a\x3d\xcd"
+ "\xd8\x81\x77\xa9\x49\x98\x6c\x09"
+ "\xc5\xa3\x61\x12\x62\x85\x6b\xcd"
+ "\xb3\xf4\x20\x0c\x41\xc4\x05\x37"
+ "\x46\x5f\xeb\x71\x8b\xf1\xaf\x6e"
+ "\xba\xf3\x50\x2e\xfe\xa8\x37\xeb"
+ "\xe8\x8c\x4f\xa4\x0c\xf1\x31\xc8"
+ "\x6e\x71\x4f\xa5\xd7\x97\x73\xe0"
+ "\x93\x4a\x2f\xda\x7b\xe0\x20\x54"
+ "\x1f\x8d\x85\x79\x0b\x7b\x5e\x75"
+ "\xb9\x07\x67\xcc\xc8\xe7\x21\x15"
+ "\xa7\xc8\x98\xff\x4b\x80\x1c\x12"
+ "\xa8\x54\xe1\x38\x52\xe6\x74\x81"
+ "\x97\x47\xa1\x41\x0e\xc0\x50\xe3"
+ "\x55\x0e\xc3\xa7\x70\x77\xce\x07"
+ "\xed\x8c\x88\xe6\xa1\x5b\x14\xec"
+ "\xe6\xde\x06\x6d\x74\xc5\xd9\xfa"
+ "\xe5\x2f\x5a\xff\xc8\x05\xee\x27"
+ "\x35\x61\xbf\x0b\x19\x78\x9b\xd2"
+ "\x04\xc7\x05\xb1\x79\xb4\xff\x5f"
+ "\xf3\xea\x67\x52\x78\xc2\xce\x70"
+ "\xa4\x05\x0b\xb2\xb3\xa8\x30\x97"
+ "\x37\x30\xe1\x91\x8d\xb3\x2a\xff",
+ .rlen = 512,
+ },
+};
+
+static struct cipher_testvec tf_xts_dec_tv_template[] = {
+ /* Generated from AES-XTS test vectors */
+ /* same as enc vectors with input and result reversed */
+ {
+ .key = "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .klen = 32,
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .input = "\x4b\xc9\x44\x4a\x11\xa3\xef\xac"
+ "\x30\x74\xe4\x44\x52\x77\x97\x43"
+ "\xa7\x60\xb2\x45\x2e\xf9\x00\x90"
+ "\x9f\xaa\xfd\x89\x6e\x9d\x4a\xe0",
+ .ilen = 32,
+ .result = "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .rlen = 32,
+ }, {
+ .key = "\x11\x11\x11\x11\x11\x11\x11\x11"
+ "\x11\x11\x11\x11\x11\x11\x11\x11"
+ "\x22\x22\x22\x22\x22\x22\x22\x22"
+ "\x22\x22\x22\x22\x22\x22\x22\x22",
+ .klen = 32,
+ .iv = "\x33\x33\x33\x33\x33\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .input = "\x57\x0e\x8f\xe5\x2a\x35\x61\x4f"
+ "\x32\xd3\xbd\x36\x05\x15\x44\x2c"
+ "\x58\x06\xf7\xf8\x00\xa8\xb6\xd5"
+ "\xc6\x28\x92\xdb\xd8\x34\xa2\xe9",
+ .ilen = 32,
+ .result = "\x44\x44\x44\x44\x44\x44\x44\x44"
+ "\x44\x44\x44\x44\x44\x44\x44\x44"
+ "\x44\x44\x44\x44\x44\x44\x44\x44"
+ "\x44\x44\x44\x44\x44\x44\x44\x44",
+ .rlen = 32,
+ }, {
+ .key = "\xff\xfe\xfd\xfc\xfb\xfa\xf9\xf8"
+ "\xf7\xf6\xf5\xf4\xf3\xf2\xf1\xf0"
+ "\x22\x22\x22\x22\x22\x22\x22\x22"
+ "\x22\x22\x22\x22\x22\x22\x22\x22",
+ .klen = 32,
+ .iv = "\x33\x33\x33\x33\x33\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .input = "\x96\x45\x8f\x8d\x7a\x75\xb1\xde"
+ "\x40\x0c\x89\x56\xf6\x4d\xa7\x07"
+ "\x38\xbb\x5b\xe9\xcd\x84\xae\xb2"
+ "\x7b\x6a\x62\xf4\x8c\xb5\x37\xea",
+ .ilen = 32,
+ .result = "\x44\x44\x44\x44\x44\x44\x44\x44"
+ "\x44\x44\x44\x44\x44\x44\x44\x44"
+ "\x44\x44\x44\x44\x44\x44\x44\x44"
+ "\x44\x44\x44\x44\x44\x44\x44\x44",
+ .rlen = 32,
+ }, {
+ .key = "\x27\x18\x28\x18\x28\x45\x90\x45"
+ "\x23\x53\x60\x28\x74\x71\x35\x26"
+ "\x31\x41\x59\x26\x53\x58\x97\x93"
+ "\x23\x84\x62\x64\x33\x83\x27\x95",
+ .klen = 32,
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .input = "\xa9\x78\xae\x1e\xea\xa2\x44\x4c"
+ "\xa2\x7a\x64\x1f\xaf\x46\xc1\xe0"
+ "\x6c\xb2\xf3\x92\x9a\xd6\x7d\x58"
+ "\xb8\x2d\xb9\x5d\x58\x07\x66\x50"
+ "\xea\x35\x35\x8c\xb2\x46\x61\x06"
+ "\x5d\x65\xfc\x57\x8f\x69\x74\xab"
+ "\x8a\x06\x69\xb5\x6c\xda\x66\xc7"
+ "\x52\x90\xbb\x8e\x6d\x8b\xb5\xa2"
+ "\x78\x1d\xc2\xa9\xc2\x73\x00\xc3"
+ "\x32\x36\x7c\x97\x6b\x4e\x8a\x50"
+ "\xe4\x91\x83\x96\x8f\xf4\x94\x1a"
+ "\xa6\x27\xe1\x33\xcb\x91\xc6\x5f"
+ "\x94\x75\xbc\xd7\x3e\x3e\x6f\x9e"
+ "\xa9\x31\x80\x5e\xe5\xdb\xc8\x53"
+ "\x01\x73\x68\x32\x25\x19\xfa\xfb"
+ "\xe4\xcf\xb9\x3e\xa2\xa0\x8f\x31"
+ "\xbf\x54\x06\x93\xa8\xb1\x0f\xb6"
+ "\x7c\x3c\xde\x6f\x0f\xfb\x0c\x11"
+ "\x39\x80\x39\x09\x97\x65\xf2\x83"
+ "\xae\xe6\xa1\x6f\x47\xb8\x49\xde"
+ "\x99\x36\x20\x7d\x97\x3b\xec\xfa"
+ "\xb4\x33\x6e\x7a\xc7\x46\x84\x49"
+ "\x91\xcd\xe1\x57\x0d\xed\x40\x08"
+ "\x13\xf1\x4e\x3e\xa4\xa4\x5c\xe6"
+ "\xd2\x0c\x20\x8f\x3e\xdf\x3f\x47"
+ "\x9a\x2f\xde\x6d\x66\xc9\x99\x4a"
+ "\x2d\x9e\x9d\x4b\x1a\x27\xa2\x12"
+ "\x99\xf0\xf8\xb1\xb6\xf6\x57\xc3"
+ "\xca\x1c\xa3\x8e\xed\x39\x28\xb5"
+ "\x10\x1b\x4b\x08\x42\x00\x4a\xd3"
+ "\xad\x5a\xc6\x8e\xc8\xbb\x95\xc4"
+ "\x4b\xaa\xfe\xd5\x42\xa8\xa3\x6d"
+ "\x3c\xf3\x34\x91\x2d\xb4\xdd\x20"
+ "\x0c\x90\x6d\xa3\x9b\x66\x9d\x24"
+ "\x02\xa6\xa9\x3f\x3f\x58\x5d\x47"
+ "\x24\x65\x63\x7e\xbd\x8c\xe6\x52"
+ "\x7d\xef\x33\x53\x63\xec\xaa\x0b"
+ "\x64\x15\xa9\xa6\x1f\x10\x00\x38"
+ "\x35\xa8\xe7\xbe\x23\x70\x22\xe0"
+ "\xd3\xb9\xe6\xfd\xe6\xaa\x03\x50"
+ "\xf3\x3c\x27\x36\x8b\xcc\xfe\x9c"
+ "\x9c\xa3\xb3\xe7\x68\x9b\xa2\x71"
+ "\xe0\x07\xd9\x1f\x68\x1f\xac\x5e"
+ "\x7a\x74\x85\xa9\x6a\x90\xab\x2c"
+ "\x38\x51\xbc\x1f\x43\x4a\x56\x1c"
+ "\xf8\x47\x03\x4e\x67\xa8\x1f\x99"
+ "\x04\x39\x73\x32\xb2\x86\x79\xe7"
+ "\x14\x28\x70\xb8\xe2\x7d\x69\x85"
+ "\xb6\x0f\xc5\xd0\xd0\x01\x5c\xe6"
+ "\x09\x0f\x75\xf7\xb6\x81\xd2\x11"
+ "\x20\x9c\xa1\xee\x11\x44\x79\xd0"
+ "\xb2\x34\x77\xda\x10\x9a\x6f\x6f"
+ "\xef\x7c\xd9\xdc\x35\xb7\x61\xdd"
+ "\xf1\xa4\xc6\x1c\xbf\x05\x22\xac"
+ "\xfe\x2f\x85\x00\x44\xdf\x33\x16"
+ "\x35\xb6\xa3\xd3\x70\xdf\x69\x35"
+ "\x6a\xc7\xb4\x99\x45\x27\xc8\x8e"
+ "\x5a\x14\x30\xd0\x55\x3e\x4f\x64"
+ "\x0d\x38\xe3\xdf\x8b\xa8\x93\x26"
+ "\x75\xae\xf6\xb5\x23\x0b\x17\x31"
+ "\xbf\x27\xb8\xb5\x94\x31\xa7\x8f"
+ "\x43\xc4\x46\x24\x22\x4f\x8f\x7e"
+ "\xe5\xf4\x6d\x1e\x0e\x18\x7a\xbb"
+ "\xa6\x8f\xfb\x49\x49\xd8\x7e\x5a",
+ .ilen = 512,
+ .result = "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+ "\x10\x11\x12\x13\x14\x15\x16\x17"
+ "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
+ "\x20\x21\x22\x23\x24\x25\x26\x27"
+ "\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f"
+ "\x30\x31\x32\x33\x34\x35\x36\x37"
+ "\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f"
+ "\x40\x41\x42\x43\x44\x45\x46\x47"
+ "\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f"
+ "\x50\x51\x52\x53\x54\x55\x56\x57"
+ "\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f"
+ "\x60\x61\x62\x63\x64\x65\x66\x67"
+ "\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f"
+ "\x70\x71\x72\x73\x74\x75\x76\x77"
+ "\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f"
+ "\x80\x81\x82\x83\x84\x85\x86\x87"
+ "\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
+ "\x90\x91\x92\x93\x94\x95\x96\x97"
+ "\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
+ "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7"
+ "\xa8\xa9\xaa\xab\xac\xad\xae\xaf"
+ "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7"
+ "\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
+ "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7"
+ "\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
+ "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7"
+ "\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf"
+ "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7"
+ "\xe8\xe9\xea\xeb\xec\xed\xee\xef"
+ "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7"
+ "\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"
+ "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+ "\x10\x11\x12\x13\x14\x15\x16\x17"
+ "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
+ "\x20\x21\x22\x23\x24\x25\x26\x27"
+ "\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f"
+ "\x30\x31\x32\x33\x34\x35\x36\x37"
+ "\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f"
+ "\x40\x41\x42\x43\x44\x45\x46\x47"
+ "\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f"
+ "\x50\x51\x52\x53\x54\x55\x56\x57"
+ "\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f"
+ "\x60\x61\x62\x63\x64\x65\x66\x67"
+ "\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f"
+ "\x70\x71\x72\x73\x74\x75\x76\x77"
+ "\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f"
+ "\x80\x81\x82\x83\x84\x85\x86\x87"
+ "\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
+ "\x90\x91\x92\x93\x94\x95\x96\x97"
+ "\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
+ "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7"
+ "\xa8\xa9\xaa\xab\xac\xad\xae\xaf"
+ "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7"
+ "\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
+ "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7"
+ "\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
+ "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7"
+ "\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf"
+ "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7"
+ "\xe8\xe9\xea\xeb\xec\xed\xee\xef"
+ "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7"
+ "\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff",
+ .rlen = 512,
+ }, {
+ .key = "\x27\x18\x28\x18\x28\x45\x90\x45"
+ "\x23\x53\x60\x28\x74\x71\x35\x26"
+ "\x62\x49\x77\x57\x24\x70\x93\x69"
+ "\x99\x59\x57\x49\x66\x96\x76\x27"
+ "\x31\x41\x59\x26\x53\x58\x97\x93"
+ "\x23\x84\x62\x64\x33\x83\x27\x95"
+ "\x02\x88\x41\x97\x16\x93\x99\x37"
+ "\x51\x05\x82\x09\x74\x94\x45\x92",
+ .klen = 64,
+ .iv = "\xff\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .input = "\xd7\x4b\x93\x7d\x13\xa2\xa2\xe1"
+ "\x35\x39\x71\x88\x76\x1e\xc9\xea"
+ "\x86\xad\xf3\x14\x48\x3d\x5e\xe9"
+ "\xe9\x2d\xb2\x56\x59\x35\x9d\xec"
+ "\x84\xfa\x7e\x9d\x6d\x33\x36\x8f"
+ "\xce\xf4\xa9\x21\x0b\x5f\x96\xec"
+ "\xcb\xf9\x57\x68\x33\x88\x39\xbf"
+ "\x2f\xbb\x59\x03\xbd\x66\x8b\x11"
+ "\x11\x65\x51\x2e\xb8\x67\x05\xd1"
+ "\x27\x11\x5c\xd4\xcc\x97\xc2\xb3"
+ "\xa9\x55\xaf\x07\x56\xd1\xdc\xf5"
+ "\x85\xdc\x46\xe6\xf0\x24\xeb\x93"
+ "\x4d\xf0\x9b\xf5\x73\x1c\xda\x03"
+ "\x22\xc8\x3a\x4f\xb4\x19\x91\x09"
+ "\x54\x0b\xf6\xfe\x17\x3d\x1a\x53"
+ "\x72\x60\x79\xcb\x0e\x32\x8a\x77"
+ "\xd5\xed\xdb\x33\xd7\x62\x16\x69"
+ "\x63\xe0\xab\xb5\xf6\x9c\x5f\x3d"
+ "\x69\x35\x61\x86\xf8\x86\xb9\x89"
+ "\x6e\x59\x35\xac\xf6\x6b\x33\xa0"
+ "\xea\xef\x96\x62\xd8\xa9\xcf\x56"
+ "\xbf\xdb\x8a\xfd\xa1\x82\x77\x73"
+ "\x3d\x94\x4a\x49\x42\x6d\x08\x60"
+ "\xa1\xea\xab\xb6\x88\x13\x94\xb8"
+ "\x51\x98\xdb\x35\x85\xdf\xf6\xb9"
+ "\x8f\xcd\xdf\x80\xd3\x40\x2d\x72"
+ "\xb8\xb2\x6c\x02\x43\x35\x22\x2a"
+ "\x31\xed\xcd\x16\x19\xdf\x62\x0f"
+ "\x29\xcf\x87\x04\xec\x02\x4f\xe4"
+ "\xa2\xed\x73\xc6\x69\xd3\x7e\x89"
+ "\x0b\x76\x10\x7c\xd6\xf9\x6a\x25"
+ "\xed\xcc\x60\x5d\x61\x20\xc1\x97"
+ "\x56\x91\x57\x28\xbe\x71\x0d\xcd"
+ "\xde\xc4\x9e\x55\x91\xbe\xd1\x28"
+ "\x9b\x90\xeb\x73\xf3\x68\x51\xc6"
+ "\xdf\x82\xcc\xd8\x1f\xce\x5b\x27"
+ "\xc0\x60\x5e\x33\xd6\xa7\x20\xea"
+ "\xb2\x54\xc7\x5d\x6a\x3b\x67\x47"
+ "\xcf\xa0\xe3\xab\x86\xaf\xc1\x42"
+ "\xe6\xb0\x23\x4a\xaf\x53\xdf\xa0"
+ "\xad\x12\x32\x31\x03\xf7\x21\xbe"
+ "\x2d\xd5\x82\x42\xb6\x4a\x3d\xcd"
+ "\xd8\x81\x77\xa9\x49\x98\x6c\x09"
+ "\xc5\xa3\x61\x12\x62\x85\x6b\xcd"
+ "\xb3\xf4\x20\x0c\x41\xc4\x05\x37"
+ "\x46\x5f\xeb\x71\x8b\xf1\xaf\x6e"
+ "\xba\xf3\x50\x2e\xfe\xa8\x37\xeb"
+ "\xe8\x8c\x4f\xa4\x0c\xf1\x31\xc8"
+ "\x6e\x71\x4f\xa5\xd7\x97\x73\xe0"
+ "\x93\x4a\x2f\xda\x7b\xe0\x20\x54"
+ "\x1f\x8d\x85\x79\x0b\x7b\x5e\x75"
+ "\xb9\x07\x67\xcc\xc8\xe7\x21\x15"
+ "\xa7\xc8\x98\xff\x4b\x80\x1c\x12"
+ "\xa8\x54\xe1\x38\x52\xe6\x74\x81"
+ "\x97\x47\xa1\x41\x0e\xc0\x50\xe3"
+ "\x55\x0e\xc3\xa7\x70\x77\xce\x07"
+ "\xed\x8c\x88\xe6\xa1\x5b\x14\xec"
+ "\xe6\xde\x06\x6d\x74\xc5\xd9\xfa"
+ "\xe5\x2f\x5a\xff\xc8\x05\xee\x27"
+ "\x35\x61\xbf\x0b\x19\x78\x9b\xd2"
+ "\x04\xc7\x05\xb1\x79\xb4\xff\x5f"
+ "\xf3\xea\x67\x52\x78\xc2\xce\x70"
+ "\xa4\x05\x0b\xb2\xb3\xa8\x30\x97"
+ "\x37\x30\xe1\x91\x8d\xb3\x2a\xff",
+ .ilen = 512,
+ .result = "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+ "\x10\x11\x12\x13\x14\x15\x16\x17"
+ "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
+ "\x20\x21\x22\x23\x24\x25\x26\x27"
+ "\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f"
+ "\x30\x31\x32\x33\x34\x35\x36\x37"
+ "\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f"
+ "\x40\x41\x42\x43\x44\x45\x46\x47"
+ "\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f"
+ "\x50\x51\x52\x53\x54\x55\x56\x57"
+ "\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f"
+ "\x60\x61\x62\x63\x64\x65\x66\x67"
+ "\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f"
+ "\x70\x71\x72\x73\x74\x75\x76\x77"
+ "\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f"
+ "\x80\x81\x82\x83\x84\x85\x86\x87"
+ "\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
+ "\x90\x91\x92\x93\x94\x95\x96\x97"
+ "\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
+ "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7"
+ "\xa8\xa9\xaa\xab\xac\xad\xae\xaf"
+ "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7"
+ "\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
+ "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7"
+ "\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
+ "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7"
+ "\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf"
+ "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7"
+ "\xe8\xe9\xea\xeb\xec\xed\xee\xef"
+ "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7"
+ "\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"
+ "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+ "\x10\x11\x12\x13\x14\x15\x16\x17"
+ "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
+ "\x20\x21\x22\x23\x24\x25\x26\x27"
+ "\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f"
+ "\x30\x31\x32\x33\x34\x35\x36\x37"
+ "\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f"
+ "\x40\x41\x42\x43\x44\x45\x46\x47"
+ "\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f"
+ "\x50\x51\x52\x53\x54\x55\x56\x57"
+ "\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f"
+ "\x60\x61\x62\x63\x64\x65\x66\x67"
+ "\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f"
+ "\x70\x71\x72\x73\x74\x75\x76\x77"
+ "\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f"
+ "\x80\x81\x82\x83\x84\x85\x86\x87"
+ "\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
+ "\x90\x91\x92\x93\x94\x95\x96\x97"
+ "\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
+ "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7"
+ "\xa8\xa9\xaa\xab\xac\xad\xae\xaf"
+ "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7"
+ "\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
+ "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7"
+ "\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
+ "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7"
+ "\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf"
+ "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7"
+ "\xe8\xe9\xea\xeb\xec\xed\xee\xef"
+ "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7"
+ "\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff",
+ .rlen = 512,
+ },
+};
+
/*
* Serpent test vectors. These are backwards because Serpent writes
* octet sequences in right-to-left mode.
*/
-#define SERPENT_ENC_TEST_VECTORS 4
-#define SERPENT_DEC_TEST_VECTORS 4
+#define SERPENT_ENC_TEST_VECTORS 5
+#define SERPENT_DEC_TEST_VECTORS 5
#define TNEPRES_ENC_TEST_VECTORS 4
#define TNEPRES_DEC_TEST_VECTORS 4
+#define SERPENT_CBC_ENC_TEST_VECTORS 1
+#define SERPENT_CBC_DEC_TEST_VECTORS 1
+
+#define SERPENT_CTR_ENC_TEST_VECTORS 2
+#define SERPENT_CTR_DEC_TEST_VECTORS 2
+
+#define SERPENT_LRW_ENC_TEST_VECTORS 8
+#define SERPENT_LRW_DEC_TEST_VECTORS 8
+
+#define SERPENT_XTS_ENC_TEST_VECTORS 5
+#define SERPENT_XTS_DEC_TEST_VECTORS 5
+
static struct cipher_testvec serpent_enc_tv_template[] = {
{
.input = "\x00\x01\x02\x03\x04\x05\x06\x07"
@@ -3140,6 +4334,50 @@
.result = "\xdd\xd2\x6b\x98\xa5\xff\xd8\x2c"
"\x05\x34\x5a\x9d\xad\xbf\xaf\x49",
.rlen = 16,
+ }, { /* Generated with Crypto++ */
+ .key = "\x85\x62\x3F\x1C\xF9\xD6\x1C\xF9"
+ "\xD6\xB3\x90\x6D\x4A\x90\x6D\x4A"
+ "\x27\x04\xE1\x27\x04\xE1\xBE\x9B"
+ "\x78\xBE\x9B\x78\x55\x32\x0F\x55",
+ .klen = 32,
+ .input = "\x56\xED\x84\x1B\x8F\x26\xBD\x31"
+ "\xC8\x5F\xF6\x6A\x01\x98\x0C\xA3"
+ "\x3A\xD1\x45\xDC\x73\x0A\x7E\x15"
+ "\xAC\x20\xB7\x4E\xE5\x59\xF0\x87"
+ "\x1E\x92\x29\xC0\x34\xCB\x62\xF9"
+ "\x6D\x04\x9B\x0F\xA6\x3D\xD4\x48"
+ "\xDF\x76\x0D\x81\x18\xAF\x23\xBA"
+ "\x51\xE8\x5C\xF3\x8A\x21\x95\x2C"
+ "\xC3\x37\xCE\x65\xFC\x70\x07\x9E"
+ "\x12\xA9\x40\xD7\x4B\xE2\x79\x10"
+ "\x84\x1B\xB2\x26\xBD\x54\xEB\x5F"
+ "\xF6\x8D\x01\x98\x2F\xC6\x3A\xD1"
+ "\x68\xFF\x73\x0A\xA1\x15\xAC\x43"
+ "\xDA\x4E\xE5\x7C\x13\x87\x1E\xB5"
+ "\x29\xC0\x57\xEE\x62\xF9\x90\x04"
+ "\x9B\x32\xC9\x3D\xD4\x6B\x02\x76"
+ "\x0D\xA4\x18\xAF\x46\xDD\x51\xE8"
+ "\x7F\x16\x8A\x21\xB8\x2C\xC3\x5A",
+ .ilen = 144,
+ .result = "\xFB\xB0\x5D\xDE\xC0\xFE\xFC\xEB"
+ "\xB1\x80\x10\x43\xDE\x62\x70\xBD"
+ "\xFA\x8A\x93\xEA\x6B\xF7\xC5\xD7"
+ "\x0C\xD1\xBB\x29\x25\x14\x4C\x22"
+ "\x77\xA6\x38\x00\xDB\xB9\xE2\x07"
+ "\xD1\xAC\x82\xBA\xEA\x67\xAA\x39"
+ "\x99\x34\x89\x5B\x54\xE9\x12\x13"
+ "\x3B\x04\xE5\x12\x42\xC5\x79\xAB"
+ "\x0D\xC7\x3C\x58\x2D\xA3\x98\xF6"
+ "\xE4\x61\x9E\x17\x0B\xCE\xE8\xAA"
+ "\xB5\x6C\x1A\x3A\x67\x52\x81\x6A"
+ "\x04\xFF\x8A\x1B\x96\xFE\xE6\x87"
+ "\x3C\xD4\x39\x7D\x36\x9B\x03\xD5"
+ "\xB6\xA0\x75\x3C\x83\xE6\x1C\x73"
+ "\x9D\x74\x2B\x77\x53\x2D\xE5\xBD"
+ "\x69\xDA\x7A\x01\xF5\x6A\x70\x39"
+ "\x30\xD4\x2C\xF2\x8E\x06\x4B\x39"
+ "\xB3\x12\x1D\xB3\x17\x46\xE6\xD6",
+ .rlen = 144,
},
};
@@ -3231,6 +4469,50 @@
.ilen = 16,
.result = zeroed_string,
.rlen = 16,
+ }, { /* Generated with Crypto++ */
+ .key = "\x85\x62\x3F\x1C\xF9\xD6\x1C\xF9"
+ "\xD6\xB3\x90\x6D\x4A\x90\x6D\x4A"
+ "\x27\x04\xE1\x27\x04\xE1\xBE\x9B"
+ "\x78\xBE\x9B\x78\x55\x32\x0F\x55",
+ .klen = 32,
+ .input = "\xFB\xB0\x5D\xDE\xC0\xFE\xFC\xEB"
+ "\xB1\x80\x10\x43\xDE\x62\x70\xBD"
+ "\xFA\x8A\x93\xEA\x6B\xF7\xC5\xD7"
+ "\x0C\xD1\xBB\x29\x25\x14\x4C\x22"
+ "\x77\xA6\x38\x00\xDB\xB9\xE2\x07"
+ "\xD1\xAC\x82\xBA\xEA\x67\xAA\x39"
+ "\x99\x34\x89\x5B\x54\xE9\x12\x13"
+ "\x3B\x04\xE5\x12\x42\xC5\x79\xAB"
+ "\x0D\xC7\x3C\x58\x2D\xA3\x98\xF6"
+ "\xE4\x61\x9E\x17\x0B\xCE\xE8\xAA"
+ "\xB5\x6C\x1A\x3A\x67\x52\x81\x6A"
+ "\x04\xFF\x8A\x1B\x96\xFE\xE6\x87"
+ "\x3C\xD4\x39\x7D\x36\x9B\x03\xD5"
+ "\xB6\xA0\x75\x3C\x83\xE6\x1C\x73"
+ "\x9D\x74\x2B\x77\x53\x2D\xE5\xBD"
+ "\x69\xDA\x7A\x01\xF5\x6A\x70\x39"
+ "\x30\xD4\x2C\xF2\x8E\x06\x4B\x39"
+ "\xB3\x12\x1D\xB3\x17\x46\xE6\xD6",
+ .ilen = 144,
+ .result = "\x56\xED\x84\x1B\x8F\x26\xBD\x31"
+ "\xC8\x5F\xF6\x6A\x01\x98\x0C\xA3"
+ "\x3A\xD1\x45\xDC\x73\x0A\x7E\x15"
+ "\xAC\x20\xB7\x4E\xE5\x59\xF0\x87"
+ "\x1E\x92\x29\xC0\x34\xCB\x62\xF9"
+ "\x6D\x04\x9B\x0F\xA6\x3D\xD4\x48"
+ "\xDF\x76\x0D\x81\x18\xAF\x23\xBA"
+ "\x51\xE8\x5C\xF3\x8A\x21\x95\x2C"
+ "\xC3\x37\xCE\x65\xFC\x70\x07\x9E"
+ "\x12\xA9\x40\xD7\x4B\xE2\x79\x10"
+ "\x84\x1B\xB2\x26\xBD\x54\xEB\x5F"
+ "\xF6\x8D\x01\x98\x2F\xC6\x3A\xD1"
+ "\x68\xFF\x73\x0A\xA1\x15\xAC\x43"
+ "\xDA\x4E\xE5\x7C\x13\x87\x1E\xB5"
+ "\x29\xC0\x57\xEE\x62\xF9\x90\x04"
+ "\x9B\x32\xC9\x3D\xD4\x6B\x02\x76"
+ "\x0D\xA4\x18\xAF\x46\xDD\x51\xE8"
+ "\x7F\x16\x8A\x21\xB8\x2C\xC3\x5A",
+ .rlen = 144,
},
};
@@ -3275,6 +4557,1479 @@
},
};
+static struct cipher_testvec serpent_cbc_enc_tv_template[] = {
+ { /* Generated with Crypto++ */
+ .key = "\x85\x62\x3F\x1C\xF9\xD6\x1C\xF9"
+ "\xD6\xB3\x90\x6D\x4A\x90\x6D\x4A"
+ "\x27\x04\xE1\x27\x04\xE1\xBE\x9B"
+ "\x78\xBE\x9B\x78\x55\x32\x0F\x55",
+ .klen = 32,
+ .iv = "\xE2\x24\x89\xEE\x53\xB8\x1D\x5F"
+ "\xC4\x29\x8E\xF3\x35\x9A\xFF\x64",
+ .input = "\x56\xED\x84\x1B\x8F\x26\xBD\x31"
+ "\xC8\x5F\xF6\x6A\x01\x98\x0C\xA3"
+ "\x3A\xD1\x45\xDC\x73\x0A\x7E\x15"
+ "\xAC\x20\xB7\x4E\xE5\x59\xF0\x87"
+ "\x1E\x92\x29\xC0\x34\xCB\x62\xF9"
+ "\x6D\x04\x9B\x0F\xA6\x3D\xD4\x48"
+ "\xDF\x76\x0D\x81\x18\xAF\x23\xBA"
+ "\x51\xE8\x5C\xF3\x8A\x21\x95\x2C"
+ "\xC3\x37\xCE\x65\xFC\x70\x07\x9E"
+ "\x12\xA9\x40\xD7\x4B\xE2\x79\x10"
+ "\x84\x1B\xB2\x26\xBD\x54\xEB\x5F"
+ "\xF6\x8D\x01\x98\x2F\xC6\x3A\xD1"
+ "\x68\xFF\x73\x0A\xA1\x15\xAC\x43"
+ "\xDA\x4E\xE5\x7C\x13\x87\x1E\xB5"
+ "\x29\xC0\x57\xEE\x62\xF9\x90\x04"
+ "\x9B\x32\xC9\x3D\xD4\x6B\x02\x76"
+ "\x0D\xA4\x18\xAF\x46\xDD\x51\xE8"
+ "\x7F\x16\x8A\x21\xB8\x2C\xC3\x5A",
+ .ilen = 144,
+ .result = "\x80\xCF\x11\x41\x1A\xB9\x4B\x9C"
+ "\xFF\xB7\x6C\xEA\xF0\xAF\x77\x6E"
+ "\x71\x75\x95\x9D\x4E\x1C\xCF\xAD"
+ "\x81\x34\xE9\x8F\xAE\x5A\x91\x1C"
+ "\x38\x63\x35\x7E\x79\x18\x0A\xE8"
+ "\x67\x06\x76\xD5\xFF\x22\x2F\xDA"
+ "\xB6\x2D\x57\x13\xB6\x3C\xBC\x97"
+ "\xFE\x53\x75\x35\x97\x7F\x51\xEA"
+ "\xDF\x5D\xE8\x9D\xCC\xD9\xAE\xE7"
+ "\x62\x67\xFF\x04\xC2\x18\x22\x5F"
+ "\x2E\x06\xC1\xE2\x26\xCD\xC6\x1E"
+ "\xE5\x2C\x4E\x87\x23\xDD\xF0\x41"
+ "\x08\xA5\xB4\x3E\x07\x1E\x0B\xBB"
+ "\x72\x84\xF8\x0A\x3F\x38\x5E\x91"
+ "\x15\x26\xE1\xDB\xA4\x3D\x74\xD2"
+ "\x41\x1E\x3F\xA9\xC6\x7D\x2A\xAB"
+ "\x27\xDF\x89\x1D\x86\x3E\xF7\x5A"
+ "\xF6\xE3\x0F\xC7\x6B\x4C\x96\x7C",
+ .rlen = 144,
+ },
+};
+
+static struct cipher_testvec serpent_cbc_dec_tv_template[] = {
+ { /* Generated with Crypto++ */
+ .key = "\x85\x62\x3F\x1C\xF9\xD6\x1C\xF9"
+ "\xD6\xB3\x90\x6D\x4A\x90\x6D\x4A"
+ "\x27\x04\xE1\x27\x04\xE1\xBE\x9B"
+ "\x78\xBE\x9B\x78\x55\x32\x0F\x55",
+ .klen = 32,
+ .iv = "\xE2\x24\x89\xEE\x53\xB8\x1D\x5F"
+ "\xC4\x29\x8E\xF3\x35\x9A\xFF\x64",
+ .input = "\x80\xCF\x11\x41\x1A\xB9\x4B\x9C"
+ "\xFF\xB7\x6C\xEA\xF0\xAF\x77\x6E"
+ "\x71\x75\x95\x9D\x4E\x1C\xCF\xAD"
+ "\x81\x34\xE9\x8F\xAE\x5A\x91\x1C"
+ "\x38\x63\x35\x7E\x79\x18\x0A\xE8"
+ "\x67\x06\x76\xD5\xFF\x22\x2F\xDA"
+ "\xB6\x2D\x57\x13\xB6\x3C\xBC\x97"
+ "\xFE\x53\x75\x35\x97\x7F\x51\xEA"
+ "\xDF\x5D\xE8\x9D\xCC\xD9\xAE\xE7"
+ "\x62\x67\xFF\x04\xC2\x18\x22\x5F"
+ "\x2E\x06\xC1\xE2\x26\xCD\xC6\x1E"
+ "\xE5\x2C\x4E\x87\x23\xDD\xF0\x41"
+ "\x08\xA5\xB4\x3E\x07\x1E\x0B\xBB"
+ "\x72\x84\xF8\x0A\x3F\x38\x5E\x91"
+ "\x15\x26\xE1\xDB\xA4\x3D\x74\xD2"
+ "\x41\x1E\x3F\xA9\xC6\x7D\x2A\xAB"
+ "\x27\xDF\x89\x1D\x86\x3E\xF7\x5A"
+ "\xF6\xE3\x0F\xC7\x6B\x4C\x96\x7C",
+ .ilen = 144,
+ .result = "\x56\xED\x84\x1B\x8F\x26\xBD\x31"
+ "\xC8\x5F\xF6\x6A\x01\x98\x0C\xA3"
+ "\x3A\xD1\x45\xDC\x73\x0A\x7E\x15"
+ "\xAC\x20\xB7\x4E\xE5\x59\xF0\x87"
+ "\x1E\x92\x29\xC0\x34\xCB\x62\xF9"
+ "\x6D\x04\x9B\x0F\xA6\x3D\xD4\x48"
+ "\xDF\x76\x0D\x81\x18\xAF\x23\xBA"
+ "\x51\xE8\x5C\xF3\x8A\x21\x95\x2C"
+ "\xC3\x37\xCE\x65\xFC\x70\x07\x9E"
+ "\x12\xA9\x40\xD7\x4B\xE2\x79\x10"
+ "\x84\x1B\xB2\x26\xBD\x54\xEB\x5F"
+ "\xF6\x8D\x01\x98\x2F\xC6\x3A\xD1"
+ "\x68\xFF\x73\x0A\xA1\x15\xAC\x43"
+ "\xDA\x4E\xE5\x7C\x13\x87\x1E\xB5"
+ "\x29\xC0\x57\xEE\x62\xF9\x90\x04"
+ "\x9B\x32\xC9\x3D\xD4\x6B\x02\x76"
+ "\x0D\xA4\x18\xAF\x46\xDD\x51\xE8"
+ "\x7F\x16\x8A\x21\xB8\x2C\xC3\x5A",
+ .rlen = 144,
+ },
+};
+
+static struct cipher_testvec serpent_ctr_enc_tv_template[] = {
+ { /* Generated with Crypto++ */
+ .key = "\x85\x62\x3F\x1C\xF9\xD6\x1C\xF9"
+ "\xD6\xB3\x90\x6D\x4A\x90\x6D\x4A"
+ "\x27\x04\xE1\x27\x04\xE1\xBE\x9B"
+ "\x78\xBE\x9B\x78\x55\x32\x0F\x55",
+ .klen = 32,
+ .iv = "\xE2\x24\x89\xEE\x53\xB8\x1D\x5F"
+ "\xC4\x29\x8E\xF3\x35\x9A\xFF\x64",
+ .input = "\x56\xED\x84\x1B\x8F\x26\xBD\x31"
+ "\xC8\x5F\xF6\x6A\x01\x98\x0C\xA3"
+ "\x3A\xD1\x45\xDC\x73\x0A\x7E\x15"
+ "\xAC\x20\xB7\x4E\xE5\x59\xF0\x87"
+ "\x1E\x92\x29\xC0\x34\xCB\x62\xF9"
+ "\x6D\x04\x9B\x0F\xA6\x3D\xD4\x48"
+ "\xDF\x76\x0D\x81\x18\xAF\x23\xBA"
+ "\x51\xE8\x5C\xF3\x8A\x21\x95\x2C"
+ "\xC3\x37\xCE\x65\xFC\x70\x07\x9E"
+ "\x12\xA9\x40\xD7\x4B\xE2\x79\x10"
+ "\x84\x1B\xB2\x26\xBD\x54\xEB\x5F"
+ "\xF6\x8D\x01\x98\x2F\xC6\x3A\xD1"
+ "\x68\xFF\x73\x0A\xA1\x15\xAC\x43"
+ "\xDA\x4E\xE5\x7C\x13\x87\x1E\xB5"
+ "\x29\xC0\x57\xEE\x62\xF9\x90\x04"
+ "\x9B\x32\xC9\x3D\xD4\x6B\x02\x76"
+ "\x0D\xA4\x18\xAF\x46\xDD\x51\xE8"
+ "\x7F\x16\x8A\x21\xB8\x2C\xC3\x5A",
+ .ilen = 144,
+ .result = "\x84\x68\xEC\xF2\x1C\x88\x20\xCA"
+ "\x37\x69\xE3\x3A\x22\x85\x48\x46"
+ "\x70\xAA\x25\xB4\xCD\x8B\x04\x4E"
+ "\x8D\x15\x2B\x98\xDF\x7B\x6D\xB9"
+ "\xE0\x4A\x73\x00\x65\xB6\x1A\x0D"
+ "\x5C\x60\xDF\x34\xDC\x60\x4C\xDF"
+ "\xB5\x1F\x26\x8C\xDA\xC1\x11\xA8"
+ "\x80\xFA\x37\x7A\x89\xAA\xAE\x7B"
+ "\x92\x6E\xB9\xDC\xC9\x62\x4F\x88"
+ "\x0A\x5D\x97\x2F\x6B\xAC\x03\x7C"
+ "\x22\xF6\x55\x5A\xFA\x35\xA5\x17"
+ "\xA1\x5C\x5E\x2B\x63\x2D\xB9\x91"
+ "\x3E\x83\x26\x00\x4E\xD5\xBE\xCE"
+ "\x79\xC4\x3D\xFC\x70\xA0\xAD\x96"
+ "\xBA\x58\x2A\x1C\xDF\xC2\x3A\xA5"
+ "\x7C\xB5\x12\x89\xED\xBF\xB6\x09"
+ "\x13\x4F\x7D\x61\x3C\x5C\x27\xFC"
+ "\x5D\xE1\x4F\xA1\xEA\xB3\xCA\xB9",
+ .rlen = 144,
+ }, { /* Generated with Crypto++ */
+ .key = "\x85\x62\x3F\x1C\xF9\xD6\x1C\xF9"
+ "\xD6\xB3\x90\x6D\x4A\x90\x6D\x4A"
+ "\x27\x04\xE1\x27\x04\xE1\xBE\x9B"
+ "\x78\xBE\x9B\x78\x55\x32\x0F\x55",
+ .klen = 32,
+ .iv = "\xE2\x24\x89\xEE\x53\xB8\x1D\x5F"
+ "\xC4\x29\x8E\xF3\x35\x9A\xFF\x64",
+ .input = "\x56\xED\x84\x1B\x8F\x26\xBD\x31"
+ "\xC8\x5F\xF6\x6A\x01\x98\x0C\xA3"
+ "\x3A\xD1\x45\xDC\x73\x0A\x7E\x15"
+ "\xAC\x20\xB7\x4E\xE5\x59\xF0\x87"
+ "\x1E\x92\x29\xC0\x34\xCB\x62\xF9"
+ "\x6D\x04\x9B\x0F\xA6\x3D\xD4\x48"
+ "\xDF\x76\x0D\x81\x18\xAF\x23\xBA"
+ "\x51\xE8\x5C\xF3\x8A\x21\x95\x2C"
+ "\xC3\x37\xCE\x65\xFC\x70\x07\x9E"
+ "\x12\xA9\x40\xD7\x4B\xE2\x79\x10"
+ "\x84\x1B\xB2\x26\xBD\x54\xEB\x5F"
+ "\xF6\x8D\x01\x98\x2F\xC6\x3A\xD1"
+ "\x68\xFF\x73\x0A\xA1\x15\xAC\x43"
+ "\xDA\x4E\xE5\x7C\x13\x87\x1E\xB5"
+ "\x29\xC0\x57\xEE\x62\xF9\x90\x04"
+ "\x9B\x32\xC9\x3D\xD4\x6B\x02\x76"
+ "\x0D\xA4\x18\xAF\x46\xDD\x51\xE8"
+ "\x7F\x16\x8A\x21\xB8\x2C\xC3\x5A"
+ "\xF1\x65\xFC",
+ .ilen = 147,
+ .result = "\x84\x68\xEC\xF2\x1C\x88\x20\xCA"
+ "\x37\x69\xE3\x3A\x22\x85\x48\x46"
+ "\x70\xAA\x25\xB4\xCD\x8B\x04\x4E"
+ "\x8D\x15\x2B\x98\xDF\x7B\x6D\xB9"
+ "\xE0\x4A\x73\x00\x65\xB6\x1A\x0D"
+ "\x5C\x60\xDF\x34\xDC\x60\x4C\xDF"
+ "\xB5\x1F\x26\x8C\xDA\xC1\x11\xA8"
+ "\x80\xFA\x37\x7A\x89\xAA\xAE\x7B"
+ "\x92\x6E\xB9\xDC\xC9\x62\x4F\x88"
+ "\x0A\x5D\x97\x2F\x6B\xAC\x03\x7C"
+ "\x22\xF6\x55\x5A\xFA\x35\xA5\x17"
+ "\xA1\x5C\x5E\x2B\x63\x2D\xB9\x91"
+ "\x3E\x83\x26\x00\x4E\xD5\xBE\xCE"
+ "\x79\xC4\x3D\xFC\x70\xA0\xAD\x96"
+ "\xBA\x58\x2A\x1C\xDF\xC2\x3A\xA5"
+ "\x7C\xB5\x12\x89\xED\xBF\xB6\x09"
+ "\x13\x4F\x7D\x61\x3C\x5C\x27\xFC"
+ "\x5D\xE1\x4F\xA1\xEA\xB3\xCA\xB9"
+ "\xE6\xD0\x97",
+ .rlen = 147,
+ },
+};
+
+static struct cipher_testvec serpent_ctr_dec_tv_template[] = {
+ { /* Generated with Crypto++ */
+ .key = "\x85\x62\x3F\x1C\xF9\xD6\x1C\xF9"
+ "\xD6\xB3\x90\x6D\x4A\x90\x6D\x4A"
+ "\x27\x04\xE1\x27\x04\xE1\xBE\x9B"
+ "\x78\xBE\x9B\x78\x55\x32\x0F\x55",
+ .klen = 32,
+ .iv = "\xE2\x24\x89\xEE\x53\xB8\x1D\x5F"
+ "\xC4\x29\x8E\xF3\x35\x9A\xFF\x64",
+ .input = "\x84\x68\xEC\xF2\x1C\x88\x20\xCA"
+ "\x37\x69\xE3\x3A\x22\x85\x48\x46"
+ "\x70\xAA\x25\xB4\xCD\x8B\x04\x4E"
+ "\x8D\x15\x2B\x98\xDF\x7B\x6D\xB9"
+ "\xE0\x4A\x73\x00\x65\xB6\x1A\x0D"
+ "\x5C\x60\xDF\x34\xDC\x60\x4C\xDF"
+ "\xB5\x1F\x26\x8C\xDA\xC1\x11\xA8"
+ "\x80\xFA\x37\x7A\x89\xAA\xAE\x7B"
+ "\x92\x6E\xB9\xDC\xC9\x62\x4F\x88"
+ "\x0A\x5D\x97\x2F\x6B\xAC\x03\x7C"
+ "\x22\xF6\x55\x5A\xFA\x35\xA5\x17"
+ "\xA1\x5C\x5E\x2B\x63\x2D\xB9\x91"
+ "\x3E\x83\x26\x00\x4E\xD5\xBE\xCE"
+ "\x79\xC4\x3D\xFC\x70\xA0\xAD\x96"
+ "\xBA\x58\x2A\x1C\xDF\xC2\x3A\xA5"
+ "\x7C\xB5\x12\x89\xED\xBF\xB6\x09"
+ "\x13\x4F\x7D\x61\x3C\x5C\x27\xFC"
+ "\x5D\xE1\x4F\xA1\xEA\xB3\xCA\xB9",
+ .ilen = 144,
+ .result = "\x56\xED\x84\x1B\x8F\x26\xBD\x31"
+ "\xC8\x5F\xF6\x6A\x01\x98\x0C\xA3"
+ "\x3A\xD1\x45\xDC\x73\x0A\x7E\x15"
+ "\xAC\x20\xB7\x4E\xE5\x59\xF0\x87"
+ "\x1E\x92\x29\xC0\x34\xCB\x62\xF9"
+ "\x6D\x04\x9B\x0F\xA6\x3D\xD4\x48"
+ "\xDF\x76\x0D\x81\x18\xAF\x23\xBA"
+ "\x51\xE8\x5C\xF3\x8A\x21\x95\x2C"
+ "\xC3\x37\xCE\x65\xFC\x70\x07\x9E"
+ "\x12\xA9\x40\xD7\x4B\xE2\x79\x10"
+ "\x84\x1B\xB2\x26\xBD\x54\xEB\x5F"
+ "\xF6\x8D\x01\x98\x2F\xC6\x3A\xD1"
+ "\x68\xFF\x73\x0A\xA1\x15\xAC\x43"
+ "\xDA\x4E\xE5\x7C\x13\x87\x1E\xB5"
+ "\x29\xC0\x57\xEE\x62\xF9\x90\x04"
+ "\x9B\x32\xC9\x3D\xD4\x6B\x02\x76"
+ "\x0D\xA4\x18\xAF\x46\xDD\x51\xE8"
+ "\x7F\x16\x8A\x21\xB8\x2C\xC3\x5A",
+ .rlen = 144,
+ }, { /* Generated with Crypto++ */
+ .key = "\x85\x62\x3F\x1C\xF9\xD6\x1C\xF9"
+ "\xD6\xB3\x90\x6D\x4A\x90\x6D\x4A"
+ "\x27\x04\xE1\x27\x04\xE1\xBE\x9B"
+ "\x78\xBE\x9B\x78\x55\x32\x0F\x55",
+ .klen = 32,
+ .iv = "\xE2\x24\x89\xEE\x53\xB8\x1D\x5F"
+ "\xC4\x29\x8E\xF3\x35\x9A\xFF\x64",
+ .input = "\x84\x68\xEC\xF2\x1C\x88\x20\xCA"
+ "\x37\x69\xE3\x3A\x22\x85\x48\x46"
+ "\x70\xAA\x25\xB4\xCD\x8B\x04\x4E"
+ "\x8D\x15\x2B\x98\xDF\x7B\x6D\xB9"
+ "\xE0\x4A\x73\x00\x65\xB6\x1A\x0D"
+ "\x5C\x60\xDF\x34\xDC\x60\x4C\xDF"
+ "\xB5\x1F\x26\x8C\xDA\xC1\x11\xA8"
+ "\x80\xFA\x37\x7A\x89\xAA\xAE\x7B"
+ "\x92\x6E\xB9\xDC\xC9\x62\x4F\x88"
+ "\x0A\x5D\x97\x2F\x6B\xAC\x03\x7C"
+ "\x22\xF6\x55\x5A\xFA\x35\xA5\x17"
+ "\xA1\x5C\x5E\x2B\x63\x2D\xB9\x91"
+ "\x3E\x83\x26\x00\x4E\xD5\xBE\xCE"
+ "\x79\xC4\x3D\xFC\x70\xA0\xAD\x96"
+ "\xBA\x58\x2A\x1C\xDF\xC2\x3A\xA5"
+ "\x7C\xB5\x12\x89\xED\xBF\xB6\x09"
+ "\x13\x4F\x7D\x61\x3C\x5C\x27\xFC"
+ "\x5D\xE1\x4F\xA1\xEA\xB3\xCA\xB9"
+ "\xE6\xD0\x97",
+ .ilen = 147,
+ .result = "\x56\xED\x84\x1B\x8F\x26\xBD\x31"
+ "\xC8\x5F\xF6\x6A\x01\x98\x0C\xA3"
+ "\x3A\xD1\x45\xDC\x73\x0A\x7E\x15"
+ "\xAC\x20\xB7\x4E\xE5\x59\xF0\x87"
+ "\x1E\x92\x29\xC0\x34\xCB\x62\xF9"
+ "\x6D\x04\x9B\x0F\xA6\x3D\xD4\x48"
+ "\xDF\x76\x0D\x81\x18\xAF\x23\xBA"
+ "\x51\xE8\x5C\xF3\x8A\x21\x95\x2C"
+ "\xC3\x37\xCE\x65\xFC\x70\x07\x9E"
+ "\x12\xA9\x40\xD7\x4B\xE2\x79\x10"
+ "\x84\x1B\xB2\x26\xBD\x54\xEB\x5F"
+ "\xF6\x8D\x01\x98\x2F\xC6\x3A\xD1"
+ "\x68\xFF\x73\x0A\xA1\x15\xAC\x43"
+ "\xDA\x4E\xE5\x7C\x13\x87\x1E\xB5"
+ "\x29\xC0\x57\xEE\x62\xF9\x90\x04"
+ "\x9B\x32\xC9\x3D\xD4\x6B\x02\x76"
+ "\x0D\xA4\x18\xAF\x46\xDD\x51\xE8"
+ "\x7F\x16\x8A\x21\xB8\x2C\xC3\x5A"
+ "\xF1\x65\xFC",
+ .rlen = 147,
+ },
+};
+
+static struct cipher_testvec serpent_lrw_enc_tv_template[] = {
+ /* Generated from AES-LRW test vectors */
+ {
+ .key = "\x45\x62\xac\x25\xf8\x28\x17\x6d"
+ "\x4c\x26\x84\x14\xb5\x68\x01\x85"
+ "\x25\x8e\x2a\x05\xe7\x3e\x9d\x03"
+ "\xee\x5a\x83\x0c\xcc\x09\x4c\x87",
+ .klen = 32,
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x01",
+ .input = "\x30\x31\x32\x33\x34\x35\x36\x37"
+ "\x38\x39\x41\x42\x43\x44\x45\x46",
+ .ilen = 16,
+ .result = "\x6f\xbf\xd4\xa4\x5d\x71\x16\x79"
+ "\x63\x9c\xa6\x8e\x40\xbe\x0d\x8a",
+ .rlen = 16,
+ }, {
+ .key = "\x59\x70\x47\x14\xf5\x57\x47\x8c"
+ "\xd7\x79\xe8\x0f\x54\x88\x79\x44"
+ "\x0d\x48\xf0\xb7\xb1\x5a\x53\xea"
+ "\x1c\xaa\x6b\x29\xc2\xca\xfb\xaf",
+ .klen = 32,
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x02",
+ .input = "\x30\x31\x32\x33\x34\x35\x36\x37"
+ "\x38\x39\x41\x42\x43\x44\x45\x46",
+ .ilen = 16,
+ .result = "\xfd\xb2\x66\x98\x80\x96\x55\xad"
+ "\x08\x94\x54\x9c\x21\x7c\x69\xe3",
+ .rlen = 16,
+ }, {
+ .key = "\xd8\x2a\x91\x34\xb2\x6a\x56\x50"
+ "\x30\xfe\x69\xe2\x37\x7f\x98\x47"
+ "\xcd\xf9\x0b\x16\x0c\x64\x8f\xb6"
+ "\xb0\x0d\x0d\x1b\xae\x85\x87\x1f",
+ .klen = 32,
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x02\x00\x00\x00\x00",
+ .input = "\x30\x31\x32\x33\x34\x35\x36\x37"
+ "\x38\x39\x41\x42\x43\x44\x45\x46",
+ .ilen = 16,
+ .result = "\x14\x5e\x3d\x70\xc0\x6e\x9c\x34"
+ "\x5b\x5e\xcf\x0f\xe4\x8c\x21\x5c",
+ .rlen = 16,
+ }, {
+ .key = "\x0f\x6a\xef\xf8\xd3\xd2\xbb\x15"
+ "\x25\x83\xf7\x3c\x1f\x01\x28\x74"
+ "\xca\xc6\xbc\x35\x4d\x4a\x65\x54"
+ "\x90\xae\x61\xcf\x7b\xae\xbd\xcc"
+ "\xad\xe4\x94\xc5\x4a\x29\xae\x70",
+ .klen = 40,
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x01",
+ .input = "\x30\x31\x32\x33\x34\x35\x36\x37"
+ "\x38\x39\x41\x42\x43\x44\x45\x46",
+ .ilen = 16,
+ .result = "\x25\x39\xaa\xa5\xf0\x65\xc8\xdc"
+ "\x5d\x45\x95\x30\x8f\xff\x2f\x1b",
+ .rlen = 16,
+ }, {
+ .key = "\x8a\xd4\xee\x10\x2f\xbd\x81\xff"
+ "\xf8\x86\xce\xac\x93\xc5\xad\xc6"
+ "\xa0\x19\x07\xc0\x9d\xf7\xbb\xdd"
+ "\x52\x13\xb2\xb7\xf0\xff\x11\xd8"
+ "\xd6\x08\xd0\xcd\x2e\xb1\x17\x6f",
+ .klen = 40,
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x02\x00\x00\x00\x00",
+ .input = "\x30\x31\x32\x33\x34\x35\x36\x37"
+ "\x38\x39\x41\x42\x43\x44\x45\x46",
+ .ilen = 16,
+ .result = "\x0c\x20\x20\x63\xd6\x8b\xfc\x8f"
+ "\xc0\xe2\x17\xbb\xd2\x59\x6f\x26",
+ .rlen = 16,
+ }, {
+ .key = "\xf8\xd4\x76\xff\xd6\x46\xee\x6c"
+ "\x23\x84\xcb\x1c\x77\xd6\x19\x5d"
+ "\xfe\xf1\xa9\xf3\x7b\xbc\x8d\x21"
+ "\xa7\x9c\x21\xf8\xcb\x90\x02\x89"
+ "\xa8\x45\x34\x8e\xc8\xc5\xb5\xf1"
+ "\x26\xf5\x0e\x76\xfe\xfd\x1b\x1e",
+ .klen = 48,
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x01",
+ .input = "\x30\x31\x32\x33\x34\x35\x36\x37"
+ "\x38\x39\x41\x42\x43\x44\x45\x46",
+ .ilen = 16,
+ .result = "\xc1\x35\x2e\x53\xf0\x96\x4d\x9c"
+ "\x2e\x18\xe6\x99\xcd\xd3\x15\x68",
+ .rlen = 16,
+ }, {
+ .key = "\xfb\x76\x15\xb2\x3d\x80\x89\x1d"
+ "\xd4\x70\x98\x0b\xc7\x95\x84\xc8"
+ "\xb2\xfb\x64\xce\x60\x97\x87\x8d"
+ "\x17\xfc\xe4\x5a\x49\xe8\x30\xb7"
+ "\x6e\x78\x17\xe7\x2d\x5e\x12\xd4"
+ "\x60\x64\x04\x7a\xf1\x2f\x9e\x0c",
+ .klen = 48,
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x02\x00\x00\x00\x00",
+ .input = "\x30\x31\x32\x33\x34\x35\x36\x37"
+ "\x38\x39\x41\x42\x43\x44\x45\x46",
+ .ilen = 16,
+ .result = "\x86\x0a\xc6\xa9\x1a\x9f\xe7\xe6"
+ "\x64\x3b\x33\xd6\xd5\x84\xd6\xdf",
+ .rlen = 16,
+ }, {
+ .key = "\xf8\xd4\x76\xff\xd6\x46\xee\x6c"
+ "\x23\x84\xcb\x1c\x77\xd6\x19\x5d"
+ "\xfe\xf1\xa9\xf3\x7b\xbc\x8d\x21"
+ "\xa7\x9c\x21\xf8\xcb\x90\x02\x89"
+ "\xa8\x45\x34\x8e\xc8\xc5\xb5\xf1"
+ "\x26\xf5\x0e\x76\xfe\xfd\x1b\x1e",
+ .klen = 48,
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x01",
+ .input = "\x05\x11\xb7\x18\xab\xc6\x2d\xac"
+ "\x70\x5d\xf6\x22\x94\xcd\xe5\x6c"
+ "\x17\x6b\xf6\x1c\xf0\xf3\x6e\xf8"
+ "\x50\x38\x1f\x71\x49\xb6\x57\xd6"
+ "\x8f\xcb\x8d\x6b\xe3\xa6\x29\x90"
+ "\xfe\x2a\x62\x82\xae\x6d\x8b\xf6"
+ "\xad\x1e\x9e\x20\x5f\x38\xbe\x04"
+ "\xda\x10\x8e\xed\xa2\xa4\x87\xab"
+ "\xda\x6b\xb4\x0c\x75\xba\xd3\x7c"
+ "\xc9\xac\x42\x31\x95\x7c\xc9\x04"
+ "\xeb\xd5\x6e\x32\x69\x8a\xdb\xa6"
+ "\x15\xd7\x3f\x4f\x2f\x66\x69\x03"
+ "\x9c\x1f\x54\x0f\xde\x1f\xf3\x65"
+ "\x4c\x96\x12\xed\x7c\x92\x03\x01"
+ "\x6f\xbc\x35\x93\xac\xf1\x27\xf1"
+ "\xb4\x96\x82\x5a\x5f\xb0\xa0\x50"
+ "\x89\xa4\x8e\x66\x44\x85\xcc\xfd"
+ "\x33\x14\x70\xe3\x96\xb2\xc3\xd3"
+ "\xbb\x54\x5a\x1a\xf9\x74\xa2\xc5"
+ "\x2d\x64\x75\xdd\xb4\x54\xe6\x74"
+ "\x8c\xd3\x9d\x9e\x86\xab\x51\x53"
+ "\xb7\x93\x3e\x6f\xd0\x4e\x2c\x40"
+ "\xf6\xa8\x2e\x3e\x9d\xf4\x66\xa5"
+ "\x76\x12\x73\x44\x1a\x56\xd7\x72"
+ "\x88\xcd\x21\x8c\x4c\x0f\xfe\xda"
+ "\x95\xe0\x3a\xa6\xa5\x84\x46\xcd"
+ "\xd5\x3e\x9d\x3a\xe2\x67\xe6\x60"
+ "\x1a\xe2\x70\x85\x58\xc2\x1b\x09"
+ "\xe1\xd7\x2c\xca\xad\xa8\x8f\xf9"
+ "\xac\xb3\x0e\xdb\xca\x2e\xe2\xb8"
+ "\x51\x71\xd9\x3c\x6c\xf1\x56\xf8"
+ "\xea\x9c\xf1\xfb\x0c\xe6\xb7\x10"
+ "\x1c\xf8\xa9\x7c\xe8\x53\x35\xc1"
+ "\x90\x3e\x76\x4a\x74\xa4\x21\x2c"
+ "\xf6\x2c\x4e\x0f\x94\x3a\x88\x2e"
+ "\x41\x09\x6a\x33\x7d\xf6\xdd\x3f"
+ "\x8d\x23\x31\x74\x84\xeb\x88\x6e"
+ "\xcc\xb9\xbc\x22\x83\x19\x07\x22"
+ "\xa5\x2d\xdf\xa5\xf3\x80\x85\x78"
+ "\x84\x39\x6a\x6d\x6a\x99\x4f\xa5"
+ "\x15\xfe\x46\xb0\xe4\x6c\xa5\x41"
+ "\x3c\xce\x8f\x42\x60\x71\xa7\x75"
+ "\x08\x40\x65\x8a\x82\xbf\xf5\x43"
+ "\x71\x96\xa9\x4d\x44\x8a\x20\xbe"
+ "\xfa\x4d\xbb\xc0\x7d\x31\x96\x65"
+ "\xe7\x75\xe5\x3e\xfd\x92\x3b\xc9"
+ "\x55\xbb\x16\x7e\xf7\xc2\x8c\xa4"
+ "\x40\x1d\xe5\xef\x0e\xdf\xe4\x9a"
+ "\x62\x73\x65\xfd\x46\x63\x25\x3d"
+ "\x2b\xaf\xe5\x64\xfe\xa5\x5c\xcf"
+ "\x24\xf3\xb4\xac\x64\xba\xdf\x4b"
+ "\xc6\x96\x7d\x81\x2d\x8d\x97\xf7"
+ "\xc5\x68\x77\x84\x32\x2b\xcc\x85"
+ "\x74\x96\xf0\x12\x77\x61\xb9\xeb"
+ "\x71\xaa\x82\xcb\x1c\xdb\x89\xc8"
+ "\xc6\xb5\xe3\x5c\x7d\x39\x07\x24"
+ "\xda\x39\x87\x45\xc0\x2b\xbb\x01"
+ "\xac\xbc\x2a\x5c\x7f\xfc\xe8\xce"
+ "\x6d\x9c\x6f\xed\xd3\xc1\xa1\xd6"
+ "\xc5\x55\xa9\x66\x2f\xe1\xc8\x32"
+ "\xa6\x5d\xa4\x3a\x98\x73\xe8\x45"
+ "\xa4\xc7\xa8\xb4\xf6\x13\x03\xf6"
+ "\xe9\x2e\xc4\x29\x0f\x84\xdb\xc4"
+ "\x21\xc4\xc2\x75\x67\x89\x37\x0a",
+ .ilen = 512,
+ .result = "\xe3\x5a\x38\x0f\x4d\x92\x3a\x74"
+ "\x15\xb1\x50\x8c\x9a\xd8\x99\x1d"
+ "\x82\xec\xf1\x5f\x03\x6d\x02\x58"
+ "\x90\x67\xfc\xdd\x8d\xe1\x38\x08"
+ "\x7b\xc9\x9b\x4b\x04\x09\x50\x15"
+ "\xce\xab\xda\x33\x30\x20\x12\xfa"
+ "\x83\xc4\xa6\x9a\x2e\x7d\x90\xd9"
+ "\xa6\xa6\x67\x43\xb4\xa7\xa8\x5c"
+ "\xbb\x6a\x49\x2b\x8b\xf8\xd0\x22"
+ "\xe5\x9e\xba\xe8\x8c\x67\xb8\x5b"
+ "\x60\xbc\xf5\xa4\x95\x4e\x66\xe5"
+ "\x6d\x8e\xa9\xf6\x65\x2e\x04\xf5"
+ "\xba\xb5\xdb\x88\xc2\xf6\x7a\x4b"
+ "\x89\x58\x7c\x9a\xae\x26\xe8\xb7"
+ "\xb7\x28\xcc\xd6\xcc\xa5\x98\x4d"
+ "\xb9\x91\xcb\xb4\xe4\x8b\x96\x47"
+ "\x5f\x03\x8b\xdd\x94\xd1\xee\x12"
+ "\xa7\x83\x80\xf2\xc1\x15\x74\x4f"
+ "\x49\xf9\xb0\x7e\x6f\xdc\x73\x2f"
+ "\xe2\xcf\xe0\x1b\x34\xa5\xa0\x52"
+ "\xfb\x3c\x5d\x85\x91\xe6\x6d\x98"
+ "\x04\xd6\xdd\x4c\x00\x64\xd9\x54"
+ "\x5c\x3c\x08\x1d\x4c\x06\x9f\xb8"
+ "\x1c\x4d\x8d\xdc\xa4\x3c\xb9\x3b"
+ "\x9e\x85\xce\xc3\xa8\x4a\x0c\xd9"
+ "\x04\xc3\x6f\x17\x66\xa9\x1f\x59"
+ "\xd9\xe2\x19\x36\xa3\x88\xb8\x0b"
+ "\x0f\x4a\x4d\xf8\xc8\x6f\xd5\x43"
+ "\xeb\xa0\xab\x1f\x61\xc0\x06\xeb"
+ "\x93\xb7\xb8\x6f\x0d\xbd\x07\x49"
+ "\xb3\xac\x5d\xcf\x31\xa0\x27\x26"
+ "\x21\xbe\x94\x2e\x19\xea\xf4\xee"
+ "\xb5\x13\x89\xf7\x94\x0b\xef\x59"
+ "\x44\xc5\x78\x8b\x3c\x3b\x71\x20"
+ "\xf9\x35\x0c\x70\x74\xdc\x5b\xc2"
+ "\xb4\x11\x0e\x2c\x61\xa1\x52\x46"
+ "\x18\x11\x16\xc6\x86\x44\xa7\xaf"
+ "\xd5\x0c\x7d\xa6\x9e\x25\x2d\x1b"
+ "\x9a\x8f\x0f\xf8\x6a\x61\xa0\xea"
+ "\x3f\x0e\x90\xd6\x8f\x83\x30\x64"
+ "\xb5\x51\x2d\x08\x3c\xcd\x99\x36"
+ "\x96\xd4\xb1\xb5\x48\x30\xca\x48"
+ "\xf7\x11\xa8\xf5\x97\x8a\x6a\x6d"
+ "\x12\x33\x2f\xc0\xe8\xda\xec\x8a"
+ "\xe1\x88\x72\x63\xde\x20\xa3\xe1"
+ "\x8e\xac\x84\x37\x35\xf5\xf7\x3f"
+ "\x00\x02\x0e\xe4\xc1\x53\x68\x3f"
+ "\xaa\xd5\xac\x52\x3d\x20\x2f\x4d"
+ "\x7c\x83\xd0\xbd\xaa\x97\x35\x36"
+ "\x98\x88\x59\x5d\xe7\x24\xe3\x90"
+ "\x9d\x30\x47\xa7\xc3\x60\x35\xf4"
+ "\xd5\xdb\x0e\x4d\x44\xc1\x81\x8b"
+ "\xfd\xbd\xc3\x2b\xba\x68\xfe\x8d"
+ "\x49\x5a\x3c\x8a\xa3\x01\xae\x25"
+ "\x42\xab\xd2\x87\x1b\x35\xd6\xd2"
+ "\xd7\x70\x1c\x1f\x72\xd1\xe1\x39"
+ "\x1c\x58\xa2\xb4\xd0\x78\x55\x72"
+ "\x76\x59\xea\xd9\xd7\x6e\x63\x8b"
+ "\xcc\x9b\xa7\x74\x89\xfc\xa3\x68"
+ "\x86\x28\xd1\xbb\x54\x8d\x66\xad"
+ "\x2a\x92\xf9\x4e\x04\x3d\xae\xfd"
+ "\x1b\x2b\x7f\xc3\x2f\x1a\x78\x0a"
+ "\x5c\xc6\x84\xfe\x7c\xcb\x26\xfd"
+ "\xd9\x51\x0f\xd7\x94\x2f\xc5\xa7",
+ .rlen = 512,
+ },
+};
+
+static struct cipher_testvec serpent_lrw_dec_tv_template[] = {
+ /* Generated from AES-LRW test vectors */
+ /* same as enc vectors with input and result reversed */
+ {
+ .key = "\x45\x62\xac\x25\xf8\x28\x17\x6d"
+ "\x4c\x26\x84\x14\xb5\x68\x01\x85"
+ "\x25\x8e\x2a\x05\xe7\x3e\x9d\x03"
+ "\xee\x5a\x83\x0c\xcc\x09\x4c\x87",
+ .klen = 32,
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x01",
+ .input = "\x6f\xbf\xd4\xa4\x5d\x71\x16\x79"
+ "\x63\x9c\xa6\x8e\x40\xbe\x0d\x8a",
+ .ilen = 16,
+ .result = "\x30\x31\x32\x33\x34\x35\x36\x37"
+ "\x38\x39\x41\x42\x43\x44\x45\x46",
+ .rlen = 16,
+ }, {
+ .key = "\x59\x70\x47\x14\xf5\x57\x47\x8c"
+ "\xd7\x79\xe8\x0f\x54\x88\x79\x44"
+ "\x0d\x48\xf0\xb7\xb1\x5a\x53\xea"
+ "\x1c\xaa\x6b\x29\xc2\xca\xfb\xaf",
+ .klen = 32,
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x02",
+ .input = "\xfd\xb2\x66\x98\x80\x96\x55\xad"
+ "\x08\x94\x54\x9c\x21\x7c\x69\xe3",
+ .ilen = 16,
+ .result = "\x30\x31\x32\x33\x34\x35\x36\x37"
+ "\x38\x39\x41\x42\x43\x44\x45\x46",
+ .rlen = 16,
+ }, {
+ .key = "\xd8\x2a\x91\x34\xb2\x6a\x56\x50"
+ "\x30\xfe\x69\xe2\x37\x7f\x98\x47"
+ "\xcd\xf9\x0b\x16\x0c\x64\x8f\xb6"
+ "\xb0\x0d\x0d\x1b\xae\x85\x87\x1f",
+ .klen = 32,
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x02\x00\x00\x00\x00",
+ .input = "\x14\x5e\x3d\x70\xc0\x6e\x9c\x34"
+ "\x5b\x5e\xcf\x0f\xe4\x8c\x21\x5c",
+ .ilen = 16,
+ .result = "\x30\x31\x32\x33\x34\x35\x36\x37"
+ "\x38\x39\x41\x42\x43\x44\x45\x46",
+ .rlen = 16,
+ }, {
+ .key = "\x0f\x6a\xef\xf8\xd3\xd2\xbb\x15"
+ "\x25\x83\xf7\x3c\x1f\x01\x28\x74"
+ "\xca\xc6\xbc\x35\x4d\x4a\x65\x54"
+ "\x90\xae\x61\xcf\x7b\xae\xbd\xcc"
+ "\xad\xe4\x94\xc5\x4a\x29\xae\x70",
+ .klen = 40,
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x01",
+ .input = "\x25\x39\xaa\xa5\xf0\x65\xc8\xdc"
+ "\x5d\x45\x95\x30\x8f\xff\x2f\x1b",
+ .ilen = 16,
+ .result = "\x30\x31\x32\x33\x34\x35\x36\x37"
+ "\x38\x39\x41\x42\x43\x44\x45\x46",
+ .rlen = 16,
+ }, {
+ .key = "\x8a\xd4\xee\x10\x2f\xbd\x81\xff"
+ "\xf8\x86\xce\xac\x93\xc5\xad\xc6"
+ "\xa0\x19\x07\xc0\x9d\xf7\xbb\xdd"
+ "\x52\x13\xb2\xb7\xf0\xff\x11\xd8"
+ "\xd6\x08\xd0\xcd\x2e\xb1\x17\x6f",
+ .klen = 40,
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x02\x00\x00\x00\x00",
+ .input = "\x0c\x20\x20\x63\xd6\x8b\xfc\x8f"
+ "\xc0\xe2\x17\xbb\xd2\x59\x6f\x26",
+ .ilen = 16,
+ .result = "\x30\x31\x32\x33\x34\x35\x36\x37"
+ "\x38\x39\x41\x42\x43\x44\x45\x46",
+ .rlen = 16,
+ }, {
+ .key = "\xf8\xd4\x76\xff\xd6\x46\xee\x6c"
+ "\x23\x84\xcb\x1c\x77\xd6\x19\x5d"
+ "\xfe\xf1\xa9\xf3\x7b\xbc\x8d\x21"
+ "\xa7\x9c\x21\xf8\xcb\x90\x02\x89"
+ "\xa8\x45\x34\x8e\xc8\xc5\xb5\xf1"
+ "\x26\xf5\x0e\x76\xfe\xfd\x1b\x1e",
+ .klen = 48,
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x01",
+ .input = "\xc1\x35\x2e\x53\xf0\x96\x4d\x9c"
+ "\x2e\x18\xe6\x99\xcd\xd3\x15\x68",
+ .ilen = 16,
+ .result = "\x30\x31\x32\x33\x34\x35\x36\x37"
+ "\x38\x39\x41\x42\x43\x44\x45\x46",
+ .rlen = 16,
+ }, {
+ .key = "\xfb\x76\x15\xb2\x3d\x80\x89\x1d"
+ "\xd4\x70\x98\x0b\xc7\x95\x84\xc8"
+ "\xb2\xfb\x64\xce\x60\x97\x87\x8d"
+ "\x17\xfc\xe4\x5a\x49\xe8\x30\xb7"
+ "\x6e\x78\x17\xe7\x2d\x5e\x12\xd4"
+ "\x60\x64\x04\x7a\xf1\x2f\x9e\x0c",
+ .klen = 48,
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x02\x00\x00\x00\x00",
+ .input = "\x86\x0a\xc6\xa9\x1a\x9f\xe7\xe6"
+ "\x64\x3b\x33\xd6\xd5\x84\xd6\xdf",
+ .ilen = 16,
+ .result = "\x30\x31\x32\x33\x34\x35\x36\x37"
+ "\x38\x39\x41\x42\x43\x44\x45\x46",
+ .rlen = 16,
+ }, {
+ .key = "\xf8\xd4\x76\xff\xd6\x46\xee\x6c"
+ "\x23\x84\xcb\x1c\x77\xd6\x19\x5d"
+ "\xfe\xf1\xa9\xf3\x7b\xbc\x8d\x21"
+ "\xa7\x9c\x21\xf8\xcb\x90\x02\x89"
+ "\xa8\x45\x34\x8e\xc8\xc5\xb5\xf1"
+ "\x26\xf5\x0e\x76\xfe\xfd\x1b\x1e",
+ .klen = 48,
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x01",
+ .input = "\xe3\x5a\x38\x0f\x4d\x92\x3a\x74"
+ "\x15\xb1\x50\x8c\x9a\xd8\x99\x1d"
+ "\x82\xec\xf1\x5f\x03\x6d\x02\x58"
+ "\x90\x67\xfc\xdd\x8d\xe1\x38\x08"
+ "\x7b\xc9\x9b\x4b\x04\x09\x50\x15"
+ "\xce\xab\xda\x33\x30\x20\x12\xfa"
+ "\x83\xc4\xa6\x9a\x2e\x7d\x90\xd9"
+ "\xa6\xa6\x67\x43\xb4\xa7\xa8\x5c"
+ "\xbb\x6a\x49\x2b\x8b\xf8\xd0\x22"
+ "\xe5\x9e\xba\xe8\x8c\x67\xb8\x5b"
+ "\x60\xbc\xf5\xa4\x95\x4e\x66\xe5"
+ "\x6d\x8e\xa9\xf6\x65\x2e\x04\xf5"
+ "\xba\xb5\xdb\x88\xc2\xf6\x7a\x4b"
+ "\x89\x58\x7c\x9a\xae\x26\xe8\xb7"
+ "\xb7\x28\xcc\xd6\xcc\xa5\x98\x4d"
+ "\xb9\x91\xcb\xb4\xe4\x8b\x96\x47"
+ "\x5f\x03\x8b\xdd\x94\xd1\xee\x12"
+ "\xa7\x83\x80\xf2\xc1\x15\x74\x4f"
+ "\x49\xf9\xb0\x7e\x6f\xdc\x73\x2f"
+ "\xe2\xcf\xe0\x1b\x34\xa5\xa0\x52"
+ "\xfb\x3c\x5d\x85\x91\xe6\x6d\x98"
+ "\x04\xd6\xdd\x4c\x00\x64\xd9\x54"
+ "\x5c\x3c\x08\x1d\x4c\x06\x9f\xb8"
+ "\x1c\x4d\x8d\xdc\xa4\x3c\xb9\x3b"
+ "\x9e\x85\xce\xc3\xa8\x4a\x0c\xd9"
+ "\x04\xc3\x6f\x17\x66\xa9\x1f\x59"
+ "\xd9\xe2\x19\x36\xa3\x88\xb8\x0b"
+ "\x0f\x4a\x4d\xf8\xc8\x6f\xd5\x43"
+ "\xeb\xa0\xab\x1f\x61\xc0\x06\xeb"
+ "\x93\xb7\xb8\x6f\x0d\xbd\x07\x49"
+ "\xb3\xac\x5d\xcf\x31\xa0\x27\x26"
+ "\x21\xbe\x94\x2e\x19\xea\xf4\xee"
+ "\xb5\x13\x89\xf7\x94\x0b\xef\x59"
+ "\x44\xc5\x78\x8b\x3c\x3b\x71\x20"
+ "\xf9\x35\x0c\x70\x74\xdc\x5b\xc2"
+ "\xb4\x11\x0e\x2c\x61\xa1\x52\x46"
+ "\x18\x11\x16\xc6\x86\x44\xa7\xaf"
+ "\xd5\x0c\x7d\xa6\x9e\x25\x2d\x1b"
+ "\x9a\x8f\x0f\xf8\x6a\x61\xa0\xea"
+ "\x3f\x0e\x90\xd6\x8f\x83\x30\x64"
+ "\xb5\x51\x2d\x08\x3c\xcd\x99\x36"
+ "\x96\xd4\xb1\xb5\x48\x30\xca\x48"
+ "\xf7\x11\xa8\xf5\x97\x8a\x6a\x6d"
+ "\x12\x33\x2f\xc0\xe8\xda\xec\x8a"
+ "\xe1\x88\x72\x63\xde\x20\xa3\xe1"
+ "\x8e\xac\x84\x37\x35\xf5\xf7\x3f"
+ "\x00\x02\x0e\xe4\xc1\x53\x68\x3f"
+ "\xaa\xd5\xac\x52\x3d\x20\x2f\x4d"
+ "\x7c\x83\xd0\xbd\xaa\x97\x35\x36"
+ "\x98\x88\x59\x5d\xe7\x24\xe3\x90"
+ "\x9d\x30\x47\xa7\xc3\x60\x35\xf4"
+ "\xd5\xdb\x0e\x4d\x44\xc1\x81\x8b"
+ "\xfd\xbd\xc3\x2b\xba\x68\xfe\x8d"
+ "\x49\x5a\x3c\x8a\xa3\x01\xae\x25"
+ "\x42\xab\xd2\x87\x1b\x35\xd6\xd2"
+ "\xd7\x70\x1c\x1f\x72\xd1\xe1\x39"
+ "\x1c\x58\xa2\xb4\xd0\x78\x55\x72"
+ "\x76\x59\xea\xd9\xd7\x6e\x63\x8b"
+ "\xcc\x9b\xa7\x74\x89\xfc\xa3\x68"
+ "\x86\x28\xd1\xbb\x54\x8d\x66\xad"
+ "\x2a\x92\xf9\x4e\x04\x3d\xae\xfd"
+ "\x1b\x2b\x7f\xc3\x2f\x1a\x78\x0a"
+ "\x5c\xc6\x84\xfe\x7c\xcb\x26\xfd"
+ "\xd9\x51\x0f\xd7\x94\x2f\xc5\xa7",
+ .ilen = 512,
+ .result = "\x05\x11\xb7\x18\xab\xc6\x2d\xac"
+ "\x70\x5d\xf6\x22\x94\xcd\xe5\x6c"
+ "\x17\x6b\xf6\x1c\xf0\xf3\x6e\xf8"
+ "\x50\x38\x1f\x71\x49\xb6\x57\xd6"
+ "\x8f\xcb\x8d\x6b\xe3\xa6\x29\x90"
+ "\xfe\x2a\x62\x82\xae\x6d\x8b\xf6"
+ "\xad\x1e\x9e\x20\x5f\x38\xbe\x04"
+ "\xda\x10\x8e\xed\xa2\xa4\x87\xab"
+ "\xda\x6b\xb4\x0c\x75\xba\xd3\x7c"
+ "\xc9\xac\x42\x31\x95\x7c\xc9\x04"
+ "\xeb\xd5\x6e\x32\x69\x8a\xdb\xa6"
+ "\x15\xd7\x3f\x4f\x2f\x66\x69\x03"
+ "\x9c\x1f\x54\x0f\xde\x1f\xf3\x65"
+ "\x4c\x96\x12\xed\x7c\x92\x03\x01"
+ "\x6f\xbc\x35\x93\xac\xf1\x27\xf1"
+ "\xb4\x96\x82\x5a\x5f\xb0\xa0\x50"
+ "\x89\xa4\x8e\x66\x44\x85\xcc\xfd"
+ "\x33\x14\x70\xe3\x96\xb2\xc3\xd3"
+ "\xbb\x54\x5a\x1a\xf9\x74\xa2\xc5"
+ "\x2d\x64\x75\xdd\xb4\x54\xe6\x74"
+ "\x8c\xd3\x9d\x9e\x86\xab\x51\x53"
+ "\xb7\x93\x3e\x6f\xd0\x4e\x2c\x40"
+ "\xf6\xa8\x2e\x3e\x9d\xf4\x66\xa5"
+ "\x76\x12\x73\x44\x1a\x56\xd7\x72"
+ "\x88\xcd\x21\x8c\x4c\x0f\xfe\xda"
+ "\x95\xe0\x3a\xa6\xa5\x84\x46\xcd"
+ "\xd5\x3e\x9d\x3a\xe2\x67\xe6\x60"
+ "\x1a\xe2\x70\x85\x58\xc2\x1b\x09"
+ "\xe1\xd7\x2c\xca\xad\xa8\x8f\xf9"
+ "\xac\xb3\x0e\xdb\xca\x2e\xe2\xb8"
+ "\x51\x71\xd9\x3c\x6c\xf1\x56\xf8"
+ "\xea\x9c\xf1\xfb\x0c\xe6\xb7\x10"
+ "\x1c\xf8\xa9\x7c\xe8\x53\x35\xc1"
+ "\x90\x3e\x76\x4a\x74\xa4\x21\x2c"
+ "\xf6\x2c\x4e\x0f\x94\x3a\x88\x2e"
+ "\x41\x09\x6a\x33\x7d\xf6\xdd\x3f"
+ "\x8d\x23\x31\x74\x84\xeb\x88\x6e"
+ "\xcc\xb9\xbc\x22\x83\x19\x07\x22"
+ "\xa5\x2d\xdf\xa5\xf3\x80\x85\x78"
+ "\x84\x39\x6a\x6d\x6a\x99\x4f\xa5"
+ "\x15\xfe\x46\xb0\xe4\x6c\xa5\x41"
+ "\x3c\xce\x8f\x42\x60\x71\xa7\x75"
+ "\x08\x40\x65\x8a\x82\xbf\xf5\x43"
+ "\x71\x96\xa9\x4d\x44\x8a\x20\xbe"
+ "\xfa\x4d\xbb\xc0\x7d\x31\x96\x65"
+ "\xe7\x75\xe5\x3e\xfd\x92\x3b\xc9"
+ "\x55\xbb\x16\x7e\xf7\xc2\x8c\xa4"
+ "\x40\x1d\xe5\xef\x0e\xdf\xe4\x9a"
+ "\x62\x73\x65\xfd\x46\x63\x25\x3d"
+ "\x2b\xaf\xe5\x64\xfe\xa5\x5c\xcf"
+ "\x24\xf3\xb4\xac\x64\xba\xdf\x4b"
+ "\xc6\x96\x7d\x81\x2d\x8d\x97\xf7"
+ "\xc5\x68\x77\x84\x32\x2b\xcc\x85"
+ "\x74\x96\xf0\x12\x77\x61\xb9\xeb"
+ "\x71\xaa\x82\xcb\x1c\xdb\x89\xc8"
+ "\xc6\xb5\xe3\x5c\x7d\x39\x07\x24"
+ "\xda\x39\x87\x45\xc0\x2b\xbb\x01"
+ "\xac\xbc\x2a\x5c\x7f\xfc\xe8\xce"
+ "\x6d\x9c\x6f\xed\xd3\xc1\xa1\xd6"
+ "\xc5\x55\xa9\x66\x2f\xe1\xc8\x32"
+ "\xa6\x5d\xa4\x3a\x98\x73\xe8\x45"
+ "\xa4\xc7\xa8\xb4\xf6\x13\x03\xf6"
+ "\xe9\x2e\xc4\x29\x0f\x84\xdb\xc4"
+ "\x21\xc4\xc2\x75\x67\x89\x37\x0a",
+ .rlen = 512,
+ },
+};
+
+static struct cipher_testvec serpent_xts_enc_tv_template[] = {
+ /* Generated from AES-XTS test vectors */
+ {
+ .key = "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .klen = 32,
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .input = "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .ilen = 32,
+ .result = "\xe1\x08\xb8\x1d\x2c\xf5\x33\x64"
+ "\xc8\x12\x04\xc7\xb3\x70\xe8\xc4"
+ "\x6a\x31\xc5\xf3\x00\xca\xb9\x16"
+ "\xde\xe2\x77\x66\xf7\xfe\x62\x08",
+ .rlen = 32,
+ }, {
+ .key = "\x11\x11\x11\x11\x11\x11\x11\x11"
+ "\x11\x11\x11\x11\x11\x11\x11\x11"
+ "\x22\x22\x22\x22\x22\x22\x22\x22"
+ "\x22\x22\x22\x22\x22\x22\x22\x22",
+ .klen = 32,
+ .iv = "\x33\x33\x33\x33\x33\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .input = "\x44\x44\x44\x44\x44\x44\x44\x44"
+ "\x44\x44\x44\x44\x44\x44\x44\x44"
+ "\x44\x44\x44\x44\x44\x44\x44\x44"
+ "\x44\x44\x44\x44\x44\x44\x44\x44",
+ .ilen = 32,
+ .result = "\x1a\x0a\x09\x5f\xcd\x07\x07\x98"
+ "\x41\x86\x12\xaf\xb3\xd7\x68\x13"
+ "\xed\x81\xcd\x06\x87\x43\x1a\xbb"
+ "\x13\x3d\xd6\x1e\x2b\xe1\x77\xbe",
+ .rlen = 32,
+ }, {
+ .key = "\xff\xfe\xfd\xfc\xfb\xfa\xf9\xf8"
+ "\xf7\xf6\xf5\xf4\xf3\xf2\xf1\xf0"
+ "\x22\x22\x22\x22\x22\x22\x22\x22"
+ "\x22\x22\x22\x22\x22\x22\x22\x22",
+ .klen = 32,
+ .iv = "\x33\x33\x33\x33\x33\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .input = "\x44\x44\x44\x44\x44\x44\x44\x44"
+ "\x44\x44\x44\x44\x44\x44\x44\x44"
+ "\x44\x44\x44\x44\x44\x44\x44\x44"
+ "\x44\x44\x44\x44\x44\x44\x44\x44",
+ .ilen = 32,
+ .result = "\xf9\x9b\x28\xb8\x5c\xaf\x8c\x61"
+ "\xb6\x1c\x81\x8f\x2c\x87\x60\x89"
+ "\x0d\x8d\x7a\xe8\x60\x48\xcc\x86"
+ "\xc1\x68\x45\xaa\x00\xe9\x24\xc5",
+ .rlen = 32,
+ }, {
+ .key = "\x27\x18\x28\x18\x28\x45\x90\x45"
+ "\x23\x53\x60\x28\x74\x71\x35\x26"
+ "\x31\x41\x59\x26\x53\x58\x97\x93"
+ "\x23\x84\x62\x64\x33\x83\x27\x95",
+ .klen = 32,
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .input = "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+ "\x10\x11\x12\x13\x14\x15\x16\x17"
+ "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
+ "\x20\x21\x22\x23\x24\x25\x26\x27"
+ "\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f"
+ "\x30\x31\x32\x33\x34\x35\x36\x37"
+ "\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f"
+ "\x40\x41\x42\x43\x44\x45\x46\x47"
+ "\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f"
+ "\x50\x51\x52\x53\x54\x55\x56\x57"
+ "\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f"
+ "\x60\x61\x62\x63\x64\x65\x66\x67"
+ "\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f"
+ "\x70\x71\x72\x73\x74\x75\x76\x77"
+ "\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f"
+ "\x80\x81\x82\x83\x84\x85\x86\x87"
+ "\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
+ "\x90\x91\x92\x93\x94\x95\x96\x97"
+ "\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
+ "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7"
+ "\xa8\xa9\xaa\xab\xac\xad\xae\xaf"
+ "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7"
+ "\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
+ "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7"
+ "\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
+ "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7"
+ "\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf"
+ "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7"
+ "\xe8\xe9\xea\xeb\xec\xed\xee\xef"
+ "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7"
+ "\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"
+ "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+ "\x10\x11\x12\x13\x14\x15\x16\x17"
+ "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
+ "\x20\x21\x22\x23\x24\x25\x26\x27"
+ "\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f"
+ "\x30\x31\x32\x33\x34\x35\x36\x37"
+ "\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f"
+ "\x40\x41\x42\x43\x44\x45\x46\x47"
+ "\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f"
+ "\x50\x51\x52\x53\x54\x55\x56\x57"
+ "\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f"
+ "\x60\x61\x62\x63\x64\x65\x66\x67"
+ "\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f"
+ "\x70\x71\x72\x73\x74\x75\x76\x77"
+ "\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f"
+ "\x80\x81\x82\x83\x84\x85\x86\x87"
+ "\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
+ "\x90\x91\x92\x93\x94\x95\x96\x97"
+ "\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
+ "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7"
+ "\xa8\xa9\xaa\xab\xac\xad\xae\xaf"
+ "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7"
+ "\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
+ "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7"
+ "\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
+ "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7"
+ "\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf"
+ "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7"
+ "\xe8\xe9\xea\xeb\xec\xed\xee\xef"
+ "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7"
+ "\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff",
+ .ilen = 512,
+ .result = "\xfe\x47\x4a\xc8\x60\x7e\xb4\x8b"
+ "\x0d\x10\xf4\xb0\x0d\xba\xf8\x53"
+ "\x65\x6e\x38\x4b\xdb\xaa\xb1\x9e"
+ "\x28\xca\xb0\x22\xb3\x85\x75\xf4"
+ "\x00\x5c\x75\x14\x06\xd6\x25\x82"
+ "\xe6\xcb\x08\xf7\x29\x90\x23\x8e"
+ "\xa4\x68\x57\xe4\xf0\xd8\x32\xf3"
+ "\x80\x51\x67\xb5\x0b\x85\x69\xe8"
+ "\x19\xfe\xc4\xc7\x3e\xea\x90\xd3"
+ "\x8f\xa3\xf2\x0a\xac\x17\x4b\xa0"
+ "\x63\x5a\x16\x0f\xf0\xce\x66\x1f"
+ "\x2c\x21\x07\xf1\xa4\x03\xa3\x44"
+ "\x41\x61\x87\x5d\x6b\xb3\xef\xd4"
+ "\xfc\xaa\x32\x7e\x55\x58\x04\x41"
+ "\xc9\x07\x33\xc6\xa2\x68\xd6\x5a"
+ "\x55\x79\x4b\x6f\xcf\x89\xb9\x19"
+ "\xe5\x54\x13\x15\xb2\x1a\xfa\x15"
+ "\xc2\xf0\x06\x59\xfa\xa0\x25\x05"
+ "\x58\xfa\x43\x91\x16\x85\x40\xbb"
+ "\x0d\x34\x4d\xc5\x1e\x20\xd5\x08"
+ "\xcd\x22\x22\x41\x11\x9f\x6c\x7c"
+ "\x8d\x57\xc9\xba\x57\xe8\x2c\xf7"
+ "\xa0\x42\xa8\xde\xfc\xa3\xca\x98"
+ "\x4b\x43\xb1\xce\x4b\xbf\x01\x67"
+ "\x6e\x29\x60\xbd\x10\x14\x84\x82"
+ "\x83\x82\x0c\x63\x73\x92\x02\x7c"
+ "\x55\x37\x20\x80\x17\x51\xc8\xbc"
+ "\x46\x02\xcb\x38\x07\x6d\xe2\x85"
+ "\xaa\x29\xaf\x24\x58\x0d\xf0\x75"
+ "\x08\x0a\xa5\x34\x25\x16\xf3\x74"
+ "\xa7\x0b\x97\xbe\xc1\xa9\xdc\x29"
+ "\x1a\x0a\x56\xc1\x1a\x91\x97\x8c"
+ "\x0b\xc7\x16\xed\x5a\x22\xa6\x2e"
+ "\x8c\x2b\x4f\x54\x76\x47\x53\x8e"
+ "\xe8\x00\xec\x92\xb9\x55\xe6\xa2"
+ "\xf3\xe2\x4f\x6a\x66\x60\xd0\x87"
+ "\xe6\xd1\xcc\xe3\x6a\xc5\x2d\x21"
+ "\xcc\x9d\x6a\xb6\x75\xaa\xe2\x19"
+ "\x21\x9f\xa1\x5e\x4c\xfd\x72\xf9"
+ "\x94\x4e\x63\xc7\xae\xfc\xed\x47"
+ "\xe2\xfe\x7a\x63\x77\xfe\x97\x82"
+ "\xb1\x10\x6e\x36\x1d\xe1\xc4\x80"
+ "\xec\x69\x41\xec\xa7\x8a\xe0\x2f"
+ "\xe3\x49\x26\xa2\x41\xb2\x08\x0f"
+ "\x28\xb4\xa7\x39\xa1\x99\x2d\x1e"
+ "\x43\x42\x35\xd0\xcf\xec\x77\x67"
+ "\xb2\x3b\x9e\x1c\x35\xde\x4f\x5e"
+ "\x73\x3f\x5d\x6f\x07\x4b\x2e\x50"
+ "\xab\x6c\x6b\xff\xea\x00\x67\xaa"
+ "\x0e\x82\x32\xdd\x3d\xb5\xe5\x76"
+ "\x2b\x77\x3f\xbe\x12\x75\xfb\x92"
+ "\xc6\x89\x67\x4d\xca\xf7\xd4\x50"
+ "\xc0\x74\x47\xcc\xd9\x0a\xd4\xc6"
+ "\x3b\x17\x2e\xe3\x35\xbb\x53\xb5"
+ "\x86\xad\x51\xcc\xd5\x96\xb8\xdc"
+ "\x03\x57\xe6\x98\x52\x2f\x61\x62"
+ "\xc4\x5c\x9c\x36\x71\x07\xfb\x94"
+ "\xe3\x02\xc4\x2b\x08\x75\xc7\x35"
+ "\xfb\x2e\x88\x7b\xbb\x67\x00\xe1"
+ "\xc9\xdd\x99\xb2\x13\x53\x1a\x4e"
+ "\x76\x87\x19\x04\x1a\x2f\x38\x3e"
+ "\xef\x91\x64\x1d\x18\x07\x4e\x31"
+ "\x88\x21\x7c\xb0\xa5\x12\x4c\x3c"
+ "\xb0\x20\xbd\xda\xdf\xf9\x7c\xdd",
+ .rlen = 512,
+ }, {
+ .key = "\x27\x18\x28\x18\x28\x45\x90\x45"
+ "\x23\x53\x60\x28\x74\x71\x35\x26"
+ "\x62\x49\x77\x57\x24\x70\x93\x69"
+ "\x99\x59\x57\x49\x66\x96\x76\x27"
+ "\x31\x41\x59\x26\x53\x58\x97\x93"
+ "\x23\x84\x62\x64\x33\x83\x27\x95"
+ "\x02\x88\x41\x97\x16\x93\x99\x37"
+ "\x51\x05\x82\x09\x74\x94\x45\x92",
+ .klen = 64,
+ .iv = "\xff\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .input = "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+ "\x10\x11\x12\x13\x14\x15\x16\x17"
+ "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
+ "\x20\x21\x22\x23\x24\x25\x26\x27"
+ "\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f"
+ "\x30\x31\x32\x33\x34\x35\x36\x37"
+ "\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f"
+ "\x40\x41\x42\x43\x44\x45\x46\x47"
+ "\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f"
+ "\x50\x51\x52\x53\x54\x55\x56\x57"
+ "\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f"
+ "\x60\x61\x62\x63\x64\x65\x66\x67"
+ "\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f"
+ "\x70\x71\x72\x73\x74\x75\x76\x77"
+ "\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f"
+ "\x80\x81\x82\x83\x84\x85\x86\x87"
+ "\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
+ "\x90\x91\x92\x93\x94\x95\x96\x97"
+ "\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
+ "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7"
+ "\xa8\xa9\xaa\xab\xac\xad\xae\xaf"
+ "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7"
+ "\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
+ "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7"
+ "\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
+ "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7"
+ "\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf"
+ "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7"
+ "\xe8\xe9\xea\xeb\xec\xed\xee\xef"
+ "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7"
+ "\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"
+ "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+ "\x10\x11\x12\x13\x14\x15\x16\x17"
+ "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
+ "\x20\x21\x22\x23\x24\x25\x26\x27"
+ "\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f"
+ "\x30\x31\x32\x33\x34\x35\x36\x37"
+ "\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f"
+ "\x40\x41\x42\x43\x44\x45\x46\x47"
+ "\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f"
+ "\x50\x51\x52\x53\x54\x55\x56\x57"
+ "\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f"
+ "\x60\x61\x62\x63\x64\x65\x66\x67"
+ "\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f"
+ "\x70\x71\x72\x73\x74\x75\x76\x77"
+ "\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f"
+ "\x80\x81\x82\x83\x84\x85\x86\x87"
+ "\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
+ "\x90\x91\x92\x93\x94\x95\x96\x97"
+ "\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
+ "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7"
+ "\xa8\xa9\xaa\xab\xac\xad\xae\xaf"
+ "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7"
+ "\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
+ "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7"
+ "\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
+ "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7"
+ "\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf"
+ "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7"
+ "\xe8\xe9\xea\xeb\xec\xed\xee\xef"
+ "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7"
+ "\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff",
+ .ilen = 512,
+ .result = "\x2b\xc9\xb4\x6b\x10\x94\xa9\x32"
+ "\xaa\xb0\x20\xc6\x44\x3d\x74\x1f"
+ "\x75\x01\xa7\xf6\xf5\xf7\x62\x1b"
+ "\x80\x1b\x82\xcb\x01\x59\x91\x7f"
+ "\x80\x3a\x98\xf0\xd2\xca\xc4\xc3"
+ "\x34\xfd\xe6\x11\xf9\x33\x45\x12"
+ "\x48\xc5\x8c\x25\xf1\xc5\xc5\x23"
+ "\xd3\x44\xb4\x73\xd5\x04\xc0\xb7"
+ "\xca\x2f\xf5\xcd\xc5\xb4\xdd\xb0"
+ "\xf4\x60\xe8\xfb\xc6\x9c\xc5\x78"
+ "\xcd\xec\x7d\xdc\x19\x9c\x72\x64"
+ "\x63\x0b\x38\x2e\x76\xdd\x2d\x36"
+ "\x49\xb0\x1d\xea\x78\x9e\x00\xca"
+ "\x20\xcc\x1b\x1e\x98\x74\xab\xed"
+ "\x79\xf7\xd0\x6c\xd8\x93\x80\x29"
+ "\xac\xa5\x5e\x34\xa9\xab\xa0\x55"
+ "\x9a\xea\xaa\x95\x4d\x7b\xfe\x46"
+ "\x26\x8a\xfd\x88\xa2\xa8\xa6\xae"
+ "\x25\x42\x17\xbf\x76\x8f\x1c\x3d"
+ "\xec\x9a\xda\x64\x96\xb5\x61\xff"
+ "\x99\xeb\x12\x96\x85\x82\x9d\xd5"
+ "\x81\x85\x14\xa8\x59\xac\x8c\x94"
+ "\xbb\x3b\x85\x2b\xdf\xb3\x0c\xba"
+ "\x82\xc6\x4d\xca\x86\xea\x53\x28"
+ "\x4c\xe0\x4e\x31\xe3\x73\x2f\x79"
+ "\x9d\x42\xe1\x03\xe3\x8b\xc4\xff"
+ "\x05\xca\x81\x7b\xda\xa2\xde\x63"
+ "\x3a\x10\xbe\xc2\xac\x32\xc4\x05"
+ "\x47\x7e\xef\x67\xe2\x5f\x5b\xae"
+ "\xed\xf1\x70\x34\x16\x9a\x07\x7b"
+ "\xf2\x25\x2b\xb0\xf8\x3c\x15\x9a"
+ "\xa6\x59\x55\x5f\xc1\xf4\x1e\xcd"
+ "\x93\x1f\x06\xba\xd4\x9a\x22\x69"
+ "\xfa\x8e\x95\x0d\xf3\x23\x59\x2c"
+ "\xfe\x00\xba\xf0\x0e\xbc\x6d\xd6"
+ "\x62\xf0\x7a\x0e\x83\x3e\xdb\x32"
+ "\xfd\x43\x7d\xda\x42\x51\x87\x43"
+ "\x9d\xf9\xef\xf4\x30\x97\xf8\x09"
+ "\x88\xfc\x3f\x93\x70\xc1\x4a\xec"
+ "\x27\x5f\x11\xac\x71\xc7\x48\x46"
+ "\x2f\xf9\xdf\x8d\x9f\xf7\x2e\x56"
+ "\x0d\x4e\xb0\x32\x76\xce\x86\x81"
+ "\xcd\xdf\xe4\x00\xbf\xfd\x5f\x24"
+ "\xaf\xf7\x9a\xde\xff\x18\xac\x14"
+ "\x90\xc5\x01\x39\x34\x0f\x24\xf3"
+ "\x13\x2f\x5e\x4f\x30\x9a\x36\x40"
+ "\xec\xea\xbc\xcd\x9e\x0e\x5b\x23"
+ "\x50\x88\x97\x40\x69\xb1\x37\xf5"
+ "\xc3\x15\xf9\x3f\xb7\x79\x64\xe8"
+ "\x7b\x10\x20\xb9\x2b\x46\x83\x5b"
+ "\xd8\x39\xfc\xe4\xfa\x88\x52\xf2"
+ "\x72\xb0\x97\x4e\x89\xb3\x48\x00"
+ "\xc1\x16\x73\x50\x77\xba\xa6\x65"
+ "\x20\x2d\xb0\x02\x27\x89\xda\x99"
+ "\x45\xfb\xe9\xd3\x1d\x39\x2f\xd6"
+ "\x2a\xda\x09\x12\x11\xaf\xe6\x57"
+ "\x01\x04\x8a\xff\x86\x8b\xac\xf8"
+ "\xee\xe4\x1c\x98\x5b\xcf\x6b\x76"
+ "\xa3\x0e\x33\x74\x40\x18\x39\x72"
+ "\x66\x50\x31\xfd\x70\xdf\xe8\x51"
+ "\x96\x21\x36\xb2\x9b\xfa\x85\xd1"
+ "\x30\x05\xc8\x92\x98\x80\xff\x7a"
+ "\xaf\x43\x0b\xc5\x20\x41\x92\x20"
+ "\xd4\xa0\x91\x98\x11\x5f\x4d\xb1",
+ .rlen = 512,
+ },
+};
+
+static struct cipher_testvec serpent_xts_dec_tv_template[] = {
+ /* Generated from AES-XTS test vectors */
+ /* same as enc vectors with input and result reversed */
+ {
+ .key = "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .klen = 32,
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .input = "\xe1\x08\xb8\x1d\x2c\xf5\x33\x64"
+ "\xc8\x12\x04\xc7\xb3\x70\xe8\xc4"
+ "\x6a\x31\xc5\xf3\x00\xca\xb9\x16"
+ "\xde\xe2\x77\x66\xf7\xfe\x62\x08",
+ .ilen = 32,
+ .result = "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .rlen = 32,
+ }, {
+ .key = "\x11\x11\x11\x11\x11\x11\x11\x11"
+ "\x11\x11\x11\x11\x11\x11\x11\x11"
+ "\x22\x22\x22\x22\x22\x22\x22\x22"
+ "\x22\x22\x22\x22\x22\x22\x22\x22",
+ .klen = 32,
+ .iv = "\x33\x33\x33\x33\x33\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .input = "\x1a\x0a\x09\x5f\xcd\x07\x07\x98"
+ "\x41\x86\x12\xaf\xb3\xd7\x68\x13"
+ "\xed\x81\xcd\x06\x87\x43\x1a\xbb"
+ "\x13\x3d\xd6\x1e\x2b\xe1\x77\xbe",
+ .ilen = 32,
+ .result = "\x44\x44\x44\x44\x44\x44\x44\x44"
+ "\x44\x44\x44\x44\x44\x44\x44\x44"
+ "\x44\x44\x44\x44\x44\x44\x44\x44"
+ "\x44\x44\x44\x44\x44\x44\x44\x44",
+ .rlen = 32,
+ }, {
+ .key = "\xff\xfe\xfd\xfc\xfb\xfa\xf9\xf8"
+ "\xf7\xf6\xf5\xf4\xf3\xf2\xf1\xf0"
+ "\x22\x22\x22\x22\x22\x22\x22\x22"
+ "\x22\x22\x22\x22\x22\x22\x22\x22",
+ .klen = 32,
+ .iv = "\x33\x33\x33\x33\x33\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .input = "\xf9\x9b\x28\xb8\x5c\xaf\x8c\x61"
+ "\xb6\x1c\x81\x8f\x2c\x87\x60\x89"
+ "\x0d\x8d\x7a\xe8\x60\x48\xcc\x86"
+ "\xc1\x68\x45\xaa\x00\xe9\x24\xc5",
+ .ilen = 32,
+ .result = "\x44\x44\x44\x44\x44\x44\x44\x44"
+ "\x44\x44\x44\x44\x44\x44\x44\x44"
+ "\x44\x44\x44\x44\x44\x44\x44\x44"
+ "\x44\x44\x44\x44\x44\x44\x44\x44",
+ .rlen = 32,
+ }, {
+ .key = "\x27\x18\x28\x18\x28\x45\x90\x45"
+ "\x23\x53\x60\x28\x74\x71\x35\x26"
+ "\x31\x41\x59\x26\x53\x58\x97\x93"
+ "\x23\x84\x62\x64\x33\x83\x27\x95",
+ .klen = 32,
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .input = "\xfe\x47\x4a\xc8\x60\x7e\xb4\x8b"
+ "\x0d\x10\xf4\xb0\x0d\xba\xf8\x53"
+ "\x65\x6e\x38\x4b\xdb\xaa\xb1\x9e"
+ "\x28\xca\xb0\x22\xb3\x85\x75\xf4"
+ "\x00\x5c\x75\x14\x06\xd6\x25\x82"
+ "\xe6\xcb\x08\xf7\x29\x90\x23\x8e"
+ "\xa4\x68\x57\xe4\xf0\xd8\x32\xf3"
+ "\x80\x51\x67\xb5\x0b\x85\x69\xe8"
+ "\x19\xfe\xc4\xc7\x3e\xea\x90\xd3"
+ "\x8f\xa3\xf2\x0a\xac\x17\x4b\xa0"
+ "\x63\x5a\x16\x0f\xf0\xce\x66\x1f"
+ "\x2c\x21\x07\xf1\xa4\x03\xa3\x44"
+ "\x41\x61\x87\x5d\x6b\xb3\xef\xd4"
+ "\xfc\xaa\x32\x7e\x55\x58\x04\x41"
+ "\xc9\x07\x33\xc6\xa2\x68\xd6\x5a"
+ "\x55\x79\x4b\x6f\xcf\x89\xb9\x19"
+ "\xe5\x54\x13\x15\xb2\x1a\xfa\x15"
+ "\xc2\xf0\x06\x59\xfa\xa0\x25\x05"
+ "\x58\xfa\x43\x91\x16\x85\x40\xbb"
+ "\x0d\x34\x4d\xc5\x1e\x20\xd5\x08"
+ "\xcd\x22\x22\x41\x11\x9f\x6c\x7c"
+ "\x8d\x57\xc9\xba\x57\xe8\x2c\xf7"
+ "\xa0\x42\xa8\xde\xfc\xa3\xca\x98"
+ "\x4b\x43\xb1\xce\x4b\xbf\x01\x67"
+ "\x6e\x29\x60\xbd\x10\x14\x84\x82"
+ "\x83\x82\x0c\x63\x73\x92\x02\x7c"
+ "\x55\x37\x20\x80\x17\x51\xc8\xbc"
+ "\x46\x02\xcb\x38\x07\x6d\xe2\x85"
+ "\xaa\x29\xaf\x24\x58\x0d\xf0\x75"
+ "\x08\x0a\xa5\x34\x25\x16\xf3\x74"
+ "\xa7\x0b\x97\xbe\xc1\xa9\xdc\x29"
+ "\x1a\x0a\x56\xc1\x1a\x91\x97\x8c"
+ "\x0b\xc7\x16\xed\x5a\x22\xa6\x2e"
+ "\x8c\x2b\x4f\x54\x76\x47\x53\x8e"
+ "\xe8\x00\xec\x92\xb9\x55\xe6\xa2"
+ "\xf3\xe2\x4f\x6a\x66\x60\xd0\x87"
+ "\xe6\xd1\xcc\xe3\x6a\xc5\x2d\x21"
+ "\xcc\x9d\x6a\xb6\x75\xaa\xe2\x19"
+ "\x21\x9f\xa1\x5e\x4c\xfd\x72\xf9"
+ "\x94\x4e\x63\xc7\xae\xfc\xed\x47"
+ "\xe2\xfe\x7a\x63\x77\xfe\x97\x82"
+ "\xb1\x10\x6e\x36\x1d\xe1\xc4\x80"
+ "\xec\x69\x41\xec\xa7\x8a\xe0\x2f"
+ "\xe3\x49\x26\xa2\x41\xb2\x08\x0f"
+ "\x28\xb4\xa7\x39\xa1\x99\x2d\x1e"
+ "\x43\x42\x35\xd0\xcf\xec\x77\x67"
+ "\xb2\x3b\x9e\x1c\x35\xde\x4f\x5e"
+ "\x73\x3f\x5d\x6f\x07\x4b\x2e\x50"
+ "\xab\x6c\x6b\xff\xea\x00\x67\xaa"
+ "\x0e\x82\x32\xdd\x3d\xb5\xe5\x76"
+ "\x2b\x77\x3f\xbe\x12\x75\xfb\x92"
+ "\xc6\x89\x67\x4d\xca\xf7\xd4\x50"
+ "\xc0\x74\x47\xcc\xd9\x0a\xd4\xc6"
+ "\x3b\x17\x2e\xe3\x35\xbb\x53\xb5"
+ "\x86\xad\x51\xcc\xd5\x96\xb8\xdc"
+ "\x03\x57\xe6\x98\x52\x2f\x61\x62"
+ "\xc4\x5c\x9c\x36\x71\x07\xfb\x94"
+ "\xe3\x02\xc4\x2b\x08\x75\xc7\x35"
+ "\xfb\x2e\x88\x7b\xbb\x67\x00\xe1"
+ "\xc9\xdd\x99\xb2\x13\x53\x1a\x4e"
+ "\x76\x87\x19\x04\x1a\x2f\x38\x3e"
+ "\xef\x91\x64\x1d\x18\x07\x4e\x31"
+ "\x88\x21\x7c\xb0\xa5\x12\x4c\x3c"
+ "\xb0\x20\xbd\xda\xdf\xf9\x7c\xdd",
+ .ilen = 512,
+ .result = "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+ "\x10\x11\x12\x13\x14\x15\x16\x17"
+ "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
+ "\x20\x21\x22\x23\x24\x25\x26\x27"
+ "\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f"
+ "\x30\x31\x32\x33\x34\x35\x36\x37"
+ "\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f"
+ "\x40\x41\x42\x43\x44\x45\x46\x47"
+ "\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f"
+ "\x50\x51\x52\x53\x54\x55\x56\x57"
+ "\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f"
+ "\x60\x61\x62\x63\x64\x65\x66\x67"
+ "\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f"
+ "\x70\x71\x72\x73\x74\x75\x76\x77"
+ "\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f"
+ "\x80\x81\x82\x83\x84\x85\x86\x87"
+ "\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
+ "\x90\x91\x92\x93\x94\x95\x96\x97"
+ "\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
+ "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7"
+ "\xa8\xa9\xaa\xab\xac\xad\xae\xaf"
+ "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7"
+ "\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
+ "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7"
+ "\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
+ "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7"
+ "\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf"
+ "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7"
+ "\xe8\xe9\xea\xeb\xec\xed\xee\xef"
+ "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7"
+ "\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"
+ "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+ "\x10\x11\x12\x13\x14\x15\x16\x17"
+ "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
+ "\x20\x21\x22\x23\x24\x25\x26\x27"
+ "\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f"
+ "\x30\x31\x32\x33\x34\x35\x36\x37"
+ "\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f"
+ "\x40\x41\x42\x43\x44\x45\x46\x47"
+ "\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f"
+ "\x50\x51\x52\x53\x54\x55\x56\x57"
+ "\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f"
+ "\x60\x61\x62\x63\x64\x65\x66\x67"
+ "\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f"
+ "\x70\x71\x72\x73\x74\x75\x76\x77"
+ "\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f"
+ "\x80\x81\x82\x83\x84\x85\x86\x87"
+ "\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
+ "\x90\x91\x92\x93\x94\x95\x96\x97"
+ "\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
+ "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7"
+ "\xa8\xa9\xaa\xab\xac\xad\xae\xaf"
+ "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7"
+ "\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
+ "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7"
+ "\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
+ "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7"
+ "\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf"
+ "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7"
+ "\xe8\xe9\xea\xeb\xec\xed\xee\xef"
+ "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7"
+ "\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff",
+ .rlen = 512,
+ }, {
+ .key = "\x27\x18\x28\x18\x28\x45\x90\x45"
+ "\x23\x53\x60\x28\x74\x71\x35\x26"
+ "\x62\x49\x77\x57\x24\x70\x93\x69"
+ "\x99\x59\x57\x49\x66\x96\x76\x27"
+ "\x31\x41\x59\x26\x53\x58\x97\x93"
+ "\x23\x84\x62\x64\x33\x83\x27\x95"
+ "\x02\x88\x41\x97\x16\x93\x99\x37"
+ "\x51\x05\x82\x09\x74\x94\x45\x92",
+ .klen = 64,
+ .iv = "\xff\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .input = "\x2b\xc9\xb4\x6b\x10\x94\xa9\x32"
+ "\xaa\xb0\x20\xc6\x44\x3d\x74\x1f"
+ "\x75\x01\xa7\xf6\xf5\xf7\x62\x1b"
+ "\x80\x1b\x82\xcb\x01\x59\x91\x7f"
+ "\x80\x3a\x98\xf0\xd2\xca\xc4\xc3"
+ "\x34\xfd\xe6\x11\xf9\x33\x45\x12"
+ "\x48\xc5\x8c\x25\xf1\xc5\xc5\x23"
+ "\xd3\x44\xb4\x73\xd5\x04\xc0\xb7"
+ "\xca\x2f\xf5\xcd\xc5\xb4\xdd\xb0"
+ "\xf4\x60\xe8\xfb\xc6\x9c\xc5\x78"
+ "\xcd\xec\x7d\xdc\x19\x9c\x72\x64"
+ "\x63\x0b\x38\x2e\x76\xdd\x2d\x36"
+ "\x49\xb0\x1d\xea\x78\x9e\x00\xca"
+ "\x20\xcc\x1b\x1e\x98\x74\xab\xed"
+ "\x79\xf7\xd0\x6c\xd8\x93\x80\x29"
+ "\xac\xa5\x5e\x34\xa9\xab\xa0\x55"
+ "\x9a\xea\xaa\x95\x4d\x7b\xfe\x46"
+ "\x26\x8a\xfd\x88\xa2\xa8\xa6\xae"
+ "\x25\x42\x17\xbf\x76\x8f\x1c\x3d"
+ "\xec\x9a\xda\x64\x96\xb5\x61\xff"
+ "\x99\xeb\x12\x96\x85\x82\x9d\xd5"
+ "\x81\x85\x14\xa8\x59\xac\x8c\x94"
+ "\xbb\x3b\x85\x2b\xdf\xb3\x0c\xba"
+ "\x82\xc6\x4d\xca\x86\xea\x53\x28"
+ "\x4c\xe0\x4e\x31\xe3\x73\x2f\x79"
+ "\x9d\x42\xe1\x03\xe3\x8b\xc4\xff"
+ "\x05\xca\x81\x7b\xda\xa2\xde\x63"
+ "\x3a\x10\xbe\xc2\xac\x32\xc4\x05"
+ "\x47\x7e\xef\x67\xe2\x5f\x5b\xae"
+ "\xed\xf1\x70\x34\x16\x9a\x07\x7b"
+ "\xf2\x25\x2b\xb0\xf8\x3c\x15\x9a"
+ "\xa6\x59\x55\x5f\xc1\xf4\x1e\xcd"
+ "\x93\x1f\x06\xba\xd4\x9a\x22\x69"
+ "\xfa\x8e\x95\x0d\xf3\x23\x59\x2c"
+ "\xfe\x00\xba\xf0\x0e\xbc\x6d\xd6"
+ "\x62\xf0\x7a\x0e\x83\x3e\xdb\x32"
+ "\xfd\x43\x7d\xda\x42\x51\x87\x43"
+ "\x9d\xf9\xef\xf4\x30\x97\xf8\x09"
+ "\x88\xfc\x3f\x93\x70\xc1\x4a\xec"
+ "\x27\x5f\x11\xac\x71\xc7\x48\x46"
+ "\x2f\xf9\xdf\x8d\x9f\xf7\x2e\x56"
+ "\x0d\x4e\xb0\x32\x76\xce\x86\x81"
+ "\xcd\xdf\xe4\x00\xbf\xfd\x5f\x24"
+ "\xaf\xf7\x9a\xde\xff\x18\xac\x14"
+ "\x90\xc5\x01\x39\x34\x0f\x24\xf3"
+ "\x13\x2f\x5e\x4f\x30\x9a\x36\x40"
+ "\xec\xea\xbc\xcd\x9e\x0e\x5b\x23"
+ "\x50\x88\x97\x40\x69\xb1\x37\xf5"
+ "\xc3\x15\xf9\x3f\xb7\x79\x64\xe8"
+ "\x7b\x10\x20\xb9\x2b\x46\x83\x5b"
+ "\xd8\x39\xfc\xe4\xfa\x88\x52\xf2"
+ "\x72\xb0\x97\x4e\x89\xb3\x48\x00"
+ "\xc1\x16\x73\x50\x77\xba\xa6\x65"
+ "\x20\x2d\xb0\x02\x27\x89\xda\x99"
+ "\x45\xfb\xe9\xd3\x1d\x39\x2f\xd6"
+ "\x2a\xda\x09\x12\x11\xaf\xe6\x57"
+ "\x01\x04\x8a\xff\x86\x8b\xac\xf8"
+ "\xee\xe4\x1c\x98\x5b\xcf\x6b\x76"
+ "\xa3\x0e\x33\x74\x40\x18\x39\x72"
+ "\x66\x50\x31\xfd\x70\xdf\xe8\x51"
+ "\x96\x21\x36\xb2\x9b\xfa\x85\xd1"
+ "\x30\x05\xc8\x92\x98\x80\xff\x7a"
+ "\xaf\x43\x0b\xc5\x20\x41\x92\x20"
+ "\xd4\xa0\x91\x98\x11\x5f\x4d\xb1",
+ .ilen = 512,
+ .result = "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+ "\x10\x11\x12\x13\x14\x15\x16\x17"
+ "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
+ "\x20\x21\x22\x23\x24\x25\x26\x27"
+ "\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f"
+ "\x30\x31\x32\x33\x34\x35\x36\x37"
+ "\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f"
+ "\x40\x41\x42\x43\x44\x45\x46\x47"
+ "\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f"
+ "\x50\x51\x52\x53\x54\x55\x56\x57"
+ "\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f"
+ "\x60\x61\x62\x63\x64\x65\x66\x67"
+ "\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f"
+ "\x70\x71\x72\x73\x74\x75\x76\x77"
+ "\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f"
+ "\x80\x81\x82\x83\x84\x85\x86\x87"
+ "\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
+ "\x90\x91\x92\x93\x94\x95\x96\x97"
+ "\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
+ "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7"
+ "\xa8\xa9\xaa\xab\xac\xad\xae\xaf"
+ "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7"
+ "\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
+ "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7"
+ "\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
+ "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7"
+ "\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf"
+ "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7"
+ "\xe8\xe9\xea\xeb\xec\xed\xee\xef"
+ "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7"
+ "\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"
+ "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+ "\x10\x11\x12\x13\x14\x15\x16\x17"
+ "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
+ "\x20\x21\x22\x23\x24\x25\x26\x27"
+ "\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f"
+ "\x30\x31\x32\x33\x34\x35\x36\x37"
+ "\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f"
+ "\x40\x41\x42\x43\x44\x45\x46\x47"
+ "\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f"
+ "\x50\x51\x52\x53\x54\x55\x56\x57"
+ "\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f"
+ "\x60\x61\x62\x63\x64\x65\x66\x67"
+ "\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f"
+ "\x70\x71\x72\x73\x74\x75\x76\x77"
+ "\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f"
+ "\x80\x81\x82\x83\x84\x85\x86\x87"
+ "\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
+ "\x90\x91\x92\x93\x94\x95\x96\x97"
+ "\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
+ "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7"
+ "\xa8\xa9\xaa\xab\xac\xad\xae\xaf"
+ "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7"
+ "\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
+ "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7"
+ "\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
+ "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7"
+ "\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf"
+ "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7"
+ "\xe8\xe9\xea\xeb\xec\xed\xee\xef"
+ "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7"
+ "\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff",
+ .rlen = 512,
+ },
+};
/* Cast6 test vectors from RFC 2612 */
#define CAST6_ENC_TEST_VECTORS 3
diff --git a/crypto/twofish_common.c b/crypto/twofish_common.c
index 0af216c..5f62c4f 100644
--- a/crypto/twofish_common.c
+++ b/crypto/twofish_common.c
@@ -580,12 +580,9 @@
ctx->a[(j) + 1] = rol32(y, 9)
/* Perform the key setup. */
-int twofish_setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int key_len)
+int __twofish_setkey(struct twofish_ctx *ctx, const u8 *key,
+ unsigned int key_len, u32 *flags)
{
-
- struct twofish_ctx *ctx = crypto_tfm_ctx(tfm);
- u32 *flags = &tfm->crt_flags;
-
int i, j, k;
/* Temporaries for CALC_K. */
@@ -701,7 +698,13 @@
return 0;
}
+EXPORT_SYMBOL_GPL(__twofish_setkey);
+int twofish_setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int key_len)
+{
+ return __twofish_setkey(crypto_tfm_ctx(tfm), key, key_len,
+ &tfm->crt_flags);
+}
EXPORT_SYMBOL_GPL(twofish_setkey);
MODULE_LICENSE("GPL");
diff --git a/crypto/xts.c b/crypto/xts.c
index 8517054..ca1608f 100644
--- a/crypto/xts.c
+++ b/crypto/xts.c
@@ -21,6 +21,7 @@
#include <linux/scatterlist.h>
#include <linux/slab.h>
+#include <crypto/xts.h>
#include <crypto/b128ops.h>
#include <crypto/gf128mul.h>
@@ -96,7 +97,7 @@
{
int err;
unsigned int avail;
- const int bs = crypto_cipher_blocksize(ctx->child);
+ const int bs = XTS_BLOCK_SIZE;
struct sinfo s = {
.tfm = crypto_cipher_tfm(ctx->child),
.fn = fn
@@ -165,6 +166,78 @@
crypto_cipher_alg(ctx->child)->cia_decrypt);
}
+int xts_crypt(struct blkcipher_desc *desc, struct scatterlist *sdst,
+ struct scatterlist *ssrc, unsigned int nbytes,
+ struct xts_crypt_req *req)
+{
+ const unsigned int bsize = XTS_BLOCK_SIZE;
+ const unsigned int max_blks = req->tbuflen / bsize;
+ struct blkcipher_walk walk;
+ unsigned int nblocks;
+ be128 *src, *dst, *t;
+ be128 *t_buf = req->tbuf;
+ int err, i;
+
+ BUG_ON(max_blks < 1);
+
+ blkcipher_walk_init(&walk, sdst, ssrc, nbytes);
+
+ err = blkcipher_walk_virt(desc, &walk);
+ nbytes = walk.nbytes;
+ if (!nbytes)
+ return err;
+
+ nblocks = min(nbytes / bsize, max_blks);
+ src = (be128 *)walk.src.virt.addr;
+ dst = (be128 *)walk.dst.virt.addr;
+
+ /* calculate first value of T */
+ req->tweak_fn(req->tweak_ctx, (u8 *)&t_buf[0], walk.iv);
+
+ i = 0;
+ goto first;
+
+ for (;;) {
+ do {
+ for (i = 0; i < nblocks; i++) {
+ gf128mul_x_ble(&t_buf[i], t);
+first:
+ t = &t_buf[i];
+
+ /* PP <- T xor P */
+ be128_xor(dst + i, t, src + i);
+ }
+
+ /* CC <- E(Key2,PP) */
+ req->crypt_fn(req->crypt_ctx, (u8 *)dst,
+ nblocks * bsize);
+
+ /* C <- T xor CC */
+ for (i = 0; i < nblocks; i++)
+ be128_xor(dst + i, dst + i, &t_buf[i]);
+
+ src += nblocks;
+ dst += nblocks;
+ nbytes -= nblocks * bsize;
+ nblocks = min(nbytes / bsize, max_blks);
+ } while (nblocks > 0);
+
+ *(be128 *)walk.iv = *t;
+
+ err = blkcipher_walk_done(desc, &walk, nbytes);
+ nbytes = walk.nbytes;
+ if (!nbytes)
+ break;
+
+ nblocks = min(nbytes / bsize, max_blks);
+ src = (be128 *)walk.src.virt.addr;
+ dst = (be128 *)walk.dst.virt.addr;
+ }
+
+ return err;
+}
+EXPORT_SYMBOL_GPL(xts_crypt);
+
static int init_tfm(struct crypto_tfm *tfm)
{
struct crypto_cipher *cipher;
@@ -177,7 +250,7 @@
if (IS_ERR(cipher))
return PTR_ERR(cipher);
- if (crypto_cipher_blocksize(cipher) != 16) {
+ if (crypto_cipher_blocksize(cipher) != XTS_BLOCK_SIZE) {
*flags |= CRYPTO_TFM_RES_BAD_BLOCK_LEN;
crypto_free_cipher(cipher);
return -EINVAL;
@@ -192,7 +265,7 @@
}
/* this check isn't really needed, leave it here just in case */
- if (crypto_cipher_blocksize(cipher) != 16) {
+ if (crypto_cipher_blocksize(cipher) != XTS_BLOCK_SIZE) {
crypto_free_cipher(cipher);
crypto_free_cipher(ctx->child);
*flags |= CRYPTO_TFM_RES_BAD_BLOCK_LEN;
diff --git a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c
index 7f9eba9..0eefa12 100644
--- a/drivers/acpi/pci_irq.c
+++ b/drivers/acpi/pci_irq.c
@@ -487,10 +487,10 @@
else
link_desc[0] = '\0';
- dev_info(&dev->dev, "PCI INT %c%s -> GSI %u (%s, %s) -> IRQ %d\n",
- pin_name(pin), link_desc, gsi,
- (triggering == ACPI_LEVEL_SENSITIVE) ? "level" : "edge",
- (polarity == ACPI_ACTIVE_LOW) ? "low" : "high", dev->irq);
+ dev_dbg(&dev->dev, "PCI INT %c%s -> GSI %u (%s, %s) -> IRQ %d\n",
+ pin_name(pin), link_desc, gsi,
+ (triggering == ACPI_LEVEL_SENSITIVE) ? "level" : "edge",
+ (polarity == ACPI_ACTIVE_LOW) ? "low" : "high", dev->irq);
return 0;
}
@@ -524,6 +524,6 @@
* (e.g. PCI_UNDEFINED_IRQ).
*/
- dev_info(&dev->dev, "PCI INT %c disabled\n", pin_name(pin));
+ dev_dbg(&dev->dev, "PCI INT %c disabled\n", pin_name(pin));
acpi_unregister_gsi(gsi);
}
diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig
index e95c67e..fcbec8a 100644
--- a/drivers/base/Kconfig
+++ b/drivers/base/Kconfig
@@ -172,6 +172,10 @@
bool
default n
+config GENERIC_CPU_DEVICES
+ bool
+ default n
+
source "drivers/base/regmap/Kconfig"
config DMA_SHARED_BUFFER
diff --git a/drivers/base/base.h b/drivers/base/base.h
index 7a6ae42..b858dfd 100644
--- a/drivers/base/base.h
+++ b/drivers/base/base.h
@@ -94,7 +94,7 @@
static inline int hypervisor_init(void) { return 0; }
#endif
extern int platform_bus_init(void);
-extern int cpu_dev_init(void);
+extern void cpu_dev_init(void);
extern int bus_add_device(struct device *dev);
extern void bus_probe_device(struct device *dev);
diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c
index 9a5578e..db87e78 100644
--- a/drivers/base/cpu.c
+++ b/drivers/base/cpu.c
@@ -2,6 +2,7 @@
* CPU subsystem support
*/
+#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/sched.h>
@@ -10,6 +11,7 @@
#include <linux/device.h>
#include <linux/node.h>
#include <linux/gfp.h>
+#include <linux/percpu.h>
#include "base.h"
@@ -274,16 +276,30 @@
}
EXPORT_SYMBOL_GPL(cpu_is_hotpluggable);
-int __init cpu_dev_init(void)
-{
- int err;
+#ifdef CONFIG_GENERIC_CPU_DEVICES
+static DEFINE_PER_CPU(struct cpu, cpu_devices);
+#endif
- err = subsys_system_register(&cpu_subsys, cpu_root_attr_groups);
- if (err)
- return err;
+static void __init cpu_dev_register_generic(void)
+{
+#ifdef CONFIG_GENERIC_CPU_DEVICES
+ int i;
+
+ for_each_possible_cpu(i) {
+ if (register_cpu(&per_cpu(cpu_devices, i), i))
+ panic("Failed to register CPU device");
+ }
+#endif
+}
+
+void __init cpu_dev_init(void)
+{
+ if (subsys_system_register(&cpu_subsys, cpu_root_attr_groups))
+ panic("Failed to register CPU subsystem");
+
+ cpu_dev_register_generic();
#if defined(CONFIG_SCHED_MC) || defined(CONFIG_SCHED_SMT)
- err = sched_create_sysfs_power_savings_entries(cpu_subsys.dev_root);
+ sched_create_sysfs_power_savings_entries(cpu_subsys.dev_root);
#endif
- return err;
}
diff --git a/drivers/char/hw_random/atmel-rng.c b/drivers/char/hw_random/atmel-rng.c
index 241df2e..f518b99 100644
--- a/drivers/char/hw_random/atmel-rng.c
+++ b/drivers/char/hw_random/atmel-rng.c
@@ -141,17 +141,7 @@
},
};
-static int __init atmel_trng_init(void)
-{
- return platform_driver_register(&atmel_trng_driver);
-}
-module_init(atmel_trng_init);
-
-static void __exit atmel_trng_exit(void)
-{
- platform_driver_unregister(&atmel_trng_driver);
-}
-module_exit(atmel_trng_exit);
+module_platform_driver(atmel_trng_driver);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Peter Korsgaard <jacmet@sunsite.dk>");
diff --git a/drivers/char/hw_random/n2-drv.c b/drivers/char/hw_random/n2-drv.c
index c3de70d..ebd48f0 100644
--- a/drivers/char/hw_random/n2-drv.c
+++ b/drivers/char/hw_random/n2-drv.c
@@ -770,15 +770,4 @@
.remove = __devexit_p(n2rng_remove),
};
-static int __init n2rng_init(void)
-{
- return platform_driver_register(&n2rng_driver);
-}
-
-static void __exit n2rng_exit(void)
-{
- platform_driver_unregister(&n2rng_driver);
-}
-
-module_init(n2rng_init);
-module_exit(n2rng_exit);
+module_platform_driver(n2rng_driver);
diff --git a/drivers/char/hw_random/octeon-rng.c b/drivers/char/hw_random/octeon-rng.c
index 9cd0fec..0943edc 100644
--- a/drivers/char/hw_random/octeon-rng.c
+++ b/drivers/char/hw_random/octeon-rng.c
@@ -131,18 +131,7 @@
.remove = __exit_p(octeon_rng_remove),
};
-static int __init octeon_rng_mod_init(void)
-{
- return platform_driver_register(&octeon_rng_driver);
-}
-
-static void __exit octeon_rng_mod_exit(void)
-{
- platform_driver_unregister(&octeon_rng_driver);
-}
-
-module_init(octeon_rng_mod_init);
-module_exit(octeon_rng_mod_exit);
+module_platform_driver(octeon_rng_driver);
MODULE_AUTHOR("David Daney");
MODULE_LICENSE("GPL");
diff --git a/drivers/char/hw_random/pasemi-rng.c b/drivers/char/hw_random/pasemi-rng.c
index 1d50481..3a63267 100644
--- a/drivers/char/hw_random/pasemi-rng.c
+++ b/drivers/char/hw_random/pasemi-rng.c
@@ -148,17 +148,7 @@
.remove = rng_remove,
};
-static int __init rng_init(void)
-{
- return platform_driver_register(&rng_driver);
-}
-module_init(rng_init);
-
-static void __exit rng_exit(void)
-{
- platform_driver_unregister(&rng_driver);
-}
-module_exit(rng_exit);
+module_platform_driver(rng_driver);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Egor Martovetsky <egor@pasemi.com>");
diff --git a/drivers/char/hw_random/picoxcell-rng.c b/drivers/char/hw_random/picoxcell-rng.c
index 990d55a..97bd891 100644
--- a/drivers/char/hw_random/picoxcell-rng.c
+++ b/drivers/char/hw_random/picoxcell-rng.c
@@ -191,17 +191,7 @@
},
};
-static int __init picoxcell_trng_init(void)
-{
- return platform_driver_register(&picoxcell_trng_driver);
-}
-module_init(picoxcell_trng_init);
-
-static void __exit picoxcell_trng_exit(void)
-{
- platform_driver_unregister(&picoxcell_trng_driver);
-}
-module_exit(picoxcell_trng_exit);
+module_platform_driver(picoxcell_trng_driver);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Jamie Iles");
diff --git a/drivers/char/hw_random/ppc4xx-rng.c b/drivers/char/hw_random/ppc4xx-rng.c
index b8afa6a..c51762c 100644
--- a/drivers/char/hw_random/ppc4xx-rng.c
+++ b/drivers/char/hw_random/ppc4xx-rng.c
@@ -139,17 +139,7 @@
.remove = ppc4xx_rng_remove,
};
-static int __init ppc4xx_rng_init(void)
-{
- return platform_driver_register(&ppc4xx_rng_driver);
-}
-module_init(ppc4xx_rng_init);
-
-static void __exit ppc4xx_rng_exit(void)
-{
- platform_driver_unregister(&ppc4xx_rng_driver);
-}
-module_exit(ppc4xx_rng_exit);
+module_platform_driver(ppc4xx_rng_driver);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Josh Boyer <jwboyer@linux.vnet.ibm.com>");
diff --git a/drivers/char/hw_random/timeriomem-rng.c b/drivers/char/hw_random/timeriomem-rng.c
index a8428e6..f1a1618 100644
--- a/drivers/char/hw_random/timeriomem-rng.c
+++ b/drivers/char/hw_random/timeriomem-rng.c
@@ -149,18 +149,7 @@
.remove = __devexit_p(timeriomem_rng_remove),
};
-static int __init timeriomem_rng_init(void)
-{
- return platform_driver_register(&timeriomem_rng_driver);
-}
-
-static void __exit timeriomem_rng_exit(void)
-{
- platform_driver_unregister(&timeriomem_rng_driver);
-}
-
-module_init(timeriomem_rng_init);
-module_exit(timeriomem_rng_exit);
+module_platform_driver(timeriomem_rng_driver);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Alexander Clouter <alex@digriz.org.uk>");
diff --git a/drivers/char/tpm/Kconfig b/drivers/char/tpm/Kconfig
index fa567f1..7fc75e4 100644
--- a/drivers/char/tpm/Kconfig
+++ b/drivers/char/tpm/Kconfig
@@ -27,6 +27,7 @@
config TCG_TIS
tristate "TPM Interface Specification 1.2 Interface"
+ depends on X86
---help---
If you have a TPM security chip that is compliant with the
TCG TIS 1.2 TPM specification say Yes and it will be accessible
@@ -35,6 +36,7 @@
config TCG_NSC
tristate "National Semiconductor TPM Interface"
+ depends on X86
---help---
If you have a TPM security chip from National Semiconductor
say Yes and it will be accessible from within Linux. To
diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c
index 361a1df..6a8771f 100644
--- a/drivers/char/tpm/tpm.c
+++ b/drivers/char/tpm/tpm.c
@@ -27,6 +27,7 @@
#include <linux/slab.h>
#include <linux/mutex.h>
#include <linux/spinlock.h>
+#include <linux/freezer.h>
#include "tpm.h"
@@ -440,7 +441,6 @@
}
#define TPM_DIGEST_SIZE 20
-#define TPM_ERROR_SIZE 10
#define TPM_RET_CODE_IDX 6
enum tpm_capabilities {
@@ -469,12 +469,14 @@
len = tpm_transmit(chip,(u8 *) cmd, len);
if (len < 0)
return len;
- if (len == TPM_ERROR_SIZE) {
- err = be32_to_cpu(cmd->header.out.return_code);
- dev_dbg(chip->dev, "A TPM error (%d) occurred %s\n", err, desc);
- return err;
- }
- return 0;
+ else if (len < TPM_HEADER_SIZE)
+ return -EFAULT;
+
+ err = be32_to_cpu(cmd->header.out.return_code);
+ if (err != 0)
+ dev_err(chip->dev, "A TPM error (%d) occurred %s\n", err, desc);
+
+ return err;
}
#define TPM_INTERNAL_RESULT_SIZE 200
@@ -530,7 +532,7 @@
}
EXPORT_SYMBOL_GPL(tpm_gen_interrupt);
-void tpm_get_timeouts(struct tpm_chip *chip)
+int tpm_get_timeouts(struct tpm_chip *chip)
{
struct tpm_cmd_t tpm_cmd;
struct timeout_t *timeout_cap;
@@ -552,7 +554,7 @@
if (be32_to_cpu(tpm_cmd.header.out.return_code) != 0 ||
be32_to_cpu(tpm_cmd.header.out.length)
!= sizeof(tpm_cmd.header.out) + sizeof(u32) + 4 * sizeof(u32))
- return;
+ return -EINVAL;
timeout_cap = &tpm_cmd.params.getcap_out.cap.timeout;
/* Don't overwrite default if value is 0 */
@@ -583,12 +585,12 @@
rc = transmit_cmd(chip, &tpm_cmd, TPM_INTERNAL_RESULT_SIZE,
"attempting to determine the durations");
if (rc)
- return;
+ return rc;
if (be32_to_cpu(tpm_cmd.header.out.return_code) != 0 ||
be32_to_cpu(tpm_cmd.header.out.length)
!= sizeof(tpm_cmd.header.out) + sizeof(u32) + 3 * sizeof(u32))
- return;
+ return -EINVAL;
duration_cap = &tpm_cmd.params.getcap_out.cap.duration;
chip->vendor.duration[TPM_SHORT] =
@@ -610,20 +612,36 @@
chip->vendor.duration_adjusted = true;
dev_info(chip->dev, "Adjusting TPM timeout parameters.");
}
+ return 0;
}
EXPORT_SYMBOL_GPL(tpm_get_timeouts);
-void tpm_continue_selftest(struct tpm_chip *chip)
-{
- u8 data[] = {
- 0, 193, /* TPM_TAG_RQU_COMMAND */
- 0, 0, 0, 10, /* length */
- 0, 0, 0, 83, /* TPM_ORD_ContinueSelfTest */
- };
+#define TPM_ORD_CONTINUE_SELFTEST 83
+#define CONTINUE_SELFTEST_RESULT_SIZE 10
- tpm_transmit(chip, data, sizeof(data));
+static struct tpm_input_header continue_selftest_header = {
+ .tag = TPM_TAG_RQU_COMMAND,
+ .length = cpu_to_be32(10),
+ .ordinal = cpu_to_be32(TPM_ORD_CONTINUE_SELFTEST),
+};
+
+/**
+ * tpm_continue_selftest -- run TPM's selftest
+ * @chip: TPM chip to use
+ *
+ * Returns 0 on success, < 0 in case of fatal error or a value > 0 representing
+ * a TPM error code.
+ */
+static int tpm_continue_selftest(struct tpm_chip *chip)
+{
+ int rc;
+ struct tpm_cmd_t cmd;
+
+ cmd.header.in = continue_selftest_header;
+ rc = transmit_cmd(chip, &cmd, CONTINUE_SELFTEST_RESULT_SIZE,
+ "continue selftest");
+ return rc;
}
-EXPORT_SYMBOL_GPL(tpm_continue_selftest);
ssize_t tpm_show_enabled(struct device * dev, struct device_attribute * attr,
char *buf)
@@ -718,7 +736,7 @@
.ordinal = TPM_ORDINAL_PCRREAD
};
-int __tpm_pcr_read(struct tpm_chip *chip, int pcr_idx, u8 *res_buf)
+static int __tpm_pcr_read(struct tpm_chip *chip, int pcr_idx, u8 *res_buf)
{
int rc;
struct tpm_cmd_t cmd;
@@ -798,6 +816,45 @@
}
EXPORT_SYMBOL_GPL(tpm_pcr_extend);
+/**
+ * tpm_do_selftest - have the TPM continue its selftest and wait until it
+ * can receive further commands
+ * @chip: TPM chip to use
+ *
+ * Returns 0 on success, < 0 in case of fatal error or a value > 0 representing
+ * a TPM error code.
+ */
+int tpm_do_selftest(struct tpm_chip *chip)
+{
+ int rc;
+ u8 digest[TPM_DIGEST_SIZE];
+ unsigned int loops;
+ unsigned int delay_msec = 1000;
+ unsigned long duration;
+
+ duration = tpm_calc_ordinal_duration(chip,
+ TPM_ORD_CONTINUE_SELFTEST);
+
+ loops = jiffies_to_msecs(duration) / delay_msec;
+
+ rc = tpm_continue_selftest(chip);
+ /* This may fail if there was no TPM driver during a suspend/resume
+ * cycle; some may return 10 (BAD_ORDINAL), others 28 (FAILEDSELFTEST)
+ */
+ if (rc)
+ return rc;
+
+ do {
+ rc = __tpm_pcr_read(chip, 0, digest);
+ if (rc != TPM_WARN_DOING_SELFTEST)
+ return rc;
+ msleep(delay_msec);
+ } while (--loops > 0);
+
+ return rc;
+}
+EXPORT_SYMBOL_GPL(tpm_do_selftest);
+
int tpm_send(u32 chip_num, void *cmd, size_t buflen)
{
struct tpm_chip *chip;
@@ -1005,6 +1062,46 @@
}
EXPORT_SYMBOL_GPL(tpm_store_cancel);
+int wait_for_tpm_stat(struct tpm_chip *chip, u8 mask, unsigned long timeout,
+ wait_queue_head_t *queue)
+{
+ unsigned long stop;
+ long rc;
+ u8 status;
+
+ /* check current status */
+ status = chip->vendor.status(chip);
+ if ((status & mask) == mask)
+ return 0;
+
+ stop = jiffies + timeout;
+
+ if (chip->vendor.irq) {
+again:
+ timeout = stop - jiffies;
+ if ((long)timeout <= 0)
+ return -ETIME;
+ rc = wait_event_interruptible_timeout(*queue,
+ ((chip->vendor.status(chip)
+ & mask) == mask),
+ timeout);
+ if (rc > 0)
+ return 0;
+ if (rc == -ERESTARTSYS && freezing(current)) {
+ clear_thread_flag(TIF_SIGPENDING);
+ goto again;
+ }
+ } else {
+ do {
+ msleep(TPM_TIMEOUT);
+ status = chip->vendor.status(chip);
+ if ((status & mask) == mask)
+ return 0;
+ } while (time_before(jiffies, stop));
+ }
+ return -ETIME;
+}
+EXPORT_SYMBOL_GPL(wait_for_tpm_stat);
/*
* Device file system interface to the TPM
*
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index 9c4163c..8c1df30 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -38,6 +38,8 @@
TPM_ADDR = 0x4E,
};
+#define TPM_WARN_DOING_SELFTEST 0x802
+#define TPM_HEADER_SIZE 10
extern ssize_t tpm_show_pubek(struct device *, struct device_attribute *attr,
char *);
extern ssize_t tpm_show_pcrs(struct device *, struct device_attribute *attr,
@@ -279,9 +281,9 @@
ssize_t tpm_getcap(struct device *, __be32, cap_t *, const char *);
-extern void tpm_get_timeouts(struct tpm_chip *);
+extern int tpm_get_timeouts(struct tpm_chip *);
extern void tpm_gen_interrupt(struct tpm_chip *);
-extern void tpm_continue_selftest(struct tpm_chip *);
+extern int tpm_do_selftest(struct tpm_chip *);
extern unsigned long tpm_calc_ordinal_duration(struct tpm_chip *, u32);
extern struct tpm_chip* tpm_register_hardware(struct device *,
const struct tpm_vendor_specific *);
@@ -294,7 +296,8 @@
extern void tpm_remove_hardware(struct device *);
extern int tpm_pm_suspend(struct device *, pm_message_t);
extern int tpm_pm_resume(struct device *);
-
+extern int wait_for_tpm_stat(struct tpm_chip *, u8, unsigned long,
+ wait_queue_head_t *);
#ifdef CONFIG_ACPI
extern struct dentry ** tpm_bios_log_setup(char *);
extern void tpm_bios_log_teardown(struct dentry **);
diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c
index 3f4051a..10cc44c 100644
--- a/drivers/char/tpm/tpm_tis.c
+++ b/drivers/char/tpm/tpm_tis.c
@@ -29,8 +29,6 @@
#include <linux/freezer.h>
#include "tpm.h"
-#define TPM_HEADER_SIZE 10
-
enum tis_access {
TPM_ACCESS_VALID = 0x80,
TPM_ACCESS_ACTIVE_LOCALITY = 0x20,
@@ -193,54 +191,14 @@
return -EBUSY;
}
-static int wait_for_stat(struct tpm_chip *chip, u8 mask, unsigned long timeout,
- wait_queue_head_t *queue)
-{
- unsigned long stop;
- long rc;
- u8 status;
-
- /* check current status */
- status = tpm_tis_status(chip);
- if ((status & mask) == mask)
- return 0;
-
- stop = jiffies + timeout;
-
- if (chip->vendor.irq) {
-again:
- timeout = stop - jiffies;
- if ((long)timeout <= 0)
- return -ETIME;
- rc = wait_event_interruptible_timeout(*queue,
- ((tpm_tis_status
- (chip) & mask) ==
- mask), timeout);
- if (rc > 0)
- return 0;
- if (rc == -ERESTARTSYS && freezing(current)) {
- clear_thread_flag(TIF_SIGPENDING);
- goto again;
- }
- } else {
- do {
- msleep(TPM_TIMEOUT);
- status = tpm_tis_status(chip);
- if ((status & mask) == mask)
- return 0;
- } while (time_before(jiffies, stop));
- }
- return -ETIME;
-}
-
static int recv_data(struct tpm_chip *chip, u8 *buf, size_t count)
{
int size = 0, burstcnt;
while (size < count &&
- wait_for_stat(chip,
- TPM_STS_DATA_AVAIL | TPM_STS_VALID,
- chip->vendor.timeout_c,
- &chip->vendor.read_queue)
+ wait_for_tpm_stat(chip,
+ TPM_STS_DATA_AVAIL | TPM_STS_VALID,
+ chip->vendor.timeout_c,
+ &chip->vendor.read_queue)
== 0) {
burstcnt = get_burstcount(chip);
for (; burstcnt > 0 && size < count; burstcnt--)
@@ -282,8 +240,8 @@
goto out;
}
- wait_for_stat(chip, TPM_STS_VALID, chip->vendor.timeout_c,
- &chip->vendor.int_queue);
+ wait_for_tpm_stat(chip, TPM_STS_VALID, chip->vendor.timeout_c,
+ &chip->vendor.int_queue);
status = tpm_tis_status(chip);
if (status & TPM_STS_DATA_AVAIL) { /* retry? */
dev_err(chip->dev, "Error left over data\n");
@@ -317,7 +275,7 @@
status = tpm_tis_status(chip);
if ((status & TPM_STS_COMMAND_READY) == 0) {
tpm_tis_ready(chip);
- if (wait_for_stat
+ if (wait_for_tpm_stat
(chip, TPM_STS_COMMAND_READY, chip->vendor.timeout_b,
&chip->vendor.int_queue) < 0) {
rc = -ETIME;
@@ -333,8 +291,8 @@
count++;
}
- wait_for_stat(chip, TPM_STS_VALID, chip->vendor.timeout_c,
- &chip->vendor.int_queue);
+ wait_for_tpm_stat(chip, TPM_STS_VALID, chip->vendor.timeout_c,
+ &chip->vendor.int_queue);
status = tpm_tis_status(chip);
if (!itpm && (status & TPM_STS_DATA_EXPECT) == 0) {
rc = -EIO;
@@ -345,8 +303,8 @@
/* write last byte */
iowrite8(buf[count],
chip->vendor.iobase + TPM_DATA_FIFO(chip->vendor.locality));
- wait_for_stat(chip, TPM_STS_VALID, chip->vendor.timeout_c,
- &chip->vendor.int_queue);
+ wait_for_tpm_stat(chip, TPM_STS_VALID, chip->vendor.timeout_c,
+ &chip->vendor.int_queue);
status = tpm_tis_status(chip);
if ((status & TPM_STS_DATA_EXPECT) != 0) {
rc = -EIO;
@@ -381,7 +339,7 @@
if (chip->vendor.irq) {
ordinal = be32_to_cpu(*((__be32 *) (buf + 6)));
- if (wait_for_stat
+ if (wait_for_tpm_stat
(chip, TPM_STS_DATA_AVAIL | TPM_STS_VALID,
tpm_calc_ordinal_duration(chip, ordinal),
&chip->vendor.read_queue) < 0) {
@@ -432,6 +390,9 @@
out:
itpm = rem_itpm;
tpm_tis_ready(chip);
+ /* some TPMs need a break here otherwise they will not work
+ * correctly on the immediately subsequent command */
+ msleep(chip->vendor.timeout_b);
release_locality(chip, chip->vendor.locality, 0);
return rc;
@@ -614,7 +575,17 @@
dev_dbg(dev, "\tData Avail Int Support\n");
/* get the timeouts before testing for irqs */
- tpm_get_timeouts(chip);
+ if (tpm_get_timeouts(chip)) {
+ dev_err(dev, "Could not get TPM timeouts and durations\n");
+ rc = -ENODEV;
+ goto out_err;
+ }
+
+ if (tpm_do_selftest(chip)) {
+ dev_err(dev, "TPM self test failed\n");
+ rc = -ENODEV;
+ goto out_err;
+ }
/* INTERRUPT Setup */
init_waitqueue_head(&chip->vendor.read_queue);
@@ -722,7 +693,6 @@
list_add(&chip->vendor.list, &tis_chips);
spin_unlock(&tis_lock);
- tpm_continue_selftest(chip);
return 0;
out_err:
@@ -790,7 +760,7 @@
ret = tpm_pm_resume(&dev->dev);
if (!ret)
- tpm_continue_selftest(chip);
+ tpm_do_selftest(chip);
return ret;
}
diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm
index 72a0044..e0664fe 100644
--- a/drivers/cpufreq/Kconfig.arm
+++ b/drivers/cpufreq/Kconfig.arm
@@ -21,12 +21,19 @@
If in doubt, say N.
+config ARM_EXYNOS_CPUFREQ
+ bool "SAMSUNG EXYNOS SoCs"
+ depends on ARCH_EXYNOS
+ select ARM_EXYNOS4210_CPUFREQ if CPU_EXYNOS4210
+ default y
+ help
+ This adds the CPUFreq driver common part for Samsung
+ EXYNOS SoCs.
+
+ If in doubt, say N.
+
config ARM_EXYNOS4210_CPUFREQ
bool "Samsung EXYNOS4210"
- depends on CPU_EXYNOS4210
- default y
help
This adds the CPUFreq driver for Samsung EXYNOS4210
SoC (S5PV310 or S5PC210).
-
- If in doubt, say N.
diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
index a48bc02..ac000fa 100644
--- a/drivers/cpufreq/Makefile
+++ b/drivers/cpufreq/Makefile
@@ -42,7 +42,9 @@
obj-$(CONFIG_UX500_SOC_DB8500) += db8500-cpufreq.o
obj-$(CONFIG_ARM_S3C64XX_CPUFREQ) += s3c64xx-cpufreq.o
obj-$(CONFIG_ARM_S5PV210_CPUFREQ) += s5pv210-cpufreq.o
+obj-$(CONFIG_ARM_EXYNOS_CPUFREQ) += exynos-cpufreq.o
obj-$(CONFIG_ARM_EXYNOS4210_CPUFREQ) += exynos4210-cpufreq.o
+obj-$(CONFIG_ARCH_OMAP2PLUS) += omap-cpufreq.o
##################################################################################
# PowerPC platform drivers
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index 8c2df34..622013f 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -204,8 +204,7 @@
pr_debug("saving %lu as reference value for loops_per_jiffy; "
"freq is %u kHz\n", l_p_j_ref, l_p_j_ref_freq);
}
- if ((val == CPUFREQ_PRECHANGE && ci->old < ci->new) ||
- (val == CPUFREQ_POSTCHANGE && ci->old > ci->new) ||
+ if ((val == CPUFREQ_POSTCHANGE && ci->old != ci->new) ||
(val == CPUFREQ_RESUMECHANGE || val == CPUFREQ_SUSPENDCHANGE)) {
loops_per_jiffy = cpufreq_scale(l_p_j_ref, l_p_j_ref_freq,
ci->new);
diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c
index 3d679ee..c3e0652 100644
--- a/drivers/cpufreq/cpufreq_ondemand.c
+++ b/drivers/cpufreq/cpufreq_ondemand.c
@@ -713,11 +713,10 @@
static int __init cpufreq_gov_dbs_init(void)
{
- cputime64_t wall;
u64 idle_time;
int cpu = get_cpu();
- idle_time = get_cpu_idle_time_us(cpu, &wall);
+ idle_time = get_cpu_idle_time_us(cpu, NULL);
put_cpu();
if (idle_time != -1ULL) {
/* Idle micro accounting is supported. Use finer thresholds */
diff --git a/drivers/cpufreq/cpufreq_userspace.c b/drivers/cpufreq/cpufreq_userspace.c
index f231015..bedac1a 100644
--- a/drivers/cpufreq/cpufreq_userspace.c
+++ b/drivers/cpufreq/cpufreq_userspace.c
@@ -47,9 +47,11 @@
if (!per_cpu(cpu_is_managed, freq->cpu))
return 0;
- pr_debug("saving cpu_cur_freq of cpu %u to be %u kHz\n",
- freq->cpu, freq->new);
- per_cpu(cpu_cur_freq, freq->cpu) = freq->new;
+ if (val == CPUFREQ_POSTCHANGE) {
+ pr_debug("saving cpu_cur_freq of cpu %u to be %u kHz\n",
+ freq->cpu, freq->new);
+ per_cpu(cpu_cur_freq, freq->cpu) = freq->new;
+ }
return 0;
}
diff --git a/drivers/cpufreq/exynos-cpufreq.c b/drivers/cpufreq/exynos-cpufreq.c
new file mode 100644
index 0000000..5467879
--- /dev/null
+++ b/drivers/cpufreq/exynos-cpufreq.c
@@ -0,0 +1,290 @@
+/*
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * EXYNOS - CPU frequency scaling support for EXYNOS series
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/regulator/consumer.h>
+#include <linux/cpufreq.h>
+#include <linux/suspend.h>
+
+#include <mach/cpufreq.h>
+
+#include <plat/cpu.h>
+
+static struct exynos_dvfs_info *exynos_info;
+
+static struct regulator *arm_regulator;
+static struct cpufreq_freqs freqs;
+
+static unsigned int locking_frequency;
+static bool frequency_locked;
+static DEFINE_MUTEX(cpufreq_lock);
+
+int exynos_verify_speed(struct cpufreq_policy *policy)
+{
+ return cpufreq_frequency_table_verify(policy,
+ exynos_info->freq_table);
+}
+
+unsigned int exynos_getspeed(unsigned int cpu)
+{
+ return clk_get_rate(exynos_info->cpu_clk) / 1000;
+}
+
+static int exynos_target(struct cpufreq_policy *policy,
+ unsigned int target_freq,
+ unsigned int relation)
+{
+ unsigned int index, old_index;
+ unsigned int arm_volt, safe_arm_volt = 0;
+ int ret = 0;
+ struct cpufreq_frequency_table *freq_table = exynos_info->freq_table;
+ unsigned int *volt_table = exynos_info->volt_table;
+ unsigned int mpll_freq_khz = exynos_info->mpll_freq_khz;
+
+ mutex_lock(&cpufreq_lock);
+
+ freqs.old = policy->cur;
+
+ if (frequency_locked && target_freq != locking_frequency) {
+ ret = -EAGAIN;
+ goto out;
+ }
+
+ if (cpufreq_frequency_table_target(policy, freq_table,
+ freqs.old, relation, &old_index)) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ if (cpufreq_frequency_table_target(policy, freq_table,
+ target_freq, relation, &index)) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ freqs.new = freq_table[index].frequency;
+ freqs.cpu = policy->cpu;
+
+ /*
+ * ARM clock source will be changed APLL to MPLL temporary
+ * To support this level, need to control regulator for
+ * required voltage level
+ */
+ if (exynos_info->need_apll_change != NULL) {
+ if (exynos_info->need_apll_change(old_index, index) &&
+ (freq_table[index].frequency < mpll_freq_khz) &&
+ (freq_table[old_index].frequency < mpll_freq_khz))
+ safe_arm_volt = volt_table[exynos_info->pll_safe_idx];
+ }
+ arm_volt = volt_table[index];
+
+ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+
+ /* When the new frequency is higher than current frequency */
+ if ((freqs.new > freqs.old) && !safe_arm_volt) {
+ /* Firstly, voltage up to increase frequency */
+ regulator_set_voltage(arm_regulator, arm_volt,
+ arm_volt);
+ }
+
+ if (safe_arm_volt)
+ regulator_set_voltage(arm_regulator, safe_arm_volt,
+ safe_arm_volt);
+ if (freqs.new != freqs.old)
+ exynos_info->set_freq(old_index, index);
+
+ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+
+ /* When the new frequency is lower than current frequency */
+ if ((freqs.new < freqs.old) ||
+ ((freqs.new > freqs.old) && safe_arm_volt)) {
+ /* down the voltage after frequency change */
+ regulator_set_voltage(arm_regulator, arm_volt,
+ arm_volt);
+ }
+
+out:
+ mutex_unlock(&cpufreq_lock);
+
+ return ret;
+}
+
+#ifdef CONFIG_PM
+static int exynos_cpufreq_suspend(struct cpufreq_policy *policy)
+{
+ return 0;
+}
+
+static int exynos_cpufreq_resume(struct cpufreq_policy *policy)
+{
+ return 0;
+}
+#endif
+
+/**
+ * exynos_cpufreq_pm_notifier - block CPUFREQ's activities in suspend-resume
+ * context
+ * @notifier
+ * @pm_event
+ * @v
+ *
+ * While frequency_locked == true, target() ignores every frequency but
+ * locking_frequency. The locking_frequency value is the initial frequency,
+ * which is set by the bootloader. In order to eliminate possible
+ * inconsistency in clock values, we save and restore frequencies during
+ * suspend and resume and block CPUFREQ activities. Note that the standard
+ * suspend/resume cannot be used as they are too deep (syscore_ops) for
+ * regulator actions.
+ */
+static int exynos_cpufreq_pm_notifier(struct notifier_block *notifier,
+ unsigned long pm_event, void *v)
+{
+ struct cpufreq_policy *policy = cpufreq_cpu_get(0); /* boot CPU */
+ static unsigned int saved_frequency;
+ unsigned int temp;
+
+ mutex_lock(&cpufreq_lock);
+ switch (pm_event) {
+ case PM_SUSPEND_PREPARE:
+ if (frequency_locked)
+ goto out;
+
+ frequency_locked = true;
+
+ if (locking_frequency) {
+ saved_frequency = exynos_getspeed(0);
+
+ mutex_unlock(&cpufreq_lock);
+ exynos_target(policy, locking_frequency,
+ CPUFREQ_RELATION_H);
+ mutex_lock(&cpufreq_lock);
+ }
+ break;
+
+ case PM_POST_SUSPEND:
+ if (saved_frequency) {
+ /*
+ * While frequency_locked, only locking_frequency
+ * is valid for target(). In order to use
+ * saved_frequency while keeping frequency_locked,
+ * we temporarly overwrite locking_frequency.
+ */
+ temp = locking_frequency;
+ locking_frequency = saved_frequency;
+
+ mutex_unlock(&cpufreq_lock);
+ exynos_target(policy, locking_frequency,
+ CPUFREQ_RELATION_H);
+ mutex_lock(&cpufreq_lock);
+
+ locking_frequency = temp;
+ }
+ frequency_locked = false;
+ break;
+ }
+out:
+ mutex_unlock(&cpufreq_lock);
+
+ return NOTIFY_OK;
+}
+
+static struct notifier_block exynos_cpufreq_nb = {
+ .notifier_call = exynos_cpufreq_pm_notifier,
+};
+
+static int exynos_cpufreq_cpu_init(struct cpufreq_policy *policy)
+{
+ policy->cur = policy->min = policy->max = exynos_getspeed(policy->cpu);
+
+ cpufreq_frequency_table_get_attr(exynos_info->freq_table, policy->cpu);
+
+ /* set the transition latency value */
+ policy->cpuinfo.transition_latency = 100000;
+
+ /*
+ * EXYNOS4 multi-core processors has 2 cores
+ * that the frequency cannot be set independently.
+ * Each cpu is bound to the same speed.
+ * So the affected cpu is all of the cpus.
+ */
+ if (num_online_cpus() == 1) {
+ cpumask_copy(policy->related_cpus, cpu_possible_mask);
+ cpumask_copy(policy->cpus, cpu_online_mask);
+ } else {
+ cpumask_setall(policy->cpus);
+ }
+
+ return cpufreq_frequency_table_cpuinfo(policy, exynos_info->freq_table);
+}
+
+static struct cpufreq_driver exynos_driver = {
+ .flags = CPUFREQ_STICKY,
+ .verify = exynos_verify_speed,
+ .target = exynos_target,
+ .get = exynos_getspeed,
+ .init = exynos_cpufreq_cpu_init,
+ .name = "exynos_cpufreq",
+#ifdef CONFIG_PM
+ .suspend = exynos_cpufreq_suspend,
+ .resume = exynos_cpufreq_resume,
+#endif
+};
+
+static int __init exynos_cpufreq_init(void)
+{
+ int ret = -EINVAL;
+
+ exynos_info = kzalloc(sizeof(struct exynos_dvfs_info), GFP_KERNEL);
+ if (!exynos_info)
+ return -ENOMEM;
+
+ if (soc_is_exynos4210())
+ ret = exynos4210_cpufreq_init(exynos_info);
+ else
+ pr_err("%s: CPU type not found\n", __func__);
+
+ if (ret)
+ goto err_vdd_arm;
+
+ if (exynos_info->set_freq == NULL) {
+ pr_err("%s: No set_freq function (ERR)\n", __func__);
+ goto err_vdd_arm;
+ }
+
+ arm_regulator = regulator_get(NULL, "vdd_arm");
+ if (IS_ERR(arm_regulator)) {
+ pr_err("%s: failed to get resource vdd_arm\n", __func__);
+ goto err_vdd_arm;
+ }
+
+ register_pm_notifier(&exynos_cpufreq_nb);
+
+ if (cpufreq_register_driver(&exynos_driver)) {
+ pr_err("%s: failed to register cpufreq driver\n", __func__);
+ goto err_cpufreq;
+ }
+
+ return 0;
+err_cpufreq:
+ unregister_pm_notifier(&exynos_cpufreq_nb);
+
+ if (!IS_ERR(arm_regulator))
+ regulator_put(arm_regulator);
+err_vdd_arm:
+ kfree(exynos_info);
+ pr_debug("%s: failed initialization\n", __func__);
+ return -EINVAL;
+}
+late_initcall(exynos_cpufreq_init);
diff --git a/drivers/cpufreq/exynos4210-cpufreq.c b/drivers/cpufreq/exynos4210-cpufreq.c
index ab9741f..065da5b 100644
--- a/drivers/cpufreq/exynos4210-cpufreq.c
+++ b/drivers/cpufreq/exynos4210-cpufreq.c
@@ -2,61 +2,52 @@
* Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
* http://www.samsung.com
*
- * EXYNOS4 - CPU frequency scaling support
+ * EXYNOS4210 - CPU frequency scaling support
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
-#include <linux/types.h>
+#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/err.h>
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/slab.h>
-#include <linux/regulator/consumer.h>
#include <linux/cpufreq.h>
-#include <linux/notifier.h>
-#include <linux/suspend.h>
-#include <mach/map.h>
#include <mach/regs-clock.h>
-#include <mach/regs-mem.h>
+#include <mach/cpufreq.h>
-#include <plat/clock.h>
-#include <plat/pm.h>
+#define CPUFREQ_LEVEL_END L5
+
+static int max_support_idx = L0;
+static int min_support_idx = (CPUFREQ_LEVEL_END - 1);
static struct clk *cpu_clk;
static struct clk *moutcore;
static struct clk *mout_mpll;
static struct clk *mout_apll;
-static struct regulator *arm_regulator;
-static struct regulator *int_regulator;
-
-static struct cpufreq_freqs freqs;
-static unsigned int memtype;
-
-static unsigned int locking_frequency;
-static bool frequency_locked;
-static DEFINE_MUTEX(cpufreq_lock);
-
-enum exynos4_memory_type {
- DDR2 = 4,
- LPDDR2,
- DDR3,
+struct cpufreq_clkdiv {
+ unsigned int index;
+ unsigned int clkdiv;
};
-enum cpufreq_level_index {
- L0, L1, L2, L3, CPUFREQ_LEVEL_END,
+static unsigned int exynos4210_volt_table[CPUFREQ_LEVEL_END] = {
+ 1250000, 1150000, 1050000, 975000, 950000,
};
-static struct cpufreq_frequency_table exynos4_freq_table[] = {
- {L0, 1000*1000},
- {L1, 800*1000},
- {L2, 400*1000},
- {L3, 100*1000},
+
+static struct cpufreq_clkdiv exynos4210_clkdiv_table[CPUFREQ_LEVEL_END];
+
+static struct cpufreq_frequency_table exynos4210_freq_table[] = {
+ {L0, 1200*1000},
+ {L1, 1000*1000},
+ {L2, 800*1000},
+ {L3, 500*1000},
+ {L4, 200*1000},
{0, CPUFREQ_TABLE_END},
};
@@ -67,17 +58,20 @@
* DIVATB, DIVPCLK_DBG, DIVAPLL }
*/
- /* ARM L0: 1000MHz */
- { 0, 3, 7, 3, 3, 0, 1 },
+ /* ARM L0: 1200MHz */
+ { 0, 3, 7, 3, 4, 1, 7 },
- /* ARM L1: 800MHz */
- { 0, 3, 7, 3, 3, 0, 1 },
+ /* ARM L1: 1000MHz */
+ { 0, 3, 7, 3, 4, 1, 7 },
- /* ARM L2: 400MHz */
- { 0, 1, 3, 1, 3, 0, 1 },
+ /* ARM L2: 800MHz */
+ { 0, 3, 7, 3, 3, 1, 7 },
- /* ARM L3: 100MHz */
- { 0, 0, 1, 0, 3, 1, 1 },
+ /* ARM L3: 500MHz */
+ { 0, 3, 7, 3, 3, 1, 7 },
+
+ /* ARM L4: 200MHz */
+ { 0, 1, 3, 1, 3, 1, 0 },
};
static unsigned int clkdiv_cpu1[CPUFREQ_LEVEL_END][2] = {
@@ -86,147 +80,46 @@
* { DIVCOPY, DIVHPM }
*/
- /* ARM L0: 1000MHz */
+ /* ARM L0: 1200MHz */
+ { 5, 0 },
+
+ /* ARM L1: 1000MHz */
+ { 4, 0 },
+
+ /* ARM L2: 800MHz */
{ 3, 0 },
- /* ARM L1: 800MHz */
+ /* ARM L3: 500MHz */
{ 3, 0 },
- /* ARM L2: 400MHz */
- { 3, 0 },
-
- /* ARM L3: 100MHz */
+ /* ARM L4: 200MHz */
{ 3, 0 },
};
-static unsigned int clkdiv_dmc0[CPUFREQ_LEVEL_END][8] = {
- /*
- * Clock divider value for following
- * { DIVACP, DIVACP_PCLK, DIVDPHY, DIVDMC, DIVDMCD
- * DIVDMCP, DIVCOPY2, DIVCORE_TIMERS }
- */
+static unsigned int exynos4210_apll_pms_table[CPUFREQ_LEVEL_END] = {
+ /* APLL FOUT L0: 1200MHz */
+ ((150 << 16) | (3 << 8) | 1),
- /* DMC L0: 400MHz */
- { 3, 1, 1, 1, 1, 1, 3, 1 },
-
- /* DMC L1: 400MHz */
- { 3, 1, 1, 1, 1, 1, 3, 1 },
-
- /* DMC L2: 266.7MHz */
- { 7, 1, 1, 2, 1, 1, 3, 1 },
-
- /* DMC L3: 200MHz */
- { 7, 1, 1, 3, 1, 1, 3, 1 },
-};
-
-static unsigned int clkdiv_top[CPUFREQ_LEVEL_END][5] = {
- /*
- * Clock divider value for following
- * { DIVACLK200, DIVACLK100, DIVACLK160, DIVACLK133, DIVONENAND }
- */
-
- /* ACLK200 L0: 200MHz */
- { 3, 7, 4, 5, 1 },
-
- /* ACLK200 L1: 200MHz */
- { 3, 7, 4, 5, 1 },
-
- /* ACLK200 L2: 160MHz */
- { 4, 7, 5, 7, 1 },
-
- /* ACLK200 L3: 133.3MHz */
- { 5, 7, 7, 7, 1 },
-};
-
-static unsigned int clkdiv_lr_bus[CPUFREQ_LEVEL_END][2] = {
- /*
- * Clock divider value for following
- * { DIVGDL/R, DIVGPL/R }
- */
-
- /* ACLK_GDL/R L0: 200MHz */
- { 3, 1 },
-
- /* ACLK_GDL/R L1: 200MHz */
- { 3, 1 },
-
- /* ACLK_GDL/R L2: 160MHz */
- { 4, 1 },
-
- /* ACLK_GDL/R L3: 133.3MHz */
- { 5, 1 },
-};
-
-struct cpufreq_voltage_table {
- unsigned int index; /* any */
- unsigned int arm_volt; /* uV */
- unsigned int int_volt;
-};
-
-static struct cpufreq_voltage_table exynos4_volt_table[CPUFREQ_LEVEL_END] = {
- {
- .index = L0,
- .arm_volt = 1200000,
- .int_volt = 1100000,
- }, {
- .index = L1,
- .arm_volt = 1100000,
- .int_volt = 1100000,
- }, {
- .index = L2,
- .arm_volt = 1000000,
- .int_volt = 1000000,
- }, {
- .index = L3,
- .arm_volt = 900000,
- .int_volt = 1000000,
- },
-};
-
-static unsigned int exynos4_apll_pms_table[CPUFREQ_LEVEL_END] = {
- /* APLL FOUT L0: 1000MHz */
+ /* APLL FOUT L1: 1000MHz */
((250 << 16) | (6 << 8) | 1),
- /* APLL FOUT L1: 800MHz */
+ /* APLL FOUT L2: 800MHz */
((200 << 16) | (6 << 8) | 1),
- /* APLL FOUT L2 : 400MHz */
- ((200 << 16) | (6 << 8) | 2),
+ /* APLL FOUT L3: 500MHz */
+ ((250 << 16) | (6 << 8) | 2),
- /* APLL FOUT L3: 100MHz */
- ((200 << 16) | (6 << 8) | 4),
+ /* APLL FOUT L4: 200MHz */
+ ((200 << 16) | (6 << 8) | 3),
};
-static int exynos4_verify_speed(struct cpufreq_policy *policy)
-{
- return cpufreq_frequency_table_verify(policy, exynos4_freq_table);
-}
-
-static unsigned int exynos4_getspeed(unsigned int cpu)
-{
- return clk_get_rate(cpu_clk) / 1000;
-}
-
-static void exynos4_set_clkdiv(unsigned int div_index)
+static void exynos4210_set_clkdiv(unsigned int div_index)
{
unsigned int tmp;
/* Change Divider - CPU0 */
- tmp = __raw_readl(S5P_CLKDIV_CPU);
-
- tmp &= ~(S5P_CLKDIV_CPU0_CORE_MASK | S5P_CLKDIV_CPU0_COREM0_MASK |
- S5P_CLKDIV_CPU0_COREM1_MASK | S5P_CLKDIV_CPU0_PERIPH_MASK |
- S5P_CLKDIV_CPU0_ATB_MASK | S5P_CLKDIV_CPU0_PCLKDBG_MASK |
- S5P_CLKDIV_CPU0_APLL_MASK);
-
- tmp |= ((clkdiv_cpu0[div_index][0] << S5P_CLKDIV_CPU0_CORE_SHIFT) |
- (clkdiv_cpu0[div_index][1] << S5P_CLKDIV_CPU0_COREM0_SHIFT) |
- (clkdiv_cpu0[div_index][2] << S5P_CLKDIV_CPU0_COREM1_SHIFT) |
- (clkdiv_cpu0[div_index][3] << S5P_CLKDIV_CPU0_PERIPH_SHIFT) |
- (clkdiv_cpu0[div_index][4] << S5P_CLKDIV_CPU0_ATB_SHIFT) |
- (clkdiv_cpu0[div_index][5] << S5P_CLKDIV_CPU0_PCLKDBG_SHIFT) |
- (clkdiv_cpu0[div_index][6] << S5P_CLKDIV_CPU0_APLL_SHIFT));
+ tmp = exynos4210_clkdiv_table[div_index].clkdiv;
__raw_writel(tmp, S5P_CLKDIV_CPU);
@@ -248,83 +141,9 @@
do {
tmp = __raw_readl(S5P_CLKDIV_STATCPU1);
} while (tmp & 0x11);
-
- /* Change Divider - DMC0 */
-
- tmp = __raw_readl(S5P_CLKDIV_DMC0);
-
- tmp &= ~(S5P_CLKDIV_DMC0_ACP_MASK | S5P_CLKDIV_DMC0_ACPPCLK_MASK |
- S5P_CLKDIV_DMC0_DPHY_MASK | S5P_CLKDIV_DMC0_DMC_MASK |
- S5P_CLKDIV_DMC0_DMCD_MASK | S5P_CLKDIV_DMC0_DMCP_MASK |
- S5P_CLKDIV_DMC0_COPY2_MASK | S5P_CLKDIV_DMC0_CORETI_MASK);
-
- tmp |= ((clkdiv_dmc0[div_index][0] << S5P_CLKDIV_DMC0_ACP_SHIFT) |
- (clkdiv_dmc0[div_index][1] << S5P_CLKDIV_DMC0_ACPPCLK_SHIFT) |
- (clkdiv_dmc0[div_index][2] << S5P_CLKDIV_DMC0_DPHY_SHIFT) |
- (clkdiv_dmc0[div_index][3] << S5P_CLKDIV_DMC0_DMC_SHIFT) |
- (clkdiv_dmc0[div_index][4] << S5P_CLKDIV_DMC0_DMCD_SHIFT) |
- (clkdiv_dmc0[div_index][5] << S5P_CLKDIV_DMC0_DMCP_SHIFT) |
- (clkdiv_dmc0[div_index][6] << S5P_CLKDIV_DMC0_COPY2_SHIFT) |
- (clkdiv_dmc0[div_index][7] << S5P_CLKDIV_DMC0_CORETI_SHIFT));
-
- __raw_writel(tmp, S5P_CLKDIV_DMC0);
-
- do {
- tmp = __raw_readl(S5P_CLKDIV_STAT_DMC0);
- } while (tmp & 0x11111111);
-
- /* Change Divider - TOP */
-
- tmp = __raw_readl(S5P_CLKDIV_TOP);
-
- tmp &= ~(S5P_CLKDIV_TOP_ACLK200_MASK | S5P_CLKDIV_TOP_ACLK100_MASK |
- S5P_CLKDIV_TOP_ACLK160_MASK | S5P_CLKDIV_TOP_ACLK133_MASK |
- S5P_CLKDIV_TOP_ONENAND_MASK);
-
- tmp |= ((clkdiv_top[div_index][0] << S5P_CLKDIV_TOP_ACLK200_SHIFT) |
- (clkdiv_top[div_index][1] << S5P_CLKDIV_TOP_ACLK100_SHIFT) |
- (clkdiv_top[div_index][2] << S5P_CLKDIV_TOP_ACLK160_SHIFT) |
- (clkdiv_top[div_index][3] << S5P_CLKDIV_TOP_ACLK133_SHIFT) |
- (clkdiv_top[div_index][4] << S5P_CLKDIV_TOP_ONENAND_SHIFT));
-
- __raw_writel(tmp, S5P_CLKDIV_TOP);
-
- do {
- tmp = __raw_readl(S5P_CLKDIV_STAT_TOP);
- } while (tmp & 0x11111);
-
- /* Change Divider - LEFTBUS */
-
- tmp = __raw_readl(S5P_CLKDIV_LEFTBUS);
-
- tmp &= ~(S5P_CLKDIV_BUS_GDLR_MASK | S5P_CLKDIV_BUS_GPLR_MASK);
-
- tmp |= ((clkdiv_lr_bus[div_index][0] << S5P_CLKDIV_BUS_GDLR_SHIFT) |
- (clkdiv_lr_bus[div_index][1] << S5P_CLKDIV_BUS_GPLR_SHIFT));
-
- __raw_writel(tmp, S5P_CLKDIV_LEFTBUS);
-
- do {
- tmp = __raw_readl(S5P_CLKDIV_STAT_LEFTBUS);
- } while (tmp & 0x11);
-
- /* Change Divider - RIGHTBUS */
-
- tmp = __raw_readl(S5P_CLKDIV_RIGHTBUS);
-
- tmp &= ~(S5P_CLKDIV_BUS_GDLR_MASK | S5P_CLKDIV_BUS_GPLR_MASK);
-
- tmp |= ((clkdiv_lr_bus[div_index][0] << S5P_CLKDIV_BUS_GDLR_SHIFT) |
- (clkdiv_lr_bus[div_index][1] << S5P_CLKDIV_BUS_GPLR_SHIFT));
-
- __raw_writel(tmp, S5P_CLKDIV_RIGHTBUS);
-
- do {
- tmp = __raw_readl(S5P_CLKDIV_STAT_RIGHTBUS);
- } while (tmp & 0x11);
}
-static void exynos4_set_apll(unsigned int index)
+static void exynos4210_set_apll(unsigned int index)
{
unsigned int tmp;
@@ -343,7 +162,7 @@
/* 3. Change PLL PMS values */
tmp = __raw_readl(S5P_APLL_CON0);
tmp &= ~((0x3ff << 16) | (0x3f << 8) | (0x7 << 0));
- tmp |= exynos4_apll_pms_table[index];
+ tmp |= exynos4210_apll_pms_table[index];
__raw_writel(tmp, S5P_APLL_CON0);
/* 4. wait_lock_time */
@@ -360,328 +179,126 @@
} while (tmp != (0x1 << S5P_CLKSRC_CPU_MUXCORE_SHIFT));
}
-static void exynos4_set_frequency(unsigned int old_index, unsigned int new_index)
+bool exynos4210_pms_change(unsigned int old_index, unsigned int new_index)
+{
+ unsigned int old_pm = (exynos4210_apll_pms_table[old_index] >> 8);
+ unsigned int new_pm = (exynos4210_apll_pms_table[new_index] >> 8);
+
+ return (old_pm == new_pm) ? 0 : 1;
+}
+
+static void exynos4210_set_frequency(unsigned int old_index,
+ unsigned int new_index)
{
unsigned int tmp;
if (old_index > new_index) {
- /* The frequency changing to L0 needs to change apll */
- if (freqs.new == exynos4_freq_table[L0].frequency) {
+ if (!exynos4210_pms_change(old_index, new_index)) {
/* 1. Change the system clock divider values */
- exynos4_set_clkdiv(new_index);
-
- /* 2. Change the apll m,p,s value */
- exynos4_set_apll(new_index);
- } else {
- /* 1. Change the system clock divider values */
- exynos4_set_clkdiv(new_index);
+ exynos4210_set_clkdiv(new_index);
/* 2. Change just s value in apll m,p,s value */
tmp = __raw_readl(S5P_APLL_CON0);
tmp &= ~(0x7 << 0);
- tmp |= (exynos4_apll_pms_table[new_index] & 0x7);
+ tmp |= (exynos4210_apll_pms_table[new_index] & 0x7);
__raw_writel(tmp, S5P_APLL_CON0);
- }
- }
-
- else if (old_index < new_index) {
- /* The frequency changing from L0 needs to change apll */
- if (freqs.old == exynos4_freq_table[L0].frequency) {
- /* 1. Change the apll m,p,s value */
- exynos4_set_apll(new_index);
-
- /* 2. Change the system clock divider values */
- exynos4_set_clkdiv(new_index);
} else {
+ /* Clock Configuration Procedure */
+ /* 1. Change the system clock divider values */
+ exynos4210_set_clkdiv(new_index);
+ /* 2. Change the apll m,p,s value */
+ exynos4210_set_apll(new_index);
+ }
+ } else if (old_index < new_index) {
+ if (!exynos4210_pms_change(old_index, new_index)) {
/* 1. Change just s value in apll m,p,s value */
tmp = __raw_readl(S5P_APLL_CON0);
tmp &= ~(0x7 << 0);
- tmp |= (exynos4_apll_pms_table[new_index] & 0x7);
+ tmp |= (exynos4210_apll_pms_table[new_index] & 0x7);
__raw_writel(tmp, S5P_APLL_CON0);
/* 2. Change the system clock divider values */
- exynos4_set_clkdiv(new_index);
+ exynos4210_set_clkdiv(new_index);
+ } else {
+ /* Clock Configuration Procedure */
+ /* 1. Change the apll m,p,s value */
+ exynos4210_set_apll(new_index);
+ /* 2. Change the system clock divider values */
+ exynos4210_set_clkdiv(new_index);
}
}
}
-static int exynos4_target(struct cpufreq_policy *policy,
- unsigned int target_freq,
- unsigned int relation)
+int exynos4210_cpufreq_init(struct exynos_dvfs_info *info)
{
- unsigned int index, old_index;
- unsigned int arm_volt, int_volt;
- int err = -EINVAL;
+ int i;
+ unsigned int tmp;
+ unsigned long rate;
- freqs.old = exynos4_getspeed(policy->cpu);
-
- mutex_lock(&cpufreq_lock);
-
- if (frequency_locked && target_freq != locking_frequency) {
- err = -EAGAIN;
- goto out;
- }
-
- if (cpufreq_frequency_table_target(policy, exynos4_freq_table,
- freqs.old, relation, &old_index))
- goto out;
-
- if (cpufreq_frequency_table_target(policy, exynos4_freq_table,
- target_freq, relation, &index))
- goto out;
-
- err = 0;
-
- freqs.new = exynos4_freq_table[index].frequency;
- freqs.cpu = policy->cpu;
-
- if (freqs.new == freqs.old)
- goto out;
-
- /* get the voltage value */
- arm_volt = exynos4_volt_table[index].arm_volt;
- int_volt = exynos4_volt_table[index].int_volt;
-
- cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
-
- /* control regulator */
- if (freqs.new > freqs.old) {
- /* Voltage up */
- regulator_set_voltage(arm_regulator, arm_volt, arm_volt);
- regulator_set_voltage(int_regulator, int_volt, int_volt);
- }
-
- /* Clock Configuration Procedure */
- exynos4_set_frequency(old_index, index);
-
- /* control regulator */
- if (freqs.new < freqs.old) {
- /* Voltage down */
- regulator_set_voltage(arm_regulator, arm_volt, arm_volt);
- regulator_set_voltage(int_regulator, int_volt, int_volt);
- }
-
- cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
-
-out:
- mutex_unlock(&cpufreq_lock);
- return err;
-}
-
-#ifdef CONFIG_PM
-/*
- * These suspend/resume are used as syscore_ops, it is already too
- * late to set regulator voltages at this stage.
- */
-static int exynos4_cpufreq_suspend(struct cpufreq_policy *policy)
-{
- return 0;
-}
-
-static int exynos4_cpufreq_resume(struct cpufreq_policy *policy)
-{
- return 0;
-}
-#endif
-
-/**
- * exynos4_cpufreq_pm_notifier - block CPUFREQ's activities in suspend-resume
- * context
- * @notifier
- * @pm_event
- * @v
- *
- * While frequency_locked == true, target() ignores every frequency but
- * locking_frequency. The locking_frequency value is the initial frequency,
- * which is set by the bootloader. In order to eliminate possible
- * inconsistency in clock values, we save and restore frequencies during
- * suspend and resume and block CPUFREQ activities. Note that the standard
- * suspend/resume cannot be used as they are too deep (syscore_ops) for
- * regulator actions.
- */
-static int exynos4_cpufreq_pm_notifier(struct notifier_block *notifier,
- unsigned long pm_event, void *v)
-{
- struct cpufreq_policy *policy = cpufreq_cpu_get(0); /* boot CPU */
- static unsigned int saved_frequency;
- unsigned int temp;
-
- mutex_lock(&cpufreq_lock);
- switch (pm_event) {
- case PM_SUSPEND_PREPARE:
- if (frequency_locked)
- goto out;
- frequency_locked = true;
-
- if (locking_frequency) {
- saved_frequency = exynos4_getspeed(0);
-
- mutex_unlock(&cpufreq_lock);
- exynos4_target(policy, locking_frequency,
- CPUFREQ_RELATION_H);
- mutex_lock(&cpufreq_lock);
- }
-
- break;
- case PM_POST_SUSPEND:
-
- if (saved_frequency) {
- /*
- * While frequency_locked, only locking_frequency
- * is valid for target(). In order to use
- * saved_frequency while keeping frequency_locked,
- * we temporarly overwrite locking_frequency.
- */
- temp = locking_frequency;
- locking_frequency = saved_frequency;
-
- mutex_unlock(&cpufreq_lock);
- exynos4_target(policy, locking_frequency,
- CPUFREQ_RELATION_H);
- mutex_lock(&cpufreq_lock);
-
- locking_frequency = temp;
- }
-
- frequency_locked = false;
- break;
- }
-out:
- mutex_unlock(&cpufreq_lock);
-
- return NOTIFY_OK;
-}
-
-static struct notifier_block exynos4_cpufreq_nb = {
- .notifier_call = exynos4_cpufreq_pm_notifier,
-};
-
-static int exynos4_cpufreq_cpu_init(struct cpufreq_policy *policy)
-{
- int ret;
-
- policy->cur = policy->min = policy->max = exynos4_getspeed(policy->cpu);
-
- cpufreq_frequency_table_get_attr(exynos4_freq_table, policy->cpu);
-
- /* set the transition latency value */
- policy->cpuinfo.transition_latency = 100000;
-
- /*
- * EXYNOS4 multi-core processors has 2 cores
- * that the frequency cannot be set independently.
- * Each cpu is bound to the same speed.
- * So the affected cpu is all of the cpus.
- */
- cpumask_setall(policy->cpus);
-
- ret = cpufreq_frequency_table_cpuinfo(policy, exynos4_freq_table);
- if (ret)
- return ret;
-
- cpufreq_frequency_table_get_attr(exynos4_freq_table, policy->cpu);
-
- return 0;
-}
-
-static int exynos4_cpufreq_cpu_exit(struct cpufreq_policy *policy)
-{
- cpufreq_frequency_table_put_attr(policy->cpu);
- return 0;
-}
-
-static struct freq_attr *exynos4_cpufreq_attr[] = {
- &cpufreq_freq_attr_scaling_available_freqs,
- NULL,
-};
-
-static struct cpufreq_driver exynos4_driver = {
- .flags = CPUFREQ_STICKY,
- .verify = exynos4_verify_speed,
- .target = exynos4_target,
- .get = exynos4_getspeed,
- .init = exynos4_cpufreq_cpu_init,
- .exit = exynos4_cpufreq_cpu_exit,
- .name = "exynos4_cpufreq",
- .attr = exynos4_cpufreq_attr,
-#ifdef CONFIG_PM
- .suspend = exynos4_cpufreq_suspend,
- .resume = exynos4_cpufreq_resume,
-#endif
-};
-
-static int __init exynos4_cpufreq_init(void)
-{
cpu_clk = clk_get(NULL, "armclk");
if (IS_ERR(cpu_clk))
return PTR_ERR(cpu_clk);
- locking_frequency = exynos4_getspeed(0);
-
moutcore = clk_get(NULL, "moutcore");
if (IS_ERR(moutcore))
- goto out;
+ goto err_moutcore;
mout_mpll = clk_get(NULL, "mout_mpll");
if (IS_ERR(mout_mpll))
- goto out;
+ goto err_mout_mpll;
+
+ rate = clk_get_rate(mout_mpll) / 1000;
mout_apll = clk_get(NULL, "mout_apll");
if (IS_ERR(mout_apll))
- goto out;
+ goto err_mout_apll;
- arm_regulator = regulator_get(NULL, "vdd_arm");
- if (IS_ERR(arm_regulator)) {
- printk(KERN_ERR "failed to get resource %s\n", "vdd_arm");
- goto out;
+ tmp = __raw_readl(S5P_CLKDIV_CPU);
+
+ for (i = L0; i < CPUFREQ_LEVEL_END; i++) {
+ tmp &= ~(S5P_CLKDIV_CPU0_CORE_MASK |
+ S5P_CLKDIV_CPU0_COREM0_MASK |
+ S5P_CLKDIV_CPU0_COREM1_MASK |
+ S5P_CLKDIV_CPU0_PERIPH_MASK |
+ S5P_CLKDIV_CPU0_ATB_MASK |
+ S5P_CLKDIV_CPU0_PCLKDBG_MASK |
+ S5P_CLKDIV_CPU0_APLL_MASK);
+
+ tmp |= ((clkdiv_cpu0[i][0] << S5P_CLKDIV_CPU0_CORE_SHIFT) |
+ (clkdiv_cpu0[i][1] << S5P_CLKDIV_CPU0_COREM0_SHIFT) |
+ (clkdiv_cpu0[i][2] << S5P_CLKDIV_CPU0_COREM1_SHIFT) |
+ (clkdiv_cpu0[i][3] << S5P_CLKDIV_CPU0_PERIPH_SHIFT) |
+ (clkdiv_cpu0[i][4] << S5P_CLKDIV_CPU0_ATB_SHIFT) |
+ (clkdiv_cpu0[i][5] << S5P_CLKDIV_CPU0_PCLKDBG_SHIFT) |
+ (clkdiv_cpu0[i][6] << S5P_CLKDIV_CPU0_APLL_SHIFT));
+
+ exynos4210_clkdiv_table[i].clkdiv = tmp;
}
- int_regulator = regulator_get(NULL, "vdd_int");
- if (IS_ERR(int_regulator)) {
- printk(KERN_ERR "failed to get resource %s\n", "vdd_int");
- goto out;
- }
+ info->mpll_freq_khz = rate;
+ info->pm_lock_idx = L2;
+ info->pll_safe_idx = L2;
+ info->max_support_idx = max_support_idx;
+ info->min_support_idx = min_support_idx;
+ info->cpu_clk = cpu_clk;
+ info->volt_table = exynos4210_volt_table;
+ info->freq_table = exynos4210_freq_table;
+ info->set_freq = exynos4210_set_frequency;
+ info->need_apll_change = exynos4210_pms_change;
- /*
- * Check DRAM type.
- * Because DVFS level is different according to DRAM type.
- */
- memtype = __raw_readl(S5P_VA_DMC0 + S5P_DMC0_MEMCON_OFFSET);
- memtype = (memtype >> S5P_DMC0_MEMTYPE_SHIFT);
- memtype &= S5P_DMC0_MEMTYPE_MASK;
+ return 0;
- if ((memtype < DDR2) && (memtype > DDR3)) {
- printk(KERN_ERR "%s: wrong memtype= 0x%x\n", __func__, memtype);
- goto out;
- } else {
- printk(KERN_DEBUG "%s: memtype= 0x%x\n", __func__, memtype);
- }
-
- register_pm_notifier(&exynos4_cpufreq_nb);
-
- return cpufreq_register_driver(&exynos4_driver);
-
-out:
+err_mout_apll:
+ if (!IS_ERR(mout_mpll))
+ clk_put(mout_mpll);
+err_mout_mpll:
+ if (!IS_ERR(moutcore))
+ clk_put(moutcore);
+err_moutcore:
if (!IS_ERR(cpu_clk))
clk_put(cpu_clk);
- if (!IS_ERR(moutcore))
- clk_put(moutcore);
-
- if (!IS_ERR(mout_mpll))
- clk_put(mout_mpll);
-
- if (!IS_ERR(mout_apll))
- clk_put(mout_apll);
-
- if (!IS_ERR(arm_regulator))
- regulator_put(arm_regulator);
-
- if (!IS_ERR(int_regulator))
- regulator_put(int_regulator);
-
- printk(KERN_ERR "%s: failed initialization\n", __func__);
-
+ pr_debug("%s: failed initialization\n", __func__);
return -EINVAL;
}
-late_initcall(exynos4_cpufreq_init);
+EXPORT_SYMBOL(exynos4210_cpufreq_init);
diff --git a/drivers/cpufreq/omap-cpufreq.c b/drivers/cpufreq/omap-cpufreq.c
new file mode 100644
index 0000000..5d04c57
--- /dev/null
+++ b/drivers/cpufreq/omap-cpufreq.c
@@ -0,0 +1,274 @@
+/*
+ * CPU frequency scaling for OMAP using OPP information
+ *
+ * Copyright (C) 2005 Nokia Corporation
+ * Written by Tony Lindgren <tony@atomide.com>
+ *
+ * Based on cpu-sa1110.c, Copyright (C) 2001 Russell King
+ *
+ * Copyright (C) 2007-2011 Texas Instruments, Inc.
+ * - OMAP3/4 support by Rajendra Nayak, Santosh Shilimkar
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/cpufreq.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/opp.h>
+#include <linux/cpu.h>
+#include <linux/module.h>
+
+#include <asm/system.h>
+#include <asm/smp_plat.h>
+#include <asm/cpu.h>
+
+#include <plat/clock.h>
+#include <plat/omap-pm.h>
+#include <plat/common.h>
+#include <plat/omap_device.h>
+
+#include <mach/hardware.h>
+
+#ifdef CONFIG_SMP
+struct lpj_info {
+ unsigned long ref;
+ unsigned int freq;
+};
+
+static DEFINE_PER_CPU(struct lpj_info, lpj_ref);
+static struct lpj_info global_lpj_ref;
+#endif
+
+static struct cpufreq_frequency_table *freq_table;
+static atomic_t freq_table_users = ATOMIC_INIT(0);
+static struct clk *mpu_clk;
+static char *mpu_clk_name;
+static struct device *mpu_dev;
+
+static int omap_verify_speed(struct cpufreq_policy *policy)
+{
+ if (!freq_table)
+ return -EINVAL;
+ return cpufreq_frequency_table_verify(policy, freq_table);
+}
+
+static unsigned int omap_getspeed(unsigned int cpu)
+{
+ unsigned long rate;
+
+ if (cpu >= NR_CPUS)
+ return 0;
+
+ rate = clk_get_rate(mpu_clk) / 1000;
+ return rate;
+}
+
+static int omap_target(struct cpufreq_policy *policy,
+ unsigned int target_freq,
+ unsigned int relation)
+{
+ unsigned int i;
+ int ret = 0;
+ struct cpufreq_freqs freqs;
+
+ if (!freq_table) {
+ dev_err(mpu_dev, "%s: cpu%d: no freq table!\n", __func__,
+ policy->cpu);
+ return -EINVAL;
+ }
+
+ ret = cpufreq_frequency_table_target(policy, freq_table, target_freq,
+ relation, &i);
+ if (ret) {
+ dev_dbg(mpu_dev, "%s: cpu%d: no freq match for %d(ret=%d)\n",
+ __func__, policy->cpu, target_freq, ret);
+ return ret;
+ }
+ freqs.new = freq_table[i].frequency;
+ if (!freqs.new) {
+ dev_err(mpu_dev, "%s: cpu%d: no match for freq %d\n", __func__,
+ policy->cpu, target_freq);
+ return -EINVAL;
+ }
+
+ freqs.old = omap_getspeed(policy->cpu);
+ freqs.cpu = policy->cpu;
+
+ if (freqs.old == freqs.new && policy->cur == freqs.new)
+ return ret;
+
+ /* notifiers */
+ for_each_cpu(i, policy->cpus) {
+ freqs.cpu = i;
+ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+ }
+
+#ifdef CONFIG_CPU_FREQ_DEBUG
+ pr_info("cpufreq-omap: transition: %u --> %u\n", freqs.old, freqs.new);
+#endif
+
+ ret = clk_set_rate(mpu_clk, freqs.new * 1000);
+ freqs.new = omap_getspeed(policy->cpu);
+
+#ifdef CONFIG_SMP
+ /*
+ * Note that loops_per_jiffy is not updated on SMP systems in
+ * cpufreq driver. So, update the per-CPU loops_per_jiffy value
+ * on frequency transition. We need to update all dependent CPUs.
+ */
+ for_each_cpu(i, policy->cpus) {
+ struct lpj_info *lpj = &per_cpu(lpj_ref, i);
+ if (!lpj->freq) {
+ lpj->ref = per_cpu(cpu_data, i).loops_per_jiffy;
+ lpj->freq = freqs.old;
+ }
+
+ per_cpu(cpu_data, i).loops_per_jiffy =
+ cpufreq_scale(lpj->ref, lpj->freq, freqs.new);
+ }
+
+ /* And don't forget to adjust the global one */
+ if (!global_lpj_ref.freq) {
+ global_lpj_ref.ref = loops_per_jiffy;
+ global_lpj_ref.freq = freqs.old;
+ }
+ loops_per_jiffy = cpufreq_scale(global_lpj_ref.ref, global_lpj_ref.freq,
+ freqs.new);
+#endif
+
+ /* notifiers */
+ for_each_cpu(i, policy->cpus) {
+ freqs.cpu = i;
+ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+ }
+
+ return ret;
+}
+
+static inline void freq_table_free(void)
+{
+ if (atomic_dec_and_test(&freq_table_users))
+ opp_free_cpufreq_table(mpu_dev, &freq_table);
+}
+
+static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy)
+{
+ int result = 0;
+
+ mpu_clk = clk_get(NULL, mpu_clk_name);
+ if (IS_ERR(mpu_clk))
+ return PTR_ERR(mpu_clk);
+
+ if (policy->cpu >= NR_CPUS) {
+ result = -EINVAL;
+ goto fail_ck;
+ }
+
+ policy->cur = policy->min = policy->max = omap_getspeed(policy->cpu);
+
+ if (atomic_inc_return(&freq_table_users) == 1)
+ result = opp_init_cpufreq_table(mpu_dev, &freq_table);
+
+ if (result) {
+ dev_err(mpu_dev, "%s: cpu%d: failed creating freq table[%d]\n",
+ __func__, policy->cpu, result);
+ goto fail_ck;
+ }
+
+ result = cpufreq_frequency_table_cpuinfo(policy, freq_table);
+ if (result)
+ goto fail_table;
+
+ cpufreq_frequency_table_get_attr(freq_table, policy->cpu);
+
+ policy->min = policy->cpuinfo.min_freq;
+ policy->max = policy->cpuinfo.max_freq;
+ policy->cur = omap_getspeed(policy->cpu);
+
+ /*
+ * On OMAP SMP configuartion, both processors share the voltage
+ * and clock. So both CPUs needs to be scaled together and hence
+ * needs software co-ordination. Use cpufreq affected_cpus
+ * interface to handle this scenario. Additional is_smp() check
+ * is to keep SMP_ON_UP build working.
+ */
+ if (is_smp()) {
+ policy->shared_type = CPUFREQ_SHARED_TYPE_ANY;
+ cpumask_setall(policy->cpus);
+ }
+
+ /* FIXME: what's the actual transition time? */
+ policy->cpuinfo.transition_latency = 300 * 1000;
+
+ return 0;
+
+fail_table:
+ freq_table_free();
+fail_ck:
+ clk_put(mpu_clk);
+ return result;
+}
+
+static int omap_cpu_exit(struct cpufreq_policy *policy)
+{
+ freq_table_free();
+ clk_put(mpu_clk);
+ return 0;
+}
+
+static struct freq_attr *omap_cpufreq_attr[] = {
+ &cpufreq_freq_attr_scaling_available_freqs,
+ NULL,
+};
+
+static struct cpufreq_driver omap_driver = {
+ .flags = CPUFREQ_STICKY,
+ .verify = omap_verify_speed,
+ .target = omap_target,
+ .get = omap_getspeed,
+ .init = omap_cpu_init,
+ .exit = omap_cpu_exit,
+ .name = "omap",
+ .attr = omap_cpufreq_attr,
+};
+
+static int __init omap_cpufreq_init(void)
+{
+ if (cpu_is_omap24xx())
+ mpu_clk_name = "virt_prcm_set";
+ else if (cpu_is_omap34xx())
+ mpu_clk_name = "dpll1_ck";
+ else if (cpu_is_omap44xx())
+ mpu_clk_name = "dpll_mpu_ck";
+
+ if (!mpu_clk_name) {
+ pr_err("%s: unsupported Silicon?\n", __func__);
+ return -EINVAL;
+ }
+
+ mpu_dev = omap_device_get_by_hwmod_name("mpu");
+ if (!mpu_dev) {
+ pr_warning("%s: unable to get the mpu device\n", __func__);
+ return -EINVAL;
+ }
+
+ return cpufreq_register_driver(&omap_driver);
+}
+
+static void __exit omap_cpufreq_exit(void)
+{
+ cpufreq_unregister_driver(&omap_driver);
+}
+
+MODULE_DESCRIPTION("cpufreq driver for OMAP SoCs");
+MODULE_LICENSE("GPL");
+module_init(omap_cpufreq_init);
+module_exit(omap_cpufreq_exit);
diff --git a/drivers/cpufreq/powernow-k8.c b/drivers/cpufreq/powernow-k8.c
index bce576d..8f9b2cee 100644
--- a/drivers/cpufreq/powernow-k8.c
+++ b/drivers/cpufreq/powernow-k8.c
@@ -1,10 +1,11 @@
/*
- * (c) 2003-2010 Advanced Micro Devices, Inc.
+ * (c) 2003-2012 Advanced Micro Devices, Inc.
* Your use of this code is subject to the terms and conditions of the
* GNU general public license version 2. See "COPYING" or
* http://www.gnu.org/licenses/gpl.html
*
- * Support : mark.langsdorf@amd.com
+ * Maintainer:
+ * Andreas Herrmann <andreas.herrmann3@amd.com>
*
* Based on the powernow-k7.c module written by Dave Jones.
* (C) 2003 Dave Jones on behalf of SuSE Labs
@@ -16,12 +17,14 @@
* Valuable input gratefully received from Dave Jones, Pavel Machek,
* Dominik Brodowski, Jacob Shin, and others.
* Originally developed by Paul Devriendt.
- * Processor information obtained from Chapter 9 (Power and Thermal Management)
- * of the "BIOS and Kernel Developer's Guide for the AMD Athlon 64 and AMD
- * Opteron Processors" available for download from www.amd.com
*
- * Tables for specific CPUs can be inferred from
- * http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/30430.pdf
+ * Processor information obtained from Chapter 9 (Power and Thermal
+ * Management) of the "BIOS and Kernel Developer's Guide (BKDG) for
+ * the AMD Athlon 64 and AMD Opteron Processors" and section "2.x
+ * Power Management" in BKDGs for newer AMD CPU families.
+ *
+ * Tables for specific CPUs can be inferred from AMD's processor
+ * power and thermal data sheets, (e.g. 30417.pdf, 30430.pdf, 43375.pdf)
*/
#include <linux/kernel.h>
@@ -54,6 +57,9 @@
static int cpu_family = CPU_OPTERON;
+/* array to map SW pstate number to acpi state */
+static u32 ps_to_as[8];
+
/* core performance boost */
static bool cpb_capable, cpb_enabled;
static struct msr __percpu *msrs;
@@ -80,9 +86,9 @@
}
static u32 find_khz_freq_from_pstate(struct cpufreq_frequency_table *data,
- u32 pstate)
+ u32 pstate)
{
- return data[pstate].frequency;
+ return data[ps_to_as[pstate]].frequency;
}
/* Return the vco fid for an input fid
@@ -926,23 +932,27 @@
invalidate_entry(powernow_table, i);
continue;
}
- rdmsr(MSR_PSTATE_DEF_BASE + index, lo, hi);
- if (!(hi & HW_PSTATE_VALID_MASK)) {
- pr_debug("invalid pstate %d, ignoring\n", index);
- invalidate_entry(powernow_table, i);
- continue;
- }
- powernow_table[i].index = index;
+ ps_to_as[index] = i;
/* Frequency may be rounded for these */
if ((boot_cpu_data.x86 == 0x10 && boot_cpu_data.x86_model < 10)
|| boot_cpu_data.x86 == 0x11) {
+
+ rdmsr(MSR_PSTATE_DEF_BASE + index, lo, hi);
+ if (!(hi & HW_PSTATE_VALID_MASK)) {
+ pr_debug("invalid pstate %d, ignoring\n", index);
+ invalidate_entry(powernow_table, i);
+ continue;
+ }
+
powernow_table[i].frequency =
freq_from_fid_did(lo & 0x3f, (lo >> 6) & 7);
} else
powernow_table[i].frequency =
data->acpi_data.states[i].core_frequency * 1000;
+
+ powernow_table[i].index = index;
}
return 0;
}
@@ -1189,7 +1199,8 @@
powernow_k8_acpi_pst_values(data, newstate);
if (cpu_family == CPU_HW_PSTATE)
- ret = transition_frequency_pstate(data, newstate);
+ ret = transition_frequency_pstate(data,
+ data->powernow_table[newstate].index);
else
ret = transition_frequency_fidvid(data, newstate);
if (ret) {
@@ -1202,7 +1213,7 @@
if (cpu_family == CPU_HW_PSTATE)
pol->cur = find_khz_freq_from_pstate(data->powernow_table,
- newstate);
+ data->powernow_table[newstate].index);
else
pol->cur = find_khz_freq_from_fid(data->currfid);
ret = 0;
diff --git a/drivers/cpufreq/s3c64xx-cpufreq.c b/drivers/cpufreq/s3c64xx-cpufreq.c
index 3475f65..a5e72cb 100644
--- a/drivers/cpufreq/s3c64xx-cpufreq.c
+++ b/drivers/cpufreq/s3c64xx-cpufreq.c
@@ -8,6 +8,8 @@
* published by the Free Software Foundation.
*/
+#define pr_fmt(fmt) "cpufreq: " fmt
+
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/init.h>
@@ -91,7 +93,7 @@
if (freqs.old == freqs.new)
return 0;
- pr_debug("cpufreq: Transition %d-%dkHz\n", freqs.old, freqs.new);
+ pr_debug("Transition %d-%dkHz\n", freqs.old, freqs.new);
cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
@@ -101,7 +103,7 @@
dvfs->vddarm_min,
dvfs->vddarm_max);
if (ret != 0) {
- pr_err("cpufreq: Failed to set VDDARM for %dkHz: %d\n",
+ pr_err("Failed to set VDDARM for %dkHz: %d\n",
freqs.new, ret);
goto err;
}
@@ -110,7 +112,7 @@
ret = clk_set_rate(armclk, freqs.new * 1000);
if (ret < 0) {
- pr_err("cpufreq: Failed to set rate %dkHz: %d\n",
+ pr_err("Failed to set rate %dkHz: %d\n",
freqs.new, ret);
goto err;
}
@@ -123,14 +125,14 @@
dvfs->vddarm_min,
dvfs->vddarm_max);
if (ret != 0) {
- pr_err("cpufreq: Failed to set VDDARM for %dkHz: %d\n",
+ pr_err("Failed to set VDDARM for %dkHz: %d\n",
freqs.new, ret);
goto err_clk;
}
}
#endif
- pr_debug("cpufreq: Set actual frequency %lukHz\n",
+ pr_debug("Set actual frequency %lukHz\n",
clk_get_rate(armclk) / 1000);
return 0;
@@ -153,7 +155,7 @@
count = regulator_count_voltages(vddarm);
if (count < 0) {
- pr_err("cpufreq: Unable to check supported voltages\n");
+ pr_err("Unable to check supported voltages\n");
}
freq = s3c64xx_freq_table;
@@ -171,7 +173,7 @@
}
if (!found) {
- pr_debug("cpufreq: %dkHz unsupported by regulator\n",
+ pr_debug("%dkHz unsupported by regulator\n",
freq->frequency);
freq->frequency = CPUFREQ_ENTRY_INVALID;
}
@@ -194,13 +196,13 @@
return -EINVAL;
if (s3c64xx_freq_table == NULL) {
- pr_err("cpufreq: No frequency information for this CPU\n");
+ pr_err("No frequency information for this CPU\n");
return -ENODEV;
}
armclk = clk_get(NULL, "armclk");
if (IS_ERR(armclk)) {
- pr_err("cpufreq: Unable to obtain ARMCLK: %ld\n",
+ pr_err("Unable to obtain ARMCLK: %ld\n",
PTR_ERR(armclk));
return PTR_ERR(armclk);
}
@@ -209,12 +211,19 @@
vddarm = regulator_get(NULL, "vddarm");
if (IS_ERR(vddarm)) {
ret = PTR_ERR(vddarm);
- pr_err("cpufreq: Failed to obtain VDDARM: %d\n", ret);
- pr_err("cpufreq: Only frequency scaling available\n");
+ pr_err("Failed to obtain VDDARM: %d\n", ret);
+ pr_err("Only frequency scaling available\n");
vddarm = NULL;
} else {
s3c64xx_cpufreq_config_regulator();
}
+
+ vddint = regulator_get(NULL, "vddint");
+ if (IS_ERR(vddint)) {
+ ret = PTR_ERR(vddint);
+ pr_err("Failed to obtain VDDINT: %d\n", ret);
+ vddint = NULL;
+ }
#endif
freq = s3c64xx_freq_table;
@@ -225,7 +234,7 @@
r = clk_round_rate(armclk, freq->frequency * 1000);
r /= 1000;
if (r != freq->frequency) {
- pr_debug("cpufreq: %dkHz unsupported by clock\n",
+ pr_debug("%dkHz unsupported by clock\n",
freq->frequency);
freq->frequency = CPUFREQ_ENTRY_INVALID;
}
@@ -248,7 +257,7 @@
ret = cpufreq_frequency_table_cpuinfo(policy, s3c64xx_freq_table);
if (ret != 0) {
- pr_err("cpufreq: Failed to configure frequency table: %d\n",
+ pr_err("Failed to configure frequency table: %d\n",
ret);
regulator_put(vddarm);
clk_put(armclk);
diff --git a/drivers/crypto/amcc/crypto4xx_core.c b/drivers/crypto/amcc/crypto4xx_core.c
index 1d103f9..13f8e1a 100644
--- a/drivers/crypto/amcc/crypto4xx_core.c
+++ b/drivers/crypto/amcc/crypto4xx_core.c
@@ -1292,18 +1292,7 @@
.remove = crypto4xx_remove,
};
-static int __init crypto4xx_init(void)
-{
- return platform_driver_register(&crypto4xx_driver);
-}
-
-static void __exit crypto4xx_exit(void)
-{
- platform_driver_unregister(&crypto4xx_driver);
-}
-
-module_init(crypto4xx_init);
-module_exit(crypto4xx_exit);
+module_platform_driver(crypto4xx_driver);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("James Hsiao <jhsiao@amcc.com>");
diff --git a/drivers/crypto/caam/caamalg.c b/drivers/crypto/caam/caamalg.c
index 4159265..e73cf2e 100644
--- a/drivers/crypto/caam/caamalg.c
+++ b/drivers/crypto/caam/caamalg.c
@@ -113,7 +113,7 @@
jump_cmd = append_jump(desc, JUMP_CLASS_CLASS1 | JUMP_TEST_ALL);
set_jump_tgt_here(desc, jump_cmd);
- append_cmd(desc, SET_OK_PROP_ERRORS | CMD_LOAD);
+ append_cmd(desc, SET_OK_NO_PROP_ERRORS | CMD_LOAD);
}
/*
@@ -213,7 +213,7 @@
set_jump_tgt_here(desc, key_jump_cmd);
/* Propagate errors from shared to job descriptor */
- append_cmd(desc, SET_OK_PROP_ERRORS | CMD_LOAD);
+ append_cmd(desc, SET_OK_NO_PROP_ERRORS | CMD_LOAD);
}
static int aead_set_sh_desc(struct crypto_aead *aead)
@@ -310,7 +310,7 @@
/* Only propagate error immediately if shared */
jump_cmd = append_jump(desc, JUMP_TEST_ALL);
set_jump_tgt_here(desc, key_jump_cmd);
- append_cmd(desc, SET_OK_PROP_ERRORS | CMD_LOAD);
+ append_cmd(desc, SET_OK_NO_PROP_ERRORS | CMD_LOAD);
set_jump_tgt_here(desc, jump_cmd);
/* Class 2 operation */
@@ -683,7 +683,7 @@
set_jump_tgt_here(desc, key_jump_cmd);
/* Propagate errors from shared to job descriptor */
- append_cmd(desc, SET_OK_PROP_ERRORS | CMD_LOAD);
+ append_cmd(desc, SET_OK_NO_PROP_ERRORS | CMD_LOAD);
/* Load iv */
append_cmd(desc, CMD_SEQ_LOAD | LDST_SRCDST_BYTE_CONTEXT |
@@ -724,7 +724,7 @@
/* For aead, only propagate error immediately if shared */
jump_cmd = append_jump(desc, JUMP_TEST_ALL);
set_jump_tgt_here(desc, key_jump_cmd);
- append_cmd(desc, SET_OK_PROP_ERRORS | CMD_LOAD);
+ append_cmd(desc, SET_OK_NO_PROP_ERRORS | CMD_LOAD);
set_jump_tgt_here(desc, jump_cmd);
/* load IV */
@@ -1806,6 +1806,25 @@
static struct caam_alg_template driver_algs[] = {
/* single-pass ipsec_esp descriptor */
{
+ .name = "authenc(hmac(md5),cbc(aes))",
+ .driver_name = "authenc-hmac-md5-cbc-aes-caam",
+ .blocksize = AES_BLOCK_SIZE,
+ .type = CRYPTO_ALG_TYPE_AEAD,
+ .template_aead = {
+ .setkey = aead_setkey,
+ .setauthsize = aead_setauthsize,
+ .encrypt = aead_encrypt,
+ .decrypt = aead_decrypt,
+ .givencrypt = aead_givencrypt,
+ .geniv = "<built-in>",
+ .ivsize = AES_BLOCK_SIZE,
+ .maxauthsize = MD5_DIGEST_SIZE,
+ },
+ .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
+ .class2_alg_type = OP_ALG_ALGSEL_MD5 | OP_ALG_AAI_HMAC_PRECOMP,
+ .alg_op = OP_ALG_ALGSEL_MD5 | OP_ALG_AAI_HMAC,
+ },
+ {
.name = "authenc(hmac(sha1),cbc(aes))",
.driver_name = "authenc-hmac-sha1-cbc-aes-caam",
.blocksize = AES_BLOCK_SIZE,
@@ -1865,6 +1884,25 @@
.alg_op = OP_ALG_ALGSEL_SHA512 | OP_ALG_AAI_HMAC,
},
{
+ .name = "authenc(hmac(md5),cbc(des3_ede))",
+ .driver_name = "authenc-hmac-md5-cbc-des3_ede-caam",
+ .blocksize = DES3_EDE_BLOCK_SIZE,
+ .type = CRYPTO_ALG_TYPE_AEAD,
+ .template_aead = {
+ .setkey = aead_setkey,
+ .setauthsize = aead_setauthsize,
+ .encrypt = aead_encrypt,
+ .decrypt = aead_decrypt,
+ .givencrypt = aead_givencrypt,
+ .geniv = "<built-in>",
+ .ivsize = DES3_EDE_BLOCK_SIZE,
+ .maxauthsize = MD5_DIGEST_SIZE,
+ },
+ .class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
+ .class2_alg_type = OP_ALG_ALGSEL_MD5 | OP_ALG_AAI_HMAC_PRECOMP,
+ .alg_op = OP_ALG_ALGSEL_MD5 | OP_ALG_AAI_HMAC,
+ },
+ {
.name = "authenc(hmac(sha1),cbc(des3_ede))",
.driver_name = "authenc-hmac-sha1-cbc-des3_ede-caam",
.blocksize = DES3_EDE_BLOCK_SIZE,
@@ -1924,6 +1962,25 @@
.alg_op = OP_ALG_ALGSEL_SHA512 | OP_ALG_AAI_HMAC,
},
{
+ .name = "authenc(hmac(md5),cbc(des))",
+ .driver_name = "authenc-hmac-md5-cbc-des-caam",
+ .blocksize = DES_BLOCK_SIZE,
+ .type = CRYPTO_ALG_TYPE_AEAD,
+ .template_aead = {
+ .setkey = aead_setkey,
+ .setauthsize = aead_setauthsize,
+ .encrypt = aead_encrypt,
+ .decrypt = aead_decrypt,
+ .givencrypt = aead_givencrypt,
+ .geniv = "<built-in>",
+ .ivsize = DES_BLOCK_SIZE,
+ .maxauthsize = MD5_DIGEST_SIZE,
+ },
+ .class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
+ .class2_alg_type = OP_ALG_ALGSEL_MD5 | OP_ALG_AAI_HMAC_PRECOMP,
+ .alg_op = OP_ALG_ALGSEL_MD5 | OP_ALG_AAI_HMAC,
+ },
+ {
.name = "authenc(hmac(sha1),cbc(des))",
.driver_name = "authenc-hmac-sha1-cbc-des-caam",
.blocksize = DES_BLOCK_SIZE,
diff --git a/drivers/crypto/caam/compat.h b/drivers/crypto/caam/compat.h
index d38f2af..a63bc65 100644
--- a/drivers/crypto/caam/compat.h
+++ b/drivers/crypto/caam/compat.h
@@ -28,6 +28,7 @@
#include <crypto/aes.h>
#include <crypto/des.h>
#include <crypto/sha.h>
+#include <crypto/md5.h>
#include <crypto/aead.h>
#include <crypto/authenc.h>
#include <crypto/scatterwalk.h>
diff --git a/drivers/crypto/caam/ctrl.c b/drivers/crypto/caam/ctrl.c
index 73988bb..8ae3ba2 100644
--- a/drivers/crypto/caam/ctrl.c
+++ b/drivers/crypto/caam/ctrl.c
@@ -52,8 +52,6 @@
struct caam_ctrl __iomem *ctrl;
struct caam_full __iomem *topregs;
struct caam_drv_private *ctrlpriv;
- struct caam_deco **deco;
- u32 deconum;
#ifdef CONFIG_DEBUG_FS
struct caam_perfmon *perfmon;
#endif
@@ -92,17 +90,6 @@
if (sizeof(dma_addr_t) == sizeof(u64))
dma_set_mask(dev, DMA_BIT_MASK(36));
- /* Find out how many DECOs are present */
- deconum = (rd_reg64(&topregs->ctrl.perfmon.cha_num) &
- CHA_NUM_DECONUM_MASK) >> CHA_NUM_DECONUM_SHIFT;
-
- ctrlpriv->deco = kmalloc(deconum * sizeof(struct caam_deco *),
- GFP_KERNEL);
-
- deco = (struct caam_deco __force **)&topregs->deco;
- for (d = 0; d < deconum; d++)
- ctrlpriv->deco[d] = deco[d];
-
/*
* Detect and enable JobRs
* First, find out how many ring spec'ed, allocate references
@@ -253,18 +240,7 @@
.remove = __devexit_p(caam_remove),
};
-static int __init caam_base_init(void)
-{
- return platform_driver_register(&caam_driver);
-}
-
-static void __exit caam_base_exit(void)
-{
- return platform_driver_unregister(&caam_driver);
-}
-
-module_init(caam_base_init);
-module_exit(caam_base_exit);
+module_platform_driver(caam_driver);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("FSL CAAM request backend");
diff --git a/drivers/crypto/caam/desc.h b/drivers/crypto/caam/desc.h
index 974a758..a17c295 100644
--- a/drivers/crypto/caam/desc.h
+++ b/drivers/crypto/caam/desc.h
@@ -9,7 +9,7 @@
#define DESC_H
/* Max size of any CAAM descriptor in 32-bit words, inclusive of header */
-#define MAX_CAAM_DESCSIZE 64
+#define MAX_CAAM_DESCSIZE 64
/* Block size of any entity covered/uncovered with a KEK/TKEK */
#define KEK_BLOCKSIZE 16
@@ -18,38 +18,38 @@
* Supported descriptor command types as they show up
* inside a descriptor command word.
*/
-#define CMD_SHIFT 27
-#define CMD_MASK 0xf8000000
+#define CMD_SHIFT 27
+#define CMD_MASK 0xf8000000
-#define CMD_KEY (0x00 << CMD_SHIFT)
-#define CMD_SEQ_KEY (0x01 << CMD_SHIFT)
-#define CMD_LOAD (0x02 << CMD_SHIFT)
-#define CMD_SEQ_LOAD (0x03 << CMD_SHIFT)
-#define CMD_FIFO_LOAD (0x04 << CMD_SHIFT)
-#define CMD_SEQ_FIFO_LOAD (0x05 << CMD_SHIFT)
-#define CMD_STORE (0x0a << CMD_SHIFT)
-#define CMD_SEQ_STORE (0x0b << CMD_SHIFT)
-#define CMD_FIFO_STORE (0x0c << CMD_SHIFT)
-#define CMD_SEQ_FIFO_STORE (0x0d << CMD_SHIFT)
-#define CMD_MOVE_LEN (0x0e << CMD_SHIFT)
-#define CMD_MOVE (0x0f << CMD_SHIFT)
-#define CMD_OPERATION (0x10 << CMD_SHIFT)
-#define CMD_SIGNATURE (0x12 << CMD_SHIFT)
-#define CMD_JUMP (0x14 << CMD_SHIFT)
-#define CMD_MATH (0x15 << CMD_SHIFT)
-#define CMD_DESC_HDR (0x16 << CMD_SHIFT)
-#define CMD_SHARED_DESC_HDR (0x17 << CMD_SHIFT)
-#define CMD_SEQ_IN_PTR (0x1e << CMD_SHIFT)
-#define CMD_SEQ_OUT_PTR (0x1f << CMD_SHIFT)
+#define CMD_KEY (0x00 << CMD_SHIFT)
+#define CMD_SEQ_KEY (0x01 << CMD_SHIFT)
+#define CMD_LOAD (0x02 << CMD_SHIFT)
+#define CMD_SEQ_LOAD (0x03 << CMD_SHIFT)
+#define CMD_FIFO_LOAD (0x04 << CMD_SHIFT)
+#define CMD_SEQ_FIFO_LOAD (0x05 << CMD_SHIFT)
+#define CMD_STORE (0x0a << CMD_SHIFT)
+#define CMD_SEQ_STORE (0x0b << CMD_SHIFT)
+#define CMD_FIFO_STORE (0x0c << CMD_SHIFT)
+#define CMD_SEQ_FIFO_STORE (0x0d << CMD_SHIFT)
+#define CMD_MOVE_LEN (0x0e << CMD_SHIFT)
+#define CMD_MOVE (0x0f << CMD_SHIFT)
+#define CMD_OPERATION (0x10 << CMD_SHIFT)
+#define CMD_SIGNATURE (0x12 << CMD_SHIFT)
+#define CMD_JUMP (0x14 << CMD_SHIFT)
+#define CMD_MATH (0x15 << CMD_SHIFT)
+#define CMD_DESC_HDR (0x16 << CMD_SHIFT)
+#define CMD_SHARED_DESC_HDR (0x17 << CMD_SHIFT)
+#define CMD_SEQ_IN_PTR (0x1e << CMD_SHIFT)
+#define CMD_SEQ_OUT_PTR (0x1f << CMD_SHIFT)
/* General-purpose class selector for all commands */
-#define CLASS_SHIFT 25
-#define CLASS_MASK (0x03 << CLASS_SHIFT)
+#define CLASS_SHIFT 25
+#define CLASS_MASK (0x03 << CLASS_SHIFT)
-#define CLASS_NONE (0x00 << CLASS_SHIFT)
-#define CLASS_1 (0x01 << CLASS_SHIFT)
-#define CLASS_2 (0x02 << CLASS_SHIFT)
-#define CLASS_BOTH (0x03 << CLASS_SHIFT)
+#define CLASS_NONE (0x00 << CLASS_SHIFT)
+#define CLASS_1 (0x01 << CLASS_SHIFT)
+#define CLASS_2 (0x02 << CLASS_SHIFT)
+#define CLASS_BOTH (0x03 << CLASS_SHIFT)
/*
* Descriptor header command constructs
@@ -60,82 +60,82 @@
* Do Not Run - marks a descriptor inexecutable if there was
* a preceding error somewhere
*/
-#define HDR_DNR 0x01000000
+#define HDR_DNR 0x01000000
/*
* ONE - should always be set. Combination of ONE (always
* set) and ZRO (always clear) forms an endianness sanity check
*/
-#define HDR_ONE 0x00800000
-#define HDR_ZRO 0x00008000
+#define HDR_ONE 0x00800000
+#define HDR_ZRO 0x00008000
/* Start Index or SharedDesc Length */
-#define HDR_START_IDX_MASK 0x3f
-#define HDR_START_IDX_SHIFT 16
+#define HDR_START_IDX_MASK 0x3f
+#define HDR_START_IDX_SHIFT 16
/* If shared descriptor header, 6-bit length */
-#define HDR_DESCLEN_SHR_MASK 0x3f
+#define HDR_DESCLEN_SHR_MASK 0x3f
/* If non-shared header, 7-bit length */
-#define HDR_DESCLEN_MASK 0x7f
+#define HDR_DESCLEN_MASK 0x7f
/* This is a TrustedDesc (if not SharedDesc) */
-#define HDR_TRUSTED 0x00004000
+#define HDR_TRUSTED 0x00004000
/* Make into TrustedDesc (if not SharedDesc) */
-#define HDR_MAKE_TRUSTED 0x00002000
+#define HDR_MAKE_TRUSTED 0x00002000
/* Save context if self-shared (if SharedDesc) */
-#define HDR_SAVECTX 0x00001000
+#define HDR_SAVECTX 0x00001000
/* Next item points to SharedDesc */
-#define HDR_SHARED 0x00001000
+#define HDR_SHARED 0x00001000
/*
* Reverse Execution Order - execute JobDesc first, then
* execute SharedDesc (normally SharedDesc goes first).
*/
-#define HDR_REVERSE 0x00000800
+#define HDR_REVERSE 0x00000800
/* Propogate DNR property to SharedDesc */
-#define HDR_PROP_DNR 0x00000800
+#define HDR_PROP_DNR 0x00000800
/* JobDesc/SharedDesc share property */
-#define HDR_SD_SHARE_MASK 0x03
-#define HDR_SD_SHARE_SHIFT 8
-#define HDR_JD_SHARE_MASK 0x07
-#define HDR_JD_SHARE_SHIFT 8
+#define HDR_SD_SHARE_MASK 0x03
+#define HDR_SD_SHARE_SHIFT 8
+#define HDR_JD_SHARE_MASK 0x07
+#define HDR_JD_SHARE_SHIFT 8
-#define HDR_SHARE_NEVER (0x00 << HDR_SD_SHARE_SHIFT)
-#define HDR_SHARE_WAIT (0x01 << HDR_SD_SHARE_SHIFT)
-#define HDR_SHARE_SERIAL (0x02 << HDR_SD_SHARE_SHIFT)
-#define HDR_SHARE_ALWAYS (0x03 << HDR_SD_SHARE_SHIFT)
-#define HDR_SHARE_DEFER (0x04 << HDR_SD_SHARE_SHIFT)
+#define HDR_SHARE_NEVER (0x00 << HDR_SD_SHARE_SHIFT)
+#define HDR_SHARE_WAIT (0x01 << HDR_SD_SHARE_SHIFT)
+#define HDR_SHARE_SERIAL (0x02 << HDR_SD_SHARE_SHIFT)
+#define HDR_SHARE_ALWAYS (0x03 << HDR_SD_SHARE_SHIFT)
+#define HDR_SHARE_DEFER (0x04 << HDR_SD_SHARE_SHIFT)
/* JobDesc/SharedDesc descriptor length */
-#define HDR_JD_LENGTH_MASK 0x7f
-#define HDR_SD_LENGTH_MASK 0x3f
+#define HDR_JD_LENGTH_MASK 0x7f
+#define HDR_SD_LENGTH_MASK 0x3f
/*
* KEY/SEQ_KEY Command Constructs
*/
-/* Key Destination Class: 01 = Class 1, 02 - Class 2 */
-#define KEY_DEST_CLASS_SHIFT 25 /* use CLASS_1 or CLASS_2 */
-#define KEY_DEST_CLASS_MASK (0x03 << KEY_DEST_CLASS_SHIFT)
+/* Key Destination Class: 01 = Class 1, 02 - Class 2 */
+#define KEY_DEST_CLASS_SHIFT 25 /* use CLASS_1 or CLASS_2 */
+#define KEY_DEST_CLASS_MASK (0x03 << KEY_DEST_CLASS_SHIFT)
/* Scatter-Gather Table/Variable Length Field */
-#define KEY_SGF 0x01000000
-#define KEY_VLF 0x01000000
+#define KEY_SGF 0x01000000
+#define KEY_VLF 0x01000000
/* Immediate - Key follows command in the descriptor */
-#define KEY_IMM 0x00800000
+#define KEY_IMM 0x00800000
/*
* Encrypted - Key is encrypted either with the KEK, or
* with the TDKEK if TK is set
*/
-#define KEY_ENC 0x00400000
+#define KEY_ENC 0x00400000
/*
* No Write Back - Do not allow key to be FIFO STOREd
@@ -156,16 +156,16 @@
* KDEST - Key Destination: 0 - class key register,
* 1 - PKHA 'e', 2 - AFHA Sbox, 3 - MDHA split-key
*/
-#define KEY_DEST_SHIFT 16
-#define KEY_DEST_MASK (0x03 << KEY_DEST_SHIFT)
+#define KEY_DEST_SHIFT 16
+#define KEY_DEST_MASK (0x03 << KEY_DEST_SHIFT)
-#define KEY_DEST_CLASS_REG (0x00 << KEY_DEST_SHIFT)
-#define KEY_DEST_PKHA_E (0x01 << KEY_DEST_SHIFT)
-#define KEY_DEST_AFHA_SBOX (0x02 << KEY_DEST_SHIFT)
-#define KEY_DEST_MDHA_SPLIT (0x03 << KEY_DEST_SHIFT)
+#define KEY_DEST_CLASS_REG (0x00 << KEY_DEST_SHIFT)
+#define KEY_DEST_PKHA_E (0x01 << KEY_DEST_SHIFT)
+#define KEY_DEST_AFHA_SBOX (0x02 << KEY_DEST_SHIFT)
+#define KEY_DEST_MDHA_SPLIT (0x03 << KEY_DEST_SHIFT)
/* Length in bytes */
-#define KEY_LENGTH_MASK 0x000003ff
+#define KEY_LENGTH_MASK 0x000003ff
/*
* LOAD/SEQ_LOAD/STORE/SEQ_STORE Command Constructs
@@ -175,25 +175,25 @@
* Load/Store Destination: 0 = class independent CCB,
* 1 = class 1 CCB, 2 = class 2 CCB, 3 = DECO
*/
-#define LDST_CLASS_SHIFT 25
-#define LDST_CLASS_MASK (0x03 << LDST_CLASS_SHIFT)
-#define LDST_CLASS_IND_CCB (0x00 << LDST_CLASS_SHIFT)
-#define LDST_CLASS_1_CCB (0x01 << LDST_CLASS_SHIFT)
-#define LDST_CLASS_2_CCB (0x02 << LDST_CLASS_SHIFT)
-#define LDST_CLASS_DECO (0x03 << LDST_CLASS_SHIFT)
+#define LDST_CLASS_SHIFT 25
+#define LDST_CLASS_MASK (0x03 << LDST_CLASS_SHIFT)
+#define LDST_CLASS_IND_CCB (0x00 << LDST_CLASS_SHIFT)
+#define LDST_CLASS_1_CCB (0x01 << LDST_CLASS_SHIFT)
+#define LDST_CLASS_2_CCB (0x02 << LDST_CLASS_SHIFT)
+#define LDST_CLASS_DECO (0x03 << LDST_CLASS_SHIFT)
/* Scatter-Gather Table/Variable Length Field */
-#define LDST_SGF 0x01000000
+#define LDST_SGF 0x01000000
#define LDST_VLF LDST_SGF
-/* Immediate - Key follows this command in descriptor */
-#define LDST_IMM_MASK 1
-#define LDST_IMM_SHIFT 23
-#define LDST_IMM (LDST_IMM_MASK << LDST_IMM_SHIFT)
+/* Immediate - Key follows this command in descriptor */
+#define LDST_IMM_MASK 1
+#define LDST_IMM_SHIFT 23
+#define LDST_IMM (LDST_IMM_MASK << LDST_IMM_SHIFT)
-/* SRC/DST - Destination for LOAD, Source for STORE */
-#define LDST_SRCDST_SHIFT 16
-#define LDST_SRCDST_MASK (0x7f << LDST_SRCDST_SHIFT)
+/* SRC/DST - Destination for LOAD, Source for STORE */
+#define LDST_SRCDST_SHIFT 16
+#define LDST_SRCDST_MASK (0x7f << LDST_SRCDST_SHIFT)
#define LDST_SRCDST_BYTE_CONTEXT (0x20 << LDST_SRCDST_SHIFT)
#define LDST_SRCDST_BYTE_KEY (0x40 << LDST_SRCDST_SHIFT)
@@ -205,64 +205,64 @@
#define LDST_SRCDST_WORD_DATASZ_REG (0x02 << LDST_SRCDST_SHIFT)
#define LDST_SRCDST_WORD_ICVSZ_REG (0x03 << LDST_SRCDST_SHIFT)
#define LDST_SRCDST_WORD_CHACTRL (0x06 << LDST_SRCDST_SHIFT)
-#define LDST_SRCDST_WORD_DECOCTRL (0x06 << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_WORD_DECOCTRL (0x06 << LDST_SRCDST_SHIFT)
#define LDST_SRCDST_WORD_IRQCTRL (0x07 << LDST_SRCDST_SHIFT)
-#define LDST_SRCDST_WORD_DECO_PCLOVRD (0x07 << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_WORD_DECO_PCLOVRD (0x07 << LDST_SRCDST_SHIFT)
#define LDST_SRCDST_WORD_CLRW (0x08 << LDST_SRCDST_SHIFT)
-#define LDST_SRCDST_WORD_DECO_MATH0 (0x08 << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_WORD_DECO_MATH0 (0x08 << LDST_SRCDST_SHIFT)
#define LDST_SRCDST_WORD_STAT (0x09 << LDST_SRCDST_SHIFT)
-#define LDST_SRCDST_WORD_DECO_MATH1 (0x09 << LDST_SRCDST_SHIFT)
-#define LDST_SRCDST_WORD_DECO_MATH2 (0x0a << LDST_SRCDST_SHIFT)
-#define LDST_SRCDST_WORD_DECO_AAD_SZ (0x0b << LDST_SRCDST_SHIFT)
-#define LDST_SRCDST_WORD_DECO_MATH3 (0x0b << LDST_SRCDST_SHIFT)
-#define LDST_SRCDST_WORD_CLASS1_ICV_SZ (0x0c << LDST_SRCDST_SHIFT)
-#define LDST_SRCDST_WORD_ALTDS_CLASS1 (0x0f << LDST_SRCDST_SHIFT)
-#define LDST_SRCDST_WORD_PKHA_A_SZ (0x10 << LDST_SRCDST_SHIFT)
-#define LDST_SRCDST_WORD_PKHA_B_SZ (0x11 << LDST_SRCDST_SHIFT)
-#define LDST_SRCDST_WORD_PKHA_N_SZ (0x12 << LDST_SRCDST_SHIFT)
-#define LDST_SRCDST_WORD_PKHA_E_SZ (0x13 << LDST_SRCDST_SHIFT)
-#define LDST_SRCDST_WORD_DESCBUF (0x40 << LDST_SRCDST_SHIFT)
-#define LDST_SRCDST_WORD_INFO_FIFO (0x7a << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_WORD_DECO_MATH1 (0x09 << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_WORD_DECO_MATH2 (0x0a << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_WORD_DECO_AAD_SZ (0x0b << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_WORD_DECO_MATH3 (0x0b << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_WORD_CLASS1_ICV_SZ (0x0c << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_WORD_ALTDS_CLASS1 (0x0f << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_WORD_PKHA_A_SZ (0x10 << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_WORD_PKHA_B_SZ (0x11 << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_WORD_PKHA_N_SZ (0x12 << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_WORD_PKHA_E_SZ (0x13 << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_WORD_DESCBUF (0x40 << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_WORD_INFO_FIFO (0x7a << LDST_SRCDST_SHIFT)
-/* Offset in source/destination */
-#define LDST_OFFSET_SHIFT 8
-#define LDST_OFFSET_MASK (0xff << LDST_OFFSET_SHIFT)
+/* Offset in source/destination */
+#define LDST_OFFSET_SHIFT 8
+#define LDST_OFFSET_MASK (0xff << LDST_OFFSET_SHIFT)
/* LDOFF definitions used when DST = LDST_SRCDST_WORD_DECOCTRL */
/* These could also be shifted by LDST_OFFSET_SHIFT - this reads better */
-#define LDOFF_CHG_SHARE_SHIFT 0
-#define LDOFF_CHG_SHARE_MASK (0x3 << LDOFF_CHG_SHARE_SHIFT)
-#define LDOFF_CHG_SHARE_NEVER (0x1 << LDOFF_CHG_SHARE_SHIFT)
-#define LDOFF_CHG_SHARE_OK_NO_PROP (0x2 << LDOFF_CHG_SHARE_SHIFT)
-#define LDOFF_CHG_SHARE_OK_PROP (0x3 << LDOFF_CHG_SHARE_SHIFT)
+#define LDOFF_CHG_SHARE_SHIFT 0
+#define LDOFF_CHG_SHARE_MASK (0x3 << LDOFF_CHG_SHARE_SHIFT)
+#define LDOFF_CHG_SHARE_NEVER (0x1 << LDOFF_CHG_SHARE_SHIFT)
+#define LDOFF_CHG_SHARE_OK_PROP (0x2 << LDOFF_CHG_SHARE_SHIFT)
+#define LDOFF_CHG_SHARE_OK_NO_PROP (0x3 << LDOFF_CHG_SHARE_SHIFT)
-#define LDOFF_ENABLE_AUTO_NFIFO (1 << 2)
-#define LDOFF_DISABLE_AUTO_NFIFO (1 << 3)
+#define LDOFF_ENABLE_AUTO_NFIFO (1 << 2)
+#define LDOFF_DISABLE_AUTO_NFIFO (1 << 3)
-#define LDOFF_CHG_NONSEQLIODN_SHIFT 4
-#define LDOFF_CHG_NONSEQLIODN_MASK (0x3 << LDOFF_CHG_NONSEQLIODN_SHIFT)
-#define LDOFF_CHG_NONSEQLIODN_SEQ (0x1 << LDOFF_CHG_NONSEQLIODN_SHIFT)
-#define LDOFF_CHG_NONSEQLIODN_NON_SEQ (0x2 << LDOFF_CHG_NONSEQLIODN_SHIFT)
-#define LDOFF_CHG_NONSEQLIODN_TRUSTED (0x3 << LDOFF_CHG_NONSEQLIODN_SHIFT)
+#define LDOFF_CHG_NONSEQLIODN_SHIFT 4
+#define LDOFF_CHG_NONSEQLIODN_MASK (0x3 << LDOFF_CHG_NONSEQLIODN_SHIFT)
+#define LDOFF_CHG_NONSEQLIODN_SEQ (0x1 << LDOFF_CHG_NONSEQLIODN_SHIFT)
+#define LDOFF_CHG_NONSEQLIODN_NON_SEQ (0x2 << LDOFF_CHG_NONSEQLIODN_SHIFT)
+#define LDOFF_CHG_NONSEQLIODN_TRUSTED (0x3 << LDOFF_CHG_NONSEQLIODN_SHIFT)
-#define LDOFF_CHG_SEQLIODN_SHIFT 6
-#define LDOFF_CHG_SEQLIODN_MASK (0x3 << LDOFF_CHG_SEQLIODN_SHIFT)
-#define LDOFF_CHG_SEQLIODN_SEQ (0x1 << LDOFF_CHG_SEQLIODN_SHIFT)
-#define LDOFF_CHG_SEQLIODN_NON_SEQ (0x2 << LDOFF_CHG_SEQLIODN_SHIFT)
-#define LDOFF_CHG_SEQLIODN_TRUSTED (0x3 << LDOFF_CHG_SEQLIODN_SHIFT)
+#define LDOFF_CHG_SEQLIODN_SHIFT 6
+#define LDOFF_CHG_SEQLIODN_MASK (0x3 << LDOFF_CHG_SEQLIODN_SHIFT)
+#define LDOFF_CHG_SEQLIODN_SEQ (0x1 << LDOFF_CHG_SEQLIODN_SHIFT)
+#define LDOFF_CHG_SEQLIODN_NON_SEQ (0x2 << LDOFF_CHG_SEQLIODN_SHIFT)
+#define LDOFF_CHG_SEQLIODN_TRUSTED (0x3 << LDOFF_CHG_SEQLIODN_SHIFT)
-/* Data length in bytes */
-#define LDST_LEN_SHIFT 0
-#define LDST_LEN_MASK (0xff << LDST_LEN_SHIFT)
+/* Data length in bytes */
+#define LDST_LEN_SHIFT 0
+#define LDST_LEN_MASK (0xff << LDST_LEN_SHIFT)
/* Special Length definitions when dst=deco-ctrl */
-#define LDLEN_ENABLE_OSL_COUNT (1 << 7)
-#define LDLEN_RST_CHA_OFIFO_PTR (1 << 6)
-#define LDLEN_RST_OFIFO (1 << 5)
-#define LDLEN_SET_OFIFO_OFF_VALID (1 << 4)
-#define LDLEN_SET_OFIFO_OFF_RSVD (1 << 3)
-#define LDLEN_SET_OFIFO_OFFSET_SHIFT 0
-#define LDLEN_SET_OFIFO_OFFSET_MASK (3 << LDLEN_SET_OFIFO_OFFSET_SHIFT)
+#define LDLEN_ENABLE_OSL_COUNT (1 << 7)
+#define LDLEN_RST_CHA_OFIFO_PTR (1 << 6)
+#define LDLEN_RST_OFIFO (1 << 5)
+#define LDLEN_SET_OFIFO_OFF_VALID (1 << 4)
+#define LDLEN_SET_OFIFO_OFF_RSVD (1 << 3)
+#define LDLEN_SET_OFIFO_OFFSET_SHIFT 0
+#define LDLEN_SET_OFIFO_OFFSET_MASK (3 << LDLEN_SET_OFIFO_OFFSET_SHIFT)
/*
* FIFO_LOAD/FIFO_STORE/SEQ_FIFO_LOAD/SEQ_FIFO_STORE
@@ -274,808 +274,808 @@
* 1 = Load for Class1, 2 = Load for Class2, 3 = Load both
* Store Source: 0 = normal, 1 = Class1key, 2 = Class2key
*/
-#define FIFOLD_CLASS_SHIFT 25
-#define FIFOLD_CLASS_MASK (0x03 << FIFOLD_CLASS_SHIFT)
-#define FIFOLD_CLASS_SKIP (0x00 << FIFOLD_CLASS_SHIFT)
-#define FIFOLD_CLASS_CLASS1 (0x01 << FIFOLD_CLASS_SHIFT)
-#define FIFOLD_CLASS_CLASS2 (0x02 << FIFOLD_CLASS_SHIFT)
-#define FIFOLD_CLASS_BOTH (0x03 << FIFOLD_CLASS_SHIFT)
+#define FIFOLD_CLASS_SHIFT 25
+#define FIFOLD_CLASS_MASK (0x03 << FIFOLD_CLASS_SHIFT)
+#define FIFOLD_CLASS_SKIP (0x00 << FIFOLD_CLASS_SHIFT)
+#define FIFOLD_CLASS_CLASS1 (0x01 << FIFOLD_CLASS_SHIFT)
+#define FIFOLD_CLASS_CLASS2 (0x02 << FIFOLD_CLASS_SHIFT)
+#define FIFOLD_CLASS_BOTH (0x03 << FIFOLD_CLASS_SHIFT)
-#define FIFOST_CLASS_SHIFT 25
-#define FIFOST_CLASS_MASK (0x03 << FIFOST_CLASS_SHIFT)
-#define FIFOST_CLASS_NORMAL (0x00 << FIFOST_CLASS_SHIFT)
-#define FIFOST_CLASS_CLASS1KEY (0x01 << FIFOST_CLASS_SHIFT)
-#define FIFOST_CLASS_CLASS2KEY (0x02 << FIFOST_CLASS_SHIFT)
+#define FIFOST_CLASS_SHIFT 25
+#define FIFOST_CLASS_MASK (0x03 << FIFOST_CLASS_SHIFT)
+#define FIFOST_CLASS_NORMAL (0x00 << FIFOST_CLASS_SHIFT)
+#define FIFOST_CLASS_CLASS1KEY (0x01 << FIFOST_CLASS_SHIFT)
+#define FIFOST_CLASS_CLASS2KEY (0x02 << FIFOST_CLASS_SHIFT)
/*
* Scatter-Gather Table/Variable Length Field
* If set for FIFO_LOAD, refers to a SG table. Within
* SEQ_FIFO_LOAD, is variable input sequence
*/
-#define FIFOLDST_SGF_SHIFT 24
-#define FIFOLDST_SGF_MASK (1 << FIFOLDST_SGF_SHIFT)
-#define FIFOLDST_VLF_MASK (1 << FIFOLDST_SGF_SHIFT)
-#define FIFOLDST_SGF (1 << FIFOLDST_SGF_SHIFT)
-#define FIFOLDST_VLF (1 << FIFOLDST_SGF_SHIFT)
+#define FIFOLDST_SGF_SHIFT 24
+#define FIFOLDST_SGF_MASK (1 << FIFOLDST_SGF_SHIFT)
+#define FIFOLDST_VLF_MASK (1 << FIFOLDST_SGF_SHIFT)
+#define FIFOLDST_SGF (1 << FIFOLDST_SGF_SHIFT)
+#define FIFOLDST_VLF (1 << FIFOLDST_SGF_SHIFT)
/* Immediate - Data follows command in descriptor */
-#define FIFOLD_IMM_SHIFT 23
-#define FIFOLD_IMM_MASK (1 << FIFOLD_IMM_SHIFT)
-#define FIFOLD_IMM (1 << FIFOLD_IMM_SHIFT)
+#define FIFOLD_IMM_SHIFT 23
+#define FIFOLD_IMM_MASK (1 << FIFOLD_IMM_SHIFT)
+#define FIFOLD_IMM (1 << FIFOLD_IMM_SHIFT)
/* Continue - Not the last FIFO store to come */
-#define FIFOST_CONT_SHIFT 23
-#define FIFOST_CONT_MASK (1 << FIFOST_CONT_SHIFT)
-#define FIFOST_CONT_MASK (1 << FIFOST_CONT_SHIFT)
+#define FIFOST_CONT_SHIFT 23
+#define FIFOST_CONT_MASK (1 << FIFOST_CONT_SHIFT)
+#define FIFOST_CONT_MASK (1 << FIFOST_CONT_SHIFT)
/*
* Extended Length - use 32-bit extended length that
* follows the pointer field. Illegal with IMM set
*/
-#define FIFOLDST_EXT_SHIFT 22
-#define FIFOLDST_EXT_MASK (1 << FIFOLDST_EXT_SHIFT)
-#define FIFOLDST_EXT (1 << FIFOLDST_EXT_SHIFT)
+#define FIFOLDST_EXT_SHIFT 22
+#define FIFOLDST_EXT_MASK (1 << FIFOLDST_EXT_SHIFT)
+#define FIFOLDST_EXT (1 << FIFOLDST_EXT_SHIFT)
/* Input data type.*/
-#define FIFOLD_TYPE_SHIFT 16
-#define FIFOLD_CONT_TYPE_SHIFT 19 /* shift past last-flush bits */
-#define FIFOLD_TYPE_MASK (0x3f << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_SHIFT 16
+#define FIFOLD_CONT_TYPE_SHIFT 19 /* shift past last-flush bits */
+#define FIFOLD_TYPE_MASK (0x3f << FIFOLD_TYPE_SHIFT)
/* PK types */
-#define FIFOLD_TYPE_PK (0x00 << FIFOLD_TYPE_SHIFT)
-#define FIFOLD_TYPE_PK_MASK (0x30 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_PK (0x00 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_PK_MASK (0x30 << FIFOLD_TYPE_SHIFT)
#define FIFOLD_TYPE_PK_TYPEMASK (0x0f << FIFOLD_TYPE_SHIFT)
-#define FIFOLD_TYPE_PK_A0 (0x00 << FIFOLD_TYPE_SHIFT)
-#define FIFOLD_TYPE_PK_A1 (0x01 << FIFOLD_TYPE_SHIFT)
-#define FIFOLD_TYPE_PK_A2 (0x02 << FIFOLD_TYPE_SHIFT)
-#define FIFOLD_TYPE_PK_A3 (0x03 << FIFOLD_TYPE_SHIFT)
-#define FIFOLD_TYPE_PK_B0 (0x04 << FIFOLD_TYPE_SHIFT)
-#define FIFOLD_TYPE_PK_B1 (0x05 << FIFOLD_TYPE_SHIFT)
-#define FIFOLD_TYPE_PK_B2 (0x06 << FIFOLD_TYPE_SHIFT)
-#define FIFOLD_TYPE_PK_B3 (0x07 << FIFOLD_TYPE_SHIFT)
-#define FIFOLD_TYPE_PK_N (0x08 << FIFOLD_TYPE_SHIFT)
-#define FIFOLD_TYPE_PK_A (0x0c << FIFOLD_TYPE_SHIFT)
-#define FIFOLD_TYPE_PK_B (0x0d << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_PK_A0 (0x00 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_PK_A1 (0x01 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_PK_A2 (0x02 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_PK_A3 (0x03 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_PK_B0 (0x04 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_PK_B1 (0x05 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_PK_B2 (0x06 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_PK_B3 (0x07 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_PK_N (0x08 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_PK_A (0x0c << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_PK_B (0x0d << FIFOLD_TYPE_SHIFT)
/* Other types. Need to OR in last/flush bits as desired */
-#define FIFOLD_TYPE_MSG_MASK (0x38 << FIFOLD_TYPE_SHIFT)
-#define FIFOLD_TYPE_MSG (0x10 << FIFOLD_TYPE_SHIFT)
-#define FIFOLD_TYPE_MSG1OUT2 (0x18 << FIFOLD_TYPE_SHIFT)
-#define FIFOLD_TYPE_IV (0x20 << FIFOLD_TYPE_SHIFT)
-#define FIFOLD_TYPE_BITDATA (0x28 << FIFOLD_TYPE_SHIFT)
-#define FIFOLD_TYPE_AAD (0x30 << FIFOLD_TYPE_SHIFT)
-#define FIFOLD_TYPE_ICV (0x38 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_MSG_MASK (0x38 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_MSG (0x10 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_MSG1OUT2 (0x18 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_IV (0x20 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_BITDATA (0x28 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_AAD (0x30 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_ICV (0x38 << FIFOLD_TYPE_SHIFT)
/* Last/Flush bits for use with "other" types above */
-#define FIFOLD_TYPE_ACT_MASK (0x07 << FIFOLD_TYPE_SHIFT)
-#define FIFOLD_TYPE_NOACTION (0x00 << FIFOLD_TYPE_SHIFT)
-#define FIFOLD_TYPE_FLUSH1 (0x01 << FIFOLD_TYPE_SHIFT)
-#define FIFOLD_TYPE_LAST1 (0x02 << FIFOLD_TYPE_SHIFT)
-#define FIFOLD_TYPE_LAST2FLUSH (0x03 << FIFOLD_TYPE_SHIFT)
-#define FIFOLD_TYPE_LAST2 (0x04 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_ACT_MASK (0x07 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_NOACTION (0x00 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_FLUSH1 (0x01 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_LAST1 (0x02 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_LAST2FLUSH (0x03 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_LAST2 (0x04 << FIFOLD_TYPE_SHIFT)
#define FIFOLD_TYPE_LAST2FLUSH1 (0x05 << FIFOLD_TYPE_SHIFT)
-#define FIFOLD_TYPE_LASTBOTH (0x06 << FIFOLD_TYPE_SHIFT)
-#define FIFOLD_TYPE_LASTBOTHFL (0x07 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_LASTBOTH (0x06 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_LASTBOTHFL (0x07 << FIFOLD_TYPE_SHIFT)
-#define FIFOLDST_LEN_MASK 0xffff
-#define FIFOLDST_EXT_LEN_MASK 0xffffffff
+#define FIFOLDST_LEN_MASK 0xffff
+#define FIFOLDST_EXT_LEN_MASK 0xffffffff
/* Output data types */
-#define FIFOST_TYPE_SHIFT 16
-#define FIFOST_TYPE_MASK (0x3f << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_SHIFT 16
+#define FIFOST_TYPE_MASK (0x3f << FIFOST_TYPE_SHIFT)
-#define FIFOST_TYPE_PKHA_A0 (0x00 << FIFOST_TYPE_SHIFT)
-#define FIFOST_TYPE_PKHA_A1 (0x01 << FIFOST_TYPE_SHIFT)
-#define FIFOST_TYPE_PKHA_A2 (0x02 << FIFOST_TYPE_SHIFT)
-#define FIFOST_TYPE_PKHA_A3 (0x03 << FIFOST_TYPE_SHIFT)
-#define FIFOST_TYPE_PKHA_B0 (0x04 << FIFOST_TYPE_SHIFT)
-#define FIFOST_TYPE_PKHA_B1 (0x05 << FIFOST_TYPE_SHIFT)
-#define FIFOST_TYPE_PKHA_B2 (0x06 << FIFOST_TYPE_SHIFT)
-#define FIFOST_TYPE_PKHA_B3 (0x07 << FIFOST_TYPE_SHIFT)
-#define FIFOST_TYPE_PKHA_N (0x08 << FIFOST_TYPE_SHIFT)
-#define FIFOST_TYPE_PKHA_A (0x0c << FIFOST_TYPE_SHIFT)
-#define FIFOST_TYPE_PKHA_B (0x0d << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_PKHA_A0 (0x00 << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_PKHA_A1 (0x01 << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_PKHA_A2 (0x02 << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_PKHA_A3 (0x03 << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_PKHA_B0 (0x04 << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_PKHA_B1 (0x05 << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_PKHA_B2 (0x06 << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_PKHA_B3 (0x07 << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_PKHA_N (0x08 << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_PKHA_A (0x0c << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_PKHA_B (0x0d << FIFOST_TYPE_SHIFT)
#define FIFOST_TYPE_AF_SBOX_JKEK (0x10 << FIFOST_TYPE_SHIFT)
#define FIFOST_TYPE_AF_SBOX_TKEK (0x21 << FIFOST_TYPE_SHIFT)
-#define FIFOST_TYPE_PKHA_E_JKEK (0x22 << FIFOST_TYPE_SHIFT)
-#define FIFOST_TYPE_PKHA_E_TKEK (0x23 << FIFOST_TYPE_SHIFT)
-#define FIFOST_TYPE_KEY_KEK (0x24 << FIFOST_TYPE_SHIFT)
-#define FIFOST_TYPE_KEY_TKEK (0x25 << FIFOST_TYPE_SHIFT)
-#define FIFOST_TYPE_SPLIT_KEK (0x26 << FIFOST_TYPE_SHIFT)
-#define FIFOST_TYPE_SPLIT_TKEK (0x27 << FIFOST_TYPE_SHIFT)
-#define FIFOST_TYPE_OUTFIFO_KEK (0x28 << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_PKHA_E_JKEK (0x22 << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_PKHA_E_TKEK (0x23 << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_KEY_KEK (0x24 << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_KEY_TKEK (0x25 << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_SPLIT_KEK (0x26 << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_SPLIT_TKEK (0x27 << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_OUTFIFO_KEK (0x28 << FIFOST_TYPE_SHIFT)
#define FIFOST_TYPE_OUTFIFO_TKEK (0x29 << FIFOST_TYPE_SHIFT)
#define FIFOST_TYPE_MESSAGE_DATA (0x30 << FIFOST_TYPE_SHIFT)
-#define FIFOST_TYPE_RNGSTORE (0x34 << FIFOST_TYPE_SHIFT)
-#define FIFOST_TYPE_RNGFIFO (0x35 << FIFOST_TYPE_SHIFT)
-#define FIFOST_TYPE_SKIP (0x3f << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_RNGSTORE (0x34 << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_RNGFIFO (0x35 << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_SKIP (0x3f << FIFOST_TYPE_SHIFT)
/*
* OPERATION Command Constructs
*/
/* Operation type selectors - OP TYPE */
-#define OP_TYPE_SHIFT 24
-#define OP_TYPE_MASK (0x07 << OP_TYPE_SHIFT)
+#define OP_TYPE_SHIFT 24
+#define OP_TYPE_MASK (0x07 << OP_TYPE_SHIFT)
-#define OP_TYPE_UNI_PROTOCOL (0x00 << OP_TYPE_SHIFT)
-#define OP_TYPE_PK (0x01 << OP_TYPE_SHIFT)
-#define OP_TYPE_CLASS1_ALG (0x02 << OP_TYPE_SHIFT)
-#define OP_TYPE_CLASS2_ALG (0x04 << OP_TYPE_SHIFT)
-#define OP_TYPE_DECAP_PROTOCOL (0x06 << OP_TYPE_SHIFT)
-#define OP_TYPE_ENCAP_PROTOCOL (0x07 << OP_TYPE_SHIFT)
+#define OP_TYPE_UNI_PROTOCOL (0x00 << OP_TYPE_SHIFT)
+#define OP_TYPE_PK (0x01 << OP_TYPE_SHIFT)
+#define OP_TYPE_CLASS1_ALG (0x02 << OP_TYPE_SHIFT)
+#define OP_TYPE_CLASS2_ALG (0x04 << OP_TYPE_SHIFT)
+#define OP_TYPE_DECAP_PROTOCOL (0x06 << OP_TYPE_SHIFT)
+#define OP_TYPE_ENCAP_PROTOCOL (0x07 << OP_TYPE_SHIFT)
/* ProtocolID selectors - PROTID */
-#define OP_PCLID_SHIFT 16
-#define OP_PCLID_MASK (0xff << 16)
+#define OP_PCLID_SHIFT 16
+#define OP_PCLID_MASK (0xff << 16)
/* Assuming OP_TYPE = OP_TYPE_UNI_PROTOCOL */
-#define OP_PCLID_IKEV1_PRF (0x01 << OP_PCLID_SHIFT)
-#define OP_PCLID_IKEV2_PRF (0x02 << OP_PCLID_SHIFT)
-#define OP_PCLID_SSL30_PRF (0x08 << OP_PCLID_SHIFT)
-#define OP_PCLID_TLS10_PRF (0x09 << OP_PCLID_SHIFT)
-#define OP_PCLID_TLS11_PRF (0x0a << OP_PCLID_SHIFT)
-#define OP_PCLID_DTLS10_PRF (0x0c << OP_PCLID_SHIFT)
-#define OP_PCLID_PRF (0x06 << OP_PCLID_SHIFT)
-#define OP_PCLID_BLOB (0x0d << OP_PCLID_SHIFT)
-#define OP_PCLID_SECRETKEY (0x11 << OP_PCLID_SHIFT)
-#define OP_PCLID_PUBLICKEYPAIR (0x14 << OP_PCLID_SHIFT)
-#define OP_PCLID_DSASIGN (0x15 << OP_PCLID_SHIFT)
-#define OP_PCLID_DSAVERIFY (0x16 << OP_PCLID_SHIFT)
+#define OP_PCLID_IKEV1_PRF (0x01 << OP_PCLID_SHIFT)
+#define OP_PCLID_IKEV2_PRF (0x02 << OP_PCLID_SHIFT)
+#define OP_PCLID_SSL30_PRF (0x08 << OP_PCLID_SHIFT)
+#define OP_PCLID_TLS10_PRF (0x09 << OP_PCLID_SHIFT)
+#define OP_PCLID_TLS11_PRF (0x0a << OP_PCLID_SHIFT)
+#define OP_PCLID_DTLS10_PRF (0x0c << OP_PCLID_SHIFT)
+#define OP_PCLID_PRF (0x06 << OP_PCLID_SHIFT)
+#define OP_PCLID_BLOB (0x0d << OP_PCLID_SHIFT)
+#define OP_PCLID_SECRETKEY (0x11 << OP_PCLID_SHIFT)
+#define OP_PCLID_PUBLICKEYPAIR (0x14 << OP_PCLID_SHIFT)
+#define OP_PCLID_DSASIGN (0x15 << OP_PCLID_SHIFT)
+#define OP_PCLID_DSAVERIFY (0x16 << OP_PCLID_SHIFT)
/* Assuming OP_TYPE = OP_TYPE_DECAP_PROTOCOL/ENCAP_PROTOCOL */
-#define OP_PCLID_IPSEC (0x01 << OP_PCLID_SHIFT)
-#define OP_PCLID_SRTP (0x02 << OP_PCLID_SHIFT)
-#define OP_PCLID_MACSEC (0x03 << OP_PCLID_SHIFT)
-#define OP_PCLID_WIFI (0x04 << OP_PCLID_SHIFT)
-#define OP_PCLID_WIMAX (0x05 << OP_PCLID_SHIFT)
-#define OP_PCLID_SSL30 (0x08 << OP_PCLID_SHIFT)
-#define OP_PCLID_TLS10 (0x09 << OP_PCLID_SHIFT)
-#define OP_PCLID_TLS11 (0x0a << OP_PCLID_SHIFT)
-#define OP_PCLID_TLS12 (0x0b << OP_PCLID_SHIFT)
-#define OP_PCLID_DTLS (0x0c << OP_PCLID_SHIFT)
+#define OP_PCLID_IPSEC (0x01 << OP_PCLID_SHIFT)
+#define OP_PCLID_SRTP (0x02 << OP_PCLID_SHIFT)
+#define OP_PCLID_MACSEC (0x03 << OP_PCLID_SHIFT)
+#define OP_PCLID_WIFI (0x04 << OP_PCLID_SHIFT)
+#define OP_PCLID_WIMAX (0x05 << OP_PCLID_SHIFT)
+#define OP_PCLID_SSL30 (0x08 << OP_PCLID_SHIFT)
+#define OP_PCLID_TLS10 (0x09 << OP_PCLID_SHIFT)
+#define OP_PCLID_TLS11 (0x0a << OP_PCLID_SHIFT)
+#define OP_PCLID_TLS12 (0x0b << OP_PCLID_SHIFT)
+#define OP_PCLID_DTLS (0x0c << OP_PCLID_SHIFT)
/*
* ProtocolInfo selectors
*/
-#define OP_PCLINFO_MASK 0xffff
+#define OP_PCLINFO_MASK 0xffff
/* for OP_PCLID_IPSEC */
-#define OP_PCL_IPSEC_CIPHER_MASK 0xff00
-#define OP_PCL_IPSEC_AUTH_MASK 0x00ff
+#define OP_PCL_IPSEC_CIPHER_MASK 0xff00
+#define OP_PCL_IPSEC_AUTH_MASK 0x00ff
-#define OP_PCL_IPSEC_DES_IV64 0x0100
-#define OP_PCL_IPSEC_DES 0x0200
-#define OP_PCL_IPSEC_3DES 0x0300
-#define OP_PCL_IPSEC_AES_CBC 0x0c00
-#define OP_PCL_IPSEC_AES_CTR 0x0d00
-#define OP_PCL_IPSEC_AES_XTS 0x1600
-#define OP_PCL_IPSEC_AES_CCM8 0x0e00
-#define OP_PCL_IPSEC_AES_CCM12 0x0f00
-#define OP_PCL_IPSEC_AES_CCM16 0x1000
-#define OP_PCL_IPSEC_AES_GCM8 0x1200
-#define OP_PCL_IPSEC_AES_GCM12 0x1300
-#define OP_PCL_IPSEC_AES_GCM16 0x1400
+#define OP_PCL_IPSEC_DES_IV64 0x0100
+#define OP_PCL_IPSEC_DES 0x0200
+#define OP_PCL_IPSEC_3DES 0x0300
+#define OP_PCL_IPSEC_AES_CBC 0x0c00
+#define OP_PCL_IPSEC_AES_CTR 0x0d00
+#define OP_PCL_IPSEC_AES_XTS 0x1600
+#define OP_PCL_IPSEC_AES_CCM8 0x0e00
+#define OP_PCL_IPSEC_AES_CCM12 0x0f00
+#define OP_PCL_IPSEC_AES_CCM16 0x1000
+#define OP_PCL_IPSEC_AES_GCM8 0x1200
+#define OP_PCL_IPSEC_AES_GCM12 0x1300
+#define OP_PCL_IPSEC_AES_GCM16 0x1400
-#define OP_PCL_IPSEC_HMAC_NULL 0x0000
-#define OP_PCL_IPSEC_HMAC_MD5_96 0x0001
-#define OP_PCL_IPSEC_HMAC_SHA1_96 0x0002
-#define OP_PCL_IPSEC_AES_XCBC_MAC_96 0x0005
-#define OP_PCL_IPSEC_HMAC_MD5_128 0x0006
-#define OP_PCL_IPSEC_HMAC_SHA1_160 0x0007
-#define OP_PCL_IPSEC_HMAC_SHA2_256_128 0x000c
-#define OP_PCL_IPSEC_HMAC_SHA2_384_192 0x000d
-#define OP_PCL_IPSEC_HMAC_SHA2_512_256 0x000e
+#define OP_PCL_IPSEC_HMAC_NULL 0x0000
+#define OP_PCL_IPSEC_HMAC_MD5_96 0x0001
+#define OP_PCL_IPSEC_HMAC_SHA1_96 0x0002
+#define OP_PCL_IPSEC_AES_XCBC_MAC_96 0x0005
+#define OP_PCL_IPSEC_HMAC_MD5_128 0x0006
+#define OP_PCL_IPSEC_HMAC_SHA1_160 0x0007
+#define OP_PCL_IPSEC_HMAC_SHA2_256_128 0x000c
+#define OP_PCL_IPSEC_HMAC_SHA2_384_192 0x000d
+#define OP_PCL_IPSEC_HMAC_SHA2_512_256 0x000e
/* For SRTP - OP_PCLID_SRTP */
-#define OP_PCL_SRTP_CIPHER_MASK 0xff00
-#define OP_PCL_SRTP_AUTH_MASK 0x00ff
+#define OP_PCL_SRTP_CIPHER_MASK 0xff00
+#define OP_PCL_SRTP_AUTH_MASK 0x00ff
-#define OP_PCL_SRTP_AES_CTR 0x0d00
+#define OP_PCL_SRTP_AES_CTR 0x0d00
-#define OP_PCL_SRTP_HMAC_SHA1_160 0x0007
+#define OP_PCL_SRTP_HMAC_SHA1_160 0x0007
/* For SSL 3.0 - OP_PCLID_SSL30 */
-#define OP_PCL_SSL30_AES_128_CBC_SHA 0x002f
-#define OP_PCL_SSL30_AES_128_CBC_SHA_2 0x0030
-#define OP_PCL_SSL30_AES_128_CBC_SHA_3 0x0031
-#define OP_PCL_SSL30_AES_128_CBC_SHA_4 0x0032
-#define OP_PCL_SSL30_AES_128_CBC_SHA_5 0x0033
-#define OP_PCL_SSL30_AES_128_CBC_SHA_6 0x0034
-#define OP_PCL_SSL30_AES_128_CBC_SHA_7 0x008c
-#define OP_PCL_SSL30_AES_128_CBC_SHA_8 0x0090
-#define OP_PCL_SSL30_AES_128_CBC_SHA_9 0x0094
-#define OP_PCL_SSL30_AES_128_CBC_SHA_10 0xc004
-#define OP_PCL_SSL30_AES_128_CBC_SHA_11 0xc009
-#define OP_PCL_SSL30_AES_128_CBC_SHA_12 0xc00e
-#define OP_PCL_SSL30_AES_128_CBC_SHA_13 0xc013
-#define OP_PCL_SSL30_AES_128_CBC_SHA_14 0xc018
-#define OP_PCL_SSL30_AES_128_CBC_SHA_15 0xc01d
-#define OP_PCL_SSL30_AES_128_CBC_SHA_16 0xc01e
-#define OP_PCL_SSL30_AES_128_CBC_SHA_17 0xc01f
+#define OP_PCL_SSL30_AES_128_CBC_SHA 0x002f
+#define OP_PCL_SSL30_AES_128_CBC_SHA_2 0x0030
+#define OP_PCL_SSL30_AES_128_CBC_SHA_3 0x0031
+#define OP_PCL_SSL30_AES_128_CBC_SHA_4 0x0032
+#define OP_PCL_SSL30_AES_128_CBC_SHA_5 0x0033
+#define OP_PCL_SSL30_AES_128_CBC_SHA_6 0x0034
+#define OP_PCL_SSL30_AES_128_CBC_SHA_7 0x008c
+#define OP_PCL_SSL30_AES_128_CBC_SHA_8 0x0090
+#define OP_PCL_SSL30_AES_128_CBC_SHA_9 0x0094
+#define OP_PCL_SSL30_AES_128_CBC_SHA_10 0xc004
+#define OP_PCL_SSL30_AES_128_CBC_SHA_11 0xc009
+#define OP_PCL_SSL30_AES_128_CBC_SHA_12 0xc00e
+#define OP_PCL_SSL30_AES_128_CBC_SHA_13 0xc013
+#define OP_PCL_SSL30_AES_128_CBC_SHA_14 0xc018
+#define OP_PCL_SSL30_AES_128_CBC_SHA_15 0xc01d
+#define OP_PCL_SSL30_AES_128_CBC_SHA_16 0xc01e
+#define OP_PCL_SSL30_AES_128_CBC_SHA_17 0xc01f
-#define OP_PCL_SSL30_AES_256_CBC_SHA 0x0035
-#define OP_PCL_SSL30_AES_256_CBC_SHA_2 0x0036
-#define OP_PCL_SSL30_AES_256_CBC_SHA_3 0x0037
-#define OP_PCL_SSL30_AES_256_CBC_SHA_4 0x0038
-#define OP_PCL_SSL30_AES_256_CBC_SHA_5 0x0039
-#define OP_PCL_SSL30_AES_256_CBC_SHA_6 0x003a
-#define OP_PCL_SSL30_AES_256_CBC_SHA_7 0x008d
-#define OP_PCL_SSL30_AES_256_CBC_SHA_8 0x0091
-#define OP_PCL_SSL30_AES_256_CBC_SHA_9 0x0095
-#define OP_PCL_SSL30_AES_256_CBC_SHA_10 0xc005
-#define OP_PCL_SSL30_AES_256_CBC_SHA_11 0xc00a
-#define OP_PCL_SSL30_AES_256_CBC_SHA_12 0xc00f
-#define OP_PCL_SSL30_AES_256_CBC_SHA_13 0xc014
-#define OP_PCL_SSL30_AES_256_CBC_SHA_14 0xc019
-#define OP_PCL_SSL30_AES_256_CBC_SHA_15 0xc020
-#define OP_PCL_SSL30_AES_256_CBC_SHA_16 0xc021
-#define OP_PCL_SSL30_AES_256_CBC_SHA_17 0xc022
+#define OP_PCL_SSL30_AES_256_CBC_SHA 0x0035
+#define OP_PCL_SSL30_AES_256_CBC_SHA_2 0x0036
+#define OP_PCL_SSL30_AES_256_CBC_SHA_3 0x0037
+#define OP_PCL_SSL30_AES_256_CBC_SHA_4 0x0038
+#define OP_PCL_SSL30_AES_256_CBC_SHA_5 0x0039
+#define OP_PCL_SSL30_AES_256_CBC_SHA_6 0x003a
+#define OP_PCL_SSL30_AES_256_CBC_SHA_7 0x008d
+#define OP_PCL_SSL30_AES_256_CBC_SHA_8 0x0091
+#define OP_PCL_SSL30_AES_256_CBC_SHA_9 0x0095
+#define OP_PCL_SSL30_AES_256_CBC_SHA_10 0xc005
+#define OP_PCL_SSL30_AES_256_CBC_SHA_11 0xc00a
+#define OP_PCL_SSL30_AES_256_CBC_SHA_12 0xc00f
+#define OP_PCL_SSL30_AES_256_CBC_SHA_13 0xc014
+#define OP_PCL_SSL30_AES_256_CBC_SHA_14 0xc019
+#define OP_PCL_SSL30_AES_256_CBC_SHA_15 0xc020
+#define OP_PCL_SSL30_AES_256_CBC_SHA_16 0xc021
+#define OP_PCL_SSL30_AES_256_CBC_SHA_17 0xc022
-#define OP_PCL_SSL30_3DES_EDE_CBC_MD5 0x0023
+#define OP_PCL_SSL30_3DES_EDE_CBC_MD5 0x0023
-#define OP_PCL_SSL30_3DES_EDE_CBC_SHA 0x001f
-#define OP_PCL_SSL30_3DES_EDE_CBC_SHA_2 0x008b
-#define OP_PCL_SSL30_3DES_EDE_CBC_SHA_3 0x008f
-#define OP_PCL_SSL30_3DES_EDE_CBC_SHA_4 0x0093
-#define OP_PCL_SSL30_3DES_EDE_CBC_SHA_5 0x000a
-#define OP_PCL_SSL30_3DES_EDE_CBC_SHA_6 0x000d
-#define OP_PCL_SSL30_3DES_EDE_CBC_SHA_7 0x0010
-#define OP_PCL_SSL30_3DES_EDE_CBC_SHA_8 0x0013
-#define OP_PCL_SSL30_3DES_EDE_CBC_SHA_9 0x0016
-#define OP_PCL_SSL30_3DES_EDE_CBC_SHA_10 0x001b
-#define OP_PCL_SSL30_3DES_EDE_CBC_SHA_11 0xc003
-#define OP_PCL_SSL30_3DES_EDE_CBC_SHA_12 0xc008
-#define OP_PCL_SSL30_3DES_EDE_CBC_SHA_13 0xc00d
-#define OP_PCL_SSL30_3DES_EDE_CBC_SHA_14 0xc012
-#define OP_PCL_SSL30_3DES_EDE_CBC_SHA_15 0xc017
-#define OP_PCL_SSL30_3DES_EDE_CBC_SHA_16 0xc01a
-#define OP_PCL_SSL30_3DES_EDE_CBC_SHA_17 0xc01b
-#define OP_PCL_SSL30_3DES_EDE_CBC_SHA_18 0xc01c
+#define OP_PCL_SSL30_3DES_EDE_CBC_SHA 0x001f
+#define OP_PCL_SSL30_3DES_EDE_CBC_SHA_2 0x008b
+#define OP_PCL_SSL30_3DES_EDE_CBC_SHA_3 0x008f
+#define OP_PCL_SSL30_3DES_EDE_CBC_SHA_4 0x0093
+#define OP_PCL_SSL30_3DES_EDE_CBC_SHA_5 0x000a
+#define OP_PCL_SSL30_3DES_EDE_CBC_SHA_6 0x000d
+#define OP_PCL_SSL30_3DES_EDE_CBC_SHA_7 0x0010
+#define OP_PCL_SSL30_3DES_EDE_CBC_SHA_8 0x0013
+#define OP_PCL_SSL30_3DES_EDE_CBC_SHA_9 0x0016
+#define OP_PCL_SSL30_3DES_EDE_CBC_SHA_10 0x001b
+#define OP_PCL_SSL30_3DES_EDE_CBC_SHA_11 0xc003
+#define OP_PCL_SSL30_3DES_EDE_CBC_SHA_12 0xc008
+#define OP_PCL_SSL30_3DES_EDE_CBC_SHA_13 0xc00d
+#define OP_PCL_SSL30_3DES_EDE_CBC_SHA_14 0xc012
+#define OP_PCL_SSL30_3DES_EDE_CBC_SHA_15 0xc017
+#define OP_PCL_SSL30_3DES_EDE_CBC_SHA_16 0xc01a
+#define OP_PCL_SSL30_3DES_EDE_CBC_SHA_17 0xc01b
+#define OP_PCL_SSL30_3DES_EDE_CBC_SHA_18 0xc01c
-#define OP_PCL_SSL30_DES40_CBC_MD5 0x0029
+#define OP_PCL_SSL30_DES40_CBC_MD5 0x0029
-#define OP_PCL_SSL30_DES_CBC_MD5 0x0022
+#define OP_PCL_SSL30_DES_CBC_MD5 0x0022
-#define OP_PCL_SSL30_DES40_CBC_SHA 0x0008
-#define OP_PCL_SSL30_DES40_CBC_SHA_2 0x000b
-#define OP_PCL_SSL30_DES40_CBC_SHA_3 0x000e
-#define OP_PCL_SSL30_DES40_CBC_SHA_4 0x0011
-#define OP_PCL_SSL30_DES40_CBC_SHA_5 0x0014
-#define OP_PCL_SSL30_DES40_CBC_SHA_6 0x0019
-#define OP_PCL_SSL30_DES40_CBC_SHA_7 0x0026
+#define OP_PCL_SSL30_DES40_CBC_SHA 0x0008
+#define OP_PCL_SSL30_DES40_CBC_SHA_2 0x000b
+#define OP_PCL_SSL30_DES40_CBC_SHA_3 0x000e
+#define OP_PCL_SSL30_DES40_CBC_SHA_4 0x0011
+#define OP_PCL_SSL30_DES40_CBC_SHA_5 0x0014
+#define OP_PCL_SSL30_DES40_CBC_SHA_6 0x0019
+#define OP_PCL_SSL30_DES40_CBC_SHA_7 0x0026
-#define OP_PCL_SSL30_DES_CBC_SHA 0x001e
-#define OP_PCL_SSL30_DES_CBC_SHA_2 0x0009
-#define OP_PCL_SSL30_DES_CBC_SHA_3 0x000c
-#define OP_PCL_SSL30_DES_CBC_SHA_4 0x000f
-#define OP_PCL_SSL30_DES_CBC_SHA_5 0x0012
-#define OP_PCL_SSL30_DES_CBC_SHA_6 0x0015
-#define OP_PCL_SSL30_DES_CBC_SHA_7 0x001a
+#define OP_PCL_SSL30_DES_CBC_SHA 0x001e
+#define OP_PCL_SSL30_DES_CBC_SHA_2 0x0009
+#define OP_PCL_SSL30_DES_CBC_SHA_3 0x000c
+#define OP_PCL_SSL30_DES_CBC_SHA_4 0x000f
+#define OP_PCL_SSL30_DES_CBC_SHA_5 0x0012
+#define OP_PCL_SSL30_DES_CBC_SHA_6 0x0015
+#define OP_PCL_SSL30_DES_CBC_SHA_7 0x001a
-#define OP_PCL_SSL30_RC4_128_MD5 0x0024
-#define OP_PCL_SSL30_RC4_128_MD5_2 0x0004
-#define OP_PCL_SSL30_RC4_128_MD5_3 0x0018
+#define OP_PCL_SSL30_RC4_128_MD5 0x0024
+#define OP_PCL_SSL30_RC4_128_MD5_2 0x0004
+#define OP_PCL_SSL30_RC4_128_MD5_3 0x0018
-#define OP_PCL_SSL30_RC4_40_MD5 0x002b
-#define OP_PCL_SSL30_RC4_40_MD5_2 0x0003
-#define OP_PCL_SSL30_RC4_40_MD5_3 0x0017
+#define OP_PCL_SSL30_RC4_40_MD5 0x002b
+#define OP_PCL_SSL30_RC4_40_MD5_2 0x0003
+#define OP_PCL_SSL30_RC4_40_MD5_3 0x0017
-#define OP_PCL_SSL30_RC4_128_SHA 0x0020
-#define OP_PCL_SSL30_RC4_128_SHA_2 0x008a
-#define OP_PCL_SSL30_RC4_128_SHA_3 0x008e
-#define OP_PCL_SSL30_RC4_128_SHA_4 0x0092
-#define OP_PCL_SSL30_RC4_128_SHA_5 0x0005
-#define OP_PCL_SSL30_RC4_128_SHA_6 0xc002
-#define OP_PCL_SSL30_RC4_128_SHA_7 0xc007
-#define OP_PCL_SSL30_RC4_128_SHA_8 0xc00c
-#define OP_PCL_SSL30_RC4_128_SHA_9 0xc011
-#define OP_PCL_SSL30_RC4_128_SHA_10 0xc016
+#define OP_PCL_SSL30_RC4_128_SHA 0x0020
+#define OP_PCL_SSL30_RC4_128_SHA_2 0x008a
+#define OP_PCL_SSL30_RC4_128_SHA_3 0x008e
+#define OP_PCL_SSL30_RC4_128_SHA_4 0x0092
+#define OP_PCL_SSL30_RC4_128_SHA_5 0x0005
+#define OP_PCL_SSL30_RC4_128_SHA_6 0xc002
+#define OP_PCL_SSL30_RC4_128_SHA_7 0xc007
+#define OP_PCL_SSL30_RC4_128_SHA_8 0xc00c
+#define OP_PCL_SSL30_RC4_128_SHA_9 0xc011
+#define OP_PCL_SSL30_RC4_128_SHA_10 0xc016
-#define OP_PCL_SSL30_RC4_40_SHA 0x0028
+#define OP_PCL_SSL30_RC4_40_SHA 0x0028
/* For TLS 1.0 - OP_PCLID_TLS10 */
-#define OP_PCL_TLS10_AES_128_CBC_SHA 0x002f
-#define OP_PCL_TLS10_AES_128_CBC_SHA_2 0x0030
-#define OP_PCL_TLS10_AES_128_CBC_SHA_3 0x0031
-#define OP_PCL_TLS10_AES_128_CBC_SHA_4 0x0032
-#define OP_PCL_TLS10_AES_128_CBC_SHA_5 0x0033
-#define OP_PCL_TLS10_AES_128_CBC_SHA_6 0x0034
-#define OP_PCL_TLS10_AES_128_CBC_SHA_7 0x008c
-#define OP_PCL_TLS10_AES_128_CBC_SHA_8 0x0090
-#define OP_PCL_TLS10_AES_128_CBC_SHA_9 0x0094
-#define OP_PCL_TLS10_AES_128_CBC_SHA_10 0xc004
-#define OP_PCL_TLS10_AES_128_CBC_SHA_11 0xc009
-#define OP_PCL_TLS10_AES_128_CBC_SHA_12 0xc00e
-#define OP_PCL_TLS10_AES_128_CBC_SHA_13 0xc013
-#define OP_PCL_TLS10_AES_128_CBC_SHA_14 0xc018
-#define OP_PCL_TLS10_AES_128_CBC_SHA_15 0xc01d
-#define OP_PCL_TLS10_AES_128_CBC_SHA_16 0xc01e
-#define OP_PCL_TLS10_AES_128_CBC_SHA_17 0xc01f
+#define OP_PCL_TLS10_AES_128_CBC_SHA 0x002f
+#define OP_PCL_TLS10_AES_128_CBC_SHA_2 0x0030
+#define OP_PCL_TLS10_AES_128_CBC_SHA_3 0x0031
+#define OP_PCL_TLS10_AES_128_CBC_SHA_4 0x0032
+#define OP_PCL_TLS10_AES_128_CBC_SHA_5 0x0033
+#define OP_PCL_TLS10_AES_128_CBC_SHA_6 0x0034
+#define OP_PCL_TLS10_AES_128_CBC_SHA_7 0x008c
+#define OP_PCL_TLS10_AES_128_CBC_SHA_8 0x0090
+#define OP_PCL_TLS10_AES_128_CBC_SHA_9 0x0094
+#define OP_PCL_TLS10_AES_128_CBC_SHA_10 0xc004
+#define OP_PCL_TLS10_AES_128_CBC_SHA_11 0xc009
+#define OP_PCL_TLS10_AES_128_CBC_SHA_12 0xc00e
+#define OP_PCL_TLS10_AES_128_CBC_SHA_13 0xc013
+#define OP_PCL_TLS10_AES_128_CBC_SHA_14 0xc018
+#define OP_PCL_TLS10_AES_128_CBC_SHA_15 0xc01d
+#define OP_PCL_TLS10_AES_128_CBC_SHA_16 0xc01e
+#define OP_PCL_TLS10_AES_128_CBC_SHA_17 0xc01f
-#define OP_PCL_TLS10_AES_256_CBC_SHA 0x0035
-#define OP_PCL_TLS10_AES_256_CBC_SHA_2 0x0036
-#define OP_PCL_TLS10_AES_256_CBC_SHA_3 0x0037
-#define OP_PCL_TLS10_AES_256_CBC_SHA_4 0x0038
-#define OP_PCL_TLS10_AES_256_CBC_SHA_5 0x0039
-#define OP_PCL_TLS10_AES_256_CBC_SHA_6 0x003a
-#define OP_PCL_TLS10_AES_256_CBC_SHA_7 0x008d
-#define OP_PCL_TLS10_AES_256_CBC_SHA_8 0x0091
-#define OP_PCL_TLS10_AES_256_CBC_SHA_9 0x0095
-#define OP_PCL_TLS10_AES_256_CBC_SHA_10 0xc005
-#define OP_PCL_TLS10_AES_256_CBC_SHA_11 0xc00a
-#define OP_PCL_TLS10_AES_256_CBC_SHA_12 0xc00f
-#define OP_PCL_TLS10_AES_256_CBC_SHA_13 0xc014
-#define OP_PCL_TLS10_AES_256_CBC_SHA_14 0xc019
-#define OP_PCL_TLS10_AES_256_CBC_SHA_15 0xc020
-#define OP_PCL_TLS10_AES_256_CBC_SHA_16 0xc021
-#define OP_PCL_TLS10_AES_256_CBC_SHA_17 0xc022
+#define OP_PCL_TLS10_AES_256_CBC_SHA 0x0035
+#define OP_PCL_TLS10_AES_256_CBC_SHA_2 0x0036
+#define OP_PCL_TLS10_AES_256_CBC_SHA_3 0x0037
+#define OP_PCL_TLS10_AES_256_CBC_SHA_4 0x0038
+#define OP_PCL_TLS10_AES_256_CBC_SHA_5 0x0039
+#define OP_PCL_TLS10_AES_256_CBC_SHA_6 0x003a
+#define OP_PCL_TLS10_AES_256_CBC_SHA_7 0x008d
+#define OP_PCL_TLS10_AES_256_CBC_SHA_8 0x0091
+#define OP_PCL_TLS10_AES_256_CBC_SHA_9 0x0095
+#define OP_PCL_TLS10_AES_256_CBC_SHA_10 0xc005
+#define OP_PCL_TLS10_AES_256_CBC_SHA_11 0xc00a
+#define OP_PCL_TLS10_AES_256_CBC_SHA_12 0xc00f
+#define OP_PCL_TLS10_AES_256_CBC_SHA_13 0xc014
+#define OP_PCL_TLS10_AES_256_CBC_SHA_14 0xc019
+#define OP_PCL_TLS10_AES_256_CBC_SHA_15 0xc020
+#define OP_PCL_TLS10_AES_256_CBC_SHA_16 0xc021
+#define OP_PCL_TLS10_AES_256_CBC_SHA_17 0xc022
-/* #define OP_PCL_TLS10_3DES_EDE_CBC_MD5 0x0023 */
+/* #define OP_PCL_TLS10_3DES_EDE_CBC_MD5 0x0023 */
-#define OP_PCL_TLS10_3DES_EDE_CBC_SHA 0x001f
-#define OP_PCL_TLS10_3DES_EDE_CBC_SHA_2 0x008b
-#define OP_PCL_TLS10_3DES_EDE_CBC_SHA_3 0x008f
-#define OP_PCL_TLS10_3DES_EDE_CBC_SHA_4 0x0093
-#define OP_PCL_TLS10_3DES_EDE_CBC_SHA_5 0x000a
-#define OP_PCL_TLS10_3DES_EDE_CBC_SHA_6 0x000d
-#define OP_PCL_TLS10_3DES_EDE_CBC_SHA_7 0x0010
-#define OP_PCL_TLS10_3DES_EDE_CBC_SHA_8 0x0013
-#define OP_PCL_TLS10_3DES_EDE_CBC_SHA_9 0x0016
-#define OP_PCL_TLS10_3DES_EDE_CBC_SHA_10 0x001b
-#define OP_PCL_TLS10_3DES_EDE_CBC_SHA_11 0xc003
-#define OP_PCL_TLS10_3DES_EDE_CBC_SHA_12 0xc008
-#define OP_PCL_TLS10_3DES_EDE_CBC_SHA_13 0xc00d
-#define OP_PCL_TLS10_3DES_EDE_CBC_SHA_14 0xc012
-#define OP_PCL_TLS10_3DES_EDE_CBC_SHA_15 0xc017
-#define OP_PCL_TLS10_3DES_EDE_CBC_SHA_16 0xc01a
-#define OP_PCL_TLS10_3DES_EDE_CBC_SHA_17 0xc01b
-#define OP_PCL_TLS10_3DES_EDE_CBC_SHA_18 0xc01c
+#define OP_PCL_TLS10_3DES_EDE_CBC_SHA 0x001f
+#define OP_PCL_TLS10_3DES_EDE_CBC_SHA_2 0x008b
+#define OP_PCL_TLS10_3DES_EDE_CBC_SHA_3 0x008f
+#define OP_PCL_TLS10_3DES_EDE_CBC_SHA_4 0x0093
+#define OP_PCL_TLS10_3DES_EDE_CBC_SHA_5 0x000a
+#define OP_PCL_TLS10_3DES_EDE_CBC_SHA_6 0x000d
+#define OP_PCL_TLS10_3DES_EDE_CBC_SHA_7 0x0010
+#define OP_PCL_TLS10_3DES_EDE_CBC_SHA_8 0x0013
+#define OP_PCL_TLS10_3DES_EDE_CBC_SHA_9 0x0016
+#define OP_PCL_TLS10_3DES_EDE_CBC_SHA_10 0x001b
+#define OP_PCL_TLS10_3DES_EDE_CBC_SHA_11 0xc003
+#define OP_PCL_TLS10_3DES_EDE_CBC_SHA_12 0xc008
+#define OP_PCL_TLS10_3DES_EDE_CBC_SHA_13 0xc00d
+#define OP_PCL_TLS10_3DES_EDE_CBC_SHA_14 0xc012
+#define OP_PCL_TLS10_3DES_EDE_CBC_SHA_15 0xc017
+#define OP_PCL_TLS10_3DES_EDE_CBC_SHA_16 0xc01a
+#define OP_PCL_TLS10_3DES_EDE_CBC_SHA_17 0xc01b
+#define OP_PCL_TLS10_3DES_EDE_CBC_SHA_18 0xc01c
-#define OP_PCL_TLS10_DES40_CBC_MD5 0x0029
+#define OP_PCL_TLS10_DES40_CBC_MD5 0x0029
-#define OP_PCL_TLS10_DES_CBC_MD5 0x0022
+#define OP_PCL_TLS10_DES_CBC_MD5 0x0022
-#define OP_PCL_TLS10_DES40_CBC_SHA 0x0008
-#define OP_PCL_TLS10_DES40_CBC_SHA_2 0x000b
-#define OP_PCL_TLS10_DES40_CBC_SHA_3 0x000e
-#define OP_PCL_TLS10_DES40_CBC_SHA_4 0x0011
-#define OP_PCL_TLS10_DES40_CBC_SHA_5 0x0014
-#define OP_PCL_TLS10_DES40_CBC_SHA_6 0x0019
-#define OP_PCL_TLS10_DES40_CBC_SHA_7 0x0026
+#define OP_PCL_TLS10_DES40_CBC_SHA 0x0008
+#define OP_PCL_TLS10_DES40_CBC_SHA_2 0x000b
+#define OP_PCL_TLS10_DES40_CBC_SHA_3 0x000e
+#define OP_PCL_TLS10_DES40_CBC_SHA_4 0x0011
+#define OP_PCL_TLS10_DES40_CBC_SHA_5 0x0014
+#define OP_PCL_TLS10_DES40_CBC_SHA_6 0x0019
+#define OP_PCL_TLS10_DES40_CBC_SHA_7 0x0026
-#define OP_PCL_TLS10_DES_CBC_SHA 0x001e
-#define OP_PCL_TLS10_DES_CBC_SHA_2 0x0009
-#define OP_PCL_TLS10_DES_CBC_SHA_3 0x000c
-#define OP_PCL_TLS10_DES_CBC_SHA_4 0x000f
-#define OP_PCL_TLS10_DES_CBC_SHA_5 0x0012
-#define OP_PCL_TLS10_DES_CBC_SHA_6 0x0015
-#define OP_PCL_TLS10_DES_CBC_SHA_7 0x001a
+#define OP_PCL_TLS10_DES_CBC_SHA 0x001e
+#define OP_PCL_TLS10_DES_CBC_SHA_2 0x0009
+#define OP_PCL_TLS10_DES_CBC_SHA_3 0x000c
+#define OP_PCL_TLS10_DES_CBC_SHA_4 0x000f
+#define OP_PCL_TLS10_DES_CBC_SHA_5 0x0012
+#define OP_PCL_TLS10_DES_CBC_SHA_6 0x0015
+#define OP_PCL_TLS10_DES_CBC_SHA_7 0x001a
-#define OP_PCL_TLS10_RC4_128_MD5 0x0024
-#define OP_PCL_TLS10_RC4_128_MD5_2 0x0004
-#define OP_PCL_TLS10_RC4_128_MD5_3 0x0018
+#define OP_PCL_TLS10_RC4_128_MD5 0x0024
+#define OP_PCL_TLS10_RC4_128_MD5_2 0x0004
+#define OP_PCL_TLS10_RC4_128_MD5_3 0x0018
-#define OP_PCL_TLS10_RC4_40_MD5 0x002b
-#define OP_PCL_TLS10_RC4_40_MD5_2 0x0003
-#define OP_PCL_TLS10_RC4_40_MD5_3 0x0017
+#define OP_PCL_TLS10_RC4_40_MD5 0x002b
+#define OP_PCL_TLS10_RC4_40_MD5_2 0x0003
+#define OP_PCL_TLS10_RC4_40_MD5_3 0x0017
-#define OP_PCL_TLS10_RC4_128_SHA 0x0020
-#define OP_PCL_TLS10_RC4_128_SHA_2 0x008a
-#define OP_PCL_TLS10_RC4_128_SHA_3 0x008e
-#define OP_PCL_TLS10_RC4_128_SHA_4 0x0092
-#define OP_PCL_TLS10_RC4_128_SHA_5 0x0005
-#define OP_PCL_TLS10_RC4_128_SHA_6 0xc002
-#define OP_PCL_TLS10_RC4_128_SHA_7 0xc007
-#define OP_PCL_TLS10_RC4_128_SHA_8 0xc00c
-#define OP_PCL_TLS10_RC4_128_SHA_9 0xc011
-#define OP_PCL_TLS10_RC4_128_SHA_10 0xc016
+#define OP_PCL_TLS10_RC4_128_SHA 0x0020
+#define OP_PCL_TLS10_RC4_128_SHA_2 0x008a
+#define OP_PCL_TLS10_RC4_128_SHA_3 0x008e
+#define OP_PCL_TLS10_RC4_128_SHA_4 0x0092
+#define OP_PCL_TLS10_RC4_128_SHA_5 0x0005
+#define OP_PCL_TLS10_RC4_128_SHA_6 0xc002
+#define OP_PCL_TLS10_RC4_128_SHA_7 0xc007
+#define OP_PCL_TLS10_RC4_128_SHA_8 0xc00c
+#define OP_PCL_TLS10_RC4_128_SHA_9 0xc011
+#define OP_PCL_TLS10_RC4_128_SHA_10 0xc016
-#define OP_PCL_TLS10_RC4_40_SHA 0x0028
+#define OP_PCL_TLS10_RC4_40_SHA 0x0028
-#define OP_PCL_TLS10_3DES_EDE_CBC_MD5 0xff23
-#define OP_PCL_TLS10_3DES_EDE_CBC_SHA160 0xff30
-#define OP_PCL_TLS10_3DES_EDE_CBC_SHA224 0xff34
-#define OP_PCL_TLS10_3DES_EDE_CBC_SHA256 0xff36
-#define OP_PCL_TLS10_3DES_EDE_CBC_SHA384 0xff33
-#define OP_PCL_TLS10_3DES_EDE_CBC_SHA512 0xff35
-#define OP_PCL_TLS10_AES_128_CBC_SHA160 0xff80
-#define OP_PCL_TLS10_AES_128_CBC_SHA224 0xff84
-#define OP_PCL_TLS10_AES_128_CBC_SHA256 0xff86
-#define OP_PCL_TLS10_AES_128_CBC_SHA384 0xff83
-#define OP_PCL_TLS10_AES_128_CBC_SHA512 0xff85
-#define OP_PCL_TLS10_AES_192_CBC_SHA160 0xff20
-#define OP_PCL_TLS10_AES_192_CBC_SHA224 0xff24
-#define OP_PCL_TLS10_AES_192_CBC_SHA256 0xff26
-#define OP_PCL_TLS10_AES_192_CBC_SHA384 0xff23
-#define OP_PCL_TLS10_AES_192_CBC_SHA512 0xff25
-#define OP_PCL_TLS10_AES_256_CBC_SHA160 0xff60
-#define OP_PCL_TLS10_AES_256_CBC_SHA224 0xff64
-#define OP_PCL_TLS10_AES_256_CBC_SHA256 0xff66
-#define OP_PCL_TLS10_AES_256_CBC_SHA384 0xff63
-#define OP_PCL_TLS10_AES_256_CBC_SHA512 0xff65
+#define OP_PCL_TLS10_3DES_EDE_CBC_MD5 0xff23
+#define OP_PCL_TLS10_3DES_EDE_CBC_SHA160 0xff30
+#define OP_PCL_TLS10_3DES_EDE_CBC_SHA224 0xff34
+#define OP_PCL_TLS10_3DES_EDE_CBC_SHA256 0xff36
+#define OP_PCL_TLS10_3DES_EDE_CBC_SHA384 0xff33
+#define OP_PCL_TLS10_3DES_EDE_CBC_SHA512 0xff35
+#define OP_PCL_TLS10_AES_128_CBC_SHA160 0xff80
+#define OP_PCL_TLS10_AES_128_CBC_SHA224 0xff84
+#define OP_PCL_TLS10_AES_128_CBC_SHA256 0xff86
+#define OP_PCL_TLS10_AES_128_CBC_SHA384 0xff83
+#define OP_PCL_TLS10_AES_128_CBC_SHA512 0xff85
+#define OP_PCL_TLS10_AES_192_CBC_SHA160 0xff20
+#define OP_PCL_TLS10_AES_192_CBC_SHA224 0xff24
+#define OP_PCL_TLS10_AES_192_CBC_SHA256 0xff26
+#define OP_PCL_TLS10_AES_192_CBC_SHA384 0xff23
+#define OP_PCL_TLS10_AES_192_CBC_SHA512 0xff25
+#define OP_PCL_TLS10_AES_256_CBC_SHA160 0xff60
+#define OP_PCL_TLS10_AES_256_CBC_SHA224 0xff64
+#define OP_PCL_TLS10_AES_256_CBC_SHA256 0xff66
+#define OP_PCL_TLS10_AES_256_CBC_SHA384 0xff63
+#define OP_PCL_TLS10_AES_256_CBC_SHA512 0xff65
/* For TLS 1.1 - OP_PCLID_TLS11 */
-#define OP_PCL_TLS11_AES_128_CBC_SHA 0x002f
-#define OP_PCL_TLS11_AES_128_CBC_SHA_2 0x0030
-#define OP_PCL_TLS11_AES_128_CBC_SHA_3 0x0031
-#define OP_PCL_TLS11_AES_128_CBC_SHA_4 0x0032
-#define OP_PCL_TLS11_AES_128_CBC_SHA_5 0x0033
-#define OP_PCL_TLS11_AES_128_CBC_SHA_6 0x0034
-#define OP_PCL_TLS11_AES_128_CBC_SHA_7 0x008c
-#define OP_PCL_TLS11_AES_128_CBC_SHA_8 0x0090
-#define OP_PCL_TLS11_AES_128_CBC_SHA_9 0x0094
-#define OP_PCL_TLS11_AES_128_CBC_SHA_10 0xc004
-#define OP_PCL_TLS11_AES_128_CBC_SHA_11 0xc009
-#define OP_PCL_TLS11_AES_128_CBC_SHA_12 0xc00e
-#define OP_PCL_TLS11_AES_128_CBC_SHA_13 0xc013
-#define OP_PCL_TLS11_AES_128_CBC_SHA_14 0xc018
-#define OP_PCL_TLS11_AES_128_CBC_SHA_15 0xc01d
-#define OP_PCL_TLS11_AES_128_CBC_SHA_16 0xc01e
-#define OP_PCL_TLS11_AES_128_CBC_SHA_17 0xc01f
+#define OP_PCL_TLS11_AES_128_CBC_SHA 0x002f
+#define OP_PCL_TLS11_AES_128_CBC_SHA_2 0x0030
+#define OP_PCL_TLS11_AES_128_CBC_SHA_3 0x0031
+#define OP_PCL_TLS11_AES_128_CBC_SHA_4 0x0032
+#define OP_PCL_TLS11_AES_128_CBC_SHA_5 0x0033
+#define OP_PCL_TLS11_AES_128_CBC_SHA_6 0x0034
+#define OP_PCL_TLS11_AES_128_CBC_SHA_7 0x008c
+#define OP_PCL_TLS11_AES_128_CBC_SHA_8 0x0090
+#define OP_PCL_TLS11_AES_128_CBC_SHA_9 0x0094
+#define OP_PCL_TLS11_AES_128_CBC_SHA_10 0xc004
+#define OP_PCL_TLS11_AES_128_CBC_SHA_11 0xc009
+#define OP_PCL_TLS11_AES_128_CBC_SHA_12 0xc00e
+#define OP_PCL_TLS11_AES_128_CBC_SHA_13 0xc013
+#define OP_PCL_TLS11_AES_128_CBC_SHA_14 0xc018
+#define OP_PCL_TLS11_AES_128_CBC_SHA_15 0xc01d
+#define OP_PCL_TLS11_AES_128_CBC_SHA_16 0xc01e
+#define OP_PCL_TLS11_AES_128_CBC_SHA_17 0xc01f
-#define OP_PCL_TLS11_AES_256_CBC_SHA 0x0035
-#define OP_PCL_TLS11_AES_256_CBC_SHA_2 0x0036
-#define OP_PCL_TLS11_AES_256_CBC_SHA_3 0x0037
-#define OP_PCL_TLS11_AES_256_CBC_SHA_4 0x0038
-#define OP_PCL_TLS11_AES_256_CBC_SHA_5 0x0039
-#define OP_PCL_TLS11_AES_256_CBC_SHA_6 0x003a
-#define OP_PCL_TLS11_AES_256_CBC_SHA_7 0x008d
-#define OP_PCL_TLS11_AES_256_CBC_SHA_8 0x0091
-#define OP_PCL_TLS11_AES_256_CBC_SHA_9 0x0095
-#define OP_PCL_TLS11_AES_256_CBC_SHA_10 0xc005
-#define OP_PCL_TLS11_AES_256_CBC_SHA_11 0xc00a
-#define OP_PCL_TLS11_AES_256_CBC_SHA_12 0xc00f
-#define OP_PCL_TLS11_AES_256_CBC_SHA_13 0xc014
-#define OP_PCL_TLS11_AES_256_CBC_SHA_14 0xc019
-#define OP_PCL_TLS11_AES_256_CBC_SHA_15 0xc020
-#define OP_PCL_TLS11_AES_256_CBC_SHA_16 0xc021
-#define OP_PCL_TLS11_AES_256_CBC_SHA_17 0xc022
+#define OP_PCL_TLS11_AES_256_CBC_SHA 0x0035
+#define OP_PCL_TLS11_AES_256_CBC_SHA_2 0x0036
+#define OP_PCL_TLS11_AES_256_CBC_SHA_3 0x0037
+#define OP_PCL_TLS11_AES_256_CBC_SHA_4 0x0038
+#define OP_PCL_TLS11_AES_256_CBC_SHA_5 0x0039
+#define OP_PCL_TLS11_AES_256_CBC_SHA_6 0x003a
+#define OP_PCL_TLS11_AES_256_CBC_SHA_7 0x008d
+#define OP_PCL_TLS11_AES_256_CBC_SHA_8 0x0091
+#define OP_PCL_TLS11_AES_256_CBC_SHA_9 0x0095
+#define OP_PCL_TLS11_AES_256_CBC_SHA_10 0xc005
+#define OP_PCL_TLS11_AES_256_CBC_SHA_11 0xc00a
+#define OP_PCL_TLS11_AES_256_CBC_SHA_12 0xc00f
+#define OP_PCL_TLS11_AES_256_CBC_SHA_13 0xc014
+#define OP_PCL_TLS11_AES_256_CBC_SHA_14 0xc019
+#define OP_PCL_TLS11_AES_256_CBC_SHA_15 0xc020
+#define OP_PCL_TLS11_AES_256_CBC_SHA_16 0xc021
+#define OP_PCL_TLS11_AES_256_CBC_SHA_17 0xc022
-/* #define OP_PCL_TLS11_3DES_EDE_CBC_MD5 0x0023 */
+/* #define OP_PCL_TLS11_3DES_EDE_CBC_MD5 0x0023 */
-#define OP_PCL_TLS11_3DES_EDE_CBC_SHA 0x001f
-#define OP_PCL_TLS11_3DES_EDE_CBC_SHA_2 0x008b
-#define OP_PCL_TLS11_3DES_EDE_CBC_SHA_3 0x008f
-#define OP_PCL_TLS11_3DES_EDE_CBC_SHA_4 0x0093
-#define OP_PCL_TLS11_3DES_EDE_CBC_SHA_5 0x000a
-#define OP_PCL_TLS11_3DES_EDE_CBC_SHA_6 0x000d
-#define OP_PCL_TLS11_3DES_EDE_CBC_SHA_7 0x0010
-#define OP_PCL_TLS11_3DES_EDE_CBC_SHA_8 0x0013
-#define OP_PCL_TLS11_3DES_EDE_CBC_SHA_9 0x0016
-#define OP_PCL_TLS11_3DES_EDE_CBC_SHA_10 0x001b
-#define OP_PCL_TLS11_3DES_EDE_CBC_SHA_11 0xc003
-#define OP_PCL_TLS11_3DES_EDE_CBC_SHA_12 0xc008
-#define OP_PCL_TLS11_3DES_EDE_CBC_SHA_13 0xc00d
-#define OP_PCL_TLS11_3DES_EDE_CBC_SHA_14 0xc012
-#define OP_PCL_TLS11_3DES_EDE_CBC_SHA_15 0xc017
-#define OP_PCL_TLS11_3DES_EDE_CBC_SHA_16 0xc01a
-#define OP_PCL_TLS11_3DES_EDE_CBC_SHA_17 0xc01b
-#define OP_PCL_TLS11_3DES_EDE_CBC_SHA_18 0xc01c
+#define OP_PCL_TLS11_3DES_EDE_CBC_SHA 0x001f
+#define OP_PCL_TLS11_3DES_EDE_CBC_SHA_2 0x008b
+#define OP_PCL_TLS11_3DES_EDE_CBC_SHA_3 0x008f
+#define OP_PCL_TLS11_3DES_EDE_CBC_SHA_4 0x0093
+#define OP_PCL_TLS11_3DES_EDE_CBC_SHA_5 0x000a
+#define OP_PCL_TLS11_3DES_EDE_CBC_SHA_6 0x000d
+#define OP_PCL_TLS11_3DES_EDE_CBC_SHA_7 0x0010
+#define OP_PCL_TLS11_3DES_EDE_CBC_SHA_8 0x0013
+#define OP_PCL_TLS11_3DES_EDE_CBC_SHA_9 0x0016
+#define OP_PCL_TLS11_3DES_EDE_CBC_SHA_10 0x001b
+#define OP_PCL_TLS11_3DES_EDE_CBC_SHA_11 0xc003
+#define OP_PCL_TLS11_3DES_EDE_CBC_SHA_12 0xc008
+#define OP_PCL_TLS11_3DES_EDE_CBC_SHA_13 0xc00d
+#define OP_PCL_TLS11_3DES_EDE_CBC_SHA_14 0xc012
+#define OP_PCL_TLS11_3DES_EDE_CBC_SHA_15 0xc017
+#define OP_PCL_TLS11_3DES_EDE_CBC_SHA_16 0xc01a
+#define OP_PCL_TLS11_3DES_EDE_CBC_SHA_17 0xc01b
+#define OP_PCL_TLS11_3DES_EDE_CBC_SHA_18 0xc01c
-#define OP_PCL_TLS11_DES40_CBC_MD5 0x0029
+#define OP_PCL_TLS11_DES40_CBC_MD5 0x0029
-#define OP_PCL_TLS11_DES_CBC_MD5 0x0022
+#define OP_PCL_TLS11_DES_CBC_MD5 0x0022
-#define OP_PCL_TLS11_DES40_CBC_SHA 0x0008
-#define OP_PCL_TLS11_DES40_CBC_SHA_2 0x000b
-#define OP_PCL_TLS11_DES40_CBC_SHA_3 0x000e
-#define OP_PCL_TLS11_DES40_CBC_SHA_4 0x0011
-#define OP_PCL_TLS11_DES40_CBC_SHA_5 0x0014
-#define OP_PCL_TLS11_DES40_CBC_SHA_6 0x0019
-#define OP_PCL_TLS11_DES40_CBC_SHA_7 0x0026
+#define OP_PCL_TLS11_DES40_CBC_SHA 0x0008
+#define OP_PCL_TLS11_DES40_CBC_SHA_2 0x000b
+#define OP_PCL_TLS11_DES40_CBC_SHA_3 0x000e
+#define OP_PCL_TLS11_DES40_CBC_SHA_4 0x0011
+#define OP_PCL_TLS11_DES40_CBC_SHA_5 0x0014
+#define OP_PCL_TLS11_DES40_CBC_SHA_6 0x0019
+#define OP_PCL_TLS11_DES40_CBC_SHA_7 0x0026
-#define OP_PCL_TLS11_DES_CBC_SHA 0x001e
-#define OP_PCL_TLS11_DES_CBC_SHA_2 0x0009
-#define OP_PCL_TLS11_DES_CBC_SHA_3 0x000c
-#define OP_PCL_TLS11_DES_CBC_SHA_4 0x000f
-#define OP_PCL_TLS11_DES_CBC_SHA_5 0x0012
-#define OP_PCL_TLS11_DES_CBC_SHA_6 0x0015
-#define OP_PCL_TLS11_DES_CBC_SHA_7 0x001a
+#define OP_PCL_TLS11_DES_CBC_SHA 0x001e
+#define OP_PCL_TLS11_DES_CBC_SHA_2 0x0009
+#define OP_PCL_TLS11_DES_CBC_SHA_3 0x000c
+#define OP_PCL_TLS11_DES_CBC_SHA_4 0x000f
+#define OP_PCL_TLS11_DES_CBC_SHA_5 0x0012
+#define OP_PCL_TLS11_DES_CBC_SHA_6 0x0015
+#define OP_PCL_TLS11_DES_CBC_SHA_7 0x001a
-#define OP_PCL_TLS11_RC4_128_MD5 0x0024
-#define OP_PCL_TLS11_RC4_128_MD5_2 0x0004
-#define OP_PCL_TLS11_RC4_128_MD5_3 0x0018
+#define OP_PCL_TLS11_RC4_128_MD5 0x0024
+#define OP_PCL_TLS11_RC4_128_MD5_2 0x0004
+#define OP_PCL_TLS11_RC4_128_MD5_3 0x0018
-#define OP_PCL_TLS11_RC4_40_MD5 0x002b
-#define OP_PCL_TLS11_RC4_40_MD5_2 0x0003
-#define OP_PCL_TLS11_RC4_40_MD5_3 0x0017
+#define OP_PCL_TLS11_RC4_40_MD5 0x002b
+#define OP_PCL_TLS11_RC4_40_MD5_2 0x0003
+#define OP_PCL_TLS11_RC4_40_MD5_3 0x0017
-#define OP_PCL_TLS11_RC4_128_SHA 0x0020
-#define OP_PCL_TLS11_RC4_128_SHA_2 0x008a
-#define OP_PCL_TLS11_RC4_128_SHA_3 0x008e
-#define OP_PCL_TLS11_RC4_128_SHA_4 0x0092
-#define OP_PCL_TLS11_RC4_128_SHA_5 0x0005
-#define OP_PCL_TLS11_RC4_128_SHA_6 0xc002
-#define OP_PCL_TLS11_RC4_128_SHA_7 0xc007
-#define OP_PCL_TLS11_RC4_128_SHA_8 0xc00c
-#define OP_PCL_TLS11_RC4_128_SHA_9 0xc011
-#define OP_PCL_TLS11_RC4_128_SHA_10 0xc016
+#define OP_PCL_TLS11_RC4_128_SHA 0x0020
+#define OP_PCL_TLS11_RC4_128_SHA_2 0x008a
+#define OP_PCL_TLS11_RC4_128_SHA_3 0x008e
+#define OP_PCL_TLS11_RC4_128_SHA_4 0x0092
+#define OP_PCL_TLS11_RC4_128_SHA_5 0x0005
+#define OP_PCL_TLS11_RC4_128_SHA_6 0xc002
+#define OP_PCL_TLS11_RC4_128_SHA_7 0xc007
+#define OP_PCL_TLS11_RC4_128_SHA_8 0xc00c
+#define OP_PCL_TLS11_RC4_128_SHA_9 0xc011
+#define OP_PCL_TLS11_RC4_128_SHA_10 0xc016
-#define OP_PCL_TLS11_RC4_40_SHA 0x0028
+#define OP_PCL_TLS11_RC4_40_SHA 0x0028
-#define OP_PCL_TLS11_3DES_EDE_CBC_MD5 0xff23
-#define OP_PCL_TLS11_3DES_EDE_CBC_SHA160 0xff30
-#define OP_PCL_TLS11_3DES_EDE_CBC_SHA224 0xff34
-#define OP_PCL_TLS11_3DES_EDE_CBC_SHA256 0xff36
-#define OP_PCL_TLS11_3DES_EDE_CBC_SHA384 0xff33
-#define OP_PCL_TLS11_3DES_EDE_CBC_SHA512 0xff35
-#define OP_PCL_TLS11_AES_128_CBC_SHA160 0xff80
-#define OP_PCL_TLS11_AES_128_CBC_SHA224 0xff84
-#define OP_PCL_TLS11_AES_128_CBC_SHA256 0xff86
-#define OP_PCL_TLS11_AES_128_CBC_SHA384 0xff83
-#define OP_PCL_TLS11_AES_128_CBC_SHA512 0xff85
-#define OP_PCL_TLS11_AES_192_CBC_SHA160 0xff20
-#define OP_PCL_TLS11_AES_192_CBC_SHA224 0xff24
-#define OP_PCL_TLS11_AES_192_CBC_SHA256 0xff26
-#define OP_PCL_TLS11_AES_192_CBC_SHA384 0xff23
-#define OP_PCL_TLS11_AES_192_CBC_SHA512 0xff25
-#define OP_PCL_TLS11_AES_256_CBC_SHA160 0xff60
-#define OP_PCL_TLS11_AES_256_CBC_SHA224 0xff64
-#define OP_PCL_TLS11_AES_256_CBC_SHA256 0xff66
-#define OP_PCL_TLS11_AES_256_CBC_SHA384 0xff63
-#define OP_PCL_TLS11_AES_256_CBC_SHA512 0xff65
+#define OP_PCL_TLS11_3DES_EDE_CBC_MD5 0xff23
+#define OP_PCL_TLS11_3DES_EDE_CBC_SHA160 0xff30
+#define OP_PCL_TLS11_3DES_EDE_CBC_SHA224 0xff34
+#define OP_PCL_TLS11_3DES_EDE_CBC_SHA256 0xff36
+#define OP_PCL_TLS11_3DES_EDE_CBC_SHA384 0xff33
+#define OP_PCL_TLS11_3DES_EDE_CBC_SHA512 0xff35
+#define OP_PCL_TLS11_AES_128_CBC_SHA160 0xff80
+#define OP_PCL_TLS11_AES_128_CBC_SHA224 0xff84
+#define OP_PCL_TLS11_AES_128_CBC_SHA256 0xff86
+#define OP_PCL_TLS11_AES_128_CBC_SHA384 0xff83
+#define OP_PCL_TLS11_AES_128_CBC_SHA512 0xff85
+#define OP_PCL_TLS11_AES_192_CBC_SHA160 0xff20
+#define OP_PCL_TLS11_AES_192_CBC_SHA224 0xff24
+#define OP_PCL_TLS11_AES_192_CBC_SHA256 0xff26
+#define OP_PCL_TLS11_AES_192_CBC_SHA384 0xff23
+#define OP_PCL_TLS11_AES_192_CBC_SHA512 0xff25
+#define OP_PCL_TLS11_AES_256_CBC_SHA160 0xff60
+#define OP_PCL_TLS11_AES_256_CBC_SHA224 0xff64
+#define OP_PCL_TLS11_AES_256_CBC_SHA256 0xff66
+#define OP_PCL_TLS11_AES_256_CBC_SHA384 0xff63
+#define OP_PCL_TLS11_AES_256_CBC_SHA512 0xff65
/* For TLS 1.2 - OP_PCLID_TLS12 */
-#define OP_PCL_TLS12_AES_128_CBC_SHA 0x002f
-#define OP_PCL_TLS12_AES_128_CBC_SHA_2 0x0030
-#define OP_PCL_TLS12_AES_128_CBC_SHA_3 0x0031
-#define OP_PCL_TLS12_AES_128_CBC_SHA_4 0x0032
-#define OP_PCL_TLS12_AES_128_CBC_SHA_5 0x0033
-#define OP_PCL_TLS12_AES_128_CBC_SHA_6 0x0034
-#define OP_PCL_TLS12_AES_128_CBC_SHA_7 0x008c
-#define OP_PCL_TLS12_AES_128_CBC_SHA_8 0x0090
-#define OP_PCL_TLS12_AES_128_CBC_SHA_9 0x0094
-#define OP_PCL_TLS12_AES_128_CBC_SHA_10 0xc004
-#define OP_PCL_TLS12_AES_128_CBC_SHA_11 0xc009
-#define OP_PCL_TLS12_AES_128_CBC_SHA_12 0xc00e
-#define OP_PCL_TLS12_AES_128_CBC_SHA_13 0xc013
-#define OP_PCL_TLS12_AES_128_CBC_SHA_14 0xc018
-#define OP_PCL_TLS12_AES_128_CBC_SHA_15 0xc01d
-#define OP_PCL_TLS12_AES_128_CBC_SHA_16 0xc01e
-#define OP_PCL_TLS12_AES_128_CBC_SHA_17 0xc01f
+#define OP_PCL_TLS12_AES_128_CBC_SHA 0x002f
+#define OP_PCL_TLS12_AES_128_CBC_SHA_2 0x0030
+#define OP_PCL_TLS12_AES_128_CBC_SHA_3 0x0031
+#define OP_PCL_TLS12_AES_128_CBC_SHA_4 0x0032
+#define OP_PCL_TLS12_AES_128_CBC_SHA_5 0x0033
+#define OP_PCL_TLS12_AES_128_CBC_SHA_6 0x0034
+#define OP_PCL_TLS12_AES_128_CBC_SHA_7 0x008c
+#define OP_PCL_TLS12_AES_128_CBC_SHA_8 0x0090
+#define OP_PCL_TLS12_AES_128_CBC_SHA_9 0x0094
+#define OP_PCL_TLS12_AES_128_CBC_SHA_10 0xc004
+#define OP_PCL_TLS12_AES_128_CBC_SHA_11 0xc009
+#define OP_PCL_TLS12_AES_128_CBC_SHA_12 0xc00e
+#define OP_PCL_TLS12_AES_128_CBC_SHA_13 0xc013
+#define OP_PCL_TLS12_AES_128_CBC_SHA_14 0xc018
+#define OP_PCL_TLS12_AES_128_CBC_SHA_15 0xc01d
+#define OP_PCL_TLS12_AES_128_CBC_SHA_16 0xc01e
+#define OP_PCL_TLS12_AES_128_CBC_SHA_17 0xc01f
-#define OP_PCL_TLS12_AES_256_CBC_SHA 0x0035
-#define OP_PCL_TLS12_AES_256_CBC_SHA_2 0x0036
-#define OP_PCL_TLS12_AES_256_CBC_SHA_3 0x0037
-#define OP_PCL_TLS12_AES_256_CBC_SHA_4 0x0038
-#define OP_PCL_TLS12_AES_256_CBC_SHA_5 0x0039
-#define OP_PCL_TLS12_AES_256_CBC_SHA_6 0x003a
-#define OP_PCL_TLS12_AES_256_CBC_SHA_7 0x008d
-#define OP_PCL_TLS12_AES_256_CBC_SHA_8 0x0091
-#define OP_PCL_TLS12_AES_256_CBC_SHA_9 0x0095
-#define OP_PCL_TLS12_AES_256_CBC_SHA_10 0xc005
-#define OP_PCL_TLS12_AES_256_CBC_SHA_11 0xc00a
-#define OP_PCL_TLS12_AES_256_CBC_SHA_12 0xc00f
-#define OP_PCL_TLS12_AES_256_CBC_SHA_13 0xc014
-#define OP_PCL_TLS12_AES_256_CBC_SHA_14 0xc019
-#define OP_PCL_TLS12_AES_256_CBC_SHA_15 0xc020
-#define OP_PCL_TLS12_AES_256_CBC_SHA_16 0xc021
-#define OP_PCL_TLS12_AES_256_CBC_SHA_17 0xc022
+#define OP_PCL_TLS12_AES_256_CBC_SHA 0x0035
+#define OP_PCL_TLS12_AES_256_CBC_SHA_2 0x0036
+#define OP_PCL_TLS12_AES_256_CBC_SHA_3 0x0037
+#define OP_PCL_TLS12_AES_256_CBC_SHA_4 0x0038
+#define OP_PCL_TLS12_AES_256_CBC_SHA_5 0x0039
+#define OP_PCL_TLS12_AES_256_CBC_SHA_6 0x003a
+#define OP_PCL_TLS12_AES_256_CBC_SHA_7 0x008d
+#define OP_PCL_TLS12_AES_256_CBC_SHA_8 0x0091
+#define OP_PCL_TLS12_AES_256_CBC_SHA_9 0x0095
+#define OP_PCL_TLS12_AES_256_CBC_SHA_10 0xc005
+#define OP_PCL_TLS12_AES_256_CBC_SHA_11 0xc00a
+#define OP_PCL_TLS12_AES_256_CBC_SHA_12 0xc00f
+#define OP_PCL_TLS12_AES_256_CBC_SHA_13 0xc014
+#define OP_PCL_TLS12_AES_256_CBC_SHA_14 0xc019
+#define OP_PCL_TLS12_AES_256_CBC_SHA_15 0xc020
+#define OP_PCL_TLS12_AES_256_CBC_SHA_16 0xc021
+#define OP_PCL_TLS12_AES_256_CBC_SHA_17 0xc022
-/* #define OP_PCL_TLS12_3DES_EDE_CBC_MD5 0x0023 */
+/* #define OP_PCL_TLS12_3DES_EDE_CBC_MD5 0x0023 */
-#define OP_PCL_TLS12_3DES_EDE_CBC_SHA 0x001f
-#define OP_PCL_TLS12_3DES_EDE_CBC_SHA_2 0x008b
-#define OP_PCL_TLS12_3DES_EDE_CBC_SHA_3 0x008f
-#define OP_PCL_TLS12_3DES_EDE_CBC_SHA_4 0x0093
-#define OP_PCL_TLS12_3DES_EDE_CBC_SHA_5 0x000a
-#define OP_PCL_TLS12_3DES_EDE_CBC_SHA_6 0x000d
-#define OP_PCL_TLS12_3DES_EDE_CBC_SHA_7 0x0010
-#define OP_PCL_TLS12_3DES_EDE_CBC_SHA_8 0x0013
-#define OP_PCL_TLS12_3DES_EDE_CBC_SHA_9 0x0016
-#define OP_PCL_TLS12_3DES_EDE_CBC_SHA_10 0x001b
-#define OP_PCL_TLS12_3DES_EDE_CBC_SHA_11 0xc003
-#define OP_PCL_TLS12_3DES_EDE_CBC_SHA_12 0xc008
-#define OP_PCL_TLS12_3DES_EDE_CBC_SHA_13 0xc00d
-#define OP_PCL_TLS12_3DES_EDE_CBC_SHA_14 0xc012
-#define OP_PCL_TLS12_3DES_EDE_CBC_SHA_15 0xc017
-#define OP_PCL_TLS12_3DES_EDE_CBC_SHA_16 0xc01a
-#define OP_PCL_TLS12_3DES_EDE_CBC_SHA_17 0xc01b
-#define OP_PCL_TLS12_3DES_EDE_CBC_SHA_18 0xc01c
+#define OP_PCL_TLS12_3DES_EDE_CBC_SHA 0x001f
+#define OP_PCL_TLS12_3DES_EDE_CBC_SHA_2 0x008b
+#define OP_PCL_TLS12_3DES_EDE_CBC_SHA_3 0x008f
+#define OP_PCL_TLS12_3DES_EDE_CBC_SHA_4 0x0093
+#define OP_PCL_TLS12_3DES_EDE_CBC_SHA_5 0x000a
+#define OP_PCL_TLS12_3DES_EDE_CBC_SHA_6 0x000d
+#define OP_PCL_TLS12_3DES_EDE_CBC_SHA_7 0x0010
+#define OP_PCL_TLS12_3DES_EDE_CBC_SHA_8 0x0013
+#define OP_PCL_TLS12_3DES_EDE_CBC_SHA_9 0x0016
+#define OP_PCL_TLS12_3DES_EDE_CBC_SHA_10 0x001b
+#define OP_PCL_TLS12_3DES_EDE_CBC_SHA_11 0xc003
+#define OP_PCL_TLS12_3DES_EDE_CBC_SHA_12 0xc008
+#define OP_PCL_TLS12_3DES_EDE_CBC_SHA_13 0xc00d
+#define OP_PCL_TLS12_3DES_EDE_CBC_SHA_14 0xc012
+#define OP_PCL_TLS12_3DES_EDE_CBC_SHA_15 0xc017
+#define OP_PCL_TLS12_3DES_EDE_CBC_SHA_16 0xc01a
+#define OP_PCL_TLS12_3DES_EDE_CBC_SHA_17 0xc01b
+#define OP_PCL_TLS12_3DES_EDE_CBC_SHA_18 0xc01c
-#define OP_PCL_TLS12_DES40_CBC_MD5 0x0029
+#define OP_PCL_TLS12_DES40_CBC_MD5 0x0029
-#define OP_PCL_TLS12_DES_CBC_MD5 0x0022
+#define OP_PCL_TLS12_DES_CBC_MD5 0x0022
-#define OP_PCL_TLS12_DES40_CBC_SHA 0x0008
-#define OP_PCL_TLS12_DES40_CBC_SHA_2 0x000b
-#define OP_PCL_TLS12_DES40_CBC_SHA_3 0x000e
-#define OP_PCL_TLS12_DES40_CBC_SHA_4 0x0011
-#define OP_PCL_TLS12_DES40_CBC_SHA_5 0x0014
-#define OP_PCL_TLS12_DES40_CBC_SHA_6 0x0019
-#define OP_PCL_TLS12_DES40_CBC_SHA_7 0x0026
+#define OP_PCL_TLS12_DES40_CBC_SHA 0x0008
+#define OP_PCL_TLS12_DES40_CBC_SHA_2 0x000b
+#define OP_PCL_TLS12_DES40_CBC_SHA_3 0x000e
+#define OP_PCL_TLS12_DES40_CBC_SHA_4 0x0011
+#define OP_PCL_TLS12_DES40_CBC_SHA_5 0x0014
+#define OP_PCL_TLS12_DES40_CBC_SHA_6 0x0019
+#define OP_PCL_TLS12_DES40_CBC_SHA_7 0x0026
-#define OP_PCL_TLS12_DES_CBC_SHA 0x001e
-#define OP_PCL_TLS12_DES_CBC_SHA_2 0x0009
-#define OP_PCL_TLS12_DES_CBC_SHA_3 0x000c
-#define OP_PCL_TLS12_DES_CBC_SHA_4 0x000f
-#define OP_PCL_TLS12_DES_CBC_SHA_5 0x0012
-#define OP_PCL_TLS12_DES_CBC_SHA_6 0x0015
-#define OP_PCL_TLS12_DES_CBC_SHA_7 0x001a
+#define OP_PCL_TLS12_DES_CBC_SHA 0x001e
+#define OP_PCL_TLS12_DES_CBC_SHA_2 0x0009
+#define OP_PCL_TLS12_DES_CBC_SHA_3 0x000c
+#define OP_PCL_TLS12_DES_CBC_SHA_4 0x000f
+#define OP_PCL_TLS12_DES_CBC_SHA_5 0x0012
+#define OP_PCL_TLS12_DES_CBC_SHA_6 0x0015
+#define OP_PCL_TLS12_DES_CBC_SHA_7 0x001a
-#define OP_PCL_TLS12_RC4_128_MD5 0x0024
-#define OP_PCL_TLS12_RC4_128_MD5_2 0x0004
-#define OP_PCL_TLS12_RC4_128_MD5_3 0x0018
+#define OP_PCL_TLS12_RC4_128_MD5 0x0024
+#define OP_PCL_TLS12_RC4_128_MD5_2 0x0004
+#define OP_PCL_TLS12_RC4_128_MD5_3 0x0018
-#define OP_PCL_TLS12_RC4_40_MD5 0x002b
-#define OP_PCL_TLS12_RC4_40_MD5_2 0x0003
-#define OP_PCL_TLS12_RC4_40_MD5_3 0x0017
+#define OP_PCL_TLS12_RC4_40_MD5 0x002b
+#define OP_PCL_TLS12_RC4_40_MD5_2 0x0003
+#define OP_PCL_TLS12_RC4_40_MD5_3 0x0017
-#define OP_PCL_TLS12_RC4_128_SHA 0x0020
-#define OP_PCL_TLS12_RC4_128_SHA_2 0x008a
-#define OP_PCL_TLS12_RC4_128_SHA_3 0x008e
-#define OP_PCL_TLS12_RC4_128_SHA_4 0x0092
-#define OP_PCL_TLS12_RC4_128_SHA_5 0x0005
-#define OP_PCL_TLS12_RC4_128_SHA_6 0xc002
-#define OP_PCL_TLS12_RC4_128_SHA_7 0xc007
-#define OP_PCL_TLS12_RC4_128_SHA_8 0xc00c
-#define OP_PCL_TLS12_RC4_128_SHA_9 0xc011
-#define OP_PCL_TLS12_RC4_128_SHA_10 0xc016
+#define OP_PCL_TLS12_RC4_128_SHA 0x0020
+#define OP_PCL_TLS12_RC4_128_SHA_2 0x008a
+#define OP_PCL_TLS12_RC4_128_SHA_3 0x008e
+#define OP_PCL_TLS12_RC4_128_SHA_4 0x0092
+#define OP_PCL_TLS12_RC4_128_SHA_5 0x0005
+#define OP_PCL_TLS12_RC4_128_SHA_6 0xc002
+#define OP_PCL_TLS12_RC4_128_SHA_7 0xc007
+#define OP_PCL_TLS12_RC4_128_SHA_8 0xc00c
+#define OP_PCL_TLS12_RC4_128_SHA_9 0xc011
+#define OP_PCL_TLS12_RC4_128_SHA_10 0xc016
-#define OP_PCL_TLS12_RC4_40_SHA 0x0028
+#define OP_PCL_TLS12_RC4_40_SHA 0x0028
-/* #define OP_PCL_TLS12_AES_128_CBC_SHA256 0x003c */
-#define OP_PCL_TLS12_AES_128_CBC_SHA256_2 0x003e
-#define OP_PCL_TLS12_AES_128_CBC_SHA256_3 0x003f
-#define OP_PCL_TLS12_AES_128_CBC_SHA256_4 0x0040
-#define OP_PCL_TLS12_AES_128_CBC_SHA256_5 0x0067
-#define OP_PCL_TLS12_AES_128_CBC_SHA256_6 0x006c
+/* #define OP_PCL_TLS12_AES_128_CBC_SHA256 0x003c */
+#define OP_PCL_TLS12_AES_128_CBC_SHA256_2 0x003e
+#define OP_PCL_TLS12_AES_128_CBC_SHA256_3 0x003f
+#define OP_PCL_TLS12_AES_128_CBC_SHA256_4 0x0040
+#define OP_PCL_TLS12_AES_128_CBC_SHA256_5 0x0067
+#define OP_PCL_TLS12_AES_128_CBC_SHA256_6 0x006c
-/* #define OP_PCL_TLS12_AES_256_CBC_SHA256 0x003d */
-#define OP_PCL_TLS12_AES_256_CBC_SHA256_2 0x0068
-#define OP_PCL_TLS12_AES_256_CBC_SHA256_3 0x0069
-#define OP_PCL_TLS12_AES_256_CBC_SHA256_4 0x006a
-#define OP_PCL_TLS12_AES_256_CBC_SHA256_5 0x006b
-#define OP_PCL_TLS12_AES_256_CBC_SHA256_6 0x006d
+/* #define OP_PCL_TLS12_AES_256_CBC_SHA256 0x003d */
+#define OP_PCL_TLS12_AES_256_CBC_SHA256_2 0x0068
+#define OP_PCL_TLS12_AES_256_CBC_SHA256_3 0x0069
+#define OP_PCL_TLS12_AES_256_CBC_SHA256_4 0x006a
+#define OP_PCL_TLS12_AES_256_CBC_SHA256_5 0x006b
+#define OP_PCL_TLS12_AES_256_CBC_SHA256_6 0x006d
/* AEAD_AES_xxx_CCM/GCM remain to be defined... */
-#define OP_PCL_TLS12_3DES_EDE_CBC_MD5 0xff23
-#define OP_PCL_TLS12_3DES_EDE_CBC_SHA160 0xff30
-#define OP_PCL_TLS12_3DES_EDE_CBC_SHA224 0xff34
-#define OP_PCL_TLS12_3DES_EDE_CBC_SHA256 0xff36
-#define OP_PCL_TLS12_3DES_EDE_CBC_SHA384 0xff33
-#define OP_PCL_TLS12_3DES_EDE_CBC_SHA512 0xff35
-#define OP_PCL_TLS12_AES_128_CBC_SHA160 0xff80
-#define OP_PCL_TLS12_AES_128_CBC_SHA224 0xff84
-#define OP_PCL_TLS12_AES_128_CBC_SHA256 0xff86
-#define OP_PCL_TLS12_AES_128_CBC_SHA384 0xff83
-#define OP_PCL_TLS12_AES_128_CBC_SHA512 0xff85
-#define OP_PCL_TLS12_AES_192_CBC_SHA160 0xff20
-#define OP_PCL_TLS12_AES_192_CBC_SHA224 0xff24
-#define OP_PCL_TLS12_AES_192_CBC_SHA256 0xff26
-#define OP_PCL_TLS12_AES_192_CBC_SHA384 0xff23
-#define OP_PCL_TLS12_AES_192_CBC_SHA512 0xff25
-#define OP_PCL_TLS12_AES_256_CBC_SHA160 0xff60
-#define OP_PCL_TLS12_AES_256_CBC_SHA224 0xff64
-#define OP_PCL_TLS12_AES_256_CBC_SHA256 0xff66
-#define OP_PCL_TLS12_AES_256_CBC_SHA384 0xff63
-#define OP_PCL_TLS12_AES_256_CBC_SHA512 0xff65
+#define OP_PCL_TLS12_3DES_EDE_CBC_MD5 0xff23
+#define OP_PCL_TLS12_3DES_EDE_CBC_SHA160 0xff30
+#define OP_PCL_TLS12_3DES_EDE_CBC_SHA224 0xff34
+#define OP_PCL_TLS12_3DES_EDE_CBC_SHA256 0xff36
+#define OP_PCL_TLS12_3DES_EDE_CBC_SHA384 0xff33
+#define OP_PCL_TLS12_3DES_EDE_CBC_SHA512 0xff35
+#define OP_PCL_TLS12_AES_128_CBC_SHA160 0xff80
+#define OP_PCL_TLS12_AES_128_CBC_SHA224 0xff84
+#define OP_PCL_TLS12_AES_128_CBC_SHA256 0xff86
+#define OP_PCL_TLS12_AES_128_CBC_SHA384 0xff83
+#define OP_PCL_TLS12_AES_128_CBC_SHA512 0xff85
+#define OP_PCL_TLS12_AES_192_CBC_SHA160 0xff20
+#define OP_PCL_TLS12_AES_192_CBC_SHA224 0xff24
+#define OP_PCL_TLS12_AES_192_CBC_SHA256 0xff26
+#define OP_PCL_TLS12_AES_192_CBC_SHA384 0xff23
+#define OP_PCL_TLS12_AES_192_CBC_SHA512 0xff25
+#define OP_PCL_TLS12_AES_256_CBC_SHA160 0xff60
+#define OP_PCL_TLS12_AES_256_CBC_SHA224 0xff64
+#define OP_PCL_TLS12_AES_256_CBC_SHA256 0xff66
+#define OP_PCL_TLS12_AES_256_CBC_SHA384 0xff63
+#define OP_PCL_TLS12_AES_256_CBC_SHA512 0xff65
/* For DTLS - OP_PCLID_DTLS */
-#define OP_PCL_DTLS_AES_128_CBC_SHA 0x002f
-#define OP_PCL_DTLS_AES_128_CBC_SHA_2 0x0030
-#define OP_PCL_DTLS_AES_128_CBC_SHA_3 0x0031
-#define OP_PCL_DTLS_AES_128_CBC_SHA_4 0x0032
-#define OP_PCL_DTLS_AES_128_CBC_SHA_5 0x0033
-#define OP_PCL_DTLS_AES_128_CBC_SHA_6 0x0034
-#define OP_PCL_DTLS_AES_128_CBC_SHA_7 0x008c
-#define OP_PCL_DTLS_AES_128_CBC_SHA_8 0x0090
-#define OP_PCL_DTLS_AES_128_CBC_SHA_9 0x0094
-#define OP_PCL_DTLS_AES_128_CBC_SHA_10 0xc004
-#define OP_PCL_DTLS_AES_128_CBC_SHA_11 0xc009
-#define OP_PCL_DTLS_AES_128_CBC_SHA_12 0xc00e
-#define OP_PCL_DTLS_AES_128_CBC_SHA_13 0xc013
-#define OP_PCL_DTLS_AES_128_CBC_SHA_14 0xc018
-#define OP_PCL_DTLS_AES_128_CBC_SHA_15 0xc01d
-#define OP_PCL_DTLS_AES_128_CBC_SHA_16 0xc01e
-#define OP_PCL_DTLS_AES_128_CBC_SHA_17 0xc01f
+#define OP_PCL_DTLS_AES_128_CBC_SHA 0x002f
+#define OP_PCL_DTLS_AES_128_CBC_SHA_2 0x0030
+#define OP_PCL_DTLS_AES_128_CBC_SHA_3 0x0031
+#define OP_PCL_DTLS_AES_128_CBC_SHA_4 0x0032
+#define OP_PCL_DTLS_AES_128_CBC_SHA_5 0x0033
+#define OP_PCL_DTLS_AES_128_CBC_SHA_6 0x0034
+#define OP_PCL_DTLS_AES_128_CBC_SHA_7 0x008c
+#define OP_PCL_DTLS_AES_128_CBC_SHA_8 0x0090
+#define OP_PCL_DTLS_AES_128_CBC_SHA_9 0x0094
+#define OP_PCL_DTLS_AES_128_CBC_SHA_10 0xc004
+#define OP_PCL_DTLS_AES_128_CBC_SHA_11 0xc009
+#define OP_PCL_DTLS_AES_128_CBC_SHA_12 0xc00e
+#define OP_PCL_DTLS_AES_128_CBC_SHA_13 0xc013
+#define OP_PCL_DTLS_AES_128_CBC_SHA_14 0xc018
+#define OP_PCL_DTLS_AES_128_CBC_SHA_15 0xc01d
+#define OP_PCL_DTLS_AES_128_CBC_SHA_16 0xc01e
+#define OP_PCL_DTLS_AES_128_CBC_SHA_17 0xc01f
-#define OP_PCL_DTLS_AES_256_CBC_SHA 0x0035
-#define OP_PCL_DTLS_AES_256_CBC_SHA_2 0x0036
-#define OP_PCL_DTLS_AES_256_CBC_SHA_3 0x0037
-#define OP_PCL_DTLS_AES_256_CBC_SHA_4 0x0038
-#define OP_PCL_DTLS_AES_256_CBC_SHA_5 0x0039
-#define OP_PCL_DTLS_AES_256_CBC_SHA_6 0x003a
-#define OP_PCL_DTLS_AES_256_CBC_SHA_7 0x008d
-#define OP_PCL_DTLS_AES_256_CBC_SHA_8 0x0091
-#define OP_PCL_DTLS_AES_256_CBC_SHA_9 0x0095
-#define OP_PCL_DTLS_AES_256_CBC_SHA_10 0xc005
-#define OP_PCL_DTLS_AES_256_CBC_SHA_11 0xc00a
-#define OP_PCL_DTLS_AES_256_CBC_SHA_12 0xc00f
-#define OP_PCL_DTLS_AES_256_CBC_SHA_13 0xc014
-#define OP_PCL_DTLS_AES_256_CBC_SHA_14 0xc019
-#define OP_PCL_DTLS_AES_256_CBC_SHA_15 0xc020
-#define OP_PCL_DTLS_AES_256_CBC_SHA_16 0xc021
-#define OP_PCL_DTLS_AES_256_CBC_SHA_17 0xc022
+#define OP_PCL_DTLS_AES_256_CBC_SHA 0x0035
+#define OP_PCL_DTLS_AES_256_CBC_SHA_2 0x0036
+#define OP_PCL_DTLS_AES_256_CBC_SHA_3 0x0037
+#define OP_PCL_DTLS_AES_256_CBC_SHA_4 0x0038
+#define OP_PCL_DTLS_AES_256_CBC_SHA_5 0x0039
+#define OP_PCL_DTLS_AES_256_CBC_SHA_6 0x003a
+#define OP_PCL_DTLS_AES_256_CBC_SHA_7 0x008d
+#define OP_PCL_DTLS_AES_256_CBC_SHA_8 0x0091
+#define OP_PCL_DTLS_AES_256_CBC_SHA_9 0x0095
+#define OP_PCL_DTLS_AES_256_CBC_SHA_10 0xc005
+#define OP_PCL_DTLS_AES_256_CBC_SHA_11 0xc00a
+#define OP_PCL_DTLS_AES_256_CBC_SHA_12 0xc00f
+#define OP_PCL_DTLS_AES_256_CBC_SHA_13 0xc014
+#define OP_PCL_DTLS_AES_256_CBC_SHA_14 0xc019
+#define OP_PCL_DTLS_AES_256_CBC_SHA_15 0xc020
+#define OP_PCL_DTLS_AES_256_CBC_SHA_16 0xc021
+#define OP_PCL_DTLS_AES_256_CBC_SHA_17 0xc022
-/* #define OP_PCL_DTLS_3DES_EDE_CBC_MD5 0x0023 */
+/* #define OP_PCL_DTLS_3DES_EDE_CBC_MD5 0x0023 */
-#define OP_PCL_DTLS_3DES_EDE_CBC_SHA 0x001f
-#define OP_PCL_DTLS_3DES_EDE_CBC_SHA_2 0x008b
-#define OP_PCL_DTLS_3DES_EDE_CBC_SHA_3 0x008f
-#define OP_PCL_DTLS_3DES_EDE_CBC_SHA_4 0x0093
-#define OP_PCL_DTLS_3DES_EDE_CBC_SHA_5 0x000a
-#define OP_PCL_DTLS_3DES_EDE_CBC_SHA_6 0x000d
-#define OP_PCL_DTLS_3DES_EDE_CBC_SHA_7 0x0010
-#define OP_PCL_DTLS_3DES_EDE_CBC_SHA_8 0x0013
-#define OP_PCL_DTLS_3DES_EDE_CBC_SHA_9 0x0016
-#define OP_PCL_DTLS_3DES_EDE_CBC_SHA_10 0x001b
-#define OP_PCL_DTLS_3DES_EDE_CBC_SHA_11 0xc003
-#define OP_PCL_DTLS_3DES_EDE_CBC_SHA_12 0xc008
-#define OP_PCL_DTLS_3DES_EDE_CBC_SHA_13 0xc00d
-#define OP_PCL_DTLS_3DES_EDE_CBC_SHA_14 0xc012
-#define OP_PCL_DTLS_3DES_EDE_CBC_SHA_15 0xc017
-#define OP_PCL_DTLS_3DES_EDE_CBC_SHA_16 0xc01a
-#define OP_PCL_DTLS_3DES_EDE_CBC_SHA_17 0xc01b
-#define OP_PCL_DTLS_3DES_EDE_CBC_SHA_18 0xc01c
+#define OP_PCL_DTLS_3DES_EDE_CBC_SHA 0x001f
+#define OP_PCL_DTLS_3DES_EDE_CBC_SHA_2 0x008b
+#define OP_PCL_DTLS_3DES_EDE_CBC_SHA_3 0x008f
+#define OP_PCL_DTLS_3DES_EDE_CBC_SHA_4 0x0093
+#define OP_PCL_DTLS_3DES_EDE_CBC_SHA_5 0x000a
+#define OP_PCL_DTLS_3DES_EDE_CBC_SHA_6 0x000d
+#define OP_PCL_DTLS_3DES_EDE_CBC_SHA_7 0x0010
+#define OP_PCL_DTLS_3DES_EDE_CBC_SHA_8 0x0013
+#define OP_PCL_DTLS_3DES_EDE_CBC_SHA_9 0x0016
+#define OP_PCL_DTLS_3DES_EDE_CBC_SHA_10 0x001b
+#define OP_PCL_DTLS_3DES_EDE_CBC_SHA_11 0xc003
+#define OP_PCL_DTLS_3DES_EDE_CBC_SHA_12 0xc008
+#define OP_PCL_DTLS_3DES_EDE_CBC_SHA_13 0xc00d
+#define OP_PCL_DTLS_3DES_EDE_CBC_SHA_14 0xc012
+#define OP_PCL_DTLS_3DES_EDE_CBC_SHA_15 0xc017
+#define OP_PCL_DTLS_3DES_EDE_CBC_SHA_16 0xc01a
+#define OP_PCL_DTLS_3DES_EDE_CBC_SHA_17 0xc01b
+#define OP_PCL_DTLS_3DES_EDE_CBC_SHA_18 0xc01c
-#define OP_PCL_DTLS_DES40_CBC_MD5 0x0029
+#define OP_PCL_DTLS_DES40_CBC_MD5 0x0029
-#define OP_PCL_DTLS_DES_CBC_MD5 0x0022
+#define OP_PCL_DTLS_DES_CBC_MD5 0x0022
-#define OP_PCL_DTLS_DES40_CBC_SHA 0x0008
-#define OP_PCL_DTLS_DES40_CBC_SHA_2 0x000b
-#define OP_PCL_DTLS_DES40_CBC_SHA_3 0x000e
-#define OP_PCL_DTLS_DES40_CBC_SHA_4 0x0011
-#define OP_PCL_DTLS_DES40_CBC_SHA_5 0x0014
-#define OP_PCL_DTLS_DES40_CBC_SHA_6 0x0019
-#define OP_PCL_DTLS_DES40_CBC_SHA_7 0x0026
+#define OP_PCL_DTLS_DES40_CBC_SHA 0x0008
+#define OP_PCL_DTLS_DES40_CBC_SHA_2 0x000b
+#define OP_PCL_DTLS_DES40_CBC_SHA_3 0x000e
+#define OP_PCL_DTLS_DES40_CBC_SHA_4 0x0011
+#define OP_PCL_DTLS_DES40_CBC_SHA_5 0x0014
+#define OP_PCL_DTLS_DES40_CBC_SHA_6 0x0019
+#define OP_PCL_DTLS_DES40_CBC_SHA_7 0x0026
-#define OP_PCL_DTLS_DES_CBC_SHA 0x001e
-#define OP_PCL_DTLS_DES_CBC_SHA_2 0x0009
-#define OP_PCL_DTLS_DES_CBC_SHA_3 0x000c
-#define OP_PCL_DTLS_DES_CBC_SHA_4 0x000f
-#define OP_PCL_DTLS_DES_CBC_SHA_5 0x0012
-#define OP_PCL_DTLS_DES_CBC_SHA_6 0x0015
-#define OP_PCL_DTLS_DES_CBC_SHA_7 0x001a
+#define OP_PCL_DTLS_DES_CBC_SHA 0x001e
+#define OP_PCL_DTLS_DES_CBC_SHA_2 0x0009
+#define OP_PCL_DTLS_DES_CBC_SHA_3 0x000c
+#define OP_PCL_DTLS_DES_CBC_SHA_4 0x000f
+#define OP_PCL_DTLS_DES_CBC_SHA_5 0x0012
+#define OP_PCL_DTLS_DES_CBC_SHA_6 0x0015
+#define OP_PCL_DTLS_DES_CBC_SHA_7 0x001a
-#define OP_PCL_DTLS_3DES_EDE_CBC_MD5 0xff23
-#define OP_PCL_DTLS_3DES_EDE_CBC_SHA160 0xff30
-#define OP_PCL_DTLS_3DES_EDE_CBC_SHA224 0xff34
-#define OP_PCL_DTLS_3DES_EDE_CBC_SHA256 0xff36
-#define OP_PCL_DTLS_3DES_EDE_CBC_SHA384 0xff33
-#define OP_PCL_DTLS_3DES_EDE_CBC_SHA512 0xff35
-#define OP_PCL_DTLS_AES_128_CBC_SHA160 0xff80
-#define OP_PCL_DTLS_AES_128_CBC_SHA224 0xff84
-#define OP_PCL_DTLS_AES_128_CBC_SHA256 0xff86
-#define OP_PCL_DTLS_AES_128_CBC_SHA384 0xff83
-#define OP_PCL_DTLS_AES_128_CBC_SHA512 0xff85
-#define OP_PCL_DTLS_AES_192_CBC_SHA160 0xff20
-#define OP_PCL_DTLS_AES_192_CBC_SHA224 0xff24
-#define OP_PCL_DTLS_AES_192_CBC_SHA256 0xff26
-#define OP_PCL_DTLS_AES_192_CBC_SHA384 0xff23
-#define OP_PCL_DTLS_AES_192_CBC_SHA512 0xff25
-#define OP_PCL_DTLS_AES_256_CBC_SHA160 0xff60
-#define OP_PCL_DTLS_AES_256_CBC_SHA224 0xff64
-#define OP_PCL_DTLS_AES_256_CBC_SHA256 0xff66
-#define OP_PCL_DTLS_AES_256_CBC_SHA384 0xff63
-#define OP_PCL_DTLS_AES_256_CBC_SHA512 0xff65
+#define OP_PCL_DTLS_3DES_EDE_CBC_MD5 0xff23
+#define OP_PCL_DTLS_3DES_EDE_CBC_SHA160 0xff30
+#define OP_PCL_DTLS_3DES_EDE_CBC_SHA224 0xff34
+#define OP_PCL_DTLS_3DES_EDE_CBC_SHA256 0xff36
+#define OP_PCL_DTLS_3DES_EDE_CBC_SHA384 0xff33
+#define OP_PCL_DTLS_3DES_EDE_CBC_SHA512 0xff35
+#define OP_PCL_DTLS_AES_128_CBC_SHA160 0xff80
+#define OP_PCL_DTLS_AES_128_CBC_SHA224 0xff84
+#define OP_PCL_DTLS_AES_128_CBC_SHA256 0xff86
+#define OP_PCL_DTLS_AES_128_CBC_SHA384 0xff83
+#define OP_PCL_DTLS_AES_128_CBC_SHA512 0xff85
+#define OP_PCL_DTLS_AES_192_CBC_SHA160 0xff20
+#define OP_PCL_DTLS_AES_192_CBC_SHA224 0xff24
+#define OP_PCL_DTLS_AES_192_CBC_SHA256 0xff26
+#define OP_PCL_DTLS_AES_192_CBC_SHA384 0xff23
+#define OP_PCL_DTLS_AES_192_CBC_SHA512 0xff25
+#define OP_PCL_DTLS_AES_256_CBC_SHA160 0xff60
+#define OP_PCL_DTLS_AES_256_CBC_SHA224 0xff64
+#define OP_PCL_DTLS_AES_256_CBC_SHA256 0xff66
+#define OP_PCL_DTLS_AES_256_CBC_SHA384 0xff63
+#define OP_PCL_DTLS_AES_256_CBC_SHA512 0xff65
/* 802.16 WiMAX protinfos */
-#define OP_PCL_WIMAX_OFDM 0x0201
-#define OP_PCL_WIMAX_OFDMA 0x0231
+#define OP_PCL_WIMAX_OFDM 0x0201
+#define OP_PCL_WIMAX_OFDMA 0x0231
/* 802.11 WiFi protinfos */
-#define OP_PCL_WIFI 0xac04
+#define OP_PCL_WIFI 0xac04
/* MacSec protinfos */
-#define OP_PCL_MACSEC 0x0001
+#define OP_PCL_MACSEC 0x0001
/* PKI unidirectional protocol protinfo bits */
-#define OP_PCL_PKPROT_TEST 0x0008
-#define OP_PCL_PKPROT_DECRYPT 0x0004
-#define OP_PCL_PKPROT_ECC 0x0002
-#define OP_PCL_PKPROT_F2M 0x0001
+#define OP_PCL_PKPROT_TEST 0x0008
+#define OP_PCL_PKPROT_DECRYPT 0x0004
+#define OP_PCL_PKPROT_ECC 0x0002
+#define OP_PCL_PKPROT_F2M 0x0001
/* For non-protocol/alg-only op commands */
#define OP_ALG_TYPE_SHIFT 24
@@ -1181,114 +1181,114 @@
#define OP_ALG_ENCRYPT 1
/* PKHA algorithm type set */
-#define OP_ALG_PK 0x00800000
-#define OP_ALG_PK_FUN_MASK 0x3f /* clrmem, modmath, or cpymem */
+#define OP_ALG_PK 0x00800000
+#define OP_ALG_PK_FUN_MASK 0x3f /* clrmem, modmath, or cpymem */
/* PKHA mode clear memory functions */
-#define OP_ALG_PKMODE_A_RAM 0x80000
-#define OP_ALG_PKMODE_B_RAM 0x40000
-#define OP_ALG_PKMODE_E_RAM 0x20000
-#define OP_ALG_PKMODE_N_RAM 0x10000
-#define OP_ALG_PKMODE_CLEARMEM 0x00001
+#define OP_ALG_PKMODE_A_RAM 0x80000
+#define OP_ALG_PKMODE_B_RAM 0x40000
+#define OP_ALG_PKMODE_E_RAM 0x20000
+#define OP_ALG_PKMODE_N_RAM 0x10000
+#define OP_ALG_PKMODE_CLEARMEM 0x00001
/* PKHA mode modular-arithmetic functions */
-#define OP_ALG_PKMODE_MOD_IN_MONTY 0x80000
-#define OP_ALG_PKMODE_MOD_OUT_MONTY 0x40000
-#define OP_ALG_PKMODE_MOD_F2M 0x20000
-#define OP_ALG_PKMODE_MOD_R2_IN 0x10000
-#define OP_ALG_PKMODE_PRJECTV 0x00800
-#define OP_ALG_PKMODE_TIME_EQ 0x400
-#define OP_ALG_PKMODE_OUT_B 0x000
-#define OP_ALG_PKMODE_OUT_A 0x100
-#define OP_ALG_PKMODE_MOD_ADD 0x002
-#define OP_ALG_PKMODE_MOD_SUB_AB 0x003
-#define OP_ALG_PKMODE_MOD_SUB_BA 0x004
-#define OP_ALG_PKMODE_MOD_MULT 0x005
-#define OP_ALG_PKMODE_MOD_EXPO 0x006
-#define OP_ALG_PKMODE_MOD_REDUCT 0x007
-#define OP_ALG_PKMODE_MOD_INV 0x008
-#define OP_ALG_PKMODE_MOD_ECC_ADD 0x009
-#define OP_ALG_PKMODE_MOD_ECC_DBL 0x00a
-#define OP_ALG_PKMODE_MOD_ECC_MULT 0x00b
-#define OP_ALG_PKMODE_MOD_MONT_CNST 0x00c
-#define OP_ALG_PKMODE_MOD_CRT_CNST 0x00d
-#define OP_ALG_PKMODE_MOD_GCD 0x00e
-#define OP_ALG_PKMODE_MOD_PRIMALITY 0x00f
+#define OP_ALG_PKMODE_MOD_IN_MONTY 0x80000
+#define OP_ALG_PKMODE_MOD_OUT_MONTY 0x40000
+#define OP_ALG_PKMODE_MOD_F2M 0x20000
+#define OP_ALG_PKMODE_MOD_R2_IN 0x10000
+#define OP_ALG_PKMODE_PRJECTV 0x00800
+#define OP_ALG_PKMODE_TIME_EQ 0x400
+#define OP_ALG_PKMODE_OUT_B 0x000
+#define OP_ALG_PKMODE_OUT_A 0x100
+#define OP_ALG_PKMODE_MOD_ADD 0x002
+#define OP_ALG_PKMODE_MOD_SUB_AB 0x003
+#define OP_ALG_PKMODE_MOD_SUB_BA 0x004
+#define OP_ALG_PKMODE_MOD_MULT 0x005
+#define OP_ALG_PKMODE_MOD_EXPO 0x006
+#define OP_ALG_PKMODE_MOD_REDUCT 0x007
+#define OP_ALG_PKMODE_MOD_INV 0x008
+#define OP_ALG_PKMODE_MOD_ECC_ADD 0x009
+#define OP_ALG_PKMODE_MOD_ECC_DBL 0x00a
+#define OP_ALG_PKMODE_MOD_ECC_MULT 0x00b
+#define OP_ALG_PKMODE_MOD_MONT_CNST 0x00c
+#define OP_ALG_PKMODE_MOD_CRT_CNST 0x00d
+#define OP_ALG_PKMODE_MOD_GCD 0x00e
+#define OP_ALG_PKMODE_MOD_PRIMALITY 0x00f
/* PKHA mode copy-memory functions */
-#define OP_ALG_PKMODE_SRC_REG_SHIFT 13
-#define OP_ALG_PKMODE_SRC_REG_MASK (7 << OP_ALG_PKMODE_SRC_REG_SHIFT)
-#define OP_ALG_PKMODE_DST_REG_SHIFT 10
-#define OP_ALG_PKMODE_DST_REG_MASK (7 << OP_ALG_PKMODE_DST_REG_SHIFT)
-#define OP_ALG_PKMODE_SRC_SEG_SHIFT 8
-#define OP_ALG_PKMODE_SRC_SEG_MASK (3 << OP_ALG_PKMODE_SRC_SEG_SHIFT)
-#define OP_ALG_PKMODE_DST_SEG_SHIFT 6
-#define OP_ALG_PKMODE_DST_SEG_MASK (3 << OP_ALG_PKMODE_DST_SEG_SHIFT)
+#define OP_ALG_PKMODE_SRC_REG_SHIFT 13
+#define OP_ALG_PKMODE_SRC_REG_MASK (7 << OP_ALG_PKMODE_SRC_REG_SHIFT)
+#define OP_ALG_PKMODE_DST_REG_SHIFT 10
+#define OP_ALG_PKMODE_DST_REG_MASK (7 << OP_ALG_PKMODE_DST_REG_SHIFT)
+#define OP_ALG_PKMODE_SRC_SEG_SHIFT 8
+#define OP_ALG_PKMODE_SRC_SEG_MASK (3 << OP_ALG_PKMODE_SRC_SEG_SHIFT)
+#define OP_ALG_PKMODE_DST_SEG_SHIFT 6
+#define OP_ALG_PKMODE_DST_SEG_MASK (3 << OP_ALG_PKMODE_DST_SEG_SHIFT)
-#define OP_ALG_PKMODE_SRC_REG_A (0 << OP_ALG_PKMODE_SRC_REG_SHIFT)
-#define OP_ALG_PKMODE_SRC_REG_B (1 << OP_ALG_PKMODE_SRC_REG_SHIFT)
-#define OP_ALG_PKMODE_SRC_REG_N (3 << OP_ALG_PKMODE_SRC_REG_SHIFT)
-#define OP_ALG_PKMODE_DST_REG_A (0 << OP_ALG_PKMODE_DST_REG_SHIFT)
-#define OP_ALG_PKMODE_DST_REG_B (1 << OP_ALG_PKMODE_DST_REG_SHIFT)
-#define OP_ALG_PKMODE_DST_REG_E (2 << OP_ALG_PKMODE_DST_REG_SHIFT)
-#define OP_ALG_PKMODE_DST_REG_N (3 << OP_ALG_PKMODE_DST_REG_SHIFT)
-#define OP_ALG_PKMODE_SRC_SEG_0 (0 << OP_ALG_PKMODE_SRC_SEG_SHIFT)
-#define OP_ALG_PKMODE_SRC_SEG_1 (1 << OP_ALG_PKMODE_SRC_SEG_SHIFT)
-#define OP_ALG_PKMODE_SRC_SEG_2 (2 << OP_ALG_PKMODE_SRC_SEG_SHIFT)
-#define OP_ALG_PKMODE_SRC_SEG_3 (3 << OP_ALG_PKMODE_SRC_SEG_SHIFT)
-#define OP_ALG_PKMODE_DST_SEG_0 (0 << OP_ALG_PKMODE_DST_SEG_SHIFT)
-#define OP_ALG_PKMODE_DST_SEG_1 (1 << OP_ALG_PKMODE_DST_SEG_SHIFT)
-#define OP_ALG_PKMODE_DST_SEG_2 (2 << OP_ALG_PKMODE_DST_SEG_SHIFT)
-#define OP_ALG_PKMODE_DST_SEG_3 (3 << OP_ALG_PKMODE_DST_SEG_SHIFT)
-#define OP_ALG_PKMODE_CPYMEM_N_SZ 0x80
-#define OP_ALG_PKMODE_CPYMEM_SRC_SZ 0x81
+#define OP_ALG_PKMODE_SRC_REG_A (0 << OP_ALG_PKMODE_SRC_REG_SHIFT)
+#define OP_ALG_PKMODE_SRC_REG_B (1 << OP_ALG_PKMODE_SRC_REG_SHIFT)
+#define OP_ALG_PKMODE_SRC_REG_N (3 << OP_ALG_PKMODE_SRC_REG_SHIFT)
+#define OP_ALG_PKMODE_DST_REG_A (0 << OP_ALG_PKMODE_DST_REG_SHIFT)
+#define OP_ALG_PKMODE_DST_REG_B (1 << OP_ALG_PKMODE_DST_REG_SHIFT)
+#define OP_ALG_PKMODE_DST_REG_E (2 << OP_ALG_PKMODE_DST_REG_SHIFT)
+#define OP_ALG_PKMODE_DST_REG_N (3 << OP_ALG_PKMODE_DST_REG_SHIFT)
+#define OP_ALG_PKMODE_SRC_SEG_0 (0 << OP_ALG_PKMODE_SRC_SEG_SHIFT)
+#define OP_ALG_PKMODE_SRC_SEG_1 (1 << OP_ALG_PKMODE_SRC_SEG_SHIFT)
+#define OP_ALG_PKMODE_SRC_SEG_2 (2 << OP_ALG_PKMODE_SRC_SEG_SHIFT)
+#define OP_ALG_PKMODE_SRC_SEG_3 (3 << OP_ALG_PKMODE_SRC_SEG_SHIFT)
+#define OP_ALG_PKMODE_DST_SEG_0 (0 << OP_ALG_PKMODE_DST_SEG_SHIFT)
+#define OP_ALG_PKMODE_DST_SEG_1 (1 << OP_ALG_PKMODE_DST_SEG_SHIFT)
+#define OP_ALG_PKMODE_DST_SEG_2 (2 << OP_ALG_PKMODE_DST_SEG_SHIFT)
+#define OP_ALG_PKMODE_DST_SEG_3 (3 << OP_ALG_PKMODE_DST_SEG_SHIFT)
+#define OP_ALG_PKMODE_CPYMEM_N_SZ 0x80
+#define OP_ALG_PKMODE_CPYMEM_SRC_SZ 0x81
/*
* SEQ_IN_PTR Command Constructs
*/
/* Release Buffers */
-#define SQIN_RBS 0x04000000
+#define SQIN_RBS 0x04000000
/* Sequence pointer is really a descriptor */
-#define SQIN_INL 0x02000000
+#define SQIN_INL 0x02000000
/* Sequence pointer is a scatter-gather table */
-#define SQIN_SGF 0x01000000
+#define SQIN_SGF 0x01000000
/* Appends to a previous pointer */
-#define SQIN_PRE 0x00800000
+#define SQIN_PRE 0x00800000
/* Use extended length following pointer */
-#define SQIN_EXT 0x00400000
+#define SQIN_EXT 0x00400000
/* Restore sequence with pointer/length */
-#define SQIN_RTO 0x00200000
+#define SQIN_RTO 0x00200000
/* Replace job descriptor */
-#define SQIN_RJD 0x00100000
+#define SQIN_RJD 0x00100000
-#define SQIN_LEN_SHIFT 0
-#define SQIN_LEN_MASK (0xffff << SQIN_LEN_SHIFT)
+#define SQIN_LEN_SHIFT 0
+#define SQIN_LEN_MASK (0xffff << SQIN_LEN_SHIFT)
/*
* SEQ_OUT_PTR Command Constructs
*/
/* Sequence pointer is a scatter-gather table */
-#define SQOUT_SGF 0x01000000
+#define SQOUT_SGF 0x01000000
/* Appends to a previous pointer */
-#define SQOUT_PRE 0x00800000
+#define SQOUT_PRE 0x00800000
/* Restore sequence with pointer/length */
-#define SQOUT_RTO 0x00200000
+#define SQOUT_RTO 0x00200000
/* Use extended length following pointer */
-#define SQOUT_EXT 0x00400000
+#define SQOUT_EXT 0x00400000
-#define SQOUT_LEN_SHIFT 0
-#define SQOUT_LEN_MASK (0xffff << SQOUT_LEN_SHIFT)
+#define SQOUT_LEN_SHIFT 0
+#define SQOUT_LEN_MASK (0xffff << SQOUT_LEN_SHIFT)
/*
@@ -1296,196 +1296,196 @@
*/
/* TYPE field is all that's relevant */
-#define SIGN_TYPE_SHIFT 16
-#define SIGN_TYPE_MASK (0x0f << SIGN_TYPE_SHIFT)
+#define SIGN_TYPE_SHIFT 16
+#define SIGN_TYPE_MASK (0x0f << SIGN_TYPE_SHIFT)
-#define SIGN_TYPE_FINAL (0x00 << SIGN_TYPE_SHIFT)
+#define SIGN_TYPE_FINAL (0x00 << SIGN_TYPE_SHIFT)
#define SIGN_TYPE_FINAL_RESTORE (0x01 << SIGN_TYPE_SHIFT)
#define SIGN_TYPE_FINAL_NONZERO (0x02 << SIGN_TYPE_SHIFT)
-#define SIGN_TYPE_IMM_2 (0x0a << SIGN_TYPE_SHIFT)
-#define SIGN_TYPE_IMM_3 (0x0b << SIGN_TYPE_SHIFT)
-#define SIGN_TYPE_IMM_4 (0x0c << SIGN_TYPE_SHIFT)
+#define SIGN_TYPE_IMM_2 (0x0a << SIGN_TYPE_SHIFT)
+#define SIGN_TYPE_IMM_3 (0x0b << SIGN_TYPE_SHIFT)
+#define SIGN_TYPE_IMM_4 (0x0c << SIGN_TYPE_SHIFT)
/*
* MOVE Command Constructs
*/
-#define MOVE_AUX_SHIFT 25
-#define MOVE_AUX_MASK (3 << MOVE_AUX_SHIFT)
-#define MOVE_AUX_MS (2 << MOVE_AUX_SHIFT)
-#define MOVE_AUX_LS (1 << MOVE_AUX_SHIFT)
+#define MOVE_AUX_SHIFT 25
+#define MOVE_AUX_MASK (3 << MOVE_AUX_SHIFT)
+#define MOVE_AUX_MS (2 << MOVE_AUX_SHIFT)
+#define MOVE_AUX_LS (1 << MOVE_AUX_SHIFT)
-#define MOVE_WAITCOMP_SHIFT 24
-#define MOVE_WAITCOMP_MASK (1 << MOVE_WAITCOMP_SHIFT)
-#define MOVE_WAITCOMP (1 << MOVE_WAITCOMP_SHIFT)
+#define MOVE_WAITCOMP_SHIFT 24
+#define MOVE_WAITCOMP_MASK (1 << MOVE_WAITCOMP_SHIFT)
+#define MOVE_WAITCOMP (1 << MOVE_WAITCOMP_SHIFT)
-#define MOVE_SRC_SHIFT 20
-#define MOVE_SRC_MASK (0x0f << MOVE_SRC_SHIFT)
-#define MOVE_SRC_CLASS1CTX (0x00 << MOVE_SRC_SHIFT)
-#define MOVE_SRC_CLASS2CTX (0x01 << MOVE_SRC_SHIFT)
-#define MOVE_SRC_OUTFIFO (0x02 << MOVE_SRC_SHIFT)
-#define MOVE_SRC_DESCBUF (0x03 << MOVE_SRC_SHIFT)
-#define MOVE_SRC_MATH0 (0x04 << MOVE_SRC_SHIFT)
-#define MOVE_SRC_MATH1 (0x05 << MOVE_SRC_SHIFT)
-#define MOVE_SRC_MATH2 (0x06 << MOVE_SRC_SHIFT)
-#define MOVE_SRC_MATH3 (0x07 << MOVE_SRC_SHIFT)
-#define MOVE_SRC_INFIFO (0x08 << MOVE_SRC_SHIFT)
-#define MOVE_SRC_INFIFO_CL (0x09 << MOVE_SRC_SHIFT)
+#define MOVE_SRC_SHIFT 20
+#define MOVE_SRC_MASK (0x0f << MOVE_SRC_SHIFT)
+#define MOVE_SRC_CLASS1CTX (0x00 << MOVE_SRC_SHIFT)
+#define MOVE_SRC_CLASS2CTX (0x01 << MOVE_SRC_SHIFT)
+#define MOVE_SRC_OUTFIFO (0x02 << MOVE_SRC_SHIFT)
+#define MOVE_SRC_DESCBUF (0x03 << MOVE_SRC_SHIFT)
+#define MOVE_SRC_MATH0 (0x04 << MOVE_SRC_SHIFT)
+#define MOVE_SRC_MATH1 (0x05 << MOVE_SRC_SHIFT)
+#define MOVE_SRC_MATH2 (0x06 << MOVE_SRC_SHIFT)
+#define MOVE_SRC_MATH3 (0x07 << MOVE_SRC_SHIFT)
+#define MOVE_SRC_INFIFO (0x08 << MOVE_SRC_SHIFT)
+#define MOVE_SRC_INFIFO_CL (0x09 << MOVE_SRC_SHIFT)
-#define MOVE_DEST_SHIFT 16
-#define MOVE_DEST_MASK (0x0f << MOVE_DEST_SHIFT)
-#define MOVE_DEST_CLASS1CTX (0x00 << MOVE_DEST_SHIFT)
-#define MOVE_DEST_CLASS2CTX (0x01 << MOVE_DEST_SHIFT)
-#define MOVE_DEST_OUTFIFO (0x02 << MOVE_DEST_SHIFT)
-#define MOVE_DEST_DESCBUF (0x03 << MOVE_DEST_SHIFT)
-#define MOVE_DEST_MATH0 (0x04 << MOVE_DEST_SHIFT)
-#define MOVE_DEST_MATH1 (0x05 << MOVE_DEST_SHIFT)
-#define MOVE_DEST_MATH2 (0x06 << MOVE_DEST_SHIFT)
-#define MOVE_DEST_MATH3 (0x07 << MOVE_DEST_SHIFT)
-#define MOVE_DEST_CLASS1INFIFO (0x08 << MOVE_DEST_SHIFT)
-#define MOVE_DEST_CLASS2INFIFO (0x09 << MOVE_DEST_SHIFT)
-#define MOVE_DEST_PK_A (0x0c << MOVE_DEST_SHIFT)
-#define MOVE_DEST_CLASS1KEY (0x0d << MOVE_DEST_SHIFT)
-#define MOVE_DEST_CLASS2KEY (0x0e << MOVE_DEST_SHIFT)
+#define MOVE_DEST_SHIFT 16
+#define MOVE_DEST_MASK (0x0f << MOVE_DEST_SHIFT)
+#define MOVE_DEST_CLASS1CTX (0x00 << MOVE_DEST_SHIFT)
+#define MOVE_DEST_CLASS2CTX (0x01 << MOVE_DEST_SHIFT)
+#define MOVE_DEST_OUTFIFO (0x02 << MOVE_DEST_SHIFT)
+#define MOVE_DEST_DESCBUF (0x03 << MOVE_DEST_SHIFT)
+#define MOVE_DEST_MATH0 (0x04 << MOVE_DEST_SHIFT)
+#define MOVE_DEST_MATH1 (0x05 << MOVE_DEST_SHIFT)
+#define MOVE_DEST_MATH2 (0x06 << MOVE_DEST_SHIFT)
+#define MOVE_DEST_MATH3 (0x07 << MOVE_DEST_SHIFT)
+#define MOVE_DEST_CLASS1INFIFO (0x08 << MOVE_DEST_SHIFT)
+#define MOVE_DEST_CLASS2INFIFO (0x09 << MOVE_DEST_SHIFT)
+#define MOVE_DEST_PK_A (0x0c << MOVE_DEST_SHIFT)
+#define MOVE_DEST_CLASS1KEY (0x0d << MOVE_DEST_SHIFT)
+#define MOVE_DEST_CLASS2KEY (0x0e << MOVE_DEST_SHIFT)
-#define MOVE_OFFSET_SHIFT 8
-#define MOVE_OFFSET_MASK (0xff << MOVE_OFFSET_SHIFT)
+#define MOVE_OFFSET_SHIFT 8
+#define MOVE_OFFSET_MASK (0xff << MOVE_OFFSET_SHIFT)
-#define MOVE_LEN_SHIFT 0
-#define MOVE_LEN_MASK (0xff << MOVE_LEN_SHIFT)
+#define MOVE_LEN_SHIFT 0
+#define MOVE_LEN_MASK (0xff << MOVE_LEN_SHIFT)
-#define MOVELEN_MRSEL_SHIFT 0
-#define MOVELEN_MRSEL_MASK (0x3 << MOVE_LEN_SHIFT)
+#define MOVELEN_MRSEL_SHIFT 0
+#define MOVELEN_MRSEL_MASK (0x3 << MOVE_LEN_SHIFT)
/*
* MATH Command Constructs
*/
-#define MATH_IFB_SHIFT 26
-#define MATH_IFB_MASK (1 << MATH_IFB_SHIFT)
-#define MATH_IFB (1 << MATH_IFB_SHIFT)
+#define MATH_IFB_SHIFT 26
+#define MATH_IFB_MASK (1 << MATH_IFB_SHIFT)
+#define MATH_IFB (1 << MATH_IFB_SHIFT)
-#define MATH_NFU_SHIFT 25
-#define MATH_NFU_MASK (1 << MATH_NFU_SHIFT)
-#define MATH_NFU (1 << MATH_NFU_SHIFT)
+#define MATH_NFU_SHIFT 25
+#define MATH_NFU_MASK (1 << MATH_NFU_SHIFT)
+#define MATH_NFU (1 << MATH_NFU_SHIFT)
-#define MATH_STL_SHIFT 24
-#define MATH_STL_MASK (1 << MATH_STL_SHIFT)
-#define MATH_STL (1 << MATH_STL_SHIFT)
+#define MATH_STL_SHIFT 24
+#define MATH_STL_MASK (1 << MATH_STL_SHIFT)
+#define MATH_STL (1 << MATH_STL_SHIFT)
/* Function selectors */
-#define MATH_FUN_SHIFT 20
-#define MATH_FUN_MASK (0x0f << MATH_FUN_SHIFT)
-#define MATH_FUN_ADD (0x00 << MATH_FUN_SHIFT)
-#define MATH_FUN_ADDC (0x01 << MATH_FUN_SHIFT)
-#define MATH_FUN_SUB (0x02 << MATH_FUN_SHIFT)
-#define MATH_FUN_SUBB (0x03 << MATH_FUN_SHIFT)
-#define MATH_FUN_OR (0x04 << MATH_FUN_SHIFT)
-#define MATH_FUN_AND (0x05 << MATH_FUN_SHIFT)
-#define MATH_FUN_XOR (0x06 << MATH_FUN_SHIFT)
-#define MATH_FUN_LSHIFT (0x07 << MATH_FUN_SHIFT)
-#define MATH_FUN_RSHIFT (0x08 << MATH_FUN_SHIFT)
-#define MATH_FUN_SHLD (0x09 << MATH_FUN_SHIFT)
-#define MATH_FUN_ZBYT (0x0a << MATH_FUN_SHIFT)
+#define MATH_FUN_SHIFT 20
+#define MATH_FUN_MASK (0x0f << MATH_FUN_SHIFT)
+#define MATH_FUN_ADD (0x00 << MATH_FUN_SHIFT)
+#define MATH_FUN_ADDC (0x01 << MATH_FUN_SHIFT)
+#define MATH_FUN_SUB (0x02 << MATH_FUN_SHIFT)
+#define MATH_FUN_SUBB (0x03 << MATH_FUN_SHIFT)
+#define MATH_FUN_OR (0x04 << MATH_FUN_SHIFT)
+#define MATH_FUN_AND (0x05 << MATH_FUN_SHIFT)
+#define MATH_FUN_XOR (0x06 << MATH_FUN_SHIFT)
+#define MATH_FUN_LSHIFT (0x07 << MATH_FUN_SHIFT)
+#define MATH_FUN_RSHIFT (0x08 << MATH_FUN_SHIFT)
+#define MATH_FUN_SHLD (0x09 << MATH_FUN_SHIFT)
+#define MATH_FUN_ZBYT (0x0a << MATH_FUN_SHIFT)
/* Source 0 selectors */
-#define MATH_SRC0_SHIFT 16
-#define MATH_SRC0_MASK (0x0f << MATH_SRC0_SHIFT)
-#define MATH_SRC0_REG0 (0x00 << MATH_SRC0_SHIFT)
-#define MATH_SRC0_REG1 (0x01 << MATH_SRC0_SHIFT)
-#define MATH_SRC0_REG2 (0x02 << MATH_SRC0_SHIFT)
-#define MATH_SRC0_REG3 (0x03 << MATH_SRC0_SHIFT)
-#define MATH_SRC0_IMM (0x04 << MATH_SRC0_SHIFT)
-#define MATH_SRC0_SEQINLEN (0x08 << MATH_SRC0_SHIFT)
-#define MATH_SRC0_SEQOUTLEN (0x09 << MATH_SRC0_SHIFT)
-#define MATH_SRC0_VARSEQINLEN (0x0a << MATH_SRC0_SHIFT)
-#define MATH_SRC0_VARSEQOUTLEN (0x0b << MATH_SRC0_SHIFT)
-#define MATH_SRC0_ZERO (0x0c << MATH_SRC0_SHIFT)
+#define MATH_SRC0_SHIFT 16
+#define MATH_SRC0_MASK (0x0f << MATH_SRC0_SHIFT)
+#define MATH_SRC0_REG0 (0x00 << MATH_SRC0_SHIFT)
+#define MATH_SRC0_REG1 (0x01 << MATH_SRC0_SHIFT)
+#define MATH_SRC0_REG2 (0x02 << MATH_SRC0_SHIFT)
+#define MATH_SRC0_REG3 (0x03 << MATH_SRC0_SHIFT)
+#define MATH_SRC0_IMM (0x04 << MATH_SRC0_SHIFT)
+#define MATH_SRC0_SEQINLEN (0x08 << MATH_SRC0_SHIFT)
+#define MATH_SRC0_SEQOUTLEN (0x09 << MATH_SRC0_SHIFT)
+#define MATH_SRC0_VARSEQINLEN (0x0a << MATH_SRC0_SHIFT)
+#define MATH_SRC0_VARSEQOUTLEN (0x0b << MATH_SRC0_SHIFT)
+#define MATH_SRC0_ZERO (0x0c << MATH_SRC0_SHIFT)
/* Source 1 selectors */
-#define MATH_SRC1_SHIFT 12
-#define MATH_SRC1_MASK (0x0f << MATH_SRC1_SHIFT)
-#define MATH_SRC1_REG0 (0x00 << MATH_SRC1_SHIFT)
-#define MATH_SRC1_REG1 (0x01 << MATH_SRC1_SHIFT)
-#define MATH_SRC1_REG2 (0x02 << MATH_SRC1_SHIFT)
-#define MATH_SRC1_REG3 (0x03 << MATH_SRC1_SHIFT)
-#define MATH_SRC1_IMM (0x04 << MATH_SRC1_SHIFT)
-#define MATH_SRC1_INFIFO (0x0a << MATH_SRC1_SHIFT)
-#define MATH_SRC1_OUTFIFO (0x0b << MATH_SRC1_SHIFT)
-#define MATH_SRC1_ONE (0x0c << MATH_SRC1_SHIFT)
+#define MATH_SRC1_SHIFT 12
+#define MATH_SRC1_MASK (0x0f << MATH_SRC1_SHIFT)
+#define MATH_SRC1_REG0 (0x00 << MATH_SRC1_SHIFT)
+#define MATH_SRC1_REG1 (0x01 << MATH_SRC1_SHIFT)
+#define MATH_SRC1_REG2 (0x02 << MATH_SRC1_SHIFT)
+#define MATH_SRC1_REG3 (0x03 << MATH_SRC1_SHIFT)
+#define MATH_SRC1_IMM (0x04 << MATH_SRC1_SHIFT)
+#define MATH_SRC1_INFIFO (0x0a << MATH_SRC1_SHIFT)
+#define MATH_SRC1_OUTFIFO (0x0b << MATH_SRC1_SHIFT)
+#define MATH_SRC1_ONE (0x0c << MATH_SRC1_SHIFT)
/* Destination selectors */
-#define MATH_DEST_SHIFT 8
-#define MATH_DEST_MASK (0x0f << MATH_DEST_SHIFT)
-#define MATH_DEST_REG0 (0x00 << MATH_DEST_SHIFT)
-#define MATH_DEST_REG1 (0x01 << MATH_DEST_SHIFT)
-#define MATH_DEST_REG2 (0x02 << MATH_DEST_SHIFT)
-#define MATH_DEST_REG3 (0x03 << MATH_DEST_SHIFT)
-#define MATH_DEST_SEQINLEN (0x08 << MATH_DEST_SHIFT)
-#define MATH_DEST_SEQOUTLEN (0x09 << MATH_DEST_SHIFT)
-#define MATH_DEST_VARSEQINLEN (0x0a << MATH_DEST_SHIFT)
-#define MATH_DEST_VARSEQOUTLEN (0x0b << MATH_DEST_SHIFT)
-#define MATH_DEST_NONE (0x0f << MATH_DEST_SHIFT)
+#define MATH_DEST_SHIFT 8
+#define MATH_DEST_MASK (0x0f << MATH_DEST_SHIFT)
+#define MATH_DEST_REG0 (0x00 << MATH_DEST_SHIFT)
+#define MATH_DEST_REG1 (0x01 << MATH_DEST_SHIFT)
+#define MATH_DEST_REG2 (0x02 << MATH_DEST_SHIFT)
+#define MATH_DEST_REG3 (0x03 << MATH_DEST_SHIFT)
+#define MATH_DEST_SEQINLEN (0x08 << MATH_DEST_SHIFT)
+#define MATH_DEST_SEQOUTLEN (0x09 << MATH_DEST_SHIFT)
+#define MATH_DEST_VARSEQINLEN (0x0a << MATH_DEST_SHIFT)
+#define MATH_DEST_VARSEQOUTLEN (0x0b << MATH_DEST_SHIFT)
+#define MATH_DEST_NONE (0x0f << MATH_DEST_SHIFT)
/* Length selectors */
-#define MATH_LEN_SHIFT 0
-#define MATH_LEN_MASK (0x0f << MATH_LEN_SHIFT)
-#define MATH_LEN_1BYTE 0x01
-#define MATH_LEN_2BYTE 0x02
-#define MATH_LEN_4BYTE 0x04
-#define MATH_LEN_8BYTE 0x08
+#define MATH_LEN_SHIFT 0
+#define MATH_LEN_MASK (0x0f << MATH_LEN_SHIFT)
+#define MATH_LEN_1BYTE 0x01
+#define MATH_LEN_2BYTE 0x02
+#define MATH_LEN_4BYTE 0x04
+#define MATH_LEN_8BYTE 0x08
/*
* JUMP Command Constructs
*/
-#define JUMP_CLASS_SHIFT 25
+#define JUMP_CLASS_SHIFT 25
#define JUMP_CLASS_MASK (3 << JUMP_CLASS_SHIFT)
#define JUMP_CLASS_NONE 0
#define JUMP_CLASS_CLASS1 (1 << JUMP_CLASS_SHIFT)
#define JUMP_CLASS_CLASS2 (2 << JUMP_CLASS_SHIFT)
#define JUMP_CLASS_BOTH (3 << JUMP_CLASS_SHIFT)
-#define JUMP_JSL_SHIFT 24
-#define JUMP_JSL_MASK (1 << JUMP_JSL_SHIFT)
-#define JUMP_JSL (1 << JUMP_JSL_SHIFT)
+#define JUMP_JSL_SHIFT 24
+#define JUMP_JSL_MASK (1 << JUMP_JSL_SHIFT)
+#define JUMP_JSL (1 << JUMP_JSL_SHIFT)
-#define JUMP_TYPE_SHIFT 22
-#define JUMP_TYPE_MASK (0x03 << JUMP_TYPE_SHIFT)
-#define JUMP_TYPE_LOCAL (0x00 << JUMP_TYPE_SHIFT)
-#define JUMP_TYPE_NONLOCAL (0x01 << JUMP_TYPE_SHIFT)
-#define JUMP_TYPE_HALT (0x02 << JUMP_TYPE_SHIFT)
-#define JUMP_TYPE_HALT_USER (0x03 << JUMP_TYPE_SHIFT)
+#define JUMP_TYPE_SHIFT 22
+#define JUMP_TYPE_MASK (0x03 << JUMP_TYPE_SHIFT)
+#define JUMP_TYPE_LOCAL (0x00 << JUMP_TYPE_SHIFT)
+#define JUMP_TYPE_NONLOCAL (0x01 << JUMP_TYPE_SHIFT)
+#define JUMP_TYPE_HALT (0x02 << JUMP_TYPE_SHIFT)
+#define JUMP_TYPE_HALT_USER (0x03 << JUMP_TYPE_SHIFT)
-#define JUMP_TEST_SHIFT 16
-#define JUMP_TEST_MASK (0x03 << JUMP_TEST_SHIFT)
-#define JUMP_TEST_ALL (0x00 << JUMP_TEST_SHIFT)
-#define JUMP_TEST_INVALL (0x01 << JUMP_TEST_SHIFT)
-#define JUMP_TEST_ANY (0x02 << JUMP_TEST_SHIFT)
-#define JUMP_TEST_INVANY (0x03 << JUMP_TEST_SHIFT)
+#define JUMP_TEST_SHIFT 16
+#define JUMP_TEST_MASK (0x03 << JUMP_TEST_SHIFT)
+#define JUMP_TEST_ALL (0x00 << JUMP_TEST_SHIFT)
+#define JUMP_TEST_INVALL (0x01 << JUMP_TEST_SHIFT)
+#define JUMP_TEST_ANY (0x02 << JUMP_TEST_SHIFT)
+#define JUMP_TEST_INVANY (0x03 << JUMP_TEST_SHIFT)
/* Condition codes. JSL bit is factored in */
-#define JUMP_COND_SHIFT 8
-#define JUMP_COND_MASK (0x100ff << JUMP_COND_SHIFT)
-#define JUMP_COND_PK_0 (0x80 << JUMP_COND_SHIFT)
-#define JUMP_COND_PK_GCD_1 (0x40 << JUMP_COND_SHIFT)
-#define JUMP_COND_PK_PRIME (0x20 << JUMP_COND_SHIFT)
-#define JUMP_COND_MATH_N (0x08 << JUMP_COND_SHIFT)
-#define JUMP_COND_MATH_Z (0x04 << JUMP_COND_SHIFT)
-#define JUMP_COND_MATH_C (0x02 << JUMP_COND_SHIFT)
-#define JUMP_COND_MATH_NV (0x01 << JUMP_COND_SHIFT)
+#define JUMP_COND_SHIFT 8
+#define JUMP_COND_MASK (0x100ff << JUMP_COND_SHIFT)
+#define JUMP_COND_PK_0 (0x80 << JUMP_COND_SHIFT)
+#define JUMP_COND_PK_GCD_1 (0x40 << JUMP_COND_SHIFT)
+#define JUMP_COND_PK_PRIME (0x20 << JUMP_COND_SHIFT)
+#define JUMP_COND_MATH_N (0x08 << JUMP_COND_SHIFT)
+#define JUMP_COND_MATH_Z (0x04 << JUMP_COND_SHIFT)
+#define JUMP_COND_MATH_C (0x02 << JUMP_COND_SHIFT)
+#define JUMP_COND_MATH_NV (0x01 << JUMP_COND_SHIFT)
-#define JUMP_COND_JRP ((0x80 << JUMP_COND_SHIFT) | JUMP_JSL)
-#define JUMP_COND_SHRD ((0x40 << JUMP_COND_SHIFT) | JUMP_JSL)
-#define JUMP_COND_SELF ((0x20 << JUMP_COND_SHIFT) | JUMP_JSL)
-#define JUMP_COND_CALM ((0x10 << JUMP_COND_SHIFT) | JUMP_JSL)
-#define JUMP_COND_NIP ((0x08 << JUMP_COND_SHIFT) | JUMP_JSL)
-#define JUMP_COND_NIFP ((0x04 << JUMP_COND_SHIFT) | JUMP_JSL)
-#define JUMP_COND_NOP ((0x02 << JUMP_COND_SHIFT) | JUMP_JSL)
-#define JUMP_COND_NCP ((0x01 << JUMP_COND_SHIFT) | JUMP_JSL)
+#define JUMP_COND_JRP ((0x80 << JUMP_COND_SHIFT) | JUMP_JSL)
+#define JUMP_COND_SHRD ((0x40 << JUMP_COND_SHIFT) | JUMP_JSL)
+#define JUMP_COND_SELF ((0x20 << JUMP_COND_SHIFT) | JUMP_JSL)
+#define JUMP_COND_CALM ((0x10 << JUMP_COND_SHIFT) | JUMP_JSL)
+#define JUMP_COND_NIP ((0x08 << JUMP_COND_SHIFT) | JUMP_JSL)
+#define JUMP_COND_NIFP ((0x04 << JUMP_COND_SHIFT) | JUMP_JSL)
+#define JUMP_COND_NOP ((0x02 << JUMP_COND_SHIFT) | JUMP_JSL)
+#define JUMP_COND_NCP ((0x01 << JUMP_COND_SHIFT) | JUMP_JSL)
-#define JUMP_OFFSET_SHIFT 0
-#define JUMP_OFFSET_MASK (0xff << JUMP_OFFSET_SHIFT)
+#define JUMP_OFFSET_SHIFT 0
+#define JUMP_OFFSET_MASK (0xff << JUMP_OFFSET_SHIFT)
/*
* NFIFO ENTRY
@@ -1500,20 +1500,20 @@
#define NFIFOENTRY_DEST_BOTH (3 << NFIFOENTRY_DEST_SHIFT)
#define NFIFOENTRY_LC2_SHIFT 29
-#define NFIFOENTRY_LC2_MASK (1 << NFIFOENTRY_LC2_SHIFT)
-#define NFIFOENTRY_LC2 (1 << NFIFOENTRY_LC2_SHIFT)
+#define NFIFOENTRY_LC2_MASK (1 << NFIFOENTRY_LC2_SHIFT)
+#define NFIFOENTRY_LC2 (1 << NFIFOENTRY_LC2_SHIFT)
#define NFIFOENTRY_LC1_SHIFT 28
-#define NFIFOENTRY_LC1_MASK (1 << NFIFOENTRY_LC1_SHIFT)
-#define NFIFOENTRY_LC1 (1 << NFIFOENTRY_LC1_SHIFT)
+#define NFIFOENTRY_LC1_MASK (1 << NFIFOENTRY_LC1_SHIFT)
+#define NFIFOENTRY_LC1 (1 << NFIFOENTRY_LC1_SHIFT)
#define NFIFOENTRY_FC2_SHIFT 27
-#define NFIFOENTRY_FC2_MASK (1 << NFIFOENTRY_FC2_SHIFT)
-#define NFIFOENTRY_FC2 (1 << NFIFOENTRY_FC2_SHIFT)
+#define NFIFOENTRY_FC2_MASK (1 << NFIFOENTRY_FC2_SHIFT)
+#define NFIFOENTRY_FC2 (1 << NFIFOENTRY_FC2_SHIFT)
#define NFIFOENTRY_FC1_SHIFT 26
-#define NFIFOENTRY_FC1_MASK (1 << NFIFOENTRY_FC1_SHIFT)
-#define NFIFOENTRY_FC1 (1 << NFIFOENTRY_FC1_SHIFT)
+#define NFIFOENTRY_FC1_MASK (1 << NFIFOENTRY_FC1_SHIFT)
+#define NFIFOENTRY_FC1 (1 << NFIFOENTRY_FC1_SHIFT)
#define NFIFOENTRY_STYPE_SHIFT 24
#define NFIFOENTRY_STYPE_MASK (3 << NFIFOENTRY_STYPE_SHIFT)
@@ -1525,60 +1525,59 @@
#define NFIFOENTRY_DTYPE_SHIFT 20
#define NFIFOENTRY_DTYPE_MASK (0xF << NFIFOENTRY_DTYPE_SHIFT)
-#define NFIFOENTRY_DTYPE_SBOX (0x0 << NFIFOENTRY_DTYPE_SHIFT)
-#define NFIFOENTRY_DTYPE_AAD (0x1 << NFIFOENTRY_DTYPE_SHIFT)
-#define NFIFOENTRY_DTYPE_IV (0x2 << NFIFOENTRY_DTYPE_SHIFT)
-#define NFIFOENTRY_DTYPE_SAD (0x3 << NFIFOENTRY_DTYPE_SHIFT)
-#define NFIFOENTRY_DTYPE_ICV (0xA << NFIFOENTRY_DTYPE_SHIFT)
-#define NFIFOENTRY_DTYPE_SKIP (0xE << NFIFOENTRY_DTYPE_SHIFT)
-#define NFIFOENTRY_DTYPE_MSG (0xF << NFIFOENTRY_DTYPE_SHIFT)
+#define NFIFOENTRY_DTYPE_SBOX (0x0 << NFIFOENTRY_DTYPE_SHIFT)
+#define NFIFOENTRY_DTYPE_AAD (0x1 << NFIFOENTRY_DTYPE_SHIFT)
+#define NFIFOENTRY_DTYPE_IV (0x2 << NFIFOENTRY_DTYPE_SHIFT)
+#define NFIFOENTRY_DTYPE_SAD (0x3 << NFIFOENTRY_DTYPE_SHIFT)
+#define NFIFOENTRY_DTYPE_ICV (0xA << NFIFOENTRY_DTYPE_SHIFT)
+#define NFIFOENTRY_DTYPE_SKIP (0xE << NFIFOENTRY_DTYPE_SHIFT)
+#define NFIFOENTRY_DTYPE_MSG (0xF << NFIFOENTRY_DTYPE_SHIFT)
-#define NFIFOENTRY_DTYPE_PK_A0 (0x0 << NFIFOENTRY_DTYPE_SHIFT)
-#define NFIFOENTRY_DTYPE_PK_A1 (0x1 << NFIFOENTRY_DTYPE_SHIFT)
-#define NFIFOENTRY_DTYPE_PK_A2 (0x2 << NFIFOENTRY_DTYPE_SHIFT)
-#define NFIFOENTRY_DTYPE_PK_A3 (0x3 << NFIFOENTRY_DTYPE_SHIFT)
-#define NFIFOENTRY_DTYPE_PK_B0 (0x4 << NFIFOENTRY_DTYPE_SHIFT)
-#define NFIFOENTRY_DTYPE_PK_B1 (0x5 << NFIFOENTRY_DTYPE_SHIFT)
-#define NFIFOENTRY_DTYPE_PK_B2 (0x6 << NFIFOENTRY_DTYPE_SHIFT)
-#define NFIFOENTRY_DTYPE_PK_B3 (0x7 << NFIFOENTRY_DTYPE_SHIFT)
-#define NFIFOENTRY_DTYPE_PK_N (0x8 << NFIFOENTRY_DTYPE_SHIFT)
-#define NFIFOENTRY_DTYPE_PK_E (0x9 << NFIFOENTRY_DTYPE_SHIFT)
-#define NFIFOENTRY_DTYPE_PK_A (0xC << NFIFOENTRY_DTYPE_SHIFT)
-#define NFIFOENTRY_DTYPE_PK_B (0xD << NFIFOENTRY_DTYPE_SHIFT)
+#define NFIFOENTRY_DTYPE_PK_A0 (0x0 << NFIFOENTRY_DTYPE_SHIFT)
+#define NFIFOENTRY_DTYPE_PK_A1 (0x1 << NFIFOENTRY_DTYPE_SHIFT)
+#define NFIFOENTRY_DTYPE_PK_A2 (0x2 << NFIFOENTRY_DTYPE_SHIFT)
+#define NFIFOENTRY_DTYPE_PK_A3 (0x3 << NFIFOENTRY_DTYPE_SHIFT)
+#define NFIFOENTRY_DTYPE_PK_B0 (0x4 << NFIFOENTRY_DTYPE_SHIFT)
+#define NFIFOENTRY_DTYPE_PK_B1 (0x5 << NFIFOENTRY_DTYPE_SHIFT)
+#define NFIFOENTRY_DTYPE_PK_B2 (0x6 << NFIFOENTRY_DTYPE_SHIFT)
+#define NFIFOENTRY_DTYPE_PK_B3 (0x7 << NFIFOENTRY_DTYPE_SHIFT)
+#define NFIFOENTRY_DTYPE_PK_N (0x8 << NFIFOENTRY_DTYPE_SHIFT)
+#define NFIFOENTRY_DTYPE_PK_E (0x9 << NFIFOENTRY_DTYPE_SHIFT)
+#define NFIFOENTRY_DTYPE_PK_A (0xC << NFIFOENTRY_DTYPE_SHIFT)
+#define NFIFOENTRY_DTYPE_PK_B (0xD << NFIFOENTRY_DTYPE_SHIFT)
#define NFIFOENTRY_BND_SHIFT 19
-#define NFIFOENTRY_BND_MASK (1 << NFIFOENTRY_BND_SHIFT)
-#define NFIFOENTRY_BND (1 << NFIFOENTRY_BND_SHIFT)
+#define NFIFOENTRY_BND_MASK (1 << NFIFOENTRY_BND_SHIFT)
+#define NFIFOENTRY_BND (1 << NFIFOENTRY_BND_SHIFT)
#define NFIFOENTRY_PTYPE_SHIFT 16
#define NFIFOENTRY_PTYPE_MASK (0x7 << NFIFOENTRY_PTYPE_SHIFT)
-#define NFIFOENTRY_PTYPE_ZEROS (0x0 << NFIFOENTRY_PTYPE_SHIFT)
-#define NFIFOENTRY_PTYPE_RND_NOZEROS (0x1 << NFIFOENTRY_PTYPE_SHIFT)
-#define NFIFOENTRY_PTYPE_INCREMENT (0x2 << NFIFOENTRY_PTYPE_SHIFT)
-#define NFIFOENTRY_PTYPE_RND (0x3 << NFIFOENTRY_PTYPE_SHIFT)
-#define NFIFOENTRY_PTYPE_ZEROS_NZ (0x4 << NFIFOENTRY_PTYPE_SHIFT)
-#define NFIFOENTRY_PTYPE_RND_NZ_LZ (0x5 << NFIFOENTRY_PTYPE_SHIFT)
-#define NFIFOENTRY_PTYPE_N (0x6 << NFIFOENTRY_PTYPE_SHIFT)
-#define NFIFOENTRY_PTYPE_RND_NZ_N (0x7 << NFIFOENTRY_PTYPE_SHIFT)
+#define NFIFOENTRY_PTYPE_ZEROS (0x0 << NFIFOENTRY_PTYPE_SHIFT)
+#define NFIFOENTRY_PTYPE_RND_NOZEROS (0x1 << NFIFOENTRY_PTYPE_SHIFT)
+#define NFIFOENTRY_PTYPE_INCREMENT (0x2 << NFIFOENTRY_PTYPE_SHIFT)
+#define NFIFOENTRY_PTYPE_RND (0x3 << NFIFOENTRY_PTYPE_SHIFT)
+#define NFIFOENTRY_PTYPE_ZEROS_NZ (0x4 << NFIFOENTRY_PTYPE_SHIFT)
+#define NFIFOENTRY_PTYPE_RND_NZ_LZ (0x5 << NFIFOENTRY_PTYPE_SHIFT)
+#define NFIFOENTRY_PTYPE_N (0x6 << NFIFOENTRY_PTYPE_SHIFT)
+#define NFIFOENTRY_PTYPE_RND_NZ_N (0x7 << NFIFOENTRY_PTYPE_SHIFT)
-#define NFIFOENTRY_OC_SHIFT 15
-#define NFIFOENTRY_OC_MASK (1 << NFIFOENTRY_OC_SHIFT)
-#define NFIFOENTRY_OC (1 << NFIFOENTRY_OC_SHIFT)
+#define NFIFOENTRY_OC_SHIFT 15
+#define NFIFOENTRY_OC_MASK (1 << NFIFOENTRY_OC_SHIFT)
+#define NFIFOENTRY_OC (1 << NFIFOENTRY_OC_SHIFT)
#define NFIFOENTRY_AST_SHIFT 14
-#define NFIFOENTRY_AST_MASK (1 << NFIFOENTRY_OC_SHIFT)
-#define NFIFOENTRY_AST (1 << NFIFOENTRY_OC_SHIFT)
+#define NFIFOENTRY_AST_MASK (1 << NFIFOENTRY_OC_SHIFT)
+#define NFIFOENTRY_AST (1 << NFIFOENTRY_OC_SHIFT)
-#define NFIFOENTRY_BM_SHIFT 11
-#define NFIFOENTRY_BM_MASK (1 << NFIFOENTRY_BM_SHIFT)
-#define NFIFOENTRY_BM (1 << NFIFOENTRY_BM_SHIFT)
+#define NFIFOENTRY_BM_SHIFT 11
+#define NFIFOENTRY_BM_MASK (1 << NFIFOENTRY_BM_SHIFT)
+#define NFIFOENTRY_BM (1 << NFIFOENTRY_BM_SHIFT)
-#define NFIFOENTRY_PS_SHIFT 10
-#define NFIFOENTRY_PS_MASK (1 << NFIFOENTRY_PS_SHIFT)
-#define NFIFOENTRY_PS (1 << NFIFOENTRY_PS_SHIFT)
-
+#define NFIFOENTRY_PS_SHIFT 10
+#define NFIFOENTRY_PS_MASK (1 << NFIFOENTRY_PS_SHIFT)
+#define NFIFOENTRY_PS (1 << NFIFOENTRY_PS_SHIFT)
#define NFIFOENTRY_DLEN_SHIFT 0
#define NFIFOENTRY_DLEN_MASK (0xFFF << NFIFOENTRY_DLEN_SHIFT)
@@ -1591,15 +1590,15 @@
*/
/* IPSec ESP CBC Encap/Decap Options */
-#define PDBOPTS_ESPCBC_ARSNONE 0x00 /* no antireplay window */
-#define PDBOPTS_ESPCBC_ARS32 0x40 /* 32-entry antireplay window */
-#define PDBOPTS_ESPCBC_ARS64 0xc0 /* 64-entry antireplay window */
-#define PDBOPTS_ESPCBC_IVSRC 0x20 /* IV comes from internal random gen */
-#define PDBOPTS_ESPCBC_ESN 0x10 /* extended sequence included */
-#define PDBOPTS_ESPCBC_OUTFMT 0x08 /* output only decapsulation (decap) */
-#define PDBOPTS_ESPCBC_IPHDRSRC 0x08 /* IP header comes from PDB (encap) */
-#define PDBOPTS_ESPCBC_INCIPHDR 0x04 /* Prepend IP header to output frame */
-#define PDBOPTS_ESPCBC_IPVSN 0x02 /* process IPv6 header */
-#define PDBOPTS_ESPCBC_TUNNEL 0x01 /* tunnel mode next-header byte */
+#define PDBOPTS_ESPCBC_ARSNONE 0x00 /* no antireplay window */
+#define PDBOPTS_ESPCBC_ARS32 0x40 /* 32-entry antireplay window */
+#define PDBOPTS_ESPCBC_ARS64 0xc0 /* 64-entry antireplay window */
+#define PDBOPTS_ESPCBC_IVSRC 0x20 /* IV comes from internal random gen */
+#define PDBOPTS_ESPCBC_ESN 0x10 /* extended sequence included */
+#define PDBOPTS_ESPCBC_OUTFMT 0x08 /* output only decapsulation (decap) */
+#define PDBOPTS_ESPCBC_IPHDRSRC 0x08 /* IP header comes from PDB (encap) */
+#define PDBOPTS_ESPCBC_INCIPHDR 0x04 /* Prepend IP header to output frame */
+#define PDBOPTS_ESPCBC_IPVSN 0x02 /* process IPv6 header */
+#define PDBOPTS_ESPCBC_TUNNEL 0x01 /* tunnel mode next-header byte */
#endif /* DESC_H */
diff --git a/drivers/crypto/caam/desc_constr.h b/drivers/crypto/caam/desc_constr.h
index 0991323..348b882 100644
--- a/drivers/crypto/caam/desc_constr.h
+++ b/drivers/crypto/caam/desc_constr.h
@@ -18,9 +18,10 @@
#define PRINT_POS
#endif
-#define SET_OK_PROP_ERRORS (IMMEDIATE | LDST_CLASS_DECO | \
- LDST_SRCDST_WORD_DECOCTRL | \
- (LDOFF_CHG_SHARE_OK_PROP << LDST_OFFSET_SHIFT))
+#define SET_OK_NO_PROP_ERRORS (IMMEDIATE | LDST_CLASS_DECO | \
+ LDST_SRCDST_WORD_DECOCTRL | \
+ (LDOFF_CHG_SHARE_OK_NO_PROP << \
+ LDST_OFFSET_SHIFT))
#define DISABLE_AUTO_INFO_FIFO (IMMEDIATE | LDST_CLASS_DECO | \
LDST_SRCDST_WORD_DECOCTRL | \
(LDOFF_DISABLE_AUTO_NFIFO << LDST_OFFSET_SHIFT))
diff --git a/drivers/crypto/caam/regs.h b/drivers/crypto/caam/regs.h
index aee394e..e9f7a70 100644
--- a/drivers/crypto/caam/regs.h
+++ b/drivers/crypto/caam/regs.h
@@ -657,7 +657,6 @@
u64 rsvd[512];
struct caam_assurance assure;
struct caam_queue_if qi;
- struct caam_deco *deco;
};
#endif /* REGS_H */
diff --git a/drivers/crypto/mv_cesa.c b/drivers/crypto/mv_cesa.c
index dcd8bab..597235a 100644
--- a/drivers/crypto/mv_cesa.c
+++ b/drivers/crypto/mv_cesa.c
@@ -1128,17 +1128,7 @@
};
MODULE_ALIAS("platform:mv_crypto");
-static int __init mv_crypto_init(void)
-{
- return platform_driver_register(&marvell_crypto);
-}
-module_init(mv_crypto_init);
-
-static void __exit mv_crypto_exit(void)
-{
- platform_driver_unregister(&marvell_crypto);
-}
-module_exit(mv_crypto_exit);
+module_platform_driver(marvell_crypto);
MODULE_AUTHOR("Sebastian Andrzej Siewior <sebastian@breakpoint.cc>");
MODULE_DESCRIPTION("Support for Marvell's cryptographic engine");
diff --git a/drivers/crypto/picoxcell_crypto.c b/drivers/crypto/picoxcell_crypto.c
index a2b553e..58480d0 100644
--- a/drivers/crypto/picoxcell_crypto.c
+++ b/drivers/crypto/picoxcell_crypto.c
@@ -873,7 +873,7 @@
* request for any other size (192 bits) then we need to do a software
* fallback.
*/
- if ((len != AES_KEYSIZE_128 || len != AES_KEYSIZE_256) &&
+ if (len != AES_KEYSIZE_128 && len != AES_KEYSIZE_256 &&
ctx->sw_cipher) {
/*
* Set the fallback transform to use the same request flags as
@@ -886,7 +886,7 @@
err = crypto_ablkcipher_setkey(ctx->sw_cipher, key, len);
if (err)
goto sw_setkey_failed;
- } else if ((len != AES_KEYSIZE_128 || len != AES_KEYSIZE_256) &&
+ } else if (len != AES_KEYSIZE_128 && len != AES_KEYSIZE_256 &&
!ctx->sw_cipher)
err = -EINVAL;
@@ -1854,17 +1854,7 @@
.id_table = spacc_id_table,
};
-static int __init spacc_init(void)
-{
- return platform_driver_register(&spacc_driver);
-}
-module_init(spacc_init);
-
-static void __exit spacc_exit(void)
-{
- platform_driver_unregister(&spacc_driver);
-}
-module_exit(spacc_exit);
+module_platform_driver(spacc_driver);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Jamie Iles");
diff --git a/drivers/crypto/s5p-sss.c b/drivers/crypto/s5p-sss.c
index 8115417..3376bca 100644
--- a/drivers/crypto/s5p-sss.c
+++ b/drivers/crypto/s5p-sss.c
@@ -683,18 +683,7 @@
},
};
-static int __init s5p_aes_mod_init(void)
-{
- return platform_driver_register(&s5p_aes_crypto);
-}
-
-static void __exit s5p_aes_mod_exit(void)
-{
- platform_driver_unregister(&s5p_aes_crypto);
-}
-
-module_init(s5p_aes_mod_init);
-module_exit(s5p_aes_mod_exit);
+module_platform_driver(s5p_aes_crypto);
MODULE_DESCRIPTION("S5PV210 AES hw acceleration support.");
MODULE_LICENSE("GPL v2");
diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index dbe76b5..2d8c789 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -99,6 +99,8 @@
/* per-channel fifo management */
struct talitos_channel {
+ void __iomem *reg;
+
/* request fifo */
struct talitos_request *fifo;
@@ -120,7 +122,7 @@
struct device *dev;
struct platform_device *ofdev;
void __iomem *reg;
- int irq;
+ int irq[2];
/* SEC version geometry (from device tree node) */
unsigned int num_channels;
@@ -144,7 +146,7 @@
atomic_t last_chan ____cacheline_aligned;
/* request callback tasklet */
- struct tasklet_struct done_task;
+ struct tasklet_struct done_task[2];
/* list of registered algorithms */
struct list_head alg_list;
@@ -157,6 +159,7 @@
#define TALITOS_FTR_SRC_LINK_TBL_LEN_INCLUDES_EXTENT 0x00000001
#define TALITOS_FTR_HW_AUTH_CHECK 0x00000002
#define TALITOS_FTR_SHA224_HWINIT 0x00000004
+#define TALITOS_FTR_HMAC_OK 0x00000008
static void to_talitos_ptr(struct talitos_ptr *talitos_ptr, dma_addr_t dma_addr)
{
@@ -196,9 +199,9 @@
struct talitos_private *priv = dev_get_drvdata(dev);
unsigned int timeout = TALITOS_TIMEOUT;
- setbits32(priv->reg + TALITOS_CCCR(ch), TALITOS_CCCR_RESET);
+ setbits32(priv->chan[ch].reg + TALITOS_CCCR, TALITOS_CCCR_RESET);
- while ((in_be32(priv->reg + TALITOS_CCCR(ch)) & TALITOS_CCCR_RESET)
+ while ((in_be32(priv->chan[ch].reg + TALITOS_CCCR) & TALITOS_CCCR_RESET)
&& --timeout)
cpu_relax();
@@ -208,12 +211,12 @@
}
/* set 36-bit addressing, done writeback enable and done IRQ enable */
- setbits32(priv->reg + TALITOS_CCCR_LO(ch), TALITOS_CCCR_LO_EAE |
+ setbits32(priv->chan[ch].reg + TALITOS_CCCR_LO, TALITOS_CCCR_LO_EAE |
TALITOS_CCCR_LO_CDWE | TALITOS_CCCR_LO_CDIE);
/* and ICCR writeback, if available */
if (priv->features & TALITOS_FTR_HW_AUTH_CHECK)
- setbits32(priv->reg + TALITOS_CCCR_LO(ch),
+ setbits32(priv->chan[ch].reg + TALITOS_CCCR_LO,
TALITOS_CCCR_LO_IWSE);
return 0;
@@ -223,13 +226,19 @@
{
struct talitos_private *priv = dev_get_drvdata(dev);
unsigned int timeout = TALITOS_TIMEOUT;
+ u32 mcr = TALITOS_MCR_SWR;
- setbits32(priv->reg + TALITOS_MCR, TALITOS_MCR_SWR);
+ setbits32(priv->reg + TALITOS_MCR, mcr);
while ((in_be32(priv->reg + TALITOS_MCR) & TALITOS_MCR_SWR)
&& --timeout)
cpu_relax();
+ if (priv->irq[1]) {
+ mcr = TALITOS_MCR_RCA1 | TALITOS_MCR_RCA3;
+ setbits32(priv->reg + TALITOS_MCR, mcr);
+ }
+
if (timeout == 0) {
dev_err(dev, "failed to reset device\n");
return -EIO;
@@ -327,8 +336,9 @@
/* GO! */
wmb();
- out_be32(priv->reg + TALITOS_FF(ch), upper_32_bits(request->dma_desc));
- out_be32(priv->reg + TALITOS_FF_LO(ch),
+ out_be32(priv->chan[ch].reg + TALITOS_FF,
+ upper_32_bits(request->dma_desc));
+ out_be32(priv->chan[ch].reg + TALITOS_FF_LO,
lower_32_bits(request->dma_desc));
spin_unlock_irqrestore(&priv->chan[ch].head_lock, flags);
@@ -397,21 +407,32 @@
/*
* process completed requests for channels that have done status
*/
-static void talitos_done(unsigned long data)
-{
- struct device *dev = (struct device *)data;
- struct talitos_private *priv = dev_get_drvdata(dev);
- int ch;
-
- for (ch = 0; ch < priv->num_channels; ch++)
- flush_channel(dev, ch, 0, 0);
-
- /* At this point, all completed channels have been processed.
- * Unmask done interrupts for channels completed later on.
- */
- setbits32(priv->reg + TALITOS_IMR, TALITOS_IMR_INIT);
- setbits32(priv->reg + TALITOS_IMR_LO, TALITOS_IMR_LO_INIT);
+#define DEF_TALITOS_DONE(name, ch_done_mask) \
+static void talitos_done_##name(unsigned long data) \
+{ \
+ struct device *dev = (struct device *)data; \
+ struct talitos_private *priv = dev_get_drvdata(dev); \
+ \
+ if (ch_done_mask & 1) \
+ flush_channel(dev, 0, 0, 0); \
+ if (priv->num_channels == 1) \
+ goto out; \
+ if (ch_done_mask & (1 << 2)) \
+ flush_channel(dev, 1, 0, 0); \
+ if (ch_done_mask & (1 << 4)) \
+ flush_channel(dev, 2, 0, 0); \
+ if (ch_done_mask & (1 << 6)) \
+ flush_channel(dev, 3, 0, 0); \
+ \
+out: \
+ /* At this point, all completed channels have been processed */ \
+ /* Unmask done interrupts for channels completed later on. */ \
+ setbits32(priv->reg + TALITOS_IMR, ch_done_mask); \
+ setbits32(priv->reg + TALITOS_IMR_LO, TALITOS_IMR_LO_INIT); \
}
+DEF_TALITOS_DONE(4ch, TALITOS_ISR_4CHDONE)
+DEF_TALITOS_DONE(ch0_2, TALITOS_ISR_CH_0_2_DONE)
+DEF_TALITOS_DONE(ch1_3, TALITOS_ISR_CH_1_3_DONE)
/*
* locate current (offending) descriptor
@@ -422,7 +443,7 @@
int tail = priv->chan[ch].tail;
dma_addr_t cur_desc;
- cur_desc = in_be32(priv->reg + TALITOS_CDPR_LO(ch));
+ cur_desc = in_be32(priv->chan[ch].reg + TALITOS_CDPR_LO);
while (priv->chan[ch].fifo[tail].dma_desc != cur_desc) {
tail = (tail + 1) & (priv->fifo_len - 1);
@@ -444,7 +465,7 @@
int i;
if (!desc_hdr)
- desc_hdr = in_be32(priv->reg + TALITOS_DESCBUF(ch));
+ desc_hdr = in_be32(priv->chan[ch].reg + TALITOS_DESCBUF);
switch (desc_hdr & DESC_HDR_SEL0_MASK) {
case DESC_HDR_SEL0_AFEU:
@@ -506,16 +527,15 @@
for (i = 0; i < 8; i++)
dev_err(dev, "DESCBUF 0x%08x_%08x\n",
- in_be32(priv->reg + TALITOS_DESCBUF(ch) + 8*i),
- in_be32(priv->reg + TALITOS_DESCBUF_LO(ch) + 8*i));
+ in_be32(priv->chan[ch].reg + TALITOS_DESCBUF + 8*i),
+ in_be32(priv->chan[ch].reg + TALITOS_DESCBUF_LO + 8*i));
}
/*
* recover from error interrupts
*/
-static void talitos_error(unsigned long data, u32 isr, u32 isr_lo)
+static void talitos_error(struct device *dev, u32 isr, u32 isr_lo)
{
- struct device *dev = (struct device *)data;
struct talitos_private *priv = dev_get_drvdata(dev);
unsigned int timeout = TALITOS_TIMEOUT;
int ch, error, reset_dev = 0, reset_ch = 0;
@@ -528,8 +548,8 @@
error = -EINVAL;
- v = in_be32(priv->reg + TALITOS_CCPSR(ch));
- v_lo = in_be32(priv->reg + TALITOS_CCPSR_LO(ch));
+ v = in_be32(priv->chan[ch].reg + TALITOS_CCPSR);
+ v_lo = in_be32(priv->chan[ch].reg + TALITOS_CCPSR_LO);
if (v_lo & TALITOS_CCPSR_LO_DOF) {
dev_err(dev, "double fetch fifo overflow error\n");
@@ -567,10 +587,10 @@
if (reset_ch) {
reset_channel(dev, ch);
} else {
- setbits32(priv->reg + TALITOS_CCCR(ch),
+ setbits32(priv->chan[ch].reg + TALITOS_CCCR,
TALITOS_CCCR_CONT);
- setbits32(priv->reg + TALITOS_CCCR_LO(ch), 0);
- while ((in_be32(priv->reg + TALITOS_CCCR(ch)) &
+ setbits32(priv->chan[ch].reg + TALITOS_CCCR_LO, 0);
+ while ((in_be32(priv->chan[ch].reg + TALITOS_CCCR) &
TALITOS_CCCR_CONT) && --timeout)
cpu_relax();
if (timeout == 0) {
@@ -580,7 +600,7 @@
}
}
}
- if (reset_dev || isr & ~TALITOS_ISR_CHERR || isr_lo) {
+ if (reset_dev || isr & ~TALITOS_ISR_4CHERR || isr_lo) {
dev_err(dev, "done overflow, internal time out, or rngu error: "
"ISR 0x%08x_%08x\n", isr, isr_lo);
@@ -593,30 +613,35 @@
}
}
-static irqreturn_t talitos_interrupt(int irq, void *data)
-{
- struct device *dev = data;
- struct talitos_private *priv = dev_get_drvdata(dev);
- u32 isr, isr_lo;
-
- isr = in_be32(priv->reg + TALITOS_ISR);
- isr_lo = in_be32(priv->reg + TALITOS_ISR_LO);
- /* Acknowledge interrupt */
- out_be32(priv->reg + TALITOS_ICR, isr);
- out_be32(priv->reg + TALITOS_ICR_LO, isr_lo);
-
- if (unlikely((isr & ~TALITOS_ISR_CHDONE) || isr_lo))
- talitos_error((unsigned long)data, isr, isr_lo);
- else
- if (likely(isr & TALITOS_ISR_CHDONE)) {
- /* mask further done interrupts. */
- clrbits32(priv->reg + TALITOS_IMR, TALITOS_IMR_DONE);
- /* done_task will unmask done interrupts at exit */
- tasklet_schedule(&priv->done_task);
- }
-
- return (isr || isr_lo) ? IRQ_HANDLED : IRQ_NONE;
+#define DEF_TALITOS_INTERRUPT(name, ch_done_mask, ch_err_mask, tlet) \
+static irqreturn_t talitos_interrupt_##name(int irq, void *data) \
+{ \
+ struct device *dev = data; \
+ struct talitos_private *priv = dev_get_drvdata(dev); \
+ u32 isr, isr_lo; \
+ \
+ isr = in_be32(priv->reg + TALITOS_ISR); \
+ isr_lo = in_be32(priv->reg + TALITOS_ISR_LO); \
+ /* Acknowledge interrupt */ \
+ out_be32(priv->reg + TALITOS_ICR, isr & (ch_done_mask | ch_err_mask)); \
+ out_be32(priv->reg + TALITOS_ICR_LO, isr_lo); \
+ \
+ if (unlikely((isr & ~TALITOS_ISR_4CHDONE) & ch_err_mask || isr_lo)) \
+ talitos_error(dev, isr, isr_lo); \
+ else \
+ if (likely(isr & ch_done_mask)) { \
+ /* mask further done interrupts. */ \
+ clrbits32(priv->reg + TALITOS_IMR, ch_done_mask); \
+ /* done_task will unmask done interrupts at exit */ \
+ tasklet_schedule(&priv->done_task[tlet]); \
+ } \
+ \
+ return (isr & (ch_done_mask | ch_err_mask) || isr_lo) ? IRQ_HANDLED : \
+ IRQ_NONE; \
}
+DEF_TALITOS_INTERRUPT(4ch, TALITOS_ISR_4CHDONE, TALITOS_ISR_4CHERR, 0)
+DEF_TALITOS_INTERRUPT(ch0_2, TALITOS_ISR_CH_0_2_DONE, TALITOS_ISR_CH_0_2_ERR, 0)
+DEF_TALITOS_INTERRUPT(ch1_3, TALITOS_ISR_CH_1_3_DONE, TALITOS_ISR_CH_1_3_ERR, 1)
/*
* hwrng
@@ -1874,6 +1899,97 @@
return ahash_process_req(areq, areq->nbytes);
}
+struct keyhash_result {
+ struct completion completion;
+ int err;
+};
+
+static void keyhash_complete(struct crypto_async_request *req, int err)
+{
+ struct keyhash_result *res = req->data;
+
+ if (err == -EINPROGRESS)
+ return;
+
+ res->err = err;
+ complete(&res->completion);
+}
+
+static int keyhash(struct crypto_ahash *tfm, const u8 *key, unsigned int keylen,
+ u8 *hash)
+{
+ struct talitos_ctx *ctx = crypto_tfm_ctx(crypto_ahash_tfm(tfm));
+
+ struct scatterlist sg[1];
+ struct ahash_request *req;
+ struct keyhash_result hresult;
+ int ret;
+
+ init_completion(&hresult.completion);
+
+ req = ahash_request_alloc(tfm, GFP_KERNEL);
+ if (!req)
+ return -ENOMEM;
+
+ /* Keep tfm keylen == 0 during hash of the long key */
+ ctx->keylen = 0;
+ ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
+ keyhash_complete, &hresult);
+
+ sg_init_one(&sg[0], key, keylen);
+
+ ahash_request_set_crypt(req, sg, hash, keylen);
+ ret = crypto_ahash_digest(req);
+ switch (ret) {
+ case 0:
+ break;
+ case -EINPROGRESS:
+ case -EBUSY:
+ ret = wait_for_completion_interruptible(
+ &hresult.completion);
+ if (!ret)
+ ret = hresult.err;
+ break;
+ default:
+ break;
+ }
+ ahash_request_free(req);
+
+ return ret;
+}
+
+static int ahash_setkey(struct crypto_ahash *tfm, const u8 *key,
+ unsigned int keylen)
+{
+ struct talitos_ctx *ctx = crypto_tfm_ctx(crypto_ahash_tfm(tfm));
+ unsigned int blocksize =
+ crypto_tfm_alg_blocksize(crypto_ahash_tfm(tfm));
+ unsigned int digestsize = crypto_ahash_digestsize(tfm);
+ unsigned int keysize = keylen;
+ u8 hash[SHA512_DIGEST_SIZE];
+ int ret;
+
+ if (keylen <= blocksize)
+ memcpy(ctx->key, key, keysize);
+ else {
+ /* Must get the hash of the long key */
+ ret = keyhash(tfm, key, keylen, hash);
+
+ if (ret) {
+ crypto_ahash_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
+ return -EINVAL;
+ }
+
+ keysize = digestsize;
+ memcpy(ctx->key, hash, digestsize);
+ }
+
+ ctx->keylen = keysize;
+
+ return 0;
+}
+
+
struct talitos_alg_template {
u32 type;
union {
@@ -2217,6 +2333,138 @@
DESC_HDR_SEL0_MDEUB |
DESC_HDR_MODE0_MDEUB_SHA512,
},
+ { .type = CRYPTO_ALG_TYPE_AHASH,
+ .alg.hash = {
+ .init = ahash_init,
+ .update = ahash_update,
+ .final = ahash_final,
+ .finup = ahash_finup,
+ .digest = ahash_digest,
+ .setkey = ahash_setkey,
+ .halg.digestsize = MD5_DIGEST_SIZE,
+ .halg.base = {
+ .cra_name = "hmac(md5)",
+ .cra_driver_name = "hmac-md5-talitos",
+ .cra_blocksize = MD5_BLOCK_SIZE,
+ .cra_flags = CRYPTO_ALG_TYPE_AHASH |
+ CRYPTO_ALG_ASYNC,
+ .cra_type = &crypto_ahash_type
+ }
+ },
+ .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
+ DESC_HDR_SEL0_MDEUA |
+ DESC_HDR_MODE0_MDEU_MD5,
+ },
+ { .type = CRYPTO_ALG_TYPE_AHASH,
+ .alg.hash = {
+ .init = ahash_init,
+ .update = ahash_update,
+ .final = ahash_final,
+ .finup = ahash_finup,
+ .digest = ahash_digest,
+ .setkey = ahash_setkey,
+ .halg.digestsize = SHA1_DIGEST_SIZE,
+ .halg.base = {
+ .cra_name = "hmac(sha1)",
+ .cra_driver_name = "hmac-sha1-talitos",
+ .cra_blocksize = SHA1_BLOCK_SIZE,
+ .cra_flags = CRYPTO_ALG_TYPE_AHASH |
+ CRYPTO_ALG_ASYNC,
+ .cra_type = &crypto_ahash_type
+ }
+ },
+ .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
+ DESC_HDR_SEL0_MDEUA |
+ DESC_HDR_MODE0_MDEU_SHA1,
+ },
+ { .type = CRYPTO_ALG_TYPE_AHASH,
+ .alg.hash = {
+ .init = ahash_init,
+ .update = ahash_update,
+ .final = ahash_final,
+ .finup = ahash_finup,
+ .digest = ahash_digest,
+ .setkey = ahash_setkey,
+ .halg.digestsize = SHA224_DIGEST_SIZE,
+ .halg.base = {
+ .cra_name = "hmac(sha224)",
+ .cra_driver_name = "hmac-sha224-talitos",
+ .cra_blocksize = SHA224_BLOCK_SIZE,
+ .cra_flags = CRYPTO_ALG_TYPE_AHASH |
+ CRYPTO_ALG_ASYNC,
+ .cra_type = &crypto_ahash_type
+ }
+ },
+ .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
+ DESC_HDR_SEL0_MDEUA |
+ DESC_HDR_MODE0_MDEU_SHA224,
+ },
+ { .type = CRYPTO_ALG_TYPE_AHASH,
+ .alg.hash = {
+ .init = ahash_init,
+ .update = ahash_update,
+ .final = ahash_final,
+ .finup = ahash_finup,
+ .digest = ahash_digest,
+ .setkey = ahash_setkey,
+ .halg.digestsize = SHA256_DIGEST_SIZE,
+ .halg.base = {
+ .cra_name = "hmac(sha256)",
+ .cra_driver_name = "hmac-sha256-talitos",
+ .cra_blocksize = SHA256_BLOCK_SIZE,
+ .cra_flags = CRYPTO_ALG_TYPE_AHASH |
+ CRYPTO_ALG_ASYNC,
+ .cra_type = &crypto_ahash_type
+ }
+ },
+ .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
+ DESC_HDR_SEL0_MDEUA |
+ DESC_HDR_MODE0_MDEU_SHA256,
+ },
+ { .type = CRYPTO_ALG_TYPE_AHASH,
+ .alg.hash = {
+ .init = ahash_init,
+ .update = ahash_update,
+ .final = ahash_final,
+ .finup = ahash_finup,
+ .digest = ahash_digest,
+ .setkey = ahash_setkey,
+ .halg.digestsize = SHA384_DIGEST_SIZE,
+ .halg.base = {
+ .cra_name = "hmac(sha384)",
+ .cra_driver_name = "hmac-sha384-talitos",
+ .cra_blocksize = SHA384_BLOCK_SIZE,
+ .cra_flags = CRYPTO_ALG_TYPE_AHASH |
+ CRYPTO_ALG_ASYNC,
+ .cra_type = &crypto_ahash_type
+ }
+ },
+ .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
+ DESC_HDR_SEL0_MDEUB |
+ DESC_HDR_MODE0_MDEUB_SHA384,
+ },
+ { .type = CRYPTO_ALG_TYPE_AHASH,
+ .alg.hash = {
+ .init = ahash_init,
+ .update = ahash_update,
+ .final = ahash_final,
+ .finup = ahash_finup,
+ .digest = ahash_digest,
+ .setkey = ahash_setkey,
+ .halg.digestsize = SHA512_DIGEST_SIZE,
+ .halg.base = {
+ .cra_name = "hmac(sha512)",
+ .cra_driver_name = "hmac-sha512-talitos",
+ .cra_blocksize = SHA512_BLOCK_SIZE,
+ .cra_flags = CRYPTO_ALG_TYPE_AHASH |
+ CRYPTO_ALG_ASYNC,
+ .cra_type = &crypto_ahash_type
+ }
+ },
+ .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
+ DESC_HDR_SEL0_MDEUB |
+ DESC_HDR_MODE0_MDEUB_SHA512,
+ }
};
struct talitos_crypto_alg {
@@ -2331,12 +2579,15 @@
kfree(priv->chan);
- if (priv->irq != NO_IRQ) {
- free_irq(priv->irq, dev);
- irq_dispose_mapping(priv->irq);
- }
+ for (i = 0; i < 2; i++)
+ if (priv->irq[i]) {
+ free_irq(priv->irq[i], dev);
+ irq_dispose_mapping(priv->irq[i]);
+ }
- tasklet_kill(&priv->done_task);
+ tasklet_kill(&priv->done_task[0]);
+ if (priv->irq[1])
+ tasklet_kill(&priv->done_task[1]);
iounmap(priv->reg);
@@ -2373,8 +2624,14 @@
case CRYPTO_ALG_TYPE_AHASH:
alg = &t_alg->algt.alg.hash.halg.base;
alg->cra_init = talitos_cra_init_ahash;
+ if (!(priv->features & TALITOS_FTR_HMAC_OK) &&
+ !strncmp(alg->cra_name, "hmac", 4)) {
+ kfree(t_alg);
+ return ERR_PTR(-ENOTSUPP);
+ }
if (!(priv->features & TALITOS_FTR_SHA224_HWINIT) &&
- !strcmp(alg->cra_name, "sha224")) {
+ (!strcmp(alg->cra_name, "sha224") ||
+ !strcmp(alg->cra_name, "hmac(sha224)"))) {
t_alg->algt.alg.hash.init = ahash_init_sha224_swinit;
t_alg->algt.desc_hdr_template =
DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
@@ -2397,6 +2654,54 @@
return t_alg;
}
+static int talitos_probe_irq(struct platform_device *ofdev)
+{
+ struct device *dev = &ofdev->dev;
+ struct device_node *np = ofdev->dev.of_node;
+ struct talitos_private *priv = dev_get_drvdata(dev);
+ int err;
+
+ priv->irq[0] = irq_of_parse_and_map(np, 0);
+ if (!priv->irq[0]) {
+ dev_err(dev, "failed to map irq\n");
+ return -EINVAL;
+ }
+
+ priv->irq[1] = irq_of_parse_and_map(np, 1);
+
+ /* get the primary irq line */
+ if (!priv->irq[1]) {
+ err = request_irq(priv->irq[0], talitos_interrupt_4ch, 0,
+ dev_driver_string(dev), dev);
+ goto primary_out;
+ }
+
+ err = request_irq(priv->irq[0], talitos_interrupt_ch0_2, 0,
+ dev_driver_string(dev), dev);
+ if (err)
+ goto primary_out;
+
+ /* get the secondary irq line */
+ err = request_irq(priv->irq[1], talitos_interrupt_ch1_3, 0,
+ dev_driver_string(dev), dev);
+ if (err) {
+ dev_err(dev, "failed to request secondary irq\n");
+ irq_dispose_mapping(priv->irq[1]);
+ priv->irq[1] = 0;
+ }
+
+ return err;
+
+primary_out:
+ if (err) {
+ dev_err(dev, "failed to request primary irq\n");
+ irq_dispose_mapping(priv->irq[0]);
+ priv->irq[0] = 0;
+ }
+
+ return err;
+}
+
static int talitos_probe(struct platform_device *ofdev)
{
struct device *dev = &ofdev->dev;
@@ -2413,28 +2718,22 @@
priv->ofdev = ofdev;
- tasklet_init(&priv->done_task, talitos_done, (unsigned long)dev);
+ err = talitos_probe_irq(ofdev);
+ if (err)
+ goto err_out;
+
+ if (!priv->irq[1]) {
+ tasklet_init(&priv->done_task[0], talitos_done_4ch,
+ (unsigned long)dev);
+ } else {
+ tasklet_init(&priv->done_task[0], talitos_done_ch0_2,
+ (unsigned long)dev);
+ tasklet_init(&priv->done_task[1], talitos_done_ch1_3,
+ (unsigned long)dev);
+ }
INIT_LIST_HEAD(&priv->alg_list);
- priv->irq = irq_of_parse_and_map(np, 0);
-
- if (priv->irq == NO_IRQ) {
- dev_err(dev, "failed to map irq\n");
- err = -EINVAL;
- goto err_out;
- }
-
- /* get the irq line */
- err = request_irq(priv->irq, talitos_interrupt, 0,
- dev_driver_string(dev), dev);
- if (err) {
- dev_err(dev, "failed to request irq %d\n", priv->irq);
- irq_dispose_mapping(priv->irq);
- priv->irq = NO_IRQ;
- goto err_out;
- }
-
priv->reg = of_iomap(np, 0);
if (!priv->reg) {
dev_err(dev, "failed to of_iomap\n");
@@ -2471,7 +2770,8 @@
if (of_device_is_compatible(np, "fsl,sec2.1"))
priv->features |= TALITOS_FTR_HW_AUTH_CHECK |
- TALITOS_FTR_SHA224_HWINIT;
+ TALITOS_FTR_SHA224_HWINIT |
+ TALITOS_FTR_HMAC_OK;
priv->chan = kzalloc(sizeof(struct talitos_channel) *
priv->num_channels, GFP_KERNEL);
@@ -2482,6 +2782,12 @@
}
for (i = 0; i < priv->num_channels; i++) {
+ priv->chan[i].reg = priv->reg + TALITOS_CH_STRIDE * (i + 1);
+ if (!priv->irq[1] || !(i & 1))
+ priv->chan[i].reg += TALITOS_CH_BASE_OFFSET;
+ }
+
+ for (i = 0; i < priv->num_channels; i++) {
spin_lock_init(&priv->chan[i].head_lock);
spin_lock_init(&priv->chan[i].tail_lock);
}
@@ -2530,6 +2836,8 @@
t_alg = talitos_alg_alloc(dev, &driver_algs[i]);
if (IS_ERR(t_alg)) {
err = PTR_ERR(t_alg);
+ if (err == -ENOTSUPP)
+ continue;
goto err_out;
}
@@ -2551,12 +2859,13 @@
dev_err(dev, "%s alg registration failed\n",
name);
kfree(t_alg);
- } else {
+ } else
list_add_tail(&t_alg->entry, &priv->alg_list);
- dev_info(dev, "%s\n", name);
- }
}
}
+ if (!list_empty(&priv->alg_list))
+ dev_info(dev, "%s algorithms registered in /proc/crypto\n",
+ (char *)of_get_property(np, "compatible", NULL));
return 0;
@@ -2584,17 +2893,7 @@
.remove = talitos_remove,
};
-static int __init talitos_init(void)
-{
- return platform_driver_register(&talitos_driver);
-}
-module_init(talitos_init);
-
-static void __exit talitos_exit(void)
-{
- platform_driver_unregister(&talitos_driver);
-}
-module_exit(talitos_exit);
+module_platform_driver(talitos_driver);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Kim Phillips <kim.phillips@freescale.com>");
diff --git a/drivers/crypto/talitos.h b/drivers/crypto/talitos.h
index 0b746ac..3c17395 100644
--- a/drivers/crypto/talitos.h
+++ b/drivers/crypto/talitos.h
@@ -1,7 +1,7 @@
/*
* Freescale SEC (talitos) device register and descriptor header defines
*
- * Copyright (c) 2006-2010 Freescale Semiconductor, Inc.
+ * Copyright (c) 2006-2011 Freescale Semiconductor, Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -34,28 +34,37 @@
/* global register offset addresses */
#define TALITOS_MCR 0x1030 /* master control register */
-#define TALITOS_MCR_LO 0x1038
+#define TALITOS_MCR_RCA0 (1 << 15) /* remap channel 0 */
+#define TALITOS_MCR_RCA1 (1 << 14) /* remap channel 1 */
+#define TALITOS_MCR_RCA2 (1 << 13) /* remap channel 2 */
+#define TALITOS_MCR_RCA3 (1 << 12) /* remap channel 3 */
#define TALITOS_MCR_SWR 0x1 /* s/w reset */
+#define TALITOS_MCR_LO 0x1034
#define TALITOS_IMR 0x1008 /* interrupt mask register */
#define TALITOS_IMR_INIT 0x100ff /* enable channel IRQs */
#define TALITOS_IMR_DONE 0x00055 /* done IRQs */
#define TALITOS_IMR_LO 0x100C
#define TALITOS_IMR_LO_INIT 0x20000 /* allow RNGU error IRQs */
#define TALITOS_ISR 0x1010 /* interrupt status register */
-#define TALITOS_ISR_CHERR 0xaa /* channel errors mask */
-#define TALITOS_ISR_CHDONE 0x55 /* channel done mask */
+#define TALITOS_ISR_4CHERR 0xaa /* 4 channel errors mask */
+#define TALITOS_ISR_4CHDONE 0x55 /* 4 channel done mask */
+#define TALITOS_ISR_CH_0_2_ERR 0x22 /* channels 0, 2 errors mask */
+#define TALITOS_ISR_CH_0_2_DONE 0x11 /* channels 0, 2 done mask */
+#define TALITOS_ISR_CH_1_3_ERR 0x88 /* channels 1, 3 errors mask */
+#define TALITOS_ISR_CH_1_3_DONE 0x44 /* channels 1, 3 done mask */
#define TALITOS_ISR_LO 0x1014
#define TALITOS_ICR 0x1018 /* interrupt clear register */
#define TALITOS_ICR_LO 0x101C
/* channel register address stride */
+#define TALITOS_CH_BASE_OFFSET 0x1000 /* default channel map base */
#define TALITOS_CH_STRIDE 0x100
/* channel configuration register */
-#define TALITOS_CCCR(ch) (ch * TALITOS_CH_STRIDE + 0x1108)
+#define TALITOS_CCCR 0x8
#define TALITOS_CCCR_CONT 0x2 /* channel continue */
#define TALITOS_CCCR_RESET 0x1 /* channel reset */
-#define TALITOS_CCCR_LO(ch) (ch * TALITOS_CH_STRIDE + 0x110c)
+#define TALITOS_CCCR_LO 0xc
#define TALITOS_CCCR_LO_IWSE 0x80 /* chan. ICCR writeback enab. */
#define TALITOS_CCCR_LO_EAE 0x20 /* extended address enable */
#define TALITOS_CCCR_LO_CDWE 0x10 /* chan. done writeback enab. */
@@ -63,8 +72,8 @@
#define TALITOS_CCCR_LO_CDIE 0x2 /* channel done IRQ enable */
/* CCPSR: channel pointer status register */
-#define TALITOS_CCPSR(ch) (ch * TALITOS_CH_STRIDE + 0x1110)
-#define TALITOS_CCPSR_LO(ch) (ch * TALITOS_CH_STRIDE + 0x1114)
+#define TALITOS_CCPSR 0x10
+#define TALITOS_CCPSR_LO 0x14
#define TALITOS_CCPSR_LO_DOF 0x8000 /* double FF write oflow error */
#define TALITOS_CCPSR_LO_SOF 0x4000 /* single FF write oflow error */
#define TALITOS_CCPSR_LO_MDTE 0x2000 /* master data transfer error */
@@ -79,24 +88,24 @@
#define TALITOS_CCPSR_LO_SRL 0x0010 /* scatter return/length error */
/* channel fetch fifo register */
-#define TALITOS_FF(ch) (ch * TALITOS_CH_STRIDE + 0x1148)
-#define TALITOS_FF_LO(ch) (ch * TALITOS_CH_STRIDE + 0x114c)
+#define TALITOS_FF 0x48
+#define TALITOS_FF_LO 0x4c
/* current descriptor pointer register */
-#define TALITOS_CDPR(ch) (ch * TALITOS_CH_STRIDE + 0x1140)
-#define TALITOS_CDPR_LO(ch) (ch * TALITOS_CH_STRIDE + 0x1144)
+#define TALITOS_CDPR 0x40
+#define TALITOS_CDPR_LO 0x44
/* descriptor buffer register */
-#define TALITOS_DESCBUF(ch) (ch * TALITOS_CH_STRIDE + 0x1180)
-#define TALITOS_DESCBUF_LO(ch) (ch * TALITOS_CH_STRIDE + 0x1184)
+#define TALITOS_DESCBUF 0x80
+#define TALITOS_DESCBUF_LO 0x84
/* gather link table */
-#define TALITOS_GATHER(ch) (ch * TALITOS_CH_STRIDE + 0x11c0)
-#define TALITOS_GATHER_LO(ch) (ch * TALITOS_CH_STRIDE + 0x11c4)
+#define TALITOS_GATHER 0xc0
+#define TALITOS_GATHER_LO 0xc4
/* scatter link table */
-#define TALITOS_SCATTER(ch) (ch * TALITOS_CH_STRIDE + 0x11e0)
-#define TALITOS_SCATTER_LO(ch) (ch * TALITOS_CH_STRIDE + 0x11e4)
+#define TALITOS_SCATTER 0xe0
+#define TALITOS_SCATTER_LO 0xe4
/* execution unit interrupt status registers */
#define TALITOS_DEUISR 0x2030 /* DES unit */
diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig
index efba163..9b00072 100644
--- a/drivers/firmware/Kconfig
+++ b/drivers/firmware/Kconfig
@@ -145,18 +145,6 @@
detect iSCSI boot parameters dynamically during system boot, say Y.
Otherwise, say N.
-config SIGMA
- tristate "SigmaStudio firmware loader"
- depends on I2C
- select CRC32
- default n
- help
- Enable helper functions for working with Analog Devices SigmaDSP
- parts and binary firmwares produced by Analog Devices SigmaStudio.
-
- If unsure, say N here. Drivers that need these helpers will select
- this option automatically.
-
source "drivers/firmware/google/Kconfig"
endmenu
diff --git a/drivers/firmware/Makefile b/drivers/firmware/Makefile
index 47338c9..5a7e273 100644
--- a/drivers/firmware/Makefile
+++ b/drivers/firmware/Makefile
@@ -12,6 +12,5 @@
obj-$(CONFIG_ISCSI_IBFT_FIND) += iscsi_ibft_find.o
obj-$(CONFIG_ISCSI_IBFT) += iscsi_ibft.o
obj-$(CONFIG_FIRMWARE_MEMMAP) += memmap.o
-obj-$(CONFIG_SIGMA) += sigma.o
obj-$(CONFIG_GOOGLE_FIRMWARE) += google/
diff --git a/drivers/firmware/sigma.c b/drivers/firmware/sigma.c
deleted file mode 100644
index 1eedb6f..0000000
--- a/drivers/firmware/sigma.c
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * Load Analog Devices SigmaStudio firmware files
- *
- * Copyright 2009-2011 Analog Devices Inc.
- *
- * Licensed under the GPL-2 or later.
- */
-
-#include <linux/crc32.h>
-#include <linux/delay.h>
-#include <linux/firmware.h>
-#include <linux/kernel.h>
-#include <linux/i2c.h>
-#include <linux/module.h>
-#include <linux/sigma.h>
-
-static size_t sigma_action_size(struct sigma_action *sa)
-{
- size_t payload = 0;
-
- switch (sa->instr) {
- case SIGMA_ACTION_WRITEXBYTES:
- case SIGMA_ACTION_WRITESINGLE:
- case SIGMA_ACTION_WRITESAFELOAD:
- payload = sigma_action_len(sa);
- break;
- default:
- break;
- }
-
- payload = ALIGN(payload, 2);
-
- return payload + sizeof(struct sigma_action);
-}
-
-/*
- * Returns a negative error value in case of an error, 0 if processing of
- * the firmware should be stopped after this action, 1 otherwise.
- */
-static int
-process_sigma_action(struct i2c_client *client, struct sigma_action *sa)
-{
- size_t len = sigma_action_len(sa);
- int ret;
-
- pr_debug("%s: instr:%i addr:%#x len:%zu\n", __func__,
- sa->instr, sa->addr, len);
-
- switch (sa->instr) {
- case SIGMA_ACTION_WRITEXBYTES:
- case SIGMA_ACTION_WRITESINGLE:
- case SIGMA_ACTION_WRITESAFELOAD:
- ret = i2c_master_send(client, (void *)&sa->addr, len);
- if (ret < 0)
- return -EINVAL;
- break;
- case SIGMA_ACTION_DELAY:
- udelay(len);
- len = 0;
- break;
- case SIGMA_ACTION_END:
- return 0;
- default:
- return -EINVAL;
- }
-
- return 1;
-}
-
-static int
-process_sigma_actions(struct i2c_client *client, struct sigma_firmware *ssfw)
-{
- struct sigma_action *sa;
- size_t size;
- int ret;
-
- while (ssfw->pos + sizeof(*sa) <= ssfw->fw->size) {
- sa = (struct sigma_action *)(ssfw->fw->data + ssfw->pos);
-
- size = sigma_action_size(sa);
- ssfw->pos += size;
- if (ssfw->pos > ssfw->fw->size || size == 0)
- break;
-
- ret = process_sigma_action(client, sa);
-
- pr_debug("%s: action returned %i\n", __func__, ret);
-
- if (ret <= 0)
- return ret;
- }
-
- if (ssfw->pos != ssfw->fw->size)
- return -EINVAL;
-
- return 0;
-}
-
-int process_sigma_firmware(struct i2c_client *client, const char *name)
-{
- int ret;
- struct sigma_firmware_header *ssfw_head;
- struct sigma_firmware ssfw;
- const struct firmware *fw;
- u32 crc;
-
- pr_debug("%s: loading firmware %s\n", __func__, name);
-
- /* first load the blob */
- ret = request_firmware(&fw, name, &client->dev);
- if (ret) {
- pr_debug("%s: request_firmware() failed with %i\n", __func__, ret);
- return ret;
- }
- ssfw.fw = fw;
-
- /* then verify the header */
- ret = -EINVAL;
-
- /*
- * Reject too small or unreasonable large files. The upper limit has been
- * chosen a bit arbitrarily, but it should be enough for all practical
- * purposes and having the limit makes it easier to avoid integer
- * overflows later in the loading process.
- */
- if (fw->size < sizeof(*ssfw_head) || fw->size >= 0x4000000)
- goto done;
-
- ssfw_head = (void *)fw->data;
- if (memcmp(ssfw_head->magic, SIGMA_MAGIC, ARRAY_SIZE(ssfw_head->magic)))
- goto done;
-
- crc = crc32(0, fw->data + sizeof(*ssfw_head),
- fw->size - sizeof(*ssfw_head));
- pr_debug("%s: crc=%x\n", __func__, crc);
- if (crc != le32_to_cpu(ssfw_head->crc))
- goto done;
-
- ssfw.pos = sizeof(*ssfw_head);
-
- /* finally process all of the actions */
- ret = process_sigma_actions(client, &ssfw);
-
- done:
- release_firmware(fw);
-
- pr_debug("%s: loaded %s\n", __func__, name);
-
- return ret;
-}
-EXPORT_SYMBOL(process_sigma_firmware);
-
-MODULE_LICENSE("GPL");
diff --git a/drivers/hid/hid-wacom.c b/drivers/hid/hid-wacom.c
index f218348..b47e58b 100644
--- a/drivers/hid/hid-wacom.c
+++ b/drivers/hid/hid-wacom.c
@@ -49,12 +49,14 @@
static enum power_supply_property wacom_battery_props[] = {
POWER_SUPPLY_PROP_PRESENT,
- POWER_SUPPLY_PROP_CAPACITY
+ POWER_SUPPLY_PROP_CAPACITY,
+ POWER_SUPPLY_PROP_SCOPE,
};
static enum power_supply_property wacom_ac_props[] = {
POWER_SUPPLY_PROP_PRESENT,
- POWER_SUPPLY_PROP_ONLINE
+ POWER_SUPPLY_PROP_ONLINE,
+ POWER_SUPPLY_PROP_SCOPE,
};
static int wacom_battery_get_property(struct power_supply *psy,
@@ -70,6 +72,9 @@
case POWER_SUPPLY_PROP_PRESENT:
val->intval = 1;
break;
+ case POWER_SUPPLY_PROP_SCOPE:
+ val->intval = POWER_SUPPLY_SCOPE_DEVICE;
+ break;
case POWER_SUPPLY_PROP_CAPACITY:
/* show 100% battery capacity when charging */
if (power_state == 0)
@@ -101,6 +106,9 @@
else
val->intval = 0;
break;
+ case POWER_SUPPLY_PROP_SCOPE:
+ val->intval = POWER_SUPPLY_SCOPE_DEVICE;
+ break;
default:
ret = -EINVAL;
break;
@@ -523,6 +531,8 @@
wdata->battery.type = POWER_SUPPLY_TYPE_BATTERY;
wdata->battery.use_for_apm = 0;
+ power_supply_powers(&wdata->battery, &hdev->dev);
+
ret = power_supply_register(&hdev->dev, &wdata->battery);
if (ret) {
hid_warn(hdev, "can't create sysfs battery attribute, err: %d\n",
@@ -537,6 +547,8 @@
wdata->ac.type = POWER_SUPPLY_TYPE_MAINS;
wdata->ac.use_for_apm = 0;
+ power_supply_powers(&wdata->battery, &hdev->dev);
+
ret = power_supply_register(&hdev->dev, &wdata->ac);
if (ret) {
hid_warn(hdev,
diff --git a/drivers/hid/hid-wiimote-core.c b/drivers/hid/hid-wiimote-core.c
index 61881b3..fc253b4 100644
--- a/drivers/hid/hid-wiimote-core.c
+++ b/drivers/hid/hid-wiimote-core.c
@@ -52,7 +52,8 @@
};
static enum power_supply_property wiimote_battery_props[] = {
- POWER_SUPPLY_PROP_CAPACITY
+ POWER_SUPPLY_PROP_CAPACITY,
+ POWER_SUPPLY_PROP_SCOPE,
};
static ssize_t wiimote_hid_send(struct hid_device *hdev, __u8 *buffer,
@@ -402,6 +403,11 @@
int ret = 0, state;
unsigned long flags;
+ if (psp == POWER_SUPPLY_PROP_SCOPE) {
+ val->intval = POWER_SUPPLY_SCOPE_DEVICE;
+ return 0;
+ }
+
ret = wiimote_cmd_acquire(wdata);
if (ret)
return ret;
@@ -1220,6 +1226,8 @@
wdata->battery.type = POWER_SUPPLY_TYPE_BATTERY;
wdata->battery.use_for_apm = 0;
+ power_supply_powers(&wdata->battery, &hdev->dev);
+
ret = power_supply_register(&wdata->hdev->dev, &wdata->battery);
if (ret) {
hid_err(hdev, "Cannot register battery device\n");
diff --git a/drivers/md/md.c b/drivers/md/md.c
index ca8527f..da52acb 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -7382,6 +7382,7 @@
{
struct md_rdev *rdev;
int spares = 0;
+ int removed = 0;
mddev->curr_resync_completed = 0;
@@ -7395,8 +7396,13 @@
mddev, rdev) == 0) {
sysfs_unlink_rdev(mddev, rdev);
rdev->raid_disk = -1;
+ removed++;
}
}
+ if (removed)
+ sysfs_notify(&mddev->kobj, NULL,
+ "degraded");
+
list_for_each_entry(rdev, &mddev->disks, same_set) {
if (rdev->raid_disk >= 0 &&
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index cc24f0c..a368db2 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -531,8 +531,17 @@
if (test_bit(WriteMostly, &rdev->flags)) {
/* Don't balance among write-mostly, just
* use the first as a last resort */
- if (best_disk < 0)
+ if (best_disk < 0) {
+ if (is_badblock(rdev, this_sector, sectors,
+ &first_bad, &bad_sectors)) {
+ if (first_bad < this_sector)
+ /* Cannot use this */
+ continue;
+ best_good_sectors = first_bad - this_sector;
+ } else
+ best_good_sectors = sectors;
best_disk = disk;
+ }
continue;
}
/* This is a reasonable device to use. It might
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index c8322ee..053208d 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -505,6 +505,7 @@
bool "Support Wolfson Microelectronics WM8994"
select MFD_CORE
select REGMAP_I2C
+ select REGMAP_IRQ
depends on I2C=y && GENERIC_HARDIRQS
help
The WM8994 is a highly integrated hi-fi CODEC designed for
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index d5f5743..47591fc 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -31,7 +31,7 @@
wm8350-objs += wm8350-irq.o
obj-$(CONFIG_MFD_WM8350) += wm8350.o
obj-$(CONFIG_MFD_WM8350_I2C) += wm8350-i2c.o
-obj-$(CONFIG_MFD_WM8994) += wm8994-core.o wm8994-irq.o
+obj-$(CONFIG_MFD_WM8994) += wm8994-core.o wm8994-irq.o wm8994-regmap.o
obj-$(CONFIG_TPS6105X) += tps6105x.o
obj-$(CONFIG_TPS65010) += tps65010.o
diff --git a/drivers/mfd/max8925-core.c b/drivers/mfd/max8925-core.c
index e1e59c9..ca881ef 100644
--- a/drivers/mfd/max8925-core.c
+++ b/drivers/mfd/max8925-core.c
@@ -210,21 +210,6 @@
.mask_reg = MAX8925_CHG_IRQ1_MASK,
.offs = 1 << 2,
},
- [MAX8925_IRQ_VCHG_USB_OVP] = {
- .reg = MAX8925_CHG_IRQ1,
- .mask_reg = MAX8925_CHG_IRQ1_MASK,
- .offs = 1 << 3,
- },
- [MAX8925_IRQ_VCHG_USB_F] = {
- .reg = MAX8925_CHG_IRQ1,
- .mask_reg = MAX8925_CHG_IRQ1_MASK,
- .offs = 1 << 4,
- },
- [MAX8925_IRQ_VCHG_USB_R] = {
- .reg = MAX8925_CHG_IRQ1,
- .mask_reg = MAX8925_CHG_IRQ1_MASK,
- .offs = 1 << 5,
- },
[MAX8925_IRQ_VCHG_THM_OK_R] = {
.reg = MAX8925_CHG_IRQ2,
.mask_reg = MAX8925_CHG_IRQ2_MASK,
diff --git a/drivers/mfd/wm8994-core.c b/drivers/mfd/wm8994-core.c
index 61894fc..f117e7f 100644
--- a/drivers/mfd/wm8994-core.c
+++ b/drivers/mfd/wm8994-core.c
@@ -28,11 +28,7 @@
#include <linux/mfd/wm8994/pdata.h>
#include <linux/mfd/wm8994/registers.h>
-static int wm8994_read(struct wm8994 *wm8994, unsigned short reg,
- int bytes, void *dest)
-{
- return regmap_raw_read(wm8994->regmap, reg, dest, bytes);
-}
+#include "wm8994.h"
/**
* wm8994_reg_read: Read a single WM8994 register.
@@ -68,12 +64,6 @@
return regmap_bulk_read(wm8994->regmap, reg, buf, count);
}
-static int wm8994_write(struct wm8994 *wm8994, unsigned short reg,
- int bytes, const void *src)
-{
- return regmap_raw_write(wm8994->regmap, reg, src, bytes);
-}
-
/**
* wm8994_reg_write: Write a single WM8994 register.
*
@@ -252,6 +242,20 @@
break;
}
+ switch (wm8994->type) {
+ case WM1811:
+ ret = wm8994_reg_read(wm8994, WM8994_ANTIPOP_2);
+ if (ret < 0) {
+ dev_err(dev, "Failed to read jackdet: %d\n", ret);
+ } else if (ret & WM1811_JACKDET_MODE_MASK) {
+ dev_dbg(dev, "CODEC still active, ignoring suspend\n");
+ return 0;
+ }
+ break;
+ default:
+ break;
+ }
+
/* Disable LDO pulldowns while the device is suspended if we
* don't know that something will be driving them. */
if (!wm8994->ldo_ena_always_driven)
@@ -259,25 +263,14 @@
WM8994_LDO1ENA_PD | WM8994_LDO2ENA_PD,
WM8994_LDO1ENA_PD | WM8994_LDO2ENA_PD);
- /* GPIO configuration state is saved here since we may be configuring
- * the GPIO alternate functions even if we're not using the gpiolib
- * driver for them.
- */
- ret = wm8994_read(wm8994, WM8994_GPIO_1, WM8994_NUM_GPIO_REGS * 2,
- &wm8994->gpio_regs);
- if (ret < 0)
- dev_err(dev, "Failed to save GPIO registers: %d\n", ret);
-
- /* For similar reasons we also stash the regulator states */
- ret = wm8994_read(wm8994, WM8994_LDO_1, WM8994_NUM_LDO_REGS * 2,
- &wm8994->ldo_regs);
- if (ret < 0)
- dev_err(dev, "Failed to save LDO registers: %d\n", ret);
-
/* Explicitly put the device into reset in case regulators
* don't get disabled in order to ensure consistent restart.
*/
- wm8994_reg_write(wm8994, WM8994_SOFTWARE_RESET, 0x8994);
+ wm8994_reg_write(wm8994, WM8994_SOFTWARE_RESET,
+ wm8994_reg_read(wm8994, WM8994_SOFTWARE_RESET));
+
+ regcache_cache_only(wm8994->regmap, true);
+ regcache_mark_dirty(wm8994->regmap);
wm8994->suspended = true;
@@ -294,7 +287,7 @@
static int wm8994_resume(struct device *dev)
{
struct wm8994 *wm8994 = dev_get_drvdata(dev);
- int ret, i;
+ int ret;
/* We may have lied to the PM core about suspending */
if (!wm8994->suspended)
@@ -307,27 +300,13 @@
return ret;
}
- /* Write register at a time as we use the cache on the CPU so store
- * it in native endian.
- */
- for (i = 0; i < ARRAY_SIZE(wm8994->irq_masks_cur); i++) {
- ret = wm8994_reg_write(wm8994, WM8994_INTERRUPT_STATUS_1_MASK
- + i, wm8994->irq_masks_cur[i]);
- if (ret < 0)
- dev_err(dev, "Failed to restore interrupt masks: %d\n",
- ret);
+ regcache_cache_only(wm8994->regmap, false);
+ ret = regcache_sync(wm8994->regmap);
+ if (ret != 0) {
+ dev_err(dev, "Failed to restore register map: %d\n", ret);
+ goto err_enable;
}
- ret = wm8994_write(wm8994, WM8994_LDO_1, WM8994_NUM_LDO_REGS * 2,
- &wm8994->ldo_regs);
- if (ret < 0)
- dev_err(dev, "Failed to restore LDO registers: %d\n", ret);
-
- ret = wm8994_write(wm8994, WM8994_GPIO_1, WM8994_NUM_GPIO_REGS * 2,
- &wm8994->gpio_regs);
- if (ret < 0)
- dev_err(dev, "Failed to restore GPIO registers: %d\n", ret);
-
/* Disable LDO pulldowns while the device is active */
wm8994_set_bits(wm8994, WM8994_PULL_CONTROL_2,
WM8994_LDO1ENA_PD | WM8994_LDO2ENA_PD,
@@ -336,6 +315,11 @@
wm8994->suspended = false;
return 0;
+
+err_enable:
+ regulator_bulk_disable(wm8994->num_supplies, wm8994->supplies);
+
+ return ret;
}
#endif
@@ -361,19 +345,16 @@
}
#endif
-static struct regmap_config wm8994_regmap_config = {
- .reg_bits = 16,
- .val_bits = 16,
-};
-
/*
* Instantiate the generic non-control parts of the device.
*/
static int wm8994_device_init(struct wm8994 *wm8994, int irq)
{
struct wm8994_pdata *pdata = wm8994->dev->platform_data;
+ struct regmap_config *regmap_config;
const char *devname;
int ret, i;
+ int pulls = 0;
dev_set_drvdata(wm8994->dev, wm8994);
@@ -402,9 +383,9 @@
goto err_regmap;
}
- wm8994->supplies = kzalloc(sizeof(struct regulator_bulk_data) *
- wm8994->num_supplies,
- GFP_KERNEL);
+ wm8994->supplies = devm_kzalloc(wm8994->dev,
+ sizeof(struct regulator_bulk_data) *
+ wm8994->num_supplies, GFP_KERNEL);
if (!wm8994->supplies) {
ret = -ENOMEM;
goto err_regmap;
@@ -432,7 +413,7 @@
wm8994->supplies);
if (ret != 0) {
dev_err(wm8994->dev, "Failed to get supplies: %d\n", ret);
- goto err_supplies;
+ goto err_regmap;
}
ret = regulator_bulk_enable(wm8994->num_supplies,
@@ -482,25 +463,54 @@
ret);
goto err_enable;
}
+ wm8994->revision = ret;
switch (wm8994->type) {
case WM8994:
- switch (ret) {
+ switch (wm8994->revision) {
case 0:
case 1:
dev_warn(wm8994->dev,
"revision %c not fully supported\n",
- 'A' + ret);
+ 'A' + wm8994->revision);
break;
default:
break;
}
break;
+ case WM1811:
+ /* Revision C did not change the relevant layer */
+ if (wm8994->revision > 1)
+ wm8994->revision++;
+ break;
default:
break;
}
- dev_info(wm8994->dev, "%s revision %c\n", devname, 'A' + ret);
+ dev_info(wm8994->dev, "%s revision %c\n", devname,
+ 'A' + wm8994->revision);
+
+ switch (wm8994->type) {
+ case WM1811:
+ regmap_config = &wm1811_regmap_config;
+ break;
+ case WM8994:
+ regmap_config = &wm8994_regmap_config;
+ break;
+ case WM8958:
+ regmap_config = &wm8958_regmap_config;
+ break;
+ default:
+ dev_err(wm8994->dev, "Unknown device type %d\n", wm8994->type);
+ return -EINVAL;
+ }
+
+ ret = regmap_reinit_cache(wm8994->regmap, regmap_config);
+ if (ret != 0) {
+ dev_err(wm8994->dev, "Failed to reinit register cache: %d\n",
+ ret);
+ return ret;
+ }
if (pdata) {
wm8994->irq_base = pdata->irq_base;
@@ -516,12 +526,16 @@
}
wm8994->ldo_ena_always_driven = pdata->ldo_ena_always_driven;
+
+ if (pdata->spkmode_pu)
+ pulls |= WM8994_SPKMODE_PU;
}
- /* Disable LDO pulldowns while the device is active */
+ /* Disable unneeded pulls */
wm8994_set_bits(wm8994, WM8994_PULL_CONTROL_2,
- WM8994_LDO1ENA_PD | WM8994_LDO2ENA_PD,
- 0);
+ WM8994_LDO1ENA_PD | WM8994_LDO2ENA_PD |
+ WM8994_SPKMODE_PU | WM8994_CSNADDR_PD,
+ pulls);
/* In some system designs where the regulators are not in use,
* we can achieve a small reduction in leakage currents by
@@ -560,12 +574,9 @@
wm8994->supplies);
err_get:
regulator_bulk_free(wm8994->num_supplies, wm8994->supplies);
-err_supplies:
- kfree(wm8994->supplies);
err_regmap:
regmap_exit(wm8994->regmap);
mfd_remove_devices(wm8994->dev);
- kfree(wm8994);
return ret;
}
@@ -577,18 +588,24 @@
regulator_bulk_disable(wm8994->num_supplies,
wm8994->supplies);
regulator_bulk_free(wm8994->num_supplies, wm8994->supplies);
- kfree(wm8994->supplies);
regmap_exit(wm8994->regmap);
- kfree(wm8994);
}
+static const struct of_device_id wm8994_of_match[] = {
+ { .compatible = "wlf,wm1811", },
+ { .compatible = "wlf,wm8994", },
+ { .compatible = "wlf,wm8958", },
+ { }
+};
+MODULE_DEVICE_TABLE(of, wm8994_of_match);
+
static int wm8994_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
struct wm8994 *wm8994;
int ret;
- wm8994 = kzalloc(sizeof(struct wm8994), GFP_KERNEL);
+ wm8994 = devm_kzalloc(&i2c->dev, sizeof(struct wm8994), GFP_KERNEL);
if (wm8994 == NULL)
return -ENOMEM;
@@ -597,12 +614,11 @@
wm8994->irq = i2c->irq;
wm8994->type = id->driver_data;
- wm8994->regmap = regmap_init_i2c(i2c, &wm8994_regmap_config);
+ wm8994->regmap = regmap_init_i2c(i2c, &wm8994_base_regmap_config);
if (IS_ERR(wm8994->regmap)) {
ret = PTR_ERR(wm8994->regmap);
dev_err(wm8994->dev, "Failed to allocate register map: %d\n",
ret);
- kfree(wm8994);
return ret;
}
@@ -620,6 +636,7 @@
static const struct i2c_device_id wm8994_i2c_id[] = {
{ "wm1811", WM1811 },
+ { "wm1811a", WM1811 },
{ "wm8994", WM8994 },
{ "wm8958", WM8958 },
{ }
@@ -634,6 +651,7 @@
.name = "wm8994",
.owner = THIS_MODULE,
.pm = &wm8994_pm_ops,
+ .of_match_table = wm8994_of_match,
},
.probe = wm8994_i2c_probe,
.remove = wm8994_i2c_remove,
diff --git a/drivers/mfd/wm8994-irq.c b/drivers/mfd/wm8994-irq.c
index d682f7b..46b20c4 100644
--- a/drivers/mfd/wm8994-irq.c
+++ b/drivers/mfd/wm8994-irq.c
@@ -18,248 +18,127 @@
#include <linux/irq.h>
#include <linux/mfd/core.h>
#include <linux/interrupt.h>
+#include <linux/regmap.h>
#include <linux/mfd/wm8994/core.h>
#include <linux/mfd/wm8994/registers.h>
#include <linux/delay.h>
-struct wm8994_irq_data {
- int reg;
- int mask;
-};
-
-static struct wm8994_irq_data wm8994_irqs[] = {
+static struct regmap_irq wm8994_irqs[] = {
[WM8994_IRQ_TEMP_SHUT] = {
- .reg = 2,
+ .reg_offset = 1,
.mask = WM8994_TEMP_SHUT_EINT,
},
[WM8994_IRQ_MIC1_DET] = {
- .reg = 2,
+ .reg_offset = 1,
.mask = WM8994_MIC1_DET_EINT,
},
[WM8994_IRQ_MIC1_SHRT] = {
- .reg = 2,
+ .reg_offset = 1,
.mask = WM8994_MIC1_SHRT_EINT,
},
[WM8994_IRQ_MIC2_DET] = {
- .reg = 2,
+ .reg_offset = 1,
.mask = WM8994_MIC2_DET_EINT,
},
[WM8994_IRQ_MIC2_SHRT] = {
- .reg = 2,
+ .reg_offset = 1,
.mask = WM8994_MIC2_SHRT_EINT,
},
[WM8994_IRQ_FLL1_LOCK] = {
- .reg = 2,
+ .reg_offset = 1,
.mask = WM8994_FLL1_LOCK_EINT,
},
[WM8994_IRQ_FLL2_LOCK] = {
- .reg = 2,
+ .reg_offset = 1,
.mask = WM8994_FLL2_LOCK_EINT,
},
[WM8994_IRQ_SRC1_LOCK] = {
- .reg = 2,
+ .reg_offset = 1,
.mask = WM8994_SRC1_LOCK_EINT,
},
[WM8994_IRQ_SRC2_LOCK] = {
- .reg = 2,
+ .reg_offset = 1,
.mask = WM8994_SRC2_LOCK_EINT,
},
[WM8994_IRQ_AIF1DRC1_SIG_DET] = {
- .reg = 2,
+ .reg_offset = 1,
.mask = WM8994_AIF1DRC1_SIG_DET,
},
[WM8994_IRQ_AIF1DRC2_SIG_DET] = {
- .reg = 2,
+ .reg_offset = 1,
.mask = WM8994_AIF1DRC2_SIG_DET_EINT,
},
[WM8994_IRQ_AIF2DRC_SIG_DET] = {
- .reg = 2,
+ .reg_offset = 1,
.mask = WM8994_AIF2DRC_SIG_DET_EINT,
},
[WM8994_IRQ_FIFOS_ERR] = {
- .reg = 2,
+ .reg_offset = 1,
.mask = WM8994_FIFOS_ERR_EINT,
},
[WM8994_IRQ_WSEQ_DONE] = {
- .reg = 2,
+ .reg_offset = 1,
.mask = WM8994_WSEQ_DONE_EINT,
},
[WM8994_IRQ_DCS_DONE] = {
- .reg = 2,
+ .reg_offset = 1,
.mask = WM8994_DCS_DONE_EINT,
},
[WM8994_IRQ_TEMP_WARN] = {
- .reg = 2,
+ .reg_offset = 1,
.mask = WM8994_TEMP_WARN_EINT,
},
[WM8994_IRQ_GPIO(1)] = {
- .reg = 1,
.mask = WM8994_GP1_EINT,
},
[WM8994_IRQ_GPIO(2)] = {
- .reg = 1,
.mask = WM8994_GP2_EINT,
},
[WM8994_IRQ_GPIO(3)] = {
- .reg = 1,
.mask = WM8994_GP3_EINT,
},
[WM8994_IRQ_GPIO(4)] = {
- .reg = 1,
.mask = WM8994_GP4_EINT,
},
[WM8994_IRQ_GPIO(5)] = {
- .reg = 1,
.mask = WM8994_GP5_EINT,
},
[WM8994_IRQ_GPIO(6)] = {
- .reg = 1,
.mask = WM8994_GP6_EINT,
},
[WM8994_IRQ_GPIO(7)] = {
- .reg = 1,
.mask = WM8994_GP7_EINT,
},
[WM8994_IRQ_GPIO(8)] = {
- .reg = 1,
.mask = WM8994_GP8_EINT,
},
[WM8994_IRQ_GPIO(9)] = {
- .reg = 1,
.mask = WM8994_GP8_EINT,
},
[WM8994_IRQ_GPIO(10)] = {
- .reg = 1,
.mask = WM8994_GP10_EINT,
},
[WM8994_IRQ_GPIO(11)] = {
- .reg = 1,
.mask = WM8994_GP11_EINT,
},
};
-static inline int irq_data_to_status_reg(struct wm8994_irq_data *irq_data)
-{
- return WM8994_INTERRUPT_STATUS_1 - 1 + irq_data->reg;
-}
+static struct regmap_irq_chip wm8994_irq_chip = {
+ .name = "wm8994",
+ .irqs = wm8994_irqs,
+ .num_irqs = ARRAY_SIZE(wm8994_irqs),
-static inline int irq_data_to_mask_reg(struct wm8994_irq_data *irq_data)
-{
- return WM8994_INTERRUPT_STATUS_1_MASK - 1 + irq_data->reg;
-}
-
-static inline struct wm8994_irq_data *irq_to_wm8994_irq(struct wm8994 *wm8994,
- int irq)
-{
- return &wm8994_irqs[irq - wm8994->irq_base];
-}
-
-static void wm8994_irq_lock(struct irq_data *data)
-{
- struct wm8994 *wm8994 = irq_data_get_irq_chip_data(data);
-
- mutex_lock(&wm8994->irq_lock);
-}
-
-static void wm8994_irq_sync_unlock(struct irq_data *data)
-{
- struct wm8994 *wm8994 = irq_data_get_irq_chip_data(data);
- int i;
-
- for (i = 0; i < ARRAY_SIZE(wm8994->irq_masks_cur); i++) {
- /* If there's been a change in the mask write it back
- * to the hardware. */
- if (wm8994->irq_masks_cur[i] != wm8994->irq_masks_cache[i]) {
- wm8994->irq_masks_cache[i] = wm8994->irq_masks_cur[i];
- wm8994_reg_write(wm8994,
- WM8994_INTERRUPT_STATUS_1_MASK + i,
- wm8994->irq_masks_cur[i]);
- }
- }
-
- mutex_unlock(&wm8994->irq_lock);
-}
-
-static void wm8994_irq_enable(struct irq_data *data)
-{
- struct wm8994 *wm8994 = irq_data_get_irq_chip_data(data);
- struct wm8994_irq_data *irq_data = irq_to_wm8994_irq(wm8994,
- data->irq);
-
- wm8994->irq_masks_cur[irq_data->reg - 1] &= ~irq_data->mask;
-}
-
-static void wm8994_irq_disable(struct irq_data *data)
-{
- struct wm8994 *wm8994 = irq_data_get_irq_chip_data(data);
- struct wm8994_irq_data *irq_data = irq_to_wm8994_irq(wm8994,
- data->irq);
-
- wm8994->irq_masks_cur[irq_data->reg - 1] |= irq_data->mask;
-}
-
-static struct irq_chip wm8994_irq_chip = {
- .name = "wm8994",
- .irq_bus_lock = wm8994_irq_lock,
- .irq_bus_sync_unlock = wm8994_irq_sync_unlock,
- .irq_disable = wm8994_irq_disable,
- .irq_enable = wm8994_irq_enable,
+ .num_regs = 2,
+ .status_base = WM8994_INTERRUPT_STATUS_1,
+ .mask_base = WM8994_INTERRUPT_STATUS_1_MASK,
+ .ack_base = WM8994_INTERRUPT_STATUS_1,
};
-/* The processing of the primary interrupt occurs in a thread so that
- * we can interact with the device over I2C or SPI. */
-static irqreturn_t wm8994_irq_thread(int irq, void *data)
-{
- struct wm8994 *wm8994 = data;
- unsigned int i;
- u16 status[WM8994_NUM_IRQ_REGS];
- int ret;
-
- ret = wm8994_bulk_read(wm8994, WM8994_INTERRUPT_STATUS_1,
- WM8994_NUM_IRQ_REGS, status);
- if (ret < 0) {
- dev_err(wm8994->dev, "Failed to read interrupt status: %d\n",
- ret);
- return IRQ_NONE;
- }
-
- /* Bit swap and apply masking */
- for (i = 0; i < WM8994_NUM_IRQ_REGS; i++) {
- status[i] = be16_to_cpu(status[i]);
- status[i] &= ~wm8994->irq_masks_cur[i];
- }
-
- /* Ack any unmasked IRQs */
- for (i = 0; i < ARRAY_SIZE(status); i++) {
- if (status[i])
- wm8994_reg_write(wm8994, WM8994_INTERRUPT_STATUS_1 + i,
- status[i]);
- }
-
- /* Report */
- for (i = 0; i < ARRAY_SIZE(wm8994_irqs); i++) {
- if (status[wm8994_irqs[i].reg - 1] & wm8994_irqs[i].mask)
- handle_nested_irq(wm8994->irq_base + i);
- }
-
- return IRQ_HANDLED;
-}
-
int wm8994_irq_init(struct wm8994 *wm8994)
{
- int i, cur_irq, ret;
-
- mutex_init(&wm8994->irq_lock);
-
- /* Mask the individual interrupt sources */
- for (i = 0; i < ARRAY_SIZE(wm8994->irq_masks_cur); i++) {
- wm8994->irq_masks_cur[i] = 0xffff;
- wm8994->irq_masks_cache[i] = 0xffff;
- wm8994_reg_write(wm8994, WM8994_INTERRUPT_STATUS_1_MASK + i,
- 0xffff);
- }
+ int ret;
if (!wm8994->irq) {
dev_warn(wm8994->dev,
@@ -274,30 +153,12 @@
return 0;
}
- /* Register them with genirq */
- for (cur_irq = wm8994->irq_base;
- cur_irq < ARRAY_SIZE(wm8994_irqs) + wm8994->irq_base;
- cur_irq++) {
- irq_set_chip_data(cur_irq, wm8994);
- irq_set_chip_and_handler(cur_irq, &wm8994_irq_chip,
- handle_edge_irq);
- irq_set_nested_thread(cur_irq, 1);
-
- /* ARM needs us to explicitly flag the IRQ as valid
- * and will set them noprobe when we do so. */
-#ifdef CONFIG_ARM
- set_irq_flags(cur_irq, IRQF_VALID);
-#else
- irq_set_noprobe(cur_irq);
-#endif
- }
-
- ret = request_threaded_irq(wm8994->irq, NULL, wm8994_irq_thread,
- IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
- "wm8994", wm8994);
+ ret = regmap_add_irq_chip(wm8994->regmap, wm8994->irq,
+ IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
+ wm8994->irq_base, &wm8994_irq_chip,
+ &wm8994->irq_data);
if (ret != 0) {
- dev_err(wm8994->dev, "Failed to request IRQ %d: %d\n",
- wm8994->irq, ret);
+ dev_err(wm8994->dev, "Failed to register IRQ chip: %d\n", ret);
return ret;
}
@@ -309,6 +170,5 @@
void wm8994_irq_exit(struct wm8994 *wm8994)
{
- if (wm8994->irq)
- free_irq(wm8994->irq, wm8994);
+ regmap_del_irq_chip(wm8994->irq, wm8994->irq_data);
}
diff --git a/drivers/mfd/wm8994-regmap.c b/drivers/mfd/wm8994-regmap.c
new file mode 100644
index 0000000..c598ae6
--- /dev/null
+++ b/drivers/mfd/wm8994-regmap.c
@@ -0,0 +1,1238 @@
+/*
+ * wm8994-regmap.c -- Register map data for WM8994 series devices
+ *
+ * Copyright 2011 Wolfson Microelectronics PLC.
+ *
+ * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
+ *
+ * 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.
+ *
+ */
+
+#include <linux/mfd/wm8994/core.h>
+#include <linux/mfd/wm8994/registers.h>
+#include <linux/regmap.h>
+
+#include "wm8994.h"
+
+static struct reg_default wm1811_defaults[] = {
+ { 0x0000, 0x1811 }, /* R0 - Software Reset */
+ { 0x0001, 0x0000 }, /* R1 - Power Management (1) */
+ { 0x0002, 0x6000 }, /* R2 - Power Management (2) */
+ { 0x0003, 0x0000 }, /* R3 - Power Management (3) */
+ { 0x0004, 0x0000 }, /* R4 - Power Management (4) */
+ { 0x0005, 0x0000 }, /* R5 - Power Management (5) */
+ { 0x0006, 0x0000 }, /* R6 - Power Management (6) */
+ { 0x0015, 0x0000 }, /* R21 - Input Mixer (1) */
+ { 0x0018, 0x008B }, /* R24 - Left Line Input 1&2 Volume */
+ { 0x0019, 0x008B }, /* R25 - Left Line Input 3&4 Volume */
+ { 0x001A, 0x008B }, /* R26 - Right Line Input 1&2 Volume */
+ { 0x001B, 0x008B }, /* R27 - Right Line Input 3&4 Volume */
+ { 0x001C, 0x006D }, /* R28 - Left Output Volume */
+ { 0x001D, 0x006D }, /* R29 - Right Output Volume */
+ { 0x001E, 0x0066 }, /* R30 - Line Outputs Volume */
+ { 0x001F, 0x0020 }, /* R31 - HPOUT2 Volume */
+ { 0x0020, 0x0079 }, /* R32 - Left OPGA Volume */
+ { 0x0021, 0x0079 }, /* R33 - Right OPGA Volume */
+ { 0x0022, 0x0003 }, /* R34 - SPKMIXL Attenuation */
+ { 0x0023, 0x0003 }, /* R35 - SPKMIXR Attenuation */
+ { 0x0024, 0x0011 }, /* R36 - SPKOUT Mixers */
+ { 0x0025, 0x0140 }, /* R37 - ClassD */
+ { 0x0026, 0x0079 }, /* R38 - Speaker Volume Left */
+ { 0x0027, 0x0079 }, /* R39 - Speaker Volume Right */
+ { 0x0028, 0x0000 }, /* R40 - Input Mixer (2) */
+ { 0x0029, 0x0000 }, /* R41 - Input Mixer (3) */
+ { 0x002A, 0x0000 }, /* R42 - Input Mixer (4) */
+ { 0x002B, 0x0000 }, /* R43 - Input Mixer (5) */
+ { 0x002C, 0x0000 }, /* R44 - Input Mixer (6) */
+ { 0x002D, 0x0000 }, /* R45 - Output Mixer (1) */
+ { 0x002E, 0x0000 }, /* R46 - Output Mixer (2) */
+ { 0x002F, 0x0000 }, /* R47 - Output Mixer (3) */
+ { 0x0030, 0x0000 }, /* R48 - Output Mixer (4) */
+ { 0x0031, 0x0000 }, /* R49 - Output Mixer (5) */
+ { 0x0032, 0x0000 }, /* R50 - Output Mixer (6) */
+ { 0x0033, 0x0000 }, /* R51 - HPOUT2 Mixer */
+ { 0x0034, 0x0000 }, /* R52 - Line Mixer (1) */
+ { 0x0035, 0x0000 }, /* R53 - Line Mixer (2) */
+ { 0x0036, 0x0000 }, /* R54 - Speaker Mixer */
+ { 0x0037, 0x0000 }, /* R55 - Additional Control */
+ { 0x0038, 0x0000 }, /* R56 - AntiPOP (1) */
+ { 0x0039, 0x0180 }, /* R57 - AntiPOP (2) */
+ { 0x003B, 0x000D }, /* R59 - LDO 1 */
+ { 0x003C, 0x0003 }, /* R60 - LDO 2 */
+ { 0x003D, 0x0039 }, /* R61 - MICBIAS1 */
+ { 0x003E, 0x0039 }, /* R62 - MICBIAS2 */
+ { 0x004C, 0x1F25 }, /* R76 - Charge Pump (1) */
+ { 0x004D, 0xAB19 }, /* R77 - Charge Pump (2) */
+ { 0x0051, 0x0004 }, /* R81 - Class W (1) */
+ { 0x0054, 0x0000 }, /* R84 - DC Servo (1) */
+ { 0x0055, 0x054A }, /* R85 - DC Servo (2) */
+ { 0x0058, 0x0000 }, /* R88 - DC Servo Readback */
+ { 0x0059, 0x0000 }, /* R89 - DC Servo (4) */
+ { 0x0060, 0x0000 }, /* R96 - Analogue HP (1) */
+ { 0x00C5, 0x0000 }, /* R197 - Class D Test (5) */
+ { 0x00D0, 0x7600 }, /* R208 - Mic Detect 1 */
+ { 0x00D1, 0x007F }, /* R209 - Mic Detect 2 */
+ { 0x00D2, 0x0000 }, /* R210 - Mic Detect 3 */
+ { 0x0100, 0x0100 }, /* R256 - Chip Revision */
+ { 0x0101, 0x8004 }, /* R257 - Control Interface */
+ { 0x0200, 0x0000 }, /* R512 - AIF1 Clocking (1) */
+ { 0x0201, 0x0000 }, /* R513 - AIF1 Clocking (2) */
+ { 0x0204, 0x0000 }, /* R516 - AIF2 Clocking (1) */
+ { 0x0205, 0x0000 }, /* R517 - AIF2 Clocking (2) */
+ { 0x0208, 0x0000 }, /* R520 - Clocking (1) */
+ { 0x0209, 0x0000 }, /* R521 - Clocking (2) */
+ { 0x0210, 0x0083 }, /* R528 - AIF1 Rate */
+ { 0x0211, 0x0083 }, /* R529 - AIF2 Rate */
+ { 0x0212, 0x0000 }, /* R530 - Rate Status */
+ { 0x0220, 0x0000 }, /* R544 - FLL1 Control (1) */
+ { 0x0221, 0x0000 }, /* R545 - FLL1 Control (2) */
+ { 0x0222, 0x0000 }, /* R546 - FLL1 Control (3) */
+ { 0x0223, 0x0000 }, /* R547 - FLL1 Control (4) */
+ { 0x0224, 0x0C80 }, /* R548 - FLL1 Control (5) */
+ { 0x0226, 0x0000 }, /* R550 - FLL1 EFS 1 */
+ { 0x0227, 0x0006 }, /* R551 - FLL1 EFS 2 */
+ { 0x0240, 0x0000 }, /* R576 - FLL2Control (1) */
+ { 0x0241, 0x0000 }, /* R577 - FLL2Control (2) */
+ { 0x0242, 0x0000 }, /* R578 - FLL2Control (3) */
+ { 0x0243, 0x0000 }, /* R579 - FLL2 Control (4) */
+ { 0x0244, 0x0C80 }, /* R580 - FLL2Control (5) */
+ { 0x0246, 0x0000 }, /* R582 - FLL2 EFS 1 */
+ { 0x0247, 0x0006 }, /* R583 - FLL2 EFS 2 */
+ { 0x0300, 0x4050 }, /* R768 - AIF1 Control (1) */
+ { 0x0301, 0x4000 }, /* R769 - AIF1 Control (2) */
+ { 0x0302, 0x0000 }, /* R770 - AIF1 Master/Slave */
+ { 0x0303, 0x0040 }, /* R771 - AIF1 BCLK */
+ { 0x0304, 0x0040 }, /* R772 - AIF1ADC LRCLK */
+ { 0x0305, 0x0040 }, /* R773 - AIF1DAC LRCLK */
+ { 0x0306, 0x0004 }, /* R774 - AIF1DAC Data */
+ { 0x0307, 0x0100 }, /* R775 - AIF1ADC Data */
+ { 0x0310, 0x4050 }, /* R784 - AIF2 Control (1) */
+ { 0x0311, 0x4000 }, /* R785 - AIF2 Control (2) */
+ { 0x0312, 0x0000 }, /* R786 - AIF2 Master/Slave */
+ { 0x0313, 0x0040 }, /* R787 - AIF2 BCLK */
+ { 0x0314, 0x0040 }, /* R788 - AIF2ADC LRCLK */
+ { 0x0315, 0x0040 }, /* R789 - AIF2DAC LRCLK */
+ { 0x0316, 0x0000 }, /* R790 - AIF2DAC Data */
+ { 0x0317, 0x0000 }, /* R791 - AIF2ADC Data */
+ { 0x0318, 0x0003 }, /* R792 - AIF2TX Control */
+ { 0x0320, 0x0040 }, /* R800 - AIF3 Control (1) */
+ { 0x0321, 0x0000 }, /* R801 - AIF3 Control (2) */
+ { 0x0322, 0x0000 }, /* R802 - AIF3DAC Data */
+ { 0x0323, 0x0000 }, /* R803 - AIF3ADC Data */
+ { 0x0400, 0x00C0 }, /* R1024 - AIF1 ADC1 Left Volume */
+ { 0x0401, 0x00C0 }, /* R1025 - AIF1 ADC1 Right Volume */
+ { 0x0402, 0x00C0 }, /* R1026 - AIF1 DAC1 Left Volume */
+ { 0x0403, 0x00C0 }, /* R1027 - AIF1 DAC1 Right Volume */
+ { 0x0410, 0x0000 }, /* R1040 - AIF1 ADC1 Filters */
+ { 0x0420, 0x0200 }, /* R1056 - AIF1 DAC1 Filters (1) */
+ { 0x0421, 0x0010 }, /* R1057 - AIF1 DAC1 Filters (2) */
+ { 0x0430, 0x0068 }, /* R1072 - AIF1 DAC1 Noise Gate */
+ { 0x0440, 0x0098 }, /* R1088 - AIF1 DRC1 (1) */
+ { 0x0441, 0x0845 }, /* R1089 - AIF1 DRC1 (2) */
+ { 0x0442, 0x0000 }, /* R1090 - AIF1 DRC1 (3) */
+ { 0x0443, 0x0000 }, /* R1091 - AIF1 DRC1 (4) */
+ { 0x0444, 0x0000 }, /* R1092 - AIF1 DRC1 (5) */
+ { 0x0480, 0x6318 }, /* R1152 - AIF1 DAC1 EQ Gains (1) */
+ { 0x0481, 0x6300 }, /* R1153 - AIF1 DAC1 EQ Gains (2) */
+ { 0x0482, 0x0FCA }, /* R1154 - AIF1 DAC1 EQ Band 1 A */
+ { 0x0483, 0x0400 }, /* R1155 - AIF1 DAC1 EQ Band 1 B */
+ { 0x0484, 0x00D8 }, /* R1156 - AIF1 DAC1 EQ Band 1 PG */
+ { 0x0485, 0x1EB5 }, /* R1157 - AIF1 DAC1 EQ Band 2 A */
+ { 0x0486, 0xF145 }, /* R1158 - AIF1 DAC1 EQ Band 2 B */
+ { 0x0487, 0x0B75 }, /* R1159 - AIF1 DAC1 EQ Band 2 C */
+ { 0x0488, 0x01C5 }, /* R1160 - AIF1 DAC1 EQ Band 2 PG */
+ { 0x0489, 0x1C58 }, /* R1161 - AIF1 DAC1 EQ Band 3 A */
+ { 0x048A, 0xF373 }, /* R1162 - AIF1 DAC1 EQ Band 3 B */
+ { 0x048B, 0x0A54 }, /* R1163 - AIF1 DAC1 EQ Band 3 C */
+ { 0x048C, 0x0558 }, /* R1164 - AIF1 DAC1 EQ Band 3 PG */
+ { 0x048D, 0x168E }, /* R1165 - AIF1 DAC1 EQ Band 4 A */
+ { 0x048E, 0xF829 }, /* R1166 - AIF1 DAC1 EQ Band 4 B */
+ { 0x048F, 0x07AD }, /* R1167 - AIF1 DAC1 EQ Band 4 C */
+ { 0x0490, 0x1103 }, /* R1168 - AIF1 DAC1 EQ Band 4 PG */
+ { 0x0491, 0x0564 }, /* R1169 - AIF1 DAC1 EQ Band 5 A */
+ { 0x0492, 0x0559 }, /* R1170 - AIF1 DAC1 EQ Band 5 B */
+ { 0x0493, 0x4000 }, /* R1171 - AIF1 DAC1 EQ Band 5 PG */
+ { 0x0494, 0x0000 }, /* R1172 - AIF1 DAC1 EQ Band 1 C */
+ { 0x0500, 0x00C0 }, /* R1280 - AIF2 ADC Left Volume */
+ { 0x0501, 0x00C0 }, /* R1281 - AIF2 ADC Right Volume */
+ { 0x0502, 0x00C0 }, /* R1282 - AIF2 DAC Left Volume */
+ { 0x0503, 0x00C0 }, /* R1283 - AIF2 DAC Right Volume */
+ { 0x0510, 0x0000 }, /* R1296 - AIF2 ADC Filters */
+ { 0x0520, 0x0200 }, /* R1312 - AIF2 DAC Filters (1) */
+ { 0x0521, 0x0010 }, /* R1313 - AIF2 DAC Filters (2) */
+ { 0x0530, 0x0068 }, /* R1328 - AIF2 DAC Noise Gate */
+ { 0x0540, 0x0098 }, /* R1344 - AIF2 DRC (1) */
+ { 0x0541, 0x0845 }, /* R1345 - AIF2 DRC (2) */
+ { 0x0542, 0x0000 }, /* R1346 - AIF2 DRC (3) */
+ { 0x0543, 0x0000 }, /* R1347 - AIF2 DRC (4) */
+ { 0x0544, 0x0000 }, /* R1348 - AIF2 DRC (5) */
+ { 0x0580, 0x6318 }, /* R1408 - AIF2 EQ Gains (1) */
+ { 0x0581, 0x6300 }, /* R1409 - AIF2 EQ Gains (2) */
+ { 0x0582, 0x0FCA }, /* R1410 - AIF2 EQ Band 1 A */
+ { 0x0583, 0x0400 }, /* R1411 - AIF2 EQ Band 1 B */
+ { 0x0584, 0x00D8 }, /* R1412 - AIF2 EQ Band 1 PG */
+ { 0x0585, 0x1EB5 }, /* R1413 - AIF2 EQ Band 2 A */
+ { 0x0586, 0xF145 }, /* R1414 - AIF2 EQ Band 2 B */
+ { 0x0587, 0x0B75 }, /* R1415 - AIF2 EQ Band 2 C */
+ { 0x0588, 0x01C5 }, /* R1416 - AIF2 EQ Band 2 PG */
+ { 0x0589, 0x1C58 }, /* R1417 - AIF2 EQ Band 3 A */
+ { 0x058A, 0xF373 }, /* R1418 - AIF2 EQ Band 3 B */
+ { 0x058B, 0x0A54 }, /* R1419 - AIF2 EQ Band 3 C */
+ { 0x058C, 0x0558 }, /* R1420 - AIF2 EQ Band 3 PG */
+ { 0x058D, 0x168E }, /* R1421 - AIF2 EQ Band 4 A */
+ { 0x058E, 0xF829 }, /* R1422 - AIF2 EQ Band 4 B */
+ { 0x058F, 0x07AD }, /* R1423 - AIF2 EQ Band 4 C */
+ { 0x0590, 0x1103 }, /* R1424 - AIF2 EQ Band 4 PG */
+ { 0x0591, 0x0564 }, /* R1425 - AIF2 EQ Band 5 A */
+ { 0x0592, 0x0559 }, /* R1426 - AIF2 EQ Band 5 B */
+ { 0x0593, 0x4000 }, /* R1427 - AIF2 EQ Band 5 PG */
+ { 0x0594, 0x0000 }, /* R1428 - AIF2 EQ Band 1 C */
+ { 0x0600, 0x0000 }, /* R1536 - DAC1 Mixer Volumes */
+ { 0x0601, 0x0000 }, /* R1537 - DAC1 Left Mixer Routing */
+ { 0x0602, 0x0000 }, /* R1538 - DAC1 Right Mixer Routing */
+ { 0x0603, 0x0000 }, /* R1539 - AIF2ADC Mixer Volumes */
+ { 0x0604, 0x0000 }, /* R1540 - AIF2ADC Left Mixer Routing */
+ { 0x0605, 0x0000 }, /* R1541 - AIF2ADC Right Mixer Routing */
+ { 0x0606, 0x0000 }, /* R1542 - AIF1 ADC1 Left Mixer Routing */
+ { 0x0607, 0x0000 }, /* R1543 - AIF1 ADC1 Right Mixer Routing */
+ { 0x0610, 0x02C0 }, /* R1552 - DAC1 Left Volume */
+ { 0x0611, 0x02C0 }, /* R1553 - DAC1 Right Volume */
+ { 0x0612, 0x02C0 }, /* R1554 - AIF2TX Left Volume */
+ { 0x0613, 0x02C0 }, /* R1555 - AIF2TX Right Volume */
+ { 0x0614, 0x0000 }, /* R1556 - DAC Softmute */
+ { 0x0620, 0x0002 }, /* R1568 - Oversampling */
+ { 0x0621, 0x0000 }, /* R1569 - Sidetone */
+ { 0x0700, 0x8100 }, /* R1792 - GPIO 1 */
+ { 0x0701, 0xA101 }, /* R1793 - Pull Control (MCLK2) */
+ { 0x0702, 0xA101 }, /* R1794 - Pull Control (BCLK2) */
+ { 0x0703, 0xA101 }, /* R1795 - Pull Control (DACLRCLK2) */
+ { 0x0704, 0xA101 }, /* R1796 - Pull Control (DACDAT2) */
+ { 0x0707, 0xA101 }, /* R1799 - GPIO 8 */
+ { 0x0708, 0xA101 }, /* R1800 - GPIO 9 */
+ { 0x0709, 0xA101 }, /* R1801 - GPIO 10 */
+ { 0x070A, 0xA101 }, /* R1802 - GPIO 11 */
+ { 0x0720, 0x0000 }, /* R1824 - Pull Control (1) */
+ { 0x0721, 0x0156 }, /* R1825 - Pull Control (2) */
+ { 0x0730, 0x0000 }, /* R1840 - Interrupt Status 1 */
+ { 0x0731, 0x0000 }, /* R1841 - Interrupt Status 2 */
+ { 0x0732, 0x0000 }, /* R1842 - Interrupt Raw Status 2 */
+ { 0x0738, 0x07FF }, /* R1848 - Interrupt Status 1 Mask */
+ { 0x0739, 0xDFEF }, /* R1849 - Interrupt Status 2 Mask */
+ { 0x0740, 0x0000 }, /* R1856 - Interrupt Control */
+ { 0x0748, 0x003F }, /* R1864 - IRQ Debounce */
+};
+
+static struct reg_default wm8994_defaults[] = {
+ { 0x0000, 0x8994 }, /* R0 - Software Reset */
+ { 0x0001, 0x0000 }, /* R1 - Power Management (1) */
+ { 0x0002, 0x6000 }, /* R2 - Power Management (2) */
+ { 0x0003, 0x0000 }, /* R3 - Power Management (3) */
+ { 0x0004, 0x0000 }, /* R4 - Power Management (4) */
+ { 0x0005, 0x0000 }, /* R5 - Power Management (5) */
+ { 0x0006, 0x0000 }, /* R6 - Power Management (6) */
+ { 0x0015, 0x0000 }, /* R21 - Input Mixer (1) */
+ { 0x0018, 0x008B }, /* R24 - Left Line Input 1&2 Volume */
+ { 0x0019, 0x008B }, /* R25 - Left Line Input 3&4 Volume */
+ { 0x001A, 0x008B }, /* R26 - Right Line Input 1&2 Volume */
+ { 0x001B, 0x008B }, /* R27 - Right Line Input 3&4 Volume */
+ { 0x001C, 0x006D }, /* R28 - Left Output Volume */
+ { 0x001D, 0x006D }, /* R29 - Right Output Volume */
+ { 0x001E, 0x0066 }, /* R30 - Line Outputs Volume */
+ { 0x001F, 0x0020 }, /* R31 - HPOUT2 Volume */
+ { 0x0020, 0x0079 }, /* R32 - Left OPGA Volume */
+ { 0x0021, 0x0079 }, /* R33 - Right OPGA Volume */
+ { 0x0022, 0x0003 }, /* R34 - SPKMIXL Attenuation */
+ { 0x0023, 0x0003 }, /* R35 - SPKMIXR Attenuation */
+ { 0x0024, 0x0011 }, /* R36 - SPKOUT Mixers */
+ { 0x0025, 0x0140 }, /* R37 - ClassD */
+ { 0x0026, 0x0079 }, /* R38 - Speaker Volume Left */
+ { 0x0027, 0x0079 }, /* R39 - Speaker Volume Right */
+ { 0x0028, 0x0000 }, /* R40 - Input Mixer (2) */
+ { 0x0029, 0x0000 }, /* R41 - Input Mixer (3) */
+ { 0x002A, 0x0000 }, /* R42 - Input Mixer (4) */
+ { 0x002B, 0x0000 }, /* R43 - Input Mixer (5) */
+ { 0x002C, 0x0000 }, /* R44 - Input Mixer (6) */
+ { 0x002D, 0x0000 }, /* R45 - Output Mixer (1) */
+ { 0x002E, 0x0000 }, /* R46 - Output Mixer (2) */
+ { 0x002F, 0x0000 }, /* R47 - Output Mixer (3) */
+ { 0x0030, 0x0000 }, /* R48 - Output Mixer (4) */
+ { 0x0031, 0x0000 }, /* R49 - Output Mixer (5) */
+ { 0x0032, 0x0000 }, /* R50 - Output Mixer (6) */
+ { 0x0033, 0x0000 }, /* R51 - HPOUT2 Mixer */
+ { 0x0034, 0x0000 }, /* R52 - Line Mixer (1) */
+ { 0x0035, 0x0000 }, /* R53 - Line Mixer (2) */
+ { 0x0036, 0x0000 }, /* R54 - Speaker Mixer */
+ { 0x0037, 0x0000 }, /* R55 - Additional Control */
+ { 0x0038, 0x0000 }, /* R56 - AntiPOP (1) */
+ { 0x0039, 0x0000 }, /* R57 - AntiPOP (2) */
+ { 0x003A, 0x0000 }, /* R58 - MICBIAS */
+ { 0x003B, 0x000D }, /* R59 - LDO 1 */
+ { 0x003C, 0x0003 }, /* R60 - LDO 2 */
+ { 0x004C, 0x1F25 }, /* R76 - Charge Pump (1) */
+ { 0x0051, 0x0004 }, /* R81 - Class W (1) */
+ { 0x0054, 0x0000 }, /* R84 - DC Servo (1) */
+ { 0x0055, 0x054A }, /* R85 - DC Servo (2) */
+ { 0x0057, 0x0000 }, /* R87 - DC Servo (4) */
+ { 0x0058, 0x0000 }, /* R88 - DC Servo Readback */
+ { 0x0060, 0x0000 }, /* R96 - Analogue HP (1) */
+ { 0x0100, 0x0003 }, /* R256 - Chip Revision */
+ { 0x0101, 0x8004 }, /* R257 - Control Interface */
+ { 0x0110, 0x0000 }, /* R272 - Write Sequencer Ctrl (1) */
+ { 0x0111, 0x0000 }, /* R273 - Write Sequencer Ctrl (2) */
+ { 0x0200, 0x0000 }, /* R512 - AIF1 Clocking (1) */
+ { 0x0201, 0x0000 }, /* R513 - AIF1 Clocking (2) */
+ { 0x0204, 0x0000 }, /* R516 - AIF2 Clocking (1) */
+ { 0x0205, 0x0000 }, /* R517 - AIF2 Clocking (2) */
+ { 0x0208, 0x0000 }, /* R520 - Clocking (1) */
+ { 0x0209, 0x0000 }, /* R521 - Clocking (2) */
+ { 0x0210, 0x0083 }, /* R528 - AIF1 Rate */
+ { 0x0211, 0x0083 }, /* R529 - AIF2 Rate */
+ { 0x0212, 0x0000 }, /* R530 - Rate Status */
+ { 0x0220, 0x0000 }, /* R544 - FLL1 Control (1) */
+ { 0x0221, 0x0000 }, /* R545 - FLL1 Control (2) */
+ { 0x0222, 0x0000 }, /* R546 - FLL1 Control (3) */
+ { 0x0223, 0x0000 }, /* R547 - FLL1 Control (4) */
+ { 0x0224, 0x0C80 }, /* R548 - FLL1 Control (5) */
+ { 0x0240, 0x0000 }, /* R576 - FLL2 Control (1) */
+ { 0x0241, 0x0000 }, /* R577 - FLL2 Control (2) */
+ { 0x0242, 0x0000 }, /* R578 - FLL2 Control (3) */
+ { 0x0243, 0x0000 }, /* R579 - FLL2 Control (4) */
+ { 0x0244, 0x0C80 }, /* R580 - FLL2 Control (5) */
+ { 0x0300, 0x4050 }, /* R768 - AIF1 Control (1) */
+ { 0x0301, 0x4000 }, /* R769 - AIF1 Control (2) */
+ { 0x0302, 0x0000 }, /* R770 - AIF1 Master/Slave */
+ { 0x0303, 0x0040 }, /* R771 - AIF1 BCLK */
+ { 0x0304, 0x0040 }, /* R772 - AIF1ADC LRCLK */
+ { 0x0305, 0x0040 }, /* R773 - AIF1DAC LRCLK */
+ { 0x0306, 0x0004 }, /* R774 - AIF1DAC Data */
+ { 0x0307, 0x0100 }, /* R775 - AIF1ADC Data */
+ { 0x0310, 0x4050 }, /* R784 - AIF2 Control (1) */
+ { 0x0311, 0x4000 }, /* R785 - AIF2 Control (2) */
+ { 0x0312, 0x0000 }, /* R786 - AIF2 Master/Slave */
+ { 0x0313, 0x0040 }, /* R787 - AIF2 BCLK */
+ { 0x0314, 0x0040 }, /* R788 - AIF2ADC LRCLK */
+ { 0x0315, 0x0040 }, /* R789 - AIF2DAC LRCLK */
+ { 0x0316, 0x0000 }, /* R790 - AIF2DAC Data */
+ { 0x0317, 0x0000 }, /* R791 - AIF2ADC Data */
+ { 0x0400, 0x00C0 }, /* R1024 - AIF1 ADC1 Left Volume */
+ { 0x0401, 0x00C0 }, /* R1025 - AIF1 ADC1 Right Volume */
+ { 0x0402, 0x00C0 }, /* R1026 - AIF1 DAC1 Left Volume */
+ { 0x0403, 0x00C0 }, /* R1027 - AIF1 DAC1 Right Volume */
+ { 0x0404, 0x00C0 }, /* R1028 - AIF1 ADC2 Left Volume */
+ { 0x0405, 0x00C0 }, /* R1029 - AIF1 ADC2 Right Volume */
+ { 0x0406, 0x00C0 }, /* R1030 - AIF1 DAC2 Left Volume */
+ { 0x0407, 0x00C0 }, /* R1031 - AIF1 DAC2 Right Volume */
+ { 0x0410, 0x0000 }, /* R1040 - AIF1 ADC1 Filters */
+ { 0x0411, 0x0000 }, /* R1041 - AIF1 ADC2 Filters */
+ { 0x0420, 0x0200 }, /* R1056 - AIF1 DAC1 Filters (1) */
+ { 0x0421, 0x0010 }, /* R1057 - AIF1 DAC1 Filters (2) */
+ { 0x0422, 0x0200 }, /* R1058 - AIF1 DAC2 Filters (1) */
+ { 0x0423, 0x0010 }, /* R1059 - AIF1 DAC2 Filters (2) */
+ { 0x0440, 0x0098 }, /* R1088 - AIF1 DRC1 (1) */
+ { 0x0441, 0x0845 }, /* R1089 - AIF1 DRC1 (2) */
+ { 0x0442, 0x0000 }, /* R1090 - AIF1 DRC1 (3) */
+ { 0x0443, 0x0000 }, /* R1091 - AIF1 DRC1 (4) */
+ { 0x0444, 0x0000 }, /* R1092 - AIF1 DRC1 (5) */
+ { 0x0450, 0x0098 }, /* R1104 - AIF1 DRC2 (1) */
+ { 0x0451, 0x0845 }, /* R1105 - AIF1 DRC2 (2) */
+ { 0x0452, 0x0000 }, /* R1106 - AIF1 DRC2 (3) */
+ { 0x0453, 0x0000 }, /* R1107 - AIF1 DRC2 (4) */
+ { 0x0454, 0x0000 }, /* R1108 - AIF1 DRC2 (5) */
+ { 0x0480, 0x6318 }, /* R1152 - AIF1 DAC1 EQ Gains (1) */
+ { 0x0481, 0x6300 }, /* R1153 - AIF1 DAC1 EQ Gains (2) */
+ { 0x0482, 0x0FCA }, /* R1154 - AIF1 DAC1 EQ Band 1 A */
+ { 0x0483, 0x0400 }, /* R1155 - AIF1 DAC1 EQ Band 1 B */
+ { 0x0484, 0x00D8 }, /* R1156 - AIF1 DAC1 EQ Band 1 PG */
+ { 0x0485, 0x1EB5 }, /* R1157 - AIF1 DAC1 EQ Band 2 A */
+ { 0x0486, 0xF145 }, /* R1158 - AIF1 DAC1 EQ Band 2 B */
+ { 0x0487, 0x0B75 }, /* R1159 - AIF1 DAC1 EQ Band 2 C */
+ { 0x0488, 0x01C5 }, /* R1160 - AIF1 DAC1 EQ Band 2 PG */
+ { 0x0489, 0x1C58 }, /* R1161 - AIF1 DAC1 EQ Band 3 A */
+ { 0x048A, 0xF373 }, /* R1162 - AIF1 DAC1 EQ Band 3 B */
+ { 0x048B, 0x0A54 }, /* R1163 - AIF1 DAC1 EQ Band 3 C */
+ { 0x048C, 0x0558 }, /* R1164 - AIF1 DAC1 EQ Band 3 PG */
+ { 0x048D, 0x168E }, /* R1165 - AIF1 DAC1 EQ Band 4 A */
+ { 0x048E, 0xF829 }, /* R1166 - AIF1 DAC1 EQ Band 4 B */
+ { 0x048F, 0x07AD }, /* R1167 - AIF1 DAC1 EQ Band 4 C */
+ { 0x0490, 0x1103 }, /* R1168 - AIF1 DAC1 EQ Band 4 PG */
+ { 0x0491, 0x0564 }, /* R1169 - AIF1 DAC1 EQ Band 5 A */
+ { 0x0492, 0x0559 }, /* R1170 - AIF1 DAC1 EQ Band 5 B */
+ { 0x0493, 0x4000 }, /* R1171 - AIF1 DAC1 EQ Band 5 PG */
+ { 0x04A0, 0x6318 }, /* R1184 - AIF1 DAC2 EQ Gains (1) */
+ { 0x04A1, 0x6300 }, /* R1185 - AIF1 DAC2 EQ Gains (2) */
+ { 0x04A2, 0x0FCA }, /* R1186 - AIF1 DAC2 EQ Band 1 A */
+ { 0x04A3, 0x0400 }, /* R1187 - AIF1 DAC2 EQ Band 1 B */
+ { 0x04A4, 0x00D8 }, /* R1188 - AIF1 DAC2 EQ Band 1 PG */
+ { 0x04A5, 0x1EB5 }, /* R1189 - AIF1 DAC2 EQ Band 2 A */
+ { 0x04A6, 0xF145 }, /* R1190 - AIF1 DAC2 EQ Band 2 B */
+ { 0x04A7, 0x0B75 }, /* R1191 - AIF1 DAC2 EQ Band 2 C */
+ { 0x04A8, 0x01C5 }, /* R1192 - AIF1 DAC2 EQ Band 2 PG */
+ { 0x04A9, 0x1C58 }, /* R1193 - AIF1 DAC2 EQ Band 3 A */
+ { 0x04AA, 0xF373 }, /* R1194 - AIF1 DAC2 EQ Band 3 B */
+ { 0x04AB, 0x0A54 }, /* R1195 - AIF1 DAC2 EQ Band 3 C */
+ { 0x04AC, 0x0558 }, /* R1196 - AIF1 DAC2 EQ Band 3 PG */
+ { 0x04AD, 0x168E }, /* R1197 - AIF1 DAC2 EQ Band 4 A */
+ { 0x04AE, 0xF829 }, /* R1198 - AIF1 DAC2 EQ Band 4 B */
+ { 0x04AF, 0x07AD }, /* R1199 - AIF1 DAC2 EQ Band 4 C */
+ { 0x04B0, 0x1103 }, /* R1200 - AIF1 DAC2 EQ Band 4 PG */
+ { 0x04B1, 0x0564 }, /* R1201 - AIF1 DAC2 EQ Band 5 A */
+ { 0x04B2, 0x0559 }, /* R1202 - AIF1 DAC2 EQ Band 5 B */
+ { 0x04B3, 0x4000 }, /* R1203 - AIF1 DAC2 EQ Band 5 PG */
+ { 0x0500, 0x00C0 }, /* R1280 - AIF2 ADC Left Volume */
+ { 0x0501, 0x00C0 }, /* R1281 - AIF2 ADC Right Volume */
+ { 0x0502, 0x00C0 }, /* R1282 - AIF2 DAC Left Volume */
+ { 0x0503, 0x00C0 }, /* R1283 - AIF2 DAC Right Volume */
+ { 0x0510, 0x0000 }, /* R1296 - AIF2 ADC Filters */
+ { 0x0520, 0x0200 }, /* R1312 - AIF2 DAC Filters (1) */
+ { 0x0521, 0x0010 }, /* R1313 - AIF2 DAC Filters (2) */
+ { 0x0540, 0x0098 }, /* R1344 - AIF2 DRC (1) */
+ { 0x0541, 0x0845 }, /* R1345 - AIF2 DRC (2) */
+ { 0x0542, 0x0000 }, /* R1346 - AIF2 DRC (3) */
+ { 0x0543, 0x0000 }, /* R1347 - AIF2 DRC (4) */
+ { 0x0544, 0x0000 }, /* R1348 - AIF2 DRC (5) */
+ { 0x0580, 0x6318 }, /* R1408 - AIF2 EQ Gains (1) */
+ { 0x0581, 0x6300 }, /* R1409 - AIF2 EQ Gains (2) */
+ { 0x0582, 0x0FCA }, /* R1410 - AIF2 EQ Band 1 A */
+ { 0x0583, 0x0400 }, /* R1411 - AIF2 EQ Band 1 B */
+ { 0x0584, 0x00D8 }, /* R1412 - AIF2 EQ Band 1 PG */
+ { 0x0585, 0x1EB5 }, /* R1413 - AIF2 EQ Band 2 A */
+ { 0x0586, 0xF145 }, /* R1414 - AIF2 EQ Band 2 B */
+ { 0x0587, 0x0B75 }, /* R1415 - AIF2 EQ Band 2 C */
+ { 0x0588, 0x01C5 }, /* R1416 - AIF2 EQ Band 2 PG */
+ { 0x0589, 0x1C58 }, /* R1417 - AIF2 EQ Band 3 A */
+ { 0x058A, 0xF373 }, /* R1418 - AIF2 EQ Band 3 B */
+ { 0x058B, 0x0A54 }, /* R1419 - AIF2 EQ Band 3 C */
+ { 0x058C, 0x0558 }, /* R1420 - AIF2 EQ Band 3 PG */
+ { 0x058D, 0x168E }, /* R1421 - AIF2 EQ Band 4 A */
+ { 0x058E, 0xF829 }, /* R1422 - AIF2 EQ Band 4 B */
+ { 0x058F, 0x07AD }, /* R1423 - AIF2 EQ Band 4 C */
+ { 0x0590, 0x1103 }, /* R1424 - AIF2 EQ Band 4 PG */
+ { 0x0591, 0x0564 }, /* R1425 - AIF2 EQ Band 5 A */
+ { 0x0592, 0x0559 }, /* R1426 - AIF2 EQ Band 5 B */
+ { 0x0593, 0x4000 }, /* R1427 - AIF2 EQ Band 5 PG */
+ { 0x0600, 0x0000 }, /* R1536 - DAC1 Mixer Volumes */
+ { 0x0601, 0x0000 }, /* R1537 - DAC1 Left Mixer Routing */
+ { 0x0602, 0x0000 }, /* R1538 - DAC1 Right Mixer Routing */
+ { 0x0603, 0x0000 }, /* R1539 - DAC2 Mixer Volumes */
+ { 0x0604, 0x0000 }, /* R1540 - DAC2 Left Mixer Routing */
+ { 0x0605, 0x0000 }, /* R1541 - DAC2 Right Mixer Routing */
+ { 0x0606, 0x0000 }, /* R1542 - AIF1 ADC1 Left Mixer Routing */
+ { 0x0607, 0x0000 }, /* R1543 - AIF1 ADC1 Right Mixer Routing */
+ { 0x0608, 0x0000 }, /* R1544 - AIF1 ADC2 Left Mixer Routing */
+ { 0x0609, 0x0000 }, /* R1545 - AIF1 ADC2 Right mixer Routing */
+ { 0x0610, 0x02C0 }, /* R1552 - DAC1 Left Volume */
+ { 0x0611, 0x02C0 }, /* R1553 - DAC1 Right Volume */
+ { 0x0612, 0x02C0 }, /* R1554 - DAC2 Left Volume */
+ { 0x0613, 0x02C0 }, /* R1555 - DAC2 Right Volume */
+ { 0x0614, 0x0000 }, /* R1556 - DAC Softmute */
+ { 0x0620, 0x0002 }, /* R1568 - Oversampling */
+ { 0x0621, 0x0000 }, /* R1569 - Sidetone */
+ { 0x0700, 0x8100 }, /* R1792 - GPIO 1 */
+ { 0x0701, 0xA101 }, /* R1793 - GPIO 2 */
+ { 0x0702, 0xA101 }, /* R1794 - GPIO 3 */
+ { 0x0703, 0xA101 }, /* R1795 - GPIO 4 */
+ { 0x0704, 0xA101 }, /* R1796 - GPIO 5 */
+ { 0x0705, 0xA101 }, /* R1797 - GPIO 6 */
+ { 0x0706, 0xA101 }, /* R1798 - GPIO 7 */
+ { 0x0707, 0xA101 }, /* R1799 - GPIO 8 */
+ { 0x0708, 0xA101 }, /* R1800 - GPIO 9 */
+ { 0x0709, 0xA101 }, /* R1801 - GPIO 10 */
+ { 0x070A, 0xA101 }, /* R1802 - GPIO 11 */
+ { 0x0720, 0x0000 }, /* R1824 - Pull Control (1) */
+ { 0x0721, 0x0156 }, /* R1825 - Pull Control (2) */
+ { 0x0730, 0x0000 }, /* R1840 - Interrupt Status 1 */
+ { 0x0731, 0x0000 }, /* R1841 - Interrupt Status 2 */
+ { 0x0732, 0x0000 }, /* R1842 - Interrupt Raw Status 2 */
+ { 0x0738, 0x07FF }, /* R1848 - Interrupt Status 1 Mask */
+ { 0x0739, 0xFFFF }, /* R1849 - Interrupt Status 2 Mask */
+ { 0x0740, 0x0000 }, /* R1856 - Interrupt Control */
+ { 0x0748, 0x003F }, /* R1864 - IRQ Debounce */
+};
+
+static struct reg_default wm8958_defaults[] = {
+ { 0x0000, 0x8958 }, /* R0 - Software Reset */
+ { 0x0001, 0x0000 }, /* R1 - Power Management (1) */
+ { 0x0002, 0x6000 }, /* R2 - Power Management (2) */
+ { 0x0003, 0x0000 }, /* R3 - Power Management (3) */
+ { 0x0004, 0x0000 }, /* R4 - Power Management (4) */
+ { 0x0005, 0x0000 }, /* R5 - Power Management (5) */
+ { 0x0006, 0x0000 }, /* R6 - Power Management (6) */
+ { 0x0015, 0x0000 }, /* R21 - Input Mixer (1) */
+ { 0x0018, 0x008B }, /* R24 - Left Line Input 1&2 Volume */
+ { 0x0019, 0x008B }, /* R25 - Left Line Input 3&4 Volume */
+ { 0x001A, 0x008B }, /* R26 - Right Line Input 1&2 Volume */
+ { 0x001B, 0x008B }, /* R27 - Right Line Input 3&4 Volume */
+ { 0x001C, 0x006D }, /* R28 - Left Output Volume */
+ { 0x001D, 0x006D }, /* R29 - Right Output Volume */
+ { 0x001E, 0x0066 }, /* R30 - Line Outputs Volume */
+ { 0x001F, 0x0020 }, /* R31 - HPOUT2 Volume */
+ { 0x0020, 0x0079 }, /* R32 - Left OPGA Volume */
+ { 0x0021, 0x0079 }, /* R33 - Right OPGA Volume */
+ { 0x0022, 0x0003 }, /* R34 - SPKMIXL Attenuation */
+ { 0x0023, 0x0003 }, /* R35 - SPKMIXR Attenuation */
+ { 0x0024, 0x0011 }, /* R36 - SPKOUT Mixers */
+ { 0x0025, 0x0140 }, /* R37 - ClassD */
+ { 0x0026, 0x0079 }, /* R38 - Speaker Volume Left */
+ { 0x0027, 0x0079 }, /* R39 - Speaker Volume Right */
+ { 0x0028, 0x0000 }, /* R40 - Input Mixer (2) */
+ { 0x0029, 0x0000 }, /* R41 - Input Mixer (3) */
+ { 0x002A, 0x0000 }, /* R42 - Input Mixer (4) */
+ { 0x002B, 0x0000 }, /* R43 - Input Mixer (5) */
+ { 0x002C, 0x0000 }, /* R44 - Input Mixer (6) */
+ { 0x002D, 0x0000 }, /* R45 - Output Mixer (1) */
+ { 0x002E, 0x0000 }, /* R46 - Output Mixer (2) */
+ { 0x002F, 0x0000 }, /* R47 - Output Mixer (3) */
+ { 0x0030, 0x0000 }, /* R48 - Output Mixer (4) */
+ { 0x0031, 0x0000 }, /* R49 - Output Mixer (5) */
+ { 0x0032, 0x0000 }, /* R50 - Output Mixer (6) */
+ { 0x0033, 0x0000 }, /* R51 - HPOUT2 Mixer */
+ { 0x0034, 0x0000 }, /* R52 - Line Mixer (1) */
+ { 0x0035, 0x0000 }, /* R53 - Line Mixer (2) */
+ { 0x0036, 0x0000 }, /* R54 - Speaker Mixer */
+ { 0x0037, 0x0000 }, /* R55 - Additional Control */
+ { 0x0038, 0x0000 }, /* R56 - AntiPOP (1) */
+ { 0x0039, 0x0180 }, /* R57 - AntiPOP (2) */
+ { 0x003B, 0x000D }, /* R59 - LDO 1 */
+ { 0x003C, 0x0005 }, /* R60 - LDO 2 */
+ { 0x003D, 0x0039 }, /* R61 - MICBIAS1 */
+ { 0x003E, 0x0039 }, /* R62 - MICBIAS2 */
+ { 0x004C, 0x1F25 }, /* R76 - Charge Pump (1) */
+ { 0x004D, 0xAB19 }, /* R77 - Charge Pump (2) */
+ { 0x0051, 0x0004 }, /* R81 - Class W (1) */
+ { 0x0055, 0x054A }, /* R85 - DC Servo (2) */
+ { 0x0057, 0x0000 }, /* R87 - DC Servo (4) */
+ { 0x0060, 0x0000 }, /* R96 - Analogue HP (1) */
+ { 0x00C5, 0x0000 }, /* R197 - Class D Test (5) */
+ { 0x00D0, 0x5600 }, /* R208 - Mic Detect 1 */
+ { 0x00D1, 0x007F }, /* R209 - Mic Detect 2 */
+ { 0x0101, 0x8004 }, /* R257 - Control Interface */
+ { 0x0110, 0x0000 }, /* R272 - Write Sequencer Ctrl (1) */
+ { 0x0111, 0x0000 }, /* R273 - Write Sequencer Ctrl (2) */
+ { 0x0200, 0x0000 }, /* R512 - AIF1 Clocking (1) */
+ { 0x0201, 0x0000 }, /* R513 - AIF1 Clocking (2) */
+ { 0x0204, 0x0000 }, /* R516 - AIF2 Clocking (1) */
+ { 0x0205, 0x0000 }, /* R517 - AIF2 Clocking (2) */
+ { 0x0208, 0x0000 }, /* R520 - Clocking (1) */
+ { 0x0209, 0x0000 }, /* R521 - Clocking (2) */
+ { 0x0210, 0x0083 }, /* R528 - AIF1 Rate */
+ { 0x0211, 0x0083 }, /* R529 - AIF2 Rate */
+ { 0x0220, 0x0000 }, /* R544 - FLL1 Control (1) */
+ { 0x0221, 0x0000 }, /* R545 - FLL1 Control (2) */
+ { 0x0222, 0x0000 }, /* R546 - FLL1 Control (3) */
+ { 0x0223, 0x0000 }, /* R547 - FLL1 Control (4) */
+ { 0x0224, 0x0C80 }, /* R548 - FLL1 Control (5) */
+ { 0x0226, 0x0000 }, /* R550 - FLL1 EFS 1 */
+ { 0x0227, 0x0006 }, /* R551 - FLL1 EFS 2 */
+ { 0x0240, 0x0000 }, /* R576 - FLL2Control (1) */
+ { 0x0241, 0x0000 }, /* R577 - FLL2Control (2) */
+ { 0x0242, 0x0000 }, /* R578 - FLL2Control (3) */
+ { 0x0243, 0x0000 }, /* R579 - FLL2 Control (4) */
+ { 0x0244, 0x0C80 }, /* R580 - FLL2Control (5) */
+ { 0x0246, 0x0000 }, /* R582 - FLL2 EFS 1 */
+ { 0x0247, 0x0006 }, /* R583 - FLL2 EFS 2 */
+ { 0x0300, 0x4050 }, /* R768 - AIF1 Control (1) */
+ { 0x0301, 0x4000 }, /* R769 - AIF1 Control (2) */
+ { 0x0302, 0x0000 }, /* R770 - AIF1 Master/Slave */
+ { 0x0303, 0x0040 }, /* R771 - AIF1 BCLK */
+ { 0x0304, 0x0040 }, /* R772 - AIF1ADC LRCLK */
+ { 0x0305, 0x0040 }, /* R773 - AIF1DAC LRCLK */
+ { 0x0306, 0x0004 }, /* R774 - AIF1DAC Data */
+ { 0x0307, 0x0100 }, /* R775 - AIF1ADC Data */
+ { 0x0310, 0x4053 }, /* R784 - AIF2 Control (1) */
+ { 0x0311, 0x4000 }, /* R785 - AIF2 Control (2) */
+ { 0x0312, 0x0000 }, /* R786 - AIF2 Master/Slave */
+ { 0x0313, 0x0040 }, /* R787 - AIF2 BCLK */
+ { 0x0314, 0x0040 }, /* R788 - AIF2ADC LRCLK */
+ { 0x0315, 0x0040 }, /* R789 - AIF2DAC LRCLK */
+ { 0x0316, 0x0000 }, /* R790 - AIF2DAC Data */
+ { 0x0317, 0x0000 }, /* R791 - AIF2ADC Data */
+ { 0x0320, 0x0040 }, /* R800 - AIF3 Control (1) */
+ { 0x0321, 0x0000 }, /* R801 - AIF3 Control (2) */
+ { 0x0322, 0x0000 }, /* R802 - AIF3DAC Data */
+ { 0x0323, 0x0000 }, /* R803 - AIF3ADC Data */
+ { 0x0400, 0x00C0 }, /* R1024 - AIF1 ADC1 Left Volume */
+ { 0x0401, 0x00C0 }, /* R1025 - AIF1 ADC1 Right Volume */
+ { 0x0402, 0x00C0 }, /* R1026 - AIF1 DAC1 Left Volume */
+ { 0x0403, 0x00C0 }, /* R1027 - AIF1 DAC1 Right Volume */
+ { 0x0404, 0x00C0 }, /* R1028 - AIF1 ADC2 Left Volume */
+ { 0x0405, 0x00C0 }, /* R1029 - AIF1 ADC2 Right Volume */
+ { 0x0406, 0x00C0 }, /* R1030 - AIF1 DAC2 Left Volume */
+ { 0x0407, 0x00C0 }, /* R1031 - AIF1 DAC2 Right Volume */
+ { 0x0410, 0x0000 }, /* R1040 - AIF1 ADC1 Filters */
+ { 0x0411, 0x0000 }, /* R1041 - AIF1 ADC2 Filters */
+ { 0x0420, 0x0200 }, /* R1056 - AIF1 DAC1 Filters (1) */
+ { 0x0421, 0x0010 }, /* R1057 - AIF1 DAC1 Filters (2) */
+ { 0x0422, 0x0200 }, /* R1058 - AIF1 DAC2 Filters (1) */
+ { 0x0423, 0x0010 }, /* R1059 - AIF1 DAC2 Filters (2) */
+ { 0x0430, 0x0068 }, /* R1072 - AIF1 DAC1 Noise Gate */
+ { 0x0431, 0x0068 }, /* R1073 - AIF1 DAC2 Noise Gate */
+ { 0x0440, 0x0098 }, /* R1088 - AIF1 DRC1 (1) */
+ { 0x0441, 0x0845 }, /* R1089 - AIF1 DRC1 (2) */
+ { 0x0442, 0x0000 }, /* R1090 - AIF1 DRC1 (3) */
+ { 0x0443, 0x0000 }, /* R1091 - AIF1 DRC1 (4) */
+ { 0x0444, 0x0000 }, /* R1092 - AIF1 DRC1 (5) */
+ { 0x0450, 0x0098 }, /* R1104 - AIF1 DRC2 (1) */
+ { 0x0451, 0x0845 }, /* R1105 - AIF1 DRC2 (2) */
+ { 0x0452, 0x0000 }, /* R1106 - AIF1 DRC2 (3) */
+ { 0x0453, 0x0000 }, /* R1107 - AIF1 DRC2 (4) */
+ { 0x0454, 0x0000 }, /* R1108 - AIF1 DRC2 (5) */
+ { 0x0480, 0x6318 }, /* R1152 - AIF1 DAC1 EQ Gains (1) */
+ { 0x0481, 0x6300 }, /* R1153 - AIF1 DAC1 EQ Gains (2) */
+ { 0x0482, 0x0FCA }, /* R1154 - AIF1 DAC1 EQ Band 1 A */
+ { 0x0483, 0x0400 }, /* R1155 - AIF1 DAC1 EQ Band 1 B */
+ { 0x0484, 0x00D8 }, /* R1156 - AIF1 DAC1 EQ Band 1 PG */
+ { 0x0485, 0x1EB5 }, /* R1157 - AIF1 DAC1 EQ Band 2 A */
+ { 0x0486, 0xF145 }, /* R1158 - AIF1 DAC1 EQ Band 2 B */
+ { 0x0487, 0x0B75 }, /* R1159 - AIF1 DAC1 EQ Band 2 C */
+ { 0x0488, 0x01C5 }, /* R1160 - AIF1 DAC1 EQ Band 2 PG */
+ { 0x0489, 0x1C58 }, /* R1161 - AIF1 DAC1 EQ Band 3 A */
+ { 0x048A, 0xF373 }, /* R1162 - AIF1 DAC1 EQ Band 3 B */
+ { 0x048B, 0x0A54 }, /* R1163 - AIF1 DAC1 EQ Band 3 C */
+ { 0x048C, 0x0558 }, /* R1164 - AIF1 DAC1 EQ Band 3 PG */
+ { 0x048D, 0x168E }, /* R1165 - AIF1 DAC1 EQ Band 4 A */
+ { 0x048E, 0xF829 }, /* R1166 - AIF1 DAC1 EQ Band 4 B */
+ { 0x048F, 0x07AD }, /* R1167 - AIF1 DAC1 EQ Band 4 C */
+ { 0x0490, 0x1103 }, /* R1168 - AIF1 DAC1 EQ Band 4 PG */
+ { 0x0491, 0x0564 }, /* R1169 - AIF1 DAC1 EQ Band 5 A */
+ { 0x0492, 0x0559 }, /* R1170 - AIF1 DAC1 EQ Band 5 B */
+ { 0x0493, 0x4000 }, /* R1171 - AIF1 DAC1 EQ Band 5 PG */
+ { 0x0494, 0x0000 }, /* R1172 - AIF1 DAC1 EQ Band 1 C */
+ { 0x04A0, 0x6318 }, /* R1184 - AIF1 DAC2 EQ Gains (1) */
+ { 0x04A1, 0x6300 }, /* R1185 - AIF1 DAC2 EQ Gains (2) */
+ { 0x04A2, 0x0FCA }, /* R1186 - AIF1 DAC2 EQ Band 1 A */
+ { 0x04A3, 0x0400 }, /* R1187 - AIF1 DAC2 EQ Band 1 B */
+ { 0x04A4, 0x00D8 }, /* R1188 - AIF1 DAC2 EQ Band 1 PG */
+ { 0x04A5, 0x1EB5 }, /* R1189 - AIF1 DAC2 EQ Band 2 A */
+ { 0x04A6, 0xF145 }, /* R1190 - AIF1 DAC2 EQ Band 2 B */
+ { 0x04A7, 0x0B75 }, /* R1191 - AIF1 DAC2 EQ Band 2 C */
+ { 0x04A8, 0x01C5 }, /* R1192 - AIF1 DAC2 EQ Band 2 PG */
+ { 0x04A9, 0x1C58 }, /* R1193 - AIF1 DAC2 EQ Band 3 A */
+ { 0x04AA, 0xF373 }, /* R1194 - AIF1 DAC2 EQ Band 3 B */
+ { 0x04AB, 0x0A54 }, /* R1195 - AIF1 DAC2 EQ Band 3 C */
+ { 0x04AC, 0x0558 }, /* R1196 - AIF1 DAC2 EQ Band 3 PG */
+ { 0x04AD, 0x168E }, /* R1197 - AIF1 DAC2 EQ Band 4 A */
+ { 0x04AE, 0xF829 }, /* R1198 - AIF1 DAC2 EQ Band 4 B */
+ { 0x04AF, 0x07AD }, /* R1199 - AIF1 DAC2 EQ Band 4 C */
+ { 0x04B0, 0x1103 }, /* R1200 - AIF1 DAC2 EQ Band 4 PG */
+ { 0x04B1, 0x0564 }, /* R1201 - AIF1 DAC2 EQ Band 5 A */
+ { 0x04B2, 0x0559 }, /* R1202 - AIF1 DAC2 EQ Band 5 B */
+ { 0x04B3, 0x4000 }, /* R1203 - AIF1 DAC2 EQ Band 5 PG */
+ { 0x04B4, 0x0000 }, /* R1204 - AIF1 DAC2EQ Band 1 C */
+ { 0x0500, 0x00C0 }, /* R1280 - AIF2 ADC Left Volume */
+ { 0x0501, 0x00C0 }, /* R1281 - AIF2 ADC Right Volume */
+ { 0x0502, 0x00C0 }, /* R1282 - AIF2 DAC Left Volume */
+ { 0x0503, 0x00C0 }, /* R1283 - AIF2 DAC Right Volume */
+ { 0x0510, 0x0000 }, /* R1296 - AIF2 ADC Filters */
+ { 0x0520, 0x0200 }, /* R1312 - AIF2 DAC Filters (1) */
+ { 0x0521, 0x0010 }, /* R1313 - AIF2 DAC Filters (2) */
+ { 0x0530, 0x0068 }, /* R1328 - AIF2 DAC Noise Gate */
+ { 0x0540, 0x0098 }, /* R1344 - AIF2 DRC (1) */
+ { 0x0541, 0x0845 }, /* R1345 - AIF2 DRC (2) */
+ { 0x0542, 0x0000 }, /* R1346 - AIF2 DRC (3) */
+ { 0x0543, 0x0000 }, /* R1347 - AIF2 DRC (4) */
+ { 0x0544, 0x0000 }, /* R1348 - AIF2 DRC (5) */
+ { 0x0580, 0x6318 }, /* R1408 - AIF2 EQ Gains (1) */
+ { 0x0581, 0x6300 }, /* R1409 - AIF2 EQ Gains (2) */
+ { 0x0582, 0x0FCA }, /* R1410 - AIF2 EQ Band 1 A */
+ { 0x0583, 0x0400 }, /* R1411 - AIF2 EQ Band 1 B */
+ { 0x0584, 0x00D8 }, /* R1412 - AIF2 EQ Band 1 PG */
+ { 0x0585, 0x1EB5 }, /* R1413 - AIF2 EQ Band 2 A */
+ { 0x0586, 0xF145 }, /* R1414 - AIF2 EQ Band 2 B */
+ { 0x0587, 0x0B75 }, /* R1415 - AIF2 EQ Band 2 C */
+ { 0x0588, 0x01C5 }, /* R1416 - AIF2 EQ Band 2 PG */
+ { 0x0589, 0x1C58 }, /* R1417 - AIF2 EQ Band 3 A */
+ { 0x058A, 0xF373 }, /* R1418 - AIF2 EQ Band 3 B */
+ { 0x058B, 0x0A54 }, /* R1419 - AIF2 EQ Band 3 C */
+ { 0x058C, 0x0558 }, /* R1420 - AIF2 EQ Band 3 PG */
+ { 0x058D, 0x168E }, /* R1421 - AIF2 EQ Band 4 A */
+ { 0x058E, 0xF829 }, /* R1422 - AIF2 EQ Band 4 B */
+ { 0x058F, 0x07AD }, /* R1423 - AIF2 EQ Band 4 C */
+ { 0x0590, 0x1103 }, /* R1424 - AIF2 EQ Band 4 PG */
+ { 0x0591, 0x0564 }, /* R1425 - AIF2 EQ Band 5 A */
+ { 0x0592, 0x0559 }, /* R1426 - AIF2 EQ Band 5 B */
+ { 0x0593, 0x4000 }, /* R1427 - AIF2 EQ Band 5 PG */
+ { 0x0594, 0x0000 }, /* R1428 - AIF2 EQ Band 1 C */
+ { 0x0600, 0x0000 }, /* R1536 - DAC1 Mixer Volumes */
+ { 0x0601, 0x0000 }, /* R1537 - DAC1 Left Mixer Routing */
+ { 0x0602, 0x0000 }, /* R1538 - DAC1 Right Mixer Routing */
+ { 0x0603, 0x0000 }, /* R1539 - DAC2 Mixer Volumes */
+ { 0x0604, 0x0000 }, /* R1540 - DAC2 Left Mixer Routing */
+ { 0x0605, 0x0000 }, /* R1541 - DAC2 Right Mixer Routing */
+ { 0x0606, 0x0000 }, /* R1542 - AIF1 ADC1 Left Mixer Routing */
+ { 0x0607, 0x0000 }, /* R1543 - AIF1 ADC1 Right Mixer Routing */
+ { 0x0608, 0x0000 }, /* R1544 - AIF1 ADC2 Left Mixer Routing */
+ { 0x0609, 0x0000 }, /* R1545 - AIF1 ADC2 Right mixer Routing */
+ { 0x0610, 0x02C0 }, /* R1552 - DAC1 Left Volume */
+ { 0x0611, 0x02C0 }, /* R1553 - DAC1 Right Volume */
+ { 0x0612, 0x02C0 }, /* R1554 - DAC2 Left Volume */
+ { 0x0613, 0x02C0 }, /* R1555 - DAC2 Right Volume */
+ { 0x0614, 0x0000 }, /* R1556 - DAC Softmute */
+ { 0x0620, 0x0002 }, /* R1568 - Oversampling */
+ { 0x0621, 0x0000 }, /* R1569 - Sidetone */
+ { 0x0700, 0x8100 }, /* R1792 - GPIO 1 */
+ { 0x0701, 0xA101 }, /* R1793 - Pull Control (MCLK2) */
+ { 0x0702, 0xA101 }, /* R1794 - Pull Control (BCLK2) */
+ { 0x0703, 0xA101 }, /* R1795 - Pull Control (DACLRCLK2) */
+ { 0x0704, 0xA101 }, /* R1796 - Pull Control (DACDAT2) */
+ { 0x0705, 0xA101 }, /* R1797 - GPIO 6 */
+ { 0x0707, 0xA101 }, /* R1799 - GPIO 8 */
+ { 0x0708, 0xA101 }, /* R1800 - GPIO 9 */
+ { 0x0709, 0xA101 }, /* R1801 - GPIO 10 */
+ { 0x070A, 0xA101 }, /* R1802 - GPIO 11 */
+ { 0x0720, 0x0000 }, /* R1824 - Pull Control (1) */
+ { 0x0721, 0x0156 }, /* R1825 - Pull Control (2) */
+ { 0x0738, 0x07FF }, /* R1848 - Interrupt Status 1 Mask */
+ { 0x0739, 0xFFEF }, /* R1849 - Interrupt Status 2 Mask */
+ { 0x0740, 0x0000 }, /* R1856 - Interrupt Control */
+ { 0x0748, 0x003F }, /* R1864 - IRQ Debounce */
+ { 0x0900, 0x1C00 }, /* R2304 - DSP2_Program */
+ { 0x0901, 0x0000 }, /* R2305 - DSP2_Config */
+ { 0x0A0D, 0x0000 }, /* R2573 - DSP2_ExecControl */
+ { 0x2400, 0x003F }, /* R9216 - MBC Band 1 K (1) */
+ { 0x2401, 0x8BD8 }, /* R9217 - MBC Band 1 K (2) */
+ { 0x2402, 0x0032 }, /* R9218 - MBC Band 1 N1 (1) */
+ { 0x2403, 0xF52D }, /* R9219 - MBC Band 1 N1 (2) */
+ { 0x2404, 0x0065 }, /* R9220 - MBC Band 1 N2 (1) */
+ { 0x2405, 0xAC8C }, /* R9221 - MBC Band 1 N2 (2) */
+ { 0x2406, 0x006B }, /* R9222 - MBC Band 1 N3 (1) */
+ { 0x2407, 0xE087 }, /* R9223 - MBC Band 1 N3 (2) */
+ { 0x2408, 0x0072 }, /* R9224 - MBC Band 1 N4 (1) */
+ { 0x2409, 0x1483 }, /* R9225 - MBC Band 1 N4 (2) */
+ { 0x240A, 0x0072 }, /* R9226 - MBC Band 1 N5 (1) */
+ { 0x240B, 0x1483 }, /* R9227 - MBC Band 1 N5 (2) */
+ { 0x240C, 0x0043 }, /* R9228 - MBC Band 1 X1 (1) */
+ { 0x240D, 0x3525 }, /* R9229 - MBC Band 1 X1 (2) */
+ { 0x240E, 0x0006 }, /* R9230 - MBC Band 1 X2 (1) */
+ { 0x240F, 0x6A4A }, /* R9231 - MBC Band 1 X2 (2) */
+ { 0x2410, 0x0043 }, /* R9232 - MBC Band 1 X3 (1) */
+ { 0x2411, 0x6079 }, /* R9233 - MBC Band 1 X3 (2) */
+ { 0x2412, 0x000C }, /* R9234 - MBC Band 1 Attack (1) */
+ { 0x2413, 0xCCCD }, /* R9235 - MBC Band 1 Attack (2) */
+ { 0x2414, 0x0000 }, /* R9236 - MBC Band 1 Decay (1) */
+ { 0x2415, 0x0800 }, /* R9237 - MBC Band 1 Decay (2) */
+ { 0x2416, 0x003F }, /* R9238 - MBC Band 2 K (1) */
+ { 0x2417, 0x8BD8 }, /* R9239 - MBC Band 2 K (2) */
+ { 0x2418, 0x0032 }, /* R9240 - MBC Band 2 N1 (1) */
+ { 0x2419, 0xF52D }, /* R9241 - MBC Band 2 N1 (2) */
+ { 0x241A, 0x0065 }, /* R9242 - MBC Band 2 N2 (1) */
+ { 0x241B, 0xAC8C }, /* R9243 - MBC Band 2 N2 (2) */
+ { 0x241C, 0x006B }, /* R9244 - MBC Band 2 N3 (1) */
+ { 0x241D, 0xE087 }, /* R9245 - MBC Band 2 N3 (2) */
+ { 0x241E, 0x0072 }, /* R9246 - MBC Band 2 N4 (1) */
+ { 0x241F, 0x1483 }, /* R9247 - MBC Band 2 N4 (2) */
+ { 0x2420, 0x0072 }, /* R9248 - MBC Band 2 N5 (1) */
+ { 0x2421, 0x1483 }, /* R9249 - MBC Band 2 N5 (2) */
+ { 0x2422, 0x0043 }, /* R9250 - MBC Band 2 X1 (1) */
+ { 0x2423, 0x3525 }, /* R9251 - MBC Band 2 X1 (2) */
+ { 0x2424, 0x0006 }, /* R9252 - MBC Band 2 X2 (1) */
+ { 0x2425, 0x6A4A }, /* R9253 - MBC Band 2 X2 (2) */
+ { 0x2426, 0x0043 }, /* R9254 - MBC Band 2 X3 (1) */
+ { 0x2427, 0x6079 }, /* R9255 - MBC Band 2 X3 (2) */
+ { 0x2428, 0x000C }, /* R9256 - MBC Band 2 Attack (1) */
+ { 0x2429, 0xCCCD }, /* R9257 - MBC Band 2 Attack (2) */
+ { 0x242A, 0x0000 }, /* R9258 - MBC Band 2 Decay (1) */
+ { 0x242B, 0x0800 }, /* R9259 - MBC Band 2 Decay (2) */
+ { 0x242C, 0x005A }, /* R9260 - MBC_B2_PG2 (1) */
+ { 0x242D, 0x7EFA }, /* R9261 - MBC_B2_PG2 (2) */
+ { 0x242E, 0x005A }, /* R9262 - MBC_B1_PG2 (1) */
+ { 0x242F, 0x7EFA }, /* R9263 - MBC_B1_PG2 (2) */
+ { 0x2600, 0x00A7 }, /* R9728 - MBC Crossover (1) */
+ { 0x2601, 0x0D1C }, /* R9729 - MBC Crossover (2) */
+ { 0x2602, 0x0083 }, /* R9730 - MBC HPF (1) */
+ { 0x2603, 0x98AD }, /* R9731 - MBC HPF (2) */
+ { 0x2606, 0x0008 }, /* R9734 - MBC LPF (1) */
+ { 0x2607, 0xE7A2 }, /* R9735 - MBC LPF (2) */
+ { 0x260A, 0x0055 }, /* R9738 - MBC RMS Limit (1) */
+ { 0x260B, 0x8C4B }, /* R9739 - MBC RMS Limit (2) */
+};
+
+static bool wm1811_readable_register(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case WM8994_SOFTWARE_RESET:
+ case WM8994_POWER_MANAGEMENT_1:
+ case WM8994_POWER_MANAGEMENT_2:
+ case WM8994_POWER_MANAGEMENT_3:
+ case WM8994_POWER_MANAGEMENT_4:
+ case WM8994_POWER_MANAGEMENT_5:
+ case WM8994_POWER_MANAGEMENT_6:
+ case WM8994_INPUT_MIXER_1:
+ case WM8994_LEFT_LINE_INPUT_1_2_VOLUME:
+ case WM8994_LEFT_LINE_INPUT_3_4_VOLUME:
+ case WM8994_RIGHT_LINE_INPUT_1_2_VOLUME:
+ case WM8994_RIGHT_LINE_INPUT_3_4_VOLUME:
+ case WM8994_LEFT_OUTPUT_VOLUME:
+ case WM8994_RIGHT_OUTPUT_VOLUME:
+ case WM8994_LINE_OUTPUTS_VOLUME:
+ case WM8994_HPOUT2_VOLUME:
+ case WM8994_LEFT_OPGA_VOLUME:
+ case WM8994_RIGHT_OPGA_VOLUME:
+ case WM8994_SPKMIXL_ATTENUATION:
+ case WM8994_SPKMIXR_ATTENUATION:
+ case WM8994_SPKOUT_MIXERS:
+ case WM8994_CLASSD:
+ case WM8994_SPEAKER_VOLUME_LEFT:
+ case WM8994_SPEAKER_VOLUME_RIGHT:
+ case WM8994_INPUT_MIXER_2:
+ case WM8994_INPUT_MIXER_3:
+ case WM8994_INPUT_MIXER_4:
+ case WM8994_INPUT_MIXER_5:
+ case WM8994_INPUT_MIXER_6:
+ case WM8994_OUTPUT_MIXER_1:
+ case WM8994_OUTPUT_MIXER_2:
+ case WM8994_OUTPUT_MIXER_3:
+ case WM8994_OUTPUT_MIXER_4:
+ case WM8994_OUTPUT_MIXER_5:
+ case WM8994_OUTPUT_MIXER_6:
+ case WM8994_HPOUT2_MIXER:
+ case WM8994_LINE_MIXER_1:
+ case WM8994_LINE_MIXER_2:
+ case WM8994_SPEAKER_MIXER:
+ case WM8994_ADDITIONAL_CONTROL:
+ case WM8994_ANTIPOP_1:
+ case WM8994_ANTIPOP_2:
+ case WM8994_LDO_1:
+ case WM8994_LDO_2:
+ case WM8958_MICBIAS1:
+ case WM8958_MICBIAS2:
+ case WM8994_CHARGE_PUMP_1:
+ case WM8958_CHARGE_PUMP_2:
+ case WM8994_CLASS_W_1:
+ case WM8994_DC_SERVO_1:
+ case WM8994_DC_SERVO_2:
+ case WM8994_DC_SERVO_READBACK:
+ case WM8994_DC_SERVO_4:
+ case WM8994_ANALOGUE_HP_1:
+ case WM8958_MIC_DETECT_1:
+ case WM8958_MIC_DETECT_2:
+ case WM8958_MIC_DETECT_3:
+ case WM8994_CHIP_REVISION:
+ case WM8994_CONTROL_INTERFACE:
+ case WM8994_AIF1_CLOCKING_1:
+ case WM8994_AIF1_CLOCKING_2:
+ case WM8994_AIF2_CLOCKING_1:
+ case WM8994_AIF2_CLOCKING_2:
+ case WM8994_CLOCKING_1:
+ case WM8994_CLOCKING_2:
+ case WM8994_AIF1_RATE:
+ case WM8994_AIF2_RATE:
+ case WM8994_RATE_STATUS:
+ case WM8994_FLL1_CONTROL_1:
+ case WM8994_FLL1_CONTROL_2:
+ case WM8994_FLL1_CONTROL_3:
+ case WM8994_FLL1_CONTROL_4:
+ case WM8994_FLL1_CONTROL_5:
+ case WM8958_FLL1_EFS_1:
+ case WM8958_FLL1_EFS_2:
+ case WM8994_FLL2_CONTROL_1:
+ case WM8994_FLL2_CONTROL_2:
+ case WM8994_FLL2_CONTROL_3:
+ case WM8994_FLL2_CONTROL_4:
+ case WM8994_FLL2_CONTROL_5:
+ case WM8958_FLL2_EFS_1:
+ case WM8958_FLL2_EFS_2:
+ case WM8994_AIF1_CONTROL_1:
+ case WM8994_AIF1_CONTROL_2:
+ case WM8994_AIF1_MASTER_SLAVE:
+ case WM8994_AIF1_BCLK:
+ case WM8994_AIF1ADC_LRCLK:
+ case WM8994_AIF1DAC_LRCLK:
+ case WM8994_AIF1DAC_DATA:
+ case WM8994_AIF1ADC_DATA:
+ case WM8994_AIF2_CONTROL_1:
+ case WM8994_AIF2_CONTROL_2:
+ case WM8994_AIF2_MASTER_SLAVE:
+ case WM8994_AIF2_BCLK:
+ case WM8994_AIF2ADC_LRCLK:
+ case WM8994_AIF2DAC_LRCLK:
+ case WM8994_AIF2DAC_DATA:
+ case WM8994_AIF2ADC_DATA:
+ case WM1811_AIF2TX_CONTROL:
+ case WM8958_AIF3_CONTROL_1:
+ case WM8958_AIF3_CONTROL_2:
+ case WM8958_AIF3DAC_DATA:
+ case WM8958_AIF3ADC_DATA:
+ case WM8994_AIF1_ADC1_LEFT_VOLUME:
+ case WM8994_AIF1_ADC1_RIGHT_VOLUME:
+ case WM8994_AIF1_DAC1_LEFT_VOLUME:
+ case WM8994_AIF1_DAC1_RIGHT_VOLUME:
+ case WM8994_AIF1_ADC1_FILTERS:
+ case WM8994_AIF1_DAC1_FILTERS_1:
+ case WM8994_AIF1_DAC1_FILTERS_2:
+ case WM8958_AIF1_DAC1_NOISE_GATE:
+ case WM8994_AIF1_DRC1_1:
+ case WM8994_AIF1_DRC1_2:
+ case WM8994_AIF1_DRC1_3:
+ case WM8994_AIF1_DRC1_4:
+ case WM8994_AIF1_DRC1_5:
+ case WM8994_AIF1_DAC1_EQ_GAINS_1:
+ case WM8994_AIF1_DAC1_EQ_GAINS_2:
+ case WM8994_AIF1_DAC1_EQ_BAND_1_A:
+ case WM8994_AIF1_DAC1_EQ_BAND_1_B:
+ case WM8994_AIF1_DAC1_EQ_BAND_1_PG:
+ case WM8994_AIF1_DAC1_EQ_BAND_2_A:
+ case WM8994_AIF1_DAC1_EQ_BAND_2_B:
+ case WM8994_AIF1_DAC1_EQ_BAND_2_C:
+ case WM8994_AIF1_DAC1_EQ_BAND_2_PG:
+ case WM8994_AIF1_DAC1_EQ_BAND_3_A:
+ case WM8994_AIF1_DAC1_EQ_BAND_3_B:
+ case WM8994_AIF1_DAC1_EQ_BAND_3_C:
+ case WM8994_AIF1_DAC1_EQ_BAND_3_PG:
+ case WM8994_AIF1_DAC1_EQ_BAND_4_A:
+ case WM8994_AIF1_DAC1_EQ_BAND_4_B:
+ case WM8994_AIF1_DAC1_EQ_BAND_4_C:
+ case WM8994_AIF1_DAC1_EQ_BAND_4_PG:
+ case WM8994_AIF1_DAC1_EQ_BAND_5_A:
+ case WM8994_AIF1_DAC1_EQ_BAND_5_B:
+ case WM8994_AIF1_DAC1_EQ_BAND_5_PG:
+ case WM8994_AIF1_DAC1_EQ_BAND_1_C:
+ case WM8994_AIF2_ADC_LEFT_VOLUME:
+ case WM8994_AIF2_ADC_RIGHT_VOLUME:
+ case WM8994_AIF2_DAC_LEFT_VOLUME:
+ case WM8994_AIF2_DAC_RIGHT_VOLUME:
+ case WM8994_AIF2_ADC_FILTERS:
+ case WM8994_AIF2_DAC_FILTERS_1:
+ case WM8994_AIF2_DAC_FILTERS_2:
+ case WM8958_AIF2_DAC_NOISE_GATE:
+ case WM8994_AIF2_DRC_1:
+ case WM8994_AIF2_DRC_2:
+ case WM8994_AIF2_DRC_3:
+ case WM8994_AIF2_DRC_4:
+ case WM8994_AIF2_DRC_5:
+ case WM8994_AIF2_EQ_GAINS_1:
+ case WM8994_AIF2_EQ_GAINS_2:
+ case WM8994_AIF2_EQ_BAND_1_A:
+ case WM8994_AIF2_EQ_BAND_1_B:
+ case WM8994_AIF2_EQ_BAND_1_PG:
+ case WM8994_AIF2_EQ_BAND_2_A:
+ case WM8994_AIF2_EQ_BAND_2_B:
+ case WM8994_AIF2_EQ_BAND_2_C:
+ case WM8994_AIF2_EQ_BAND_2_PG:
+ case WM8994_AIF2_EQ_BAND_3_A:
+ case WM8994_AIF2_EQ_BAND_3_B:
+ case WM8994_AIF2_EQ_BAND_3_C:
+ case WM8994_AIF2_EQ_BAND_3_PG:
+ case WM8994_AIF2_EQ_BAND_4_A:
+ case WM8994_AIF2_EQ_BAND_4_B:
+ case WM8994_AIF2_EQ_BAND_4_C:
+ case WM8994_AIF2_EQ_BAND_4_PG:
+ case WM8994_AIF2_EQ_BAND_5_A:
+ case WM8994_AIF2_EQ_BAND_5_B:
+ case WM8994_AIF2_EQ_BAND_5_PG:
+ case WM8994_AIF2_EQ_BAND_1_C:
+ case WM8994_DAC1_MIXER_VOLUMES:
+ case WM8994_DAC1_LEFT_MIXER_ROUTING:
+ case WM8994_DAC1_RIGHT_MIXER_ROUTING:
+ case WM8994_DAC2_MIXER_VOLUMES:
+ case WM8994_DAC2_LEFT_MIXER_ROUTING:
+ case WM8994_DAC2_RIGHT_MIXER_ROUTING:
+ case WM8994_AIF1_ADC1_LEFT_MIXER_ROUTING:
+ case WM8994_AIF1_ADC1_RIGHT_MIXER_ROUTING:
+ case WM8994_DAC1_LEFT_VOLUME:
+ case WM8994_DAC1_RIGHT_VOLUME:
+ case WM8994_DAC2_LEFT_VOLUME:
+ case WM8994_DAC2_RIGHT_VOLUME:
+ case WM8994_DAC_SOFTMUTE:
+ case WM8994_OVERSAMPLING:
+ case WM8994_SIDETONE:
+ case WM8994_GPIO_1:
+ case WM8994_GPIO_2:
+ case WM8994_GPIO_3:
+ case WM8994_GPIO_4:
+ case WM8994_GPIO_5:
+ case WM8994_GPIO_6:
+ case WM8994_GPIO_8:
+ case WM8994_GPIO_9:
+ case WM8994_GPIO_10:
+ case WM8994_GPIO_11:
+ case WM8994_PULL_CONTROL_1:
+ case WM8994_PULL_CONTROL_2:
+ case WM8994_INTERRUPT_STATUS_1:
+ case WM8994_INTERRUPT_STATUS_2:
+ case WM8994_INTERRUPT_RAW_STATUS_2:
+ case WM8994_INTERRUPT_STATUS_1_MASK:
+ case WM8994_INTERRUPT_STATUS_2_MASK:
+ case WM8994_INTERRUPT_CONTROL:
+ case WM8994_IRQ_DEBOUNCE:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static bool wm8994_readable_register(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case WM8994_DC_SERVO_READBACK:
+ case WM8994_WRITE_SEQUENCER_CTRL_1:
+ case WM8994_WRITE_SEQUENCER_CTRL_2:
+ case WM8994_AIF1_ADC2_LEFT_VOLUME:
+ case WM8994_AIF1_ADC2_RIGHT_VOLUME:
+ case WM8994_AIF1_DAC2_LEFT_VOLUME:
+ case WM8994_AIF1_DAC2_RIGHT_VOLUME:
+ case WM8994_AIF1_ADC2_FILTERS:
+ case WM8994_AIF1_DAC2_FILTERS_1:
+ case WM8994_AIF1_DAC2_FILTERS_2:
+ case WM8958_AIF1_DAC2_NOISE_GATE:
+ case WM8994_AIF1_DRC2_1:
+ case WM8994_AIF1_DRC2_2:
+ case WM8994_AIF1_DRC2_3:
+ case WM8994_AIF1_DRC2_4:
+ case WM8994_AIF1_DRC2_5:
+ case WM8994_AIF1_DAC2_EQ_GAINS_1:
+ case WM8994_AIF1_DAC2_EQ_GAINS_2:
+ case WM8994_AIF1_DAC2_EQ_BAND_1_A:
+ case WM8994_AIF1_DAC2_EQ_BAND_1_B:
+ case WM8994_AIF1_DAC2_EQ_BAND_1_PG:
+ case WM8994_AIF1_DAC2_EQ_BAND_2_A:
+ case WM8994_AIF1_DAC2_EQ_BAND_2_B:
+ case WM8994_AIF1_DAC2_EQ_BAND_2_C:
+ case WM8994_AIF1_DAC2_EQ_BAND_2_PG:
+ case WM8994_AIF1_DAC2_EQ_BAND_3_A:
+ case WM8994_AIF1_DAC2_EQ_BAND_3_B:
+ case WM8994_AIF1_DAC2_EQ_BAND_3_C:
+ case WM8994_AIF1_DAC2_EQ_BAND_3_PG:
+ case WM8994_AIF1_DAC2_EQ_BAND_4_A:
+ case WM8994_AIF1_DAC2_EQ_BAND_4_B:
+ case WM8994_AIF1_DAC2_EQ_BAND_4_C:
+ case WM8994_AIF1_DAC2_EQ_BAND_4_PG:
+ case WM8994_AIF1_DAC2_EQ_BAND_5_A:
+ case WM8994_AIF1_DAC2_EQ_BAND_5_B:
+ case WM8994_AIF1_DAC2_EQ_BAND_5_PG:
+ case WM8994_AIF1_DAC2_EQ_BAND_1_C:
+ case WM8994_DAC2_MIXER_VOLUMES:
+ case WM8994_DAC2_LEFT_MIXER_ROUTING:
+ case WM8994_DAC2_RIGHT_MIXER_ROUTING:
+ case WM8994_AIF1_ADC2_LEFT_MIXER_ROUTING:
+ case WM8994_AIF1_ADC2_RIGHT_MIXER_ROUTING:
+ case WM8994_DAC2_LEFT_VOLUME:
+ case WM8994_DAC2_RIGHT_VOLUME:
+ return true;
+ default:
+ return wm1811_readable_register(dev, reg);
+ }
+}
+
+static bool wm8958_readable_register(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case WM8958_DSP2_PROGRAM:
+ case WM8958_DSP2_CONFIG:
+ case WM8958_DSP2_MAGICNUM:
+ case WM8958_DSP2_RELEASEYEAR:
+ case WM8958_DSP2_RELEASEMONTHDAY:
+ case WM8958_DSP2_RELEASETIME:
+ case WM8958_DSP2_VERMAJMIN:
+ case WM8958_DSP2_VERBUILD:
+ case WM8958_DSP2_TESTREG:
+ case WM8958_DSP2_XORREG:
+ case WM8958_DSP2_SHIFTMAXX:
+ case WM8958_DSP2_SHIFTMAXY:
+ case WM8958_DSP2_SHIFTMAXZ:
+ case WM8958_DSP2_SHIFTMAXEXTLO:
+ case WM8958_DSP2_AESSELECT:
+ case WM8958_DSP2_EXECCONTROL:
+ case WM8958_DSP2_SAMPLEBREAK:
+ case WM8958_DSP2_COUNTBREAK:
+ case WM8958_DSP2_INTSTATUS:
+ case WM8958_DSP2_EVENTSTATUS:
+ case WM8958_DSP2_INTMASK:
+ case WM8958_DSP2_CONFIGDWIDTH:
+ case WM8958_DSP2_CONFIGINSTR:
+ case WM8958_DSP2_CONFIGDMEM:
+ case WM8958_DSP2_CONFIGDELAYS:
+ case WM8958_DSP2_CONFIGNUMIO:
+ case WM8958_DSP2_CONFIGEXTDEPTH:
+ case WM8958_DSP2_CONFIGMULTIPLIER:
+ case WM8958_DSP2_CONFIGCTRLDWIDTH:
+ case WM8958_DSP2_CONFIGPIPELINE:
+ case WM8958_DSP2_SHIFTMAXEXTHI:
+ case WM8958_DSP2_SWVERSIONREG:
+ case WM8958_DSP2_CONFIGXMEM:
+ case WM8958_DSP2_CONFIGYMEM:
+ case WM8958_DSP2_CONFIGZMEM:
+ case WM8958_FW_BUILD_1:
+ case WM8958_FW_BUILD_0:
+ case WM8958_FW_ID_1:
+ case WM8958_FW_ID_0:
+ case WM8958_FW_MAJOR_1:
+ case WM8958_FW_MAJOR_0:
+ case WM8958_FW_MINOR_1:
+ case WM8958_FW_MINOR_0:
+ case WM8958_FW_PATCH_1:
+ case WM8958_FW_PATCH_0:
+ case WM8958_MBC_BAND_1_K_1:
+ case WM8958_MBC_BAND_1_K_2:
+ case WM8958_MBC_BAND_1_N1_1:
+ case WM8958_MBC_BAND_1_N1_2:
+ case WM8958_MBC_BAND_1_N2_1:
+ case WM8958_MBC_BAND_1_N2_2:
+ case WM8958_MBC_BAND_1_N3_1:
+ case WM8958_MBC_BAND_1_N3_2:
+ case WM8958_MBC_BAND_1_N4_1:
+ case WM8958_MBC_BAND_1_N4_2:
+ case WM8958_MBC_BAND_1_N5_1:
+ case WM8958_MBC_BAND_1_N5_2:
+ case WM8958_MBC_BAND_1_X1_1:
+ case WM8958_MBC_BAND_1_X1_2:
+ case WM8958_MBC_BAND_1_X2_1:
+ case WM8958_MBC_BAND_1_X2_2:
+ case WM8958_MBC_BAND_1_X3_1:
+ case WM8958_MBC_BAND_1_X3_2:
+ case WM8958_MBC_BAND_1_ATTACK_1:
+ case WM8958_MBC_BAND_1_ATTACK_2:
+ case WM8958_MBC_BAND_1_DECAY_1:
+ case WM8958_MBC_BAND_1_DECAY_2:
+ case WM8958_MBC_BAND_2_K_1:
+ case WM8958_MBC_BAND_2_K_2:
+ case WM8958_MBC_BAND_2_N1_1:
+ case WM8958_MBC_BAND_2_N1_2:
+ case WM8958_MBC_BAND_2_N2_1:
+ case WM8958_MBC_BAND_2_N2_2:
+ case WM8958_MBC_BAND_2_N3_1:
+ case WM8958_MBC_BAND_2_N3_2:
+ case WM8958_MBC_BAND_2_N4_1:
+ case WM8958_MBC_BAND_2_N4_2:
+ case WM8958_MBC_BAND_2_N5_1:
+ case WM8958_MBC_BAND_2_N5_2:
+ case WM8958_MBC_BAND_2_X1_1:
+ case WM8958_MBC_BAND_2_X1_2:
+ case WM8958_MBC_BAND_2_X2_1:
+ case WM8958_MBC_BAND_2_X2_2:
+ case WM8958_MBC_BAND_2_X3_1:
+ case WM8958_MBC_BAND_2_X3_2:
+ case WM8958_MBC_BAND_2_ATTACK_1:
+ case WM8958_MBC_BAND_2_ATTACK_2:
+ case WM8958_MBC_BAND_2_DECAY_1:
+ case WM8958_MBC_BAND_2_DECAY_2:
+ case WM8958_MBC_B2_PG2_1:
+ case WM8958_MBC_B2_PG2_2:
+ case WM8958_MBC_B1_PG2_1:
+ case WM8958_MBC_B1_PG2_2:
+ case WM8958_MBC_CROSSOVER_1:
+ case WM8958_MBC_CROSSOVER_2:
+ case WM8958_MBC_HPF_1:
+ case WM8958_MBC_HPF_2:
+ case WM8958_MBC_LPF_1:
+ case WM8958_MBC_LPF_2:
+ case WM8958_MBC_RMS_LIMIT_1:
+ case WM8958_MBC_RMS_LIMIT_2:
+ return true;
+ default:
+ return wm8994_readable_register(dev, reg);
+ }
+}
+
+static bool wm8994_volatile_register(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case WM8994_SOFTWARE_RESET:
+ case WM8994_DC_SERVO_1:
+ case WM8994_DC_SERVO_READBACK:
+ case WM8994_RATE_STATUS:
+ case WM8958_MIC_DETECT_3:
+ case WM8994_DC_SERVO_4E:
+ case WM8994_CHIP_REVISION:
+ case WM8994_INTERRUPT_STATUS_1:
+ case WM8994_INTERRUPT_STATUS_2:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static bool wm1811_volatile_register(struct device *dev, unsigned int reg)
+{
+ struct wm8994 *wm8994 = dev_get_drvdata(dev);
+
+ switch (reg) {
+ case WM8994_GPIO_6:
+ if (wm8994->revision > 1)
+ return true;
+ else
+ return false;
+ default:
+ return wm8994_volatile_register(dev, reg);
+ }
+}
+
+static bool wm8958_volatile_register(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case WM8958_DSP2_MAGICNUM:
+ case WM8958_DSP2_RELEASEYEAR:
+ case WM8958_DSP2_RELEASEMONTHDAY:
+ case WM8958_DSP2_RELEASETIME:
+ case WM8958_DSP2_VERMAJMIN:
+ case WM8958_DSP2_VERBUILD:
+ case WM8958_DSP2_EXECCONTROL:
+ case WM8958_DSP2_SWVERSIONREG:
+ case WM8958_DSP2_CONFIGXMEM:
+ case WM8958_DSP2_CONFIGYMEM:
+ case WM8958_DSP2_CONFIGZMEM:
+ case WM8958_FW_BUILD_1:
+ case WM8958_FW_BUILD_0:
+ case WM8958_FW_ID_1:
+ case WM8958_FW_ID_0:
+ case WM8958_FW_MAJOR_1:
+ case WM8958_FW_MAJOR_0:
+ case WM8958_FW_MINOR_1:
+ case WM8958_FW_MINOR_0:
+ case WM8958_FW_PATCH_1:
+ case WM8958_FW_PATCH_0:
+ return true;
+ default:
+ return wm8994_volatile_register(dev, reg);
+ }
+}
+
+struct regmap_config wm1811_regmap_config = {
+ .reg_bits = 16,
+ .val_bits = 16,
+
+ .cache_type = REGCACHE_RBTREE,
+
+ .reg_defaults = wm1811_defaults,
+ .num_reg_defaults = ARRAY_SIZE(wm1811_defaults),
+
+ .max_register = WM8994_MAX_REGISTER,
+ .volatile_reg = wm1811_volatile_register,
+ .readable_reg = wm1811_readable_register,
+};
+
+struct regmap_config wm8994_regmap_config = {
+ .reg_bits = 16,
+ .val_bits = 16,
+
+ .cache_type = REGCACHE_RBTREE,
+
+ .reg_defaults = wm8994_defaults,
+ .num_reg_defaults = ARRAY_SIZE(wm8994_defaults),
+
+ .max_register = WM8994_MAX_REGISTER,
+ .volatile_reg = wm8994_volatile_register,
+ .readable_reg = wm8994_readable_register,
+};
+
+struct regmap_config wm8958_regmap_config = {
+ .reg_bits = 16,
+ .val_bits = 16,
+
+ .cache_type = REGCACHE_RBTREE,
+
+ .reg_defaults = wm8958_defaults,
+ .num_reg_defaults = ARRAY_SIZE(wm8958_defaults),
+
+ .max_register = WM8994_MAX_REGISTER,
+ .volatile_reg = wm8958_volatile_register,
+ .readable_reg = wm8958_readable_register,
+};
+
+struct regmap_config wm8994_base_regmap_config = {
+ .reg_bits = 16,
+ .val_bits = 16,
+};
diff --git a/drivers/mfd/wm8994.h b/drivers/mfd/wm8994.h
new file mode 100644
index 0000000..6f39a84
--- /dev/null
+++ b/drivers/mfd/wm8994.h
@@ -0,0 +1,25 @@
+/*
+ * wm8994.h -- WM8994 MFD internals
+ *
+ * Copyright 2011 Wolfson Microelectronics PLC.
+ *
+ * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
+ *
+ * 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.
+ *
+ */
+
+#ifndef __MFD_WM8994_H__
+#define __MFD_WM8994_H__
+
+#include <linux/regmap.h>
+
+extern struct regmap_config wm1811_regmap_config;
+extern struct regmap_config wm8994_regmap_config;
+extern struct regmap_config wm8958_regmap_config;
+extern struct regmap_config wm8994_base_regmap_config;
+
+#endif
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/srom.c b/drivers/net/wireless/brcm80211/brcmsmac/srom.c
index 6109215..5637436 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/srom.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/srom.c
@@ -764,6 +764,22 @@
}
/*
+ * The crc check is done on a little-endian array, we need
+ * to switch the bytes around before checking crc (and
+ * then switch it back).
+ */
+static int do_crc_check(u16 *buf, unsigned nwords)
+{
+ u8 crc;
+
+ cpu_to_le16_buf(buf, nwords);
+ crc = crc8(brcms_srom_crc8_table, (void *)buf, nwords << 1, CRC8_INIT_VALUE);
+ le16_to_cpu_buf(buf, nwords);
+
+ return crc == CRC8_GOOD_VALUE(brcms_srom_crc8_table);
+}
+
+/*
* Read in and validate sprom.
* Return 0 on success, nonzero on error.
*/
@@ -772,8 +788,6 @@
{
int err = 0;
uint i;
- u8 *bbuf = (u8 *)buf; /* byte buffer */
- uint nbytes = nwords << 1;
struct bcma_device *core;
uint sprom_offset;
@@ -786,9 +800,9 @@
sprom_offset = CHIPCREGOFFS(sromotp);
}
- /* read the sprom in bytes */
- for (i = 0; i < nbytes; i++)
- bbuf[i] = bcma_read8(core, sprom_offset+i);
+ /* read the sprom */
+ for (i = 0; i < nwords; i++)
+ buf[i] = bcma_read16(core, sprom_offset+i*2);
if (buf[0] == 0xffff)
/*
@@ -798,13 +812,8 @@
*/
return -ENODATA;
- if (check_crc &&
- crc8(brcms_srom_crc8_table, bbuf, nbytes, CRC8_INIT_VALUE) !=
- CRC8_GOOD_VALUE(brcms_srom_crc8_table))
+ if (check_crc && !do_crc_check(buf, nwords))
err = -EIO;
- else
- /* now correct the endianness of the byte array */
- le16_to_cpu_buf(buf, nwords);
return err;
}
diff --git a/drivers/parisc/dino.c b/drivers/parisc/dino.c
index bcd5d54..7ff10c1 100644
--- a/drivers/parisc/dino.c
+++ b/drivers/parisc/dino.c
@@ -562,19 +562,6 @@
/* Firmware doesn't set up card-mode dino, so we have to */
if (is_card_dino(&dino_dev->hba.dev->id)) {
dino_card_setup(bus, dino_dev->hba.base_addr);
- } else if(bus->parent == NULL) {
- /* must have a dino above it, reparent the resources
- * into the dino window */
- int i;
- struct resource *res = &dino_dev->hba.lmmio_space;
-
- bus->resource[0] = &(dino_dev->hba.io_space);
- for(i = 0; i < DINO_MAX_LMMIO_RESOURCES; i++) {
- if(res[i].flags == 0)
- break;
- bus->resource[i+1] = &res[i];
- }
-
} else if (bus->parent) {
int i;
@@ -927,6 +914,7 @@
const char *version = "unknown";
char *name;
int is_cujo = 0;
+ LIST_HEAD(resources);
struct pci_bus *bus;
unsigned long hpa = dev->hpa.start;
@@ -1003,26 +991,37 @@
dev->dev.platform_data = dino_dev;
+ pci_add_resource(&resources, &dino_dev->hba.io_space);
+ if (dino_dev->hba.lmmio_space.flags)
+ pci_add_resource(&resources, &dino_dev->hba.lmmio_space);
+ if (dino_dev->hba.elmmio_space.flags)
+ pci_add_resource(&resources, &dino_dev->hba.elmmio_space);
+ if (dino_dev->hba.gmmio_space.flags)
+ pci_add_resource(&resources, &dino_dev->hba.gmmio_space);
+
/*
** It's not used to avoid chicken/egg problems
** with configuration accessor functions.
*/
- dino_dev->hba.hba_bus = bus = pci_scan_bus_parented(&dev->dev,
- dino_current_bus, &dino_cfg_ops, NULL);
-
- if(bus) {
- /* This code *depends* on scanning being single threaded
- * if it isn't, this global bus number count will fail
- */
- dino_current_bus = bus->subordinate + 1;
- pci_bus_assign_resources(bus);
- pci_bus_add_devices(bus);
- } else {
+ dino_dev->hba.hba_bus = bus = pci_create_root_bus(&dev->dev,
+ dino_current_bus, &dino_cfg_ops, NULL, &resources);
+ if (!bus) {
printk(KERN_ERR "ERROR: failed to scan PCI bus on %s (duplicate bus number %d?)\n",
dev_name(&dev->dev), dino_current_bus);
+ pci_free_resource_list(&resources);
/* increment the bus number in case of duplicates */
dino_current_bus++;
+ return 0;
}
+
+ bus->subordinate = pci_scan_child_bus(bus);
+
+ /* This code *depends* on scanning being single threaded
+ * if it isn't, this global bus number count will fail
+ */
+ dino_current_bus = bus->subordinate + 1;
+ pci_bus_assign_resources(bus);
+ pci_bus_add_devices(bus);
return 0;
}
diff --git a/drivers/parisc/lba_pci.c b/drivers/parisc/lba_pci.c
index 3aeb327..d5f3d75 100644
--- a/drivers/parisc/lba_pci.c
+++ b/drivers/parisc/lba_pci.c
@@ -653,7 +653,7 @@
}
} else {
/* Host-PCI Bridge */
- int err, i;
+ int err;
DBG("lba_fixup_bus() %s [%lx/%lx]/%lx\n",
ldev->hba.io_space.name,
@@ -669,9 +669,6 @@
lba_dump_res(&ioport_resource, 2);
BUG();
}
- /* advertize Host bridge resources to PCI bus */
- bus->resource[0] = &(ldev->hba.io_space);
- i = 1;
if (ldev->hba.elmmio_space.start) {
err = request_resource(&iomem_resource,
@@ -685,35 +682,17 @@
/* lba_dump_res(&iomem_resource, 2); */
/* BUG(); */
- } else
- bus->resource[i++] = &(ldev->hba.elmmio_space);
+ }
}
-
- /* Overlaps with elmmio can (and should) fail here.
- * We will prune (or ignore) the distributed range.
- *
- * FIXME: SBA code should register all elmmio ranges first.
- * that would take care of elmmio ranges routed
- * to a different rope (already discovered) from
- * getting registered *after* LBA code has already
- * registered it's distributed lmmio range.
- */
- if (truncate_pat_collision(&iomem_resource,
- &(ldev->hba.lmmio_space))) {
-
- printk(KERN_WARNING "LBA: lmmio_space [%lx/%lx] duplicate!\n",
- (long)ldev->hba.lmmio_space.start,
- (long)ldev->hba.lmmio_space.end);
- } else {
+ if (ldev->hba.lmmio_space.flags) {
err = request_resource(&iomem_resource, &(ldev->hba.lmmio_space));
if (err < 0) {
printk(KERN_ERR "FAILED: lba_fixup_bus() request for "
"lmmio_space [%lx/%lx]\n",
(long)ldev->hba.lmmio_space.start,
(long)ldev->hba.lmmio_space.end);
- } else
- bus->resource[i++] = &(ldev->hba.lmmio_space);
+ }
}
#ifdef CONFIG_64BIT
@@ -728,7 +707,6 @@
lba_dump_res(&iomem_resource, 2);
BUG();
}
- bus->resource[i++] = &(ldev->hba.gmmio_space);
}
#endif
@@ -1404,6 +1382,7 @@
lba_driver_probe(struct parisc_device *dev)
{
struct lba_device *lba_dev;
+ LIST_HEAD(resources);
struct pci_bus *lba_bus;
struct pci_ops *cfg_ops;
u32 func_class;
@@ -1518,10 +1497,41 @@
if (lba_dev->hba.bus_num.start < lba_next_bus)
lba_dev->hba.bus_num.start = lba_next_bus;
+ /* Overlaps with elmmio can (and should) fail here.
+ * We will prune (or ignore) the distributed range.
+ *
+ * FIXME: SBA code should register all elmmio ranges first.
+ * that would take care of elmmio ranges routed
+ * to a different rope (already discovered) from
+ * getting registered *after* LBA code has already
+ * registered it's distributed lmmio range.
+ */
+ if (truncate_pat_collision(&iomem_resource,
+ &(lba_dev->hba.lmmio_space))) {
+ printk(KERN_WARNING "LBA: lmmio_space [%lx/%lx] duplicate!\n",
+ (long)lba_dev->hba.lmmio_space.start,
+ (long)lba_dev->hba.lmmio_space.end);
+ lba_dev->hba.lmmio_space.flags = 0;
+ }
+
+ pci_add_resource(&resources, &lba_dev->hba.io_space);
+ if (lba_dev->hba.elmmio_space.start)
+ pci_add_resource(&resources, &lba_dev->hba.elmmio_space);
+ if (lba_dev->hba.lmmio_space.flags)
+ pci_add_resource(&resources, &lba_dev->hba.lmmio_space);
+ if (lba_dev->hba.gmmio_space.flags)
+ pci_add_resource(&resources, &lba_dev->hba.gmmio_space);
+
dev->dev.platform_data = lba_dev;
lba_bus = lba_dev->hba.hba_bus =
- pci_scan_bus_parented(&dev->dev, lba_dev->hba.bus_num.start,
- cfg_ops, NULL);
+ pci_create_root_bus(&dev->dev, lba_dev->hba.bus_num.start,
+ cfg_ops, NULL, &resources);
+ if (!lba_bus) {
+ pci_free_resource_list(&resources);
+ return 0;
+ }
+
+ lba_bus->subordinate = pci_scan_child_bus(lba_bus);
/* This is in lieu of calling pci_assign_unassigned_resources() */
if (is_pdc_pat()) {
@@ -1551,10 +1561,8 @@
lba_dev->flags |= LBA_FLAG_SKIP_PROBE;
}
- if (lba_bus) {
- lba_next_bus = lba_bus->subordinate + 1;
- pci_bus_add_devices(lba_bus);
- }
+ lba_next_bus = lba_bus->subordinate + 1;
+ pci_bus_add_devices(lba_bus);
/* Whew! Finally done! Tell services we got this one covered. */
return 0;
diff --git a/drivers/pci/access.c b/drivers/pci/access.c
index fdaa42a..2a58164 100644
--- a/drivers/pci/access.c
+++ b/drivers/pci/access.c
@@ -13,7 +13,7 @@
* configuration space.
*/
-static DEFINE_RAW_SPINLOCK(pci_lock);
+DEFINE_RAW_SPINLOCK(pci_lock);
/*
* Wrappers for all PCI configuration access functions. They just check
@@ -127,20 +127,20 @@
* We have a bit per device to indicate it's blocked and a global wait queue
* for callers to sleep on until devices are unblocked.
*/
-static DECLARE_WAIT_QUEUE_HEAD(pci_ucfg_wait);
+static DECLARE_WAIT_QUEUE_HEAD(pci_cfg_wait);
-static noinline void pci_wait_ucfg(struct pci_dev *dev)
+static noinline void pci_wait_cfg(struct pci_dev *dev)
{
DECLARE_WAITQUEUE(wait, current);
- __add_wait_queue(&pci_ucfg_wait, &wait);
+ __add_wait_queue(&pci_cfg_wait, &wait);
do {
set_current_state(TASK_UNINTERRUPTIBLE);
raw_spin_unlock_irq(&pci_lock);
schedule();
raw_spin_lock_irq(&pci_lock);
- } while (dev->block_ucfg_access);
- __remove_wait_queue(&pci_ucfg_wait, &wait);
+ } while (dev->block_cfg_access);
+ __remove_wait_queue(&pci_cfg_wait, &wait);
}
/* Returns 0 on success, negative values indicate error. */
@@ -153,7 +153,8 @@
if (PCI_##size##_BAD) \
return -EINVAL; \
raw_spin_lock_irq(&pci_lock); \
- if (unlikely(dev->block_ucfg_access)) pci_wait_ucfg(dev); \
+ if (unlikely(dev->block_cfg_access)) \
+ pci_wait_cfg(dev); \
ret = dev->bus->ops->read(dev->bus, dev->devfn, \
pos, sizeof(type), &data); \
raw_spin_unlock_irq(&pci_lock); \
@@ -172,7 +173,8 @@
if (PCI_##size##_BAD) \
return -EINVAL; \
raw_spin_lock_irq(&pci_lock); \
- if (unlikely(dev->block_ucfg_access)) pci_wait_ucfg(dev); \
+ if (unlikely(dev->block_cfg_access)) \
+ pci_wait_cfg(dev); \
ret = dev->bus->ops->write(dev->bus, dev->devfn, \
pos, sizeof(type), val); \
raw_spin_unlock_irq(&pci_lock); \
@@ -401,36 +403,56 @@
EXPORT_SYMBOL(pci_vpd_truncate);
/**
- * pci_block_user_cfg_access - Block userspace PCI config reads/writes
+ * pci_cfg_access_lock - Lock PCI config reads/writes
* @dev: pci device struct
*
- * When user access is blocked, any reads or writes to config space will
- * sleep until access is unblocked again. We don't allow nesting of
- * block/unblock calls.
+ * When access is locked, any userspace reads or writes to config
+ * space and concurrent lock requests will sleep until access is
+ * allowed via pci_cfg_access_unlocked again.
*/
-void pci_block_user_cfg_access(struct pci_dev *dev)
+void pci_cfg_access_lock(struct pci_dev *dev)
{
- unsigned long flags;
- int was_blocked;
+ might_sleep();
- raw_spin_lock_irqsave(&pci_lock, flags);
- was_blocked = dev->block_ucfg_access;
- dev->block_ucfg_access = 1;
- raw_spin_unlock_irqrestore(&pci_lock, flags);
-
- /* If we BUG() inside the pci_lock, we're guaranteed to hose
- * the machine */
- BUG_ON(was_blocked);
+ raw_spin_lock_irq(&pci_lock);
+ if (dev->block_cfg_access)
+ pci_wait_cfg(dev);
+ dev->block_cfg_access = 1;
+ raw_spin_unlock_irq(&pci_lock);
}
-EXPORT_SYMBOL_GPL(pci_block_user_cfg_access);
+EXPORT_SYMBOL_GPL(pci_cfg_access_lock);
/**
- * pci_unblock_user_cfg_access - Unblock userspace PCI config reads/writes
+ * pci_cfg_access_trylock - try to lock PCI config reads/writes
* @dev: pci device struct
*
- * This function allows userspace PCI config accesses to resume.
+ * Same as pci_cfg_access_lock, but will return 0 if access is
+ * already locked, 1 otherwise. This function can be used from
+ * atomic contexts.
*/
-void pci_unblock_user_cfg_access(struct pci_dev *dev)
+bool pci_cfg_access_trylock(struct pci_dev *dev)
+{
+ unsigned long flags;
+ bool locked = true;
+
+ raw_spin_lock_irqsave(&pci_lock, flags);
+ if (dev->block_cfg_access)
+ locked = false;
+ else
+ dev->block_cfg_access = 1;
+ raw_spin_unlock_irqrestore(&pci_lock, flags);
+
+ return locked;
+}
+EXPORT_SYMBOL_GPL(pci_cfg_access_trylock);
+
+/**
+ * pci_cfg_access_unlock - Unlock PCI config reads/writes
+ * @dev: pci device struct
+ *
+ * This function allows PCI config accesses to resume.
+ */
+void pci_cfg_access_unlock(struct pci_dev *dev)
{
unsigned long flags;
@@ -438,10 +460,10 @@
/* This indicates a problem in the caller, but we don't need
* to kill them, unlike a double-block above. */
- WARN_ON(!dev->block_ucfg_access);
+ WARN_ON(!dev->block_cfg_access);
- dev->block_ucfg_access = 0;
- wake_up_all(&pci_ucfg_wait);
+ dev->block_cfg_access = 0;
+ wake_up_all(&pci_cfg_wait);
raw_spin_unlock_irqrestore(&pci_lock, flags);
}
-EXPORT_SYMBOL_GPL(pci_unblock_user_cfg_access);
+EXPORT_SYMBOL_GPL(pci_cfg_access_unlock);
diff --git a/drivers/pci/ats.c b/drivers/pci/ats.c
index 9dd90b3..95655d7 100644
--- a/drivers/pci/ats.c
+++ b/drivers/pci/ats.c
@@ -128,6 +128,23 @@
}
EXPORT_SYMBOL_GPL(pci_disable_ats);
+void pci_restore_ats_state(struct pci_dev *dev)
+{
+ u16 ctrl;
+
+ if (!pci_ats_enabled(dev))
+ return;
+ if (!pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ATS))
+ BUG();
+
+ ctrl = PCI_ATS_CTRL_ENABLE;
+ if (!dev->is_virtfn)
+ ctrl |= PCI_ATS_CTRL_STU(dev->ats->stu - PCI_ATS_MIN_STU);
+
+ pci_write_config_word(dev, dev->ats->pos + PCI_ATS_CTRL, ctrl);
+}
+EXPORT_SYMBOL_GPL(pci_restore_ats_state);
+
/**
* pci_ats_queue_depth - query the ATS Invalidate Queue Depth
* @dev: the PCI device
diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c
index 1e2ad92..398f5d8 100644
--- a/drivers/pci/bus.c
+++ b/drivers/pci/bus.c
@@ -18,6 +18,32 @@
#include "pci.h"
+void pci_add_resource(struct list_head *resources, struct resource *res)
+{
+ struct pci_bus_resource *bus_res;
+
+ bus_res = kzalloc(sizeof(struct pci_bus_resource), GFP_KERNEL);
+ if (!bus_res) {
+ printk(KERN_ERR "PCI: can't add bus resource %pR\n", res);
+ return;
+ }
+
+ bus_res->res = res;
+ list_add_tail(&bus_res->list, resources);
+}
+EXPORT_SYMBOL(pci_add_resource);
+
+void pci_free_resource_list(struct list_head *resources)
+{
+ struct pci_bus_resource *bus_res, *tmp;
+
+ list_for_each_entry_safe(bus_res, tmp, resources, list) {
+ list_del(&bus_res->list);
+ kfree(bus_res);
+ }
+}
+EXPORT_SYMBOL(pci_free_resource_list);
+
void pci_bus_add_resource(struct pci_bus *bus, struct resource *res,
unsigned int flags)
{
@@ -52,16 +78,12 @@
void pci_bus_remove_resources(struct pci_bus *bus)
{
- struct pci_bus_resource *bus_res, *tmp;
int i;
for (i = 0; i < PCI_BRIDGE_RESOURCE_NUM; i++)
bus->resource[i] = NULL;
- list_for_each_entry_safe(bus_res, tmp, &bus->resources, list) {
- list_del(&bus_res->list);
- kfree(bus_res);
- }
+ pci_free_resource_list(&bus->resources);
}
/**
diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c
index 1969a3e..0321fa3 100644
--- a/drivers/pci/iov.c
+++ b/drivers/pci/iov.c
@@ -347,11 +347,13 @@
return rc;
}
+ pci_write_config_dword(dev, iov->pos + PCI_SRIOV_SYS_PGSIZE, iov->pgsz);
+
iov->ctrl |= PCI_SRIOV_CTRL_VFE | PCI_SRIOV_CTRL_MSE;
- pci_block_user_cfg_access(dev);
+ pci_cfg_access_lock(dev);
pci_write_config_word(dev, iov->pos + PCI_SRIOV_CTRL, iov->ctrl);
msleep(100);
- pci_unblock_user_cfg_access(dev);
+ pci_cfg_access_unlock(dev);
iov->initial = initial;
if (nr_virtfn < initial)
@@ -379,10 +381,10 @@
virtfn_remove(dev, j, 0);
iov->ctrl &= ~(PCI_SRIOV_CTRL_VFE | PCI_SRIOV_CTRL_MSE);
- pci_block_user_cfg_access(dev);
+ pci_cfg_access_lock(dev);
pci_write_config_word(dev, iov->pos + PCI_SRIOV_CTRL, iov->ctrl);
ssleep(1);
- pci_unblock_user_cfg_access(dev);
+ pci_cfg_access_unlock(dev);
if (iov->link != dev->devfn)
sysfs_remove_link(&dev->dev.kobj, "dep_link");
@@ -405,10 +407,10 @@
virtfn_remove(dev, i, 0);
iov->ctrl &= ~(PCI_SRIOV_CTRL_VFE | PCI_SRIOV_CTRL_MSE);
- pci_block_user_cfg_access(dev);
+ pci_cfg_access_lock(dev);
pci_write_config_word(dev, iov->pos + PCI_SRIOV_CTRL, iov->ctrl);
ssleep(1);
- pci_unblock_user_cfg_access(dev);
+ pci_cfg_access_unlock(dev);
if (iov->link != dev->devfn)
sysfs_remove_link(&dev->dev.kobj, "dep_link");
@@ -452,7 +454,6 @@
found:
pci_write_config_word(dev, pos + PCI_SRIOV_CTRL, ctrl);
- pci_write_config_word(dev, pos + PCI_SRIOV_NUM_VF, total);
pci_read_config_word(dev, pos + PCI_SRIOV_VF_OFFSET, &offset);
pci_read_config_word(dev, pos + PCI_SRIOV_VF_STRIDE, &stride);
if (!offset || (total > 1 && !stride))
@@ -465,7 +466,6 @@
return -EIO;
pgsz &= ~(pgsz - 1);
- pci_write_config_dword(dev, pos + PCI_SRIOV_SYS_PGSIZE, pgsz);
nres = 0;
for (i = 0; i < PCI_SRIOV_NUM_BARS; i++) {
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index 337e16a..a825d78 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -86,6 +86,31 @@
}
#endif
+#ifndef arch_restore_msi_irqs
+# define arch_restore_msi_irqs default_restore_msi_irqs
+# define HAVE_DEFAULT_MSI_RESTORE_IRQS
+#endif
+
+#ifdef HAVE_DEFAULT_MSI_RESTORE_IRQS
+void default_restore_msi_irqs(struct pci_dev *dev, int irq)
+{
+ struct msi_desc *entry;
+
+ entry = NULL;
+ if (dev->msix_enabled) {
+ list_for_each_entry(entry, &dev->msi_list, list) {
+ if (irq == entry->irq)
+ break;
+ }
+ } else if (dev->msi_enabled) {
+ entry = irq_get_msi_desc(irq);
+ }
+
+ if (entry)
+ write_msi_msg(irq, &entry->msg);
+}
+#endif
+
static void msi_set_enable(struct pci_dev *dev, int pos, int enable)
{
u16 control;
@@ -323,8 +348,18 @@
if (list_is_last(&entry->list, &dev->msi_list))
iounmap(entry->mask_base);
}
- kobject_del(&entry->kobj);
- kobject_put(&entry->kobj);
+
+ /*
+ * Its possible that we get into this path
+ * When populate_msi_sysfs fails, which means the entries
+ * were not registered with sysfs. In that case don't
+ * unregister them.
+ */
+ if (entry->kobj.parent) {
+ kobject_del(&entry->kobj);
+ kobject_put(&entry->kobj);
+ }
+
list_del(&entry->list);
kfree(entry);
}
@@ -362,7 +397,7 @@
pci_intx_for_msi(dev, 0);
msi_set_enable(dev, pos, 0);
- write_msi_msg(dev->irq, &entry->msg);
+ arch_restore_msi_irqs(dev, dev->irq);
pci_read_config_word(dev, pos + PCI_MSI_FLAGS, &control);
msi_mask_irq(entry, msi_capable_mask(control), entry->masked);
@@ -390,7 +425,7 @@
pci_write_config_word(dev, pos + PCI_MSIX_FLAGS, control);
list_for_each_entry(entry, &dev->msi_list, list) {
- write_msi_msg(entry->irq, &entry->msg);
+ arch_restore_msi_irqs(dev, entry->irq);
msix_mask_irq(entry, entry->masked);
}
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index 12d1e81..3623d65 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -604,7 +604,8 @@
* supported as well. Drivers are supposed to support either the
* former, or the latter, but not both at the same time.
*/
- WARN_ON(ret && drv->driver.pm);
+ WARN(ret && drv->driver.pm, "driver %s device %04x:%04x\n",
+ drv->name, pci_dev->vendor, pci_dev->device);
return ret;
}
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 6d4a531..97fff78 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -88,6 +88,12 @@
u8 pci_dfl_cache_line_size __devinitdata = L1_CACHE_BYTES >> 2;
u8 pci_cache_line_size;
+/*
+ * If we set up a device for bus mastering, we need to check the latency
+ * timer as certain BIOSes forget to set it properly.
+ */
+unsigned int pcibios_max_latency = 255;
+
/**
* pci_bus_max_busnr - returns maximum PCI bus number of given bus' children
* @bus: pointer to PCI bus structure to search
@@ -959,6 +965,7 @@
/* PCI Express register must be restored first */
pci_restore_pcie_state(dev);
+ pci_restore_ats_state(dev);
/*
* The Base Address register should be programmed before the command
@@ -967,7 +974,7 @@
for (i = 15; i >= 0; i--) {
pci_read_config_dword(dev, i * 4, &val);
if (val != dev->saved_config_space[i]) {
- dev_printk(KERN_DEBUG, &dev->dev, "restoring config "
+ dev_dbg(&dev->dev, "restoring config "
"space at offset %#x (was %#x, writing %#x)\n",
i, val, (int)dev->saved_config_space[i]);
pci_write_config_dword(dev,i * 4,
@@ -1536,8 +1543,7 @@
}
out:
- dev_printk(KERN_DEBUG, &dev->dev, "PME# %s\n",
- enable ? "enabled" : "disabled");
+ dev_dbg(&dev->dev, "PME# %s\n", enable ? "enabled" : "disabled");
}
/**
@@ -2596,6 +2602,33 @@
}
/**
+ * pcibios_set_master - enable PCI bus-mastering for device dev
+ * @dev: the PCI device to enable
+ *
+ * Enables PCI bus-mastering for the device. This is the default
+ * implementation. Architecture specific implementations can override
+ * this if necessary.
+ */
+void __weak pcibios_set_master(struct pci_dev *dev)
+{
+ u8 lat;
+
+ /* The latency timer doesn't apply to PCIe (either Type 0 or Type 1) */
+ if (pci_is_pcie(dev))
+ return;
+
+ pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
+ if (lat < 16)
+ lat = (64 <= pcibios_max_latency) ? 64 : pcibios_max_latency;
+ else if (lat > pcibios_max_latency)
+ lat = pcibios_max_latency;
+ else
+ return;
+ dev_printk(KERN_DEBUG, &dev->dev, "setting latency timer to %d\n", lat);
+ pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat);
+}
+
+/**
* pci_set_master - enables bus-mastering for device dev
* @dev: the PCI device to enable
*
@@ -2768,6 +2801,116 @@
}
/**
+ * pci_intx_mask_supported - probe for INTx masking support
+ * @pdev: the PCI device to operate on
+ *
+ * Check if the device dev support INTx masking via the config space
+ * command word.
+ */
+bool pci_intx_mask_supported(struct pci_dev *dev)
+{
+ bool mask_supported = false;
+ u16 orig, new;
+
+ pci_cfg_access_lock(dev);
+
+ pci_read_config_word(dev, PCI_COMMAND, &orig);
+ pci_write_config_word(dev, PCI_COMMAND,
+ orig ^ PCI_COMMAND_INTX_DISABLE);
+ pci_read_config_word(dev, PCI_COMMAND, &new);
+
+ /*
+ * There's no way to protect against hardware bugs or detect them
+ * reliably, but as long as we know what the value should be, let's
+ * go ahead and check it.
+ */
+ if ((new ^ orig) & ~PCI_COMMAND_INTX_DISABLE) {
+ dev_err(&dev->dev, "Command register changed from "
+ "0x%x to 0x%x: driver or hardware bug?\n", orig, new);
+ } else if ((new ^ orig) & PCI_COMMAND_INTX_DISABLE) {
+ mask_supported = true;
+ pci_write_config_word(dev, PCI_COMMAND, orig);
+ }
+
+ pci_cfg_access_unlock(dev);
+ return mask_supported;
+}
+EXPORT_SYMBOL_GPL(pci_intx_mask_supported);
+
+static bool pci_check_and_set_intx_mask(struct pci_dev *dev, bool mask)
+{
+ struct pci_bus *bus = dev->bus;
+ bool mask_updated = true;
+ u32 cmd_status_dword;
+ u16 origcmd, newcmd;
+ unsigned long flags;
+ bool irq_pending;
+
+ /*
+ * We do a single dword read to retrieve both command and status.
+ * Document assumptions that make this possible.
+ */
+ BUILD_BUG_ON(PCI_COMMAND % 4);
+ BUILD_BUG_ON(PCI_COMMAND + 2 != PCI_STATUS);
+
+ raw_spin_lock_irqsave(&pci_lock, flags);
+
+ bus->ops->read(bus, dev->devfn, PCI_COMMAND, 4, &cmd_status_dword);
+
+ irq_pending = (cmd_status_dword >> 16) & PCI_STATUS_INTERRUPT;
+
+ /*
+ * Check interrupt status register to see whether our device
+ * triggered the interrupt (when masking) or the next IRQ is
+ * already pending (when unmasking).
+ */
+ if (mask != irq_pending) {
+ mask_updated = false;
+ goto done;
+ }
+
+ origcmd = cmd_status_dword;
+ newcmd = origcmd & ~PCI_COMMAND_INTX_DISABLE;
+ if (mask)
+ newcmd |= PCI_COMMAND_INTX_DISABLE;
+ if (newcmd != origcmd)
+ bus->ops->write(bus, dev->devfn, PCI_COMMAND, 2, newcmd);
+
+done:
+ raw_spin_unlock_irqrestore(&pci_lock, flags);
+
+ return mask_updated;
+}
+
+/**
+ * pci_check_and_mask_intx - mask INTx on pending interrupt
+ * @pdev: the PCI device to operate on
+ *
+ * Check if the device dev has its INTx line asserted, mask it and
+ * return true in that case. False is returned if not interrupt was
+ * pending.
+ */
+bool pci_check_and_mask_intx(struct pci_dev *dev)
+{
+ return pci_check_and_set_intx_mask(dev, true);
+}
+EXPORT_SYMBOL_GPL(pci_check_and_mask_intx);
+
+/**
+ * pci_check_and_mask_intx - unmask INTx of no interrupt is pending
+ * @pdev: the PCI device to operate on
+ *
+ * Check if the device dev has its INTx line asserted, unmask it if not
+ * and return true. False is returned and the mask remains active if
+ * there was still an interrupt pending.
+ */
+bool pci_check_and_unmask_intx(struct pci_dev *dev)
+{
+ return pci_check_and_set_intx_mask(dev, false);
+}
+EXPORT_SYMBOL_GPL(pci_check_and_unmask_intx);
+
+/**
* pci_msi_off - disables any msi or msix capabilities
* @dev: the PCI device to operate on
*
@@ -2965,7 +3108,7 @@
might_sleep();
if (!probe) {
- pci_block_user_cfg_access(dev);
+ pci_cfg_access_lock(dev);
/* block PM suspend, driver probe, etc. */
device_lock(&dev->dev);
}
@@ -2990,7 +3133,7 @@
done:
if (!probe) {
device_unlock(&dev->dev);
- pci_unblock_user_cfg_access(dev);
+ pci_cfg_access_unlock(dev);
}
return rc;
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index b74084e..1009a5e 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -136,6 +136,8 @@
/* Lock for read/write access to pci device and bus lists */
extern struct rw_semaphore pci_bus_sem;
+extern raw_spinlock_t pci_lock;
+
extern unsigned int pci_pm_d3_delay;
#ifdef CONFIG_PCI_MSI
@@ -249,6 +251,14 @@
u8 __iomem *mstate; /* VF Migration State Array */
};
+#ifdef CONFIG_PCI_ATS
+extern void pci_restore_ats_state(struct pci_dev *dev);
+#else
+static inline void pci_restore_ats_state(struct pci_dev *dev)
+{
+}
+#endif /* CONFIG_PCI_ATS */
+
#ifdef CONFIG_PCI_IOV
extern int pci_iov_init(struct pci_dev *dev);
extern void pci_iov_release(struct pci_dev *dev);
diff --git a/drivers/pci/pcie/Kconfig b/drivers/pci/pcie/Kconfig
index dc29348..72962cc 100644
--- a/drivers/pci/pcie/Kconfig
+++ b/drivers/pci/pcie/Kconfig
@@ -39,7 +39,7 @@
Power Management) and Clock Power Management. ASPM supports
state L0/L0s/L1.
- ASPM is initially set up the the firmware. With this option enabled,
+ ASPM is initially set up by the firmware. With this option enabled,
Linux can modify this state in order to disable ASPM on known-bad
hardware or configurations and enable it when known-safe.
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 04e74f4..7cc9e2f 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -1522,19 +1522,21 @@
return max;
}
-struct pci_bus * pci_create_bus(struct device *parent,
- int bus, struct pci_ops *ops, void *sysdata)
+struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
+ struct pci_ops *ops, void *sysdata, struct list_head *resources)
{
- int error;
+ int error, i;
struct pci_bus *b, *b2;
struct device *dev;
+ struct pci_bus_resource *bus_res, *n;
+ struct resource *res;
b = pci_alloc_bus();
if (!b)
return NULL;
dev = kzalloc(sizeof(*dev), GFP_KERNEL);
- if (!dev){
+ if (!dev) {
kfree(b);
return NULL;
}
@@ -1577,8 +1579,20 @@
pci_create_legacy_files(b);
b->number = b->secondary = bus;
- b->resource[0] = &ioport_resource;
- b->resource[1] = &iomem_resource;
+
+ /* Add initial resources to the bus */
+ list_for_each_entry_safe(bus_res, n, resources, list)
+ list_move_tail(&bus_res->list, &b->resources);
+
+ if (parent)
+ dev_info(parent, "PCI host bridge to bus %s\n", dev_name(&b->dev));
+ else
+ printk(KERN_INFO "PCI host bridge to bus %s\n", dev_name(&b->dev));
+
+ pci_bus_for_each_resource(b, res, i) {
+ if (res)
+ dev_info(&b->dev, "root bus resource %pR\n", res);
+ }
return b;
@@ -1594,18 +1608,58 @@
return NULL;
}
-struct pci_bus * __devinit pci_scan_bus_parented(struct device *parent,
- int bus, struct pci_ops *ops, void *sysdata)
+struct pci_bus * __devinit pci_scan_root_bus(struct device *parent, int bus,
+ struct pci_ops *ops, void *sysdata, struct list_head *resources)
{
struct pci_bus *b;
- b = pci_create_bus(parent, bus, ops, sysdata);
+ b = pci_create_root_bus(parent, bus, ops, sysdata, resources);
+ if (!b)
+ return NULL;
+
+ b->subordinate = pci_scan_child_bus(b);
+ pci_bus_add_devices(b);
+ return b;
+}
+EXPORT_SYMBOL(pci_scan_root_bus);
+
+/* Deprecated; use pci_scan_root_bus() instead */
+struct pci_bus * __devinit pci_scan_bus_parented(struct device *parent,
+ int bus, struct pci_ops *ops, void *sysdata)
+{
+ LIST_HEAD(resources);
+ struct pci_bus *b;
+
+ pci_add_resource(&resources, &ioport_resource);
+ pci_add_resource(&resources, &iomem_resource);
+ b = pci_create_root_bus(parent, bus, ops, sysdata, &resources);
if (b)
b->subordinate = pci_scan_child_bus(b);
+ else
+ pci_free_resource_list(&resources);
return b;
}
EXPORT_SYMBOL(pci_scan_bus_parented);
+struct pci_bus * __devinit pci_scan_bus(int bus, struct pci_ops *ops,
+ void *sysdata)
+{
+ LIST_HEAD(resources);
+ struct pci_bus *b;
+
+ pci_add_resource(&resources, &ioport_resource);
+ pci_add_resource(&resources, &iomem_resource);
+ b = pci_create_root_bus(NULL, bus, ops, sysdata, &resources);
+ if (b) {
+ b->subordinate = pci_scan_child_bus(b);
+ pci_bus_add_devices(b);
+ } else {
+ pci_free_resource_list(&resources);
+ }
+ return b;
+}
+EXPORT_SYMBOL(pci_scan_bus);
+
#ifdef CONFIG_HOTPLUG
/**
* pci_rescan_bus - scan a PCI bus for devices.
diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c
index 7f87bee..6def362 100644
--- a/drivers/pci/remove.c
+++ b/drivers/pci/remove.c
@@ -89,9 +89,8 @@
* device lists, remove the /proc entry, and notify userspace
* (/sbin/hotplug).
*/
-void pci_remove_bus_device(struct pci_dev *dev)
+static void __pci_remove_bus_device(struct pci_dev *dev)
{
- pci_stop_bus_device(dev);
if (dev->subordinate) {
struct pci_bus *b = dev->subordinate;
@@ -102,6 +101,11 @@
pci_destroy_dev(dev);
}
+void pci_remove_bus_device(struct pci_dev *dev)
+{
+ pci_stop_bus_device(dev);
+ __pci_remove_bus_device(dev);
+}
/**
* pci_remove_behind_bridge - remove all devices behind a PCI bridge
@@ -117,7 +121,7 @@
if (dev->subordinate)
list_for_each_safe(l, n, &dev->subordinate->devices)
- pci_remove_bus_device(pci_dev_b(l));
+ __pci_remove_bus_device(pci_dev_b(l));
}
static void pci_stop_bus_devices(struct pci_bus *bus)
diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c
index 5717509b..b66bfdb 100644
--- a/drivers/pci/setup-res.c
+++ b/drivers/pci/setup-res.c
@@ -85,9 +85,9 @@
}
}
res->flags &= ~IORESOURCE_UNSET;
- dev_info(&dev->dev, "BAR %d: set to %pR (PCI address [%#llx-%#llx])\n",
- resno, res, (unsigned long long)region.start,
- (unsigned long long)region.end);
+ dev_dbg(&dev->dev, "BAR %d: set to %pR (PCI address [%#llx-%#llx])\n",
+ resno, res, (unsigned long long)region.start,
+ (unsigned long long)region.end);
}
int pci_claim_resource(struct pci_dev *dev, int resource)
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
index 7f43cf8..f995e6e 100644
--- a/drivers/platform/x86/Kconfig
+++ b/drivers/platform/x86/Kconfig
@@ -639,7 +639,7 @@
config INTEL_SCU_IPC
bool "Intel SCU IPC Support"
- depends on X86_MRST
+ depends on X86_INTEL_MID
default y
---help---
IPC is used to bridge the communications between kernel and SCU on
diff --git a/drivers/pnp/quirks.c b/drivers/pnp/quirks.c
index dfbd5a6..258fef2 100644
--- a/drivers/pnp/quirks.c
+++ b/drivers/pnp/quirks.c
@@ -295,6 +295,45 @@
}
}
+#ifdef CONFIG_AMD_NB
+
+#include <asm/amd_nb.h>
+
+static void quirk_amd_mmconfig_area(struct pnp_dev *dev)
+{
+ resource_size_t start, end;
+ struct pnp_resource *pnp_res;
+ struct resource *res;
+ struct resource mmconfig_res, *mmconfig;
+
+ mmconfig = amd_get_mmconfig_range(&mmconfig_res);
+ if (!mmconfig)
+ return;
+
+ list_for_each_entry(pnp_res, &dev->resources, list) {
+ res = &pnp_res->res;
+ if (res->end < mmconfig->start || res->start > mmconfig->end ||
+ (res->start == mmconfig->start && res->end == mmconfig->end))
+ continue;
+
+ dev_info(&dev->dev, FW_BUG
+ "%pR covers only part of AMD MMCONFIG area %pR; adding more reservations\n",
+ res, mmconfig);
+ if (mmconfig->start < res->start) {
+ start = mmconfig->start;
+ end = res->start - 1;
+ pnp_add_mem_resource(dev, start, end, 0);
+ }
+ if (mmconfig->end > res->end) {
+ start = res->end + 1;
+ end = mmconfig->end;
+ pnp_add_mem_resource(dev, start, end, 0);
+ }
+ break;
+ }
+}
+#endif
+
/*
* PnP Quirks
* Cards or devices that need some tweaking due to incomplete resource info
@@ -322,6 +361,9 @@
/* PnP resources that might overlap PCI BARs */
{"PNP0c01", quirk_system_pci_resources},
{"PNP0c02", quirk_system_pci_resources},
+#ifdef CONFIG_AMD_NB
+ {"PNP0c01", quirk_amd_mmconfig_area},
+#endif
{""}
};
diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig
index 9f88641..3a8daf8 100644
--- a/drivers/power/Kconfig
+++ b/drivers/power/Kconfig
@@ -116,12 +116,12 @@
help
Say Y to enable support for battery measured by WM97xx aux port.
-config BATTERY_BQ20Z75
- tristate "TI BQ20z75 gas gauge"
+config BATTERY_SBS
+ tristate "SBS Compliant gas gauge"
depends on I2C
help
- Say Y to include support for TI BQ20z75 SBS-compliant
- gas gauge and protection IC.
+ Say Y to include support for SBS battery driver for SBS-compliant
+ gas gauges.
config BATTERY_BQ27x00
tristate "BQ27x00 battery driver"
@@ -150,6 +150,14 @@
Say Y here to enable support for batteries charger integrated into
DA9030 PMIC.
+config BATTERY_DA9052
+ tristate "Dialog DA9052 Battery"
+ depends on PMIC_DA9052
+ depends on BROKEN
+ help
+ Say Y here to enable support for batteries charger integrated into
+ DA9052 PMIC.
+
config BATTERY_MAX17040
tristate "Maxim MAX17040 Fuel Gauge"
depends on I2C
@@ -226,6 +234,12 @@
help
Say Y here to enable support for TWL4030 Battery Charge Interface.
+config CHARGER_LP8727
+ tristate "National Semiconductor LP8727 charger driver"
+ depends on I2C
+ help
+ Say Y here to enable support for LP8727 Charger Driver.
+
config CHARGER_GPIO
tristate "GPIO charger"
depends on GPIOLIB
@@ -236,6 +250,16 @@
This driver can be build as a module. If so, the module will be
called gpio-charger.
+config CHARGER_MANAGER
+ bool "Battery charger manager for multiple chargers"
+ depends on REGULATOR && RTC_CLASS
+ help
+ Say Y to enable charger-manager support, which allows multiple
+ chargers attached to a battery and multiple batteries attached to a
+ system. The charger-manager also can monitor charging status in
+ runtime and in suspend-to-RAM by waking up the system periodically
+ with help of suspend_again support.
+
config CHARGER_MAX8997
tristate "Maxim MAX8997/MAX8966 PMIC battery charger driver"
depends on MFD_MAX8997 && REGULATOR_MAX8997
diff --git a/drivers/power/Makefile b/drivers/power/Makefile
index b4af13d..e429008 100644
--- a/drivers/power/Makefile
+++ b/drivers/power/Makefile
@@ -22,9 +22,10 @@
obj-$(CONFIG_BATTERY_TOSA) += tosa_battery.o
obj-$(CONFIG_BATTERY_COLLIE) += collie_battery.o
obj-$(CONFIG_BATTERY_WM97XX) += wm97xx_battery.o
-obj-$(CONFIG_BATTERY_BQ20Z75) += bq20z75.o
+obj-$(CONFIG_BATTERY_SBS) += sbs-battery.o
obj-$(CONFIG_BATTERY_BQ27x00) += bq27x00_battery.o
obj-$(CONFIG_BATTERY_DA9030) += da9030_battery.o
+obj-$(CONFIG_BATTERY_DA9052) += da9052-battery.o
obj-$(CONFIG_BATTERY_MAX17040) += max17040_battery.o
obj-$(CONFIG_BATTERY_MAX17042) += max17042_battery.o
obj-$(CONFIG_BATTERY_Z2) += z2_battery.o
@@ -35,6 +36,8 @@
obj-$(CONFIG_CHARGER_ISP1704) += isp1704_charger.o
obj-$(CONFIG_CHARGER_MAX8903) += max8903_charger.o
obj-$(CONFIG_CHARGER_TWL4030) += twl4030_charger.o
+obj-$(CONFIG_CHARGER_LP8727) += lp8727_charger.o
obj-$(CONFIG_CHARGER_GPIO) += gpio-charger.o
+obj-$(CONFIG_CHARGER_MANAGER) += charger-manager.o
obj-$(CONFIG_CHARGER_MAX8997) += max8997_charger.o
obj-$(CONFIG_CHARGER_MAX8998) += max8998_charger.o
diff --git a/drivers/power/bq20z75.c b/drivers/power/bq20z75.c
deleted file mode 100644
index 9c5e5be..0000000
--- a/drivers/power/bq20z75.c
+++ /dev/null
@@ -1,794 +0,0 @@
-/*
- * Gas Gauge driver for TI's BQ20Z75
- *
- * Copyright (c) 2010, NVIDIA Corporation.
- *
- * 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 Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/err.h>
-#include <linux/power_supply.h>
-#include <linux/i2c.h>
-#include <linux/slab.h>
-#include <linux/interrupt.h>
-#include <linux/gpio.h>
-
-#include <linux/power/bq20z75.h>
-
-enum {
- REG_MANUFACTURER_DATA,
- REG_TEMPERATURE,
- REG_VOLTAGE,
- REG_CURRENT,
- REG_CAPACITY,
- REG_TIME_TO_EMPTY,
- REG_TIME_TO_FULL,
- REG_STATUS,
- REG_CYCLE_COUNT,
- REG_SERIAL_NUMBER,
- REG_REMAINING_CAPACITY,
- REG_REMAINING_CAPACITY_CHARGE,
- REG_FULL_CHARGE_CAPACITY,
- REG_FULL_CHARGE_CAPACITY_CHARGE,
- REG_DESIGN_CAPACITY,
- REG_DESIGN_CAPACITY_CHARGE,
- REG_DESIGN_VOLTAGE,
-};
-
-/* Battery Mode defines */
-#define BATTERY_MODE_OFFSET 0x03
-#define BATTERY_MODE_MASK 0x8000
-enum bq20z75_battery_mode {
- BATTERY_MODE_AMPS,
- BATTERY_MODE_WATTS
-};
-
-/* manufacturer access defines */
-#define MANUFACTURER_ACCESS_STATUS 0x0006
-#define MANUFACTURER_ACCESS_SLEEP 0x0011
-
-/* battery status value bits */
-#define BATTERY_DISCHARGING 0x40
-#define BATTERY_FULL_CHARGED 0x20
-#define BATTERY_FULL_DISCHARGED 0x10
-
-#define BQ20Z75_DATA(_psp, _addr, _min_value, _max_value) { \
- .psp = _psp, \
- .addr = _addr, \
- .min_value = _min_value, \
- .max_value = _max_value, \
-}
-
-static const struct bq20z75_device_data {
- enum power_supply_property psp;
- u8 addr;
- int min_value;
- int max_value;
-} bq20z75_data[] = {
- [REG_MANUFACTURER_DATA] =
- BQ20Z75_DATA(POWER_SUPPLY_PROP_PRESENT, 0x00, 0, 65535),
- [REG_TEMPERATURE] =
- BQ20Z75_DATA(POWER_SUPPLY_PROP_TEMP, 0x08, 0, 65535),
- [REG_VOLTAGE] =
- BQ20Z75_DATA(POWER_SUPPLY_PROP_VOLTAGE_NOW, 0x09, 0, 20000),
- [REG_CURRENT] =
- BQ20Z75_DATA(POWER_SUPPLY_PROP_CURRENT_NOW, 0x0A, -32768,
- 32767),
- [REG_CAPACITY] =
- BQ20Z75_DATA(POWER_SUPPLY_PROP_CAPACITY, 0x0E, 0, 100),
- [REG_REMAINING_CAPACITY] =
- BQ20Z75_DATA(POWER_SUPPLY_PROP_ENERGY_NOW, 0x0F, 0, 65535),
- [REG_REMAINING_CAPACITY_CHARGE] =
- BQ20Z75_DATA(POWER_SUPPLY_PROP_CHARGE_NOW, 0x0F, 0, 65535),
- [REG_FULL_CHARGE_CAPACITY] =
- BQ20Z75_DATA(POWER_SUPPLY_PROP_ENERGY_FULL, 0x10, 0, 65535),
- [REG_FULL_CHARGE_CAPACITY_CHARGE] =
- BQ20Z75_DATA(POWER_SUPPLY_PROP_CHARGE_FULL, 0x10, 0, 65535),
- [REG_TIME_TO_EMPTY] =
- BQ20Z75_DATA(POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG, 0x12, 0,
- 65535),
- [REG_TIME_TO_FULL] =
- BQ20Z75_DATA(POWER_SUPPLY_PROP_TIME_TO_FULL_AVG, 0x13, 0,
- 65535),
- [REG_STATUS] =
- BQ20Z75_DATA(POWER_SUPPLY_PROP_STATUS, 0x16, 0, 65535),
- [REG_CYCLE_COUNT] =
- BQ20Z75_DATA(POWER_SUPPLY_PROP_CYCLE_COUNT, 0x17, 0, 65535),
- [REG_DESIGN_CAPACITY] =
- BQ20Z75_DATA(POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN, 0x18, 0,
- 65535),
- [REG_DESIGN_CAPACITY_CHARGE] =
- BQ20Z75_DATA(POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN, 0x18, 0,
- 65535),
- [REG_DESIGN_VOLTAGE] =
- BQ20Z75_DATA(POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN, 0x19, 0,
- 65535),
- [REG_SERIAL_NUMBER] =
- BQ20Z75_DATA(POWER_SUPPLY_PROP_SERIAL_NUMBER, 0x1C, 0, 65535),
-};
-
-static enum power_supply_property bq20z75_properties[] = {
- POWER_SUPPLY_PROP_STATUS,
- POWER_SUPPLY_PROP_HEALTH,
- POWER_SUPPLY_PROP_PRESENT,
- POWER_SUPPLY_PROP_TECHNOLOGY,
- POWER_SUPPLY_PROP_CYCLE_COUNT,
- POWER_SUPPLY_PROP_VOLTAGE_NOW,
- POWER_SUPPLY_PROP_CURRENT_NOW,
- POWER_SUPPLY_PROP_CAPACITY,
- POWER_SUPPLY_PROP_TEMP,
- POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG,
- POWER_SUPPLY_PROP_TIME_TO_FULL_AVG,
- POWER_SUPPLY_PROP_SERIAL_NUMBER,
- POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN,
- POWER_SUPPLY_PROP_ENERGY_NOW,
- POWER_SUPPLY_PROP_ENERGY_FULL,
- POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN,
- POWER_SUPPLY_PROP_CHARGE_NOW,
- POWER_SUPPLY_PROP_CHARGE_FULL,
- POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
-};
-
-struct bq20z75_info {
- struct i2c_client *client;
- struct power_supply power_supply;
- struct bq20z75_platform_data *pdata;
- bool is_present;
- bool gpio_detect;
- bool enable_detection;
- int irq;
- int last_state;
- int poll_time;
- struct delayed_work work;
- int ignore_changes;
-};
-
-static int bq20z75_read_word_data(struct i2c_client *client, u8 address)
-{
- struct bq20z75_info *bq20z75_device = i2c_get_clientdata(client);
- s32 ret = 0;
- int retries = 1;
-
- if (bq20z75_device->pdata)
- retries = max(bq20z75_device->pdata->i2c_retry_count + 1, 1);
-
- while (retries > 0) {
- ret = i2c_smbus_read_word_data(client, address);
- if (ret >= 0)
- break;
- retries--;
- }
-
- if (ret < 0) {
- dev_dbg(&client->dev,
- "%s: i2c read at address 0x%x failed\n",
- __func__, address);
- return ret;
- }
-
- return le16_to_cpu(ret);
-}
-
-static int bq20z75_write_word_data(struct i2c_client *client, u8 address,
- u16 value)
-{
- struct bq20z75_info *bq20z75_device = i2c_get_clientdata(client);
- s32 ret = 0;
- int retries = 1;
-
- if (bq20z75_device->pdata)
- retries = max(bq20z75_device->pdata->i2c_retry_count + 1, 1);
-
- while (retries > 0) {
- ret = i2c_smbus_write_word_data(client, address,
- le16_to_cpu(value));
- if (ret >= 0)
- break;
- retries--;
- }
-
- if (ret < 0) {
- dev_dbg(&client->dev,
- "%s: i2c write to address 0x%x failed\n",
- __func__, address);
- return ret;
- }
-
- return 0;
-}
-
-static int bq20z75_get_battery_presence_and_health(
- struct i2c_client *client, enum power_supply_property psp,
- union power_supply_propval *val)
-{
- s32 ret;
- struct bq20z75_info *bq20z75_device = i2c_get_clientdata(client);
-
- if (psp == POWER_SUPPLY_PROP_PRESENT &&
- bq20z75_device->gpio_detect) {
- ret = gpio_get_value(
- bq20z75_device->pdata->battery_detect);
- if (ret == bq20z75_device->pdata->battery_detect_present)
- val->intval = 1;
- else
- val->intval = 0;
- bq20z75_device->is_present = val->intval;
- return ret;
- }
-
- /* Write to ManufacturerAccess with
- * ManufacturerAccess command and then
- * read the status */
- ret = bq20z75_write_word_data(client,
- bq20z75_data[REG_MANUFACTURER_DATA].addr,
- MANUFACTURER_ACCESS_STATUS);
- if (ret < 0) {
- if (psp == POWER_SUPPLY_PROP_PRESENT)
- val->intval = 0; /* battery removed */
- return ret;
- }
-
- ret = bq20z75_read_word_data(client,
- bq20z75_data[REG_MANUFACTURER_DATA].addr);
- if (ret < 0)
- return ret;
-
- if (ret < bq20z75_data[REG_MANUFACTURER_DATA].min_value ||
- ret > bq20z75_data[REG_MANUFACTURER_DATA].max_value) {
- val->intval = 0;
- return 0;
- }
-
- /* Mask the upper nibble of 2nd byte and
- * lower byte of response then
- * shift the result by 8 to get status*/
- ret &= 0x0F00;
- ret >>= 8;
- if (psp == POWER_SUPPLY_PROP_PRESENT) {
- if (ret == 0x0F)
- /* battery removed */
- val->intval = 0;
- else
- val->intval = 1;
- } else if (psp == POWER_SUPPLY_PROP_HEALTH) {
- if (ret == 0x09)
- val->intval = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE;
- else if (ret == 0x0B)
- val->intval = POWER_SUPPLY_HEALTH_OVERHEAT;
- else if (ret == 0x0C)
- val->intval = POWER_SUPPLY_HEALTH_DEAD;
- else
- val->intval = POWER_SUPPLY_HEALTH_GOOD;
- }
-
- return 0;
-}
-
-static int bq20z75_get_battery_property(struct i2c_client *client,
- int reg_offset, enum power_supply_property psp,
- union power_supply_propval *val)
-{
- struct bq20z75_info *bq20z75_device = i2c_get_clientdata(client);
- s32 ret;
-
- ret = bq20z75_read_word_data(client,
- bq20z75_data[reg_offset].addr);
- if (ret < 0)
- return ret;
-
- /* returned values are 16 bit */
- if (bq20z75_data[reg_offset].min_value < 0)
- ret = (s16)ret;
-
- if (ret >= bq20z75_data[reg_offset].min_value &&
- ret <= bq20z75_data[reg_offset].max_value) {
- val->intval = ret;
- if (psp != POWER_SUPPLY_PROP_STATUS)
- return 0;
-
- if (ret & BATTERY_FULL_CHARGED)
- val->intval = POWER_SUPPLY_STATUS_FULL;
- else if (ret & BATTERY_FULL_DISCHARGED)
- val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
- else if (ret & BATTERY_DISCHARGING)
- val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
- else
- val->intval = POWER_SUPPLY_STATUS_CHARGING;
-
- if (bq20z75_device->poll_time == 0)
- bq20z75_device->last_state = val->intval;
- else if (bq20z75_device->last_state != val->intval) {
- cancel_delayed_work_sync(&bq20z75_device->work);
- power_supply_changed(&bq20z75_device->power_supply);
- bq20z75_device->poll_time = 0;
- }
- } else {
- if (psp == POWER_SUPPLY_PROP_STATUS)
- val->intval = POWER_SUPPLY_STATUS_UNKNOWN;
- else
- val->intval = 0;
- }
-
- return 0;
-}
-
-static void bq20z75_unit_adjustment(struct i2c_client *client,
- enum power_supply_property psp, union power_supply_propval *val)
-{
-#define BASE_UNIT_CONVERSION 1000
-#define BATTERY_MODE_CAP_MULT_WATT (10 * BASE_UNIT_CONVERSION)
-#define TIME_UNIT_CONVERSION 60
-#define TEMP_KELVIN_TO_CELSIUS 2731
- switch (psp) {
- case POWER_SUPPLY_PROP_ENERGY_NOW:
- case POWER_SUPPLY_PROP_ENERGY_FULL:
- case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN:
- /* bq20z75 provides energy in units of 10mWh.
- * Convert to µWh
- */
- val->intval *= BATTERY_MODE_CAP_MULT_WATT;
- break;
-
- case POWER_SUPPLY_PROP_VOLTAGE_NOW:
- case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
- case POWER_SUPPLY_PROP_CURRENT_NOW:
- case POWER_SUPPLY_PROP_CHARGE_NOW:
- case POWER_SUPPLY_PROP_CHARGE_FULL:
- case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
- val->intval *= BASE_UNIT_CONVERSION;
- break;
-
- case POWER_SUPPLY_PROP_TEMP:
- /* bq20z75 provides battery temperature in 0.1K
- * so convert it to 0.1°C
- */
- val->intval -= TEMP_KELVIN_TO_CELSIUS;
- break;
-
- case POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG:
- case POWER_SUPPLY_PROP_TIME_TO_FULL_AVG:
- /* bq20z75 provides time to empty and time to full in minutes.
- * Convert to seconds
- */
- val->intval *= TIME_UNIT_CONVERSION;
- break;
-
- default:
- dev_dbg(&client->dev,
- "%s: no need for unit conversion %d\n", __func__, psp);
- }
-}
-
-static enum bq20z75_battery_mode
-bq20z75_set_battery_mode(struct i2c_client *client,
- enum bq20z75_battery_mode mode)
-{
- int ret, original_val;
-
- original_val = bq20z75_read_word_data(client, BATTERY_MODE_OFFSET);
- if (original_val < 0)
- return original_val;
-
- if ((original_val & BATTERY_MODE_MASK) == mode)
- return mode;
-
- if (mode == BATTERY_MODE_AMPS)
- ret = original_val & ~BATTERY_MODE_MASK;
- else
- ret = original_val | BATTERY_MODE_MASK;
-
- ret = bq20z75_write_word_data(client, BATTERY_MODE_OFFSET, ret);
- if (ret < 0)
- return ret;
-
- return original_val & BATTERY_MODE_MASK;
-}
-
-static int bq20z75_get_battery_capacity(struct i2c_client *client,
- int reg_offset, enum power_supply_property psp,
- union power_supply_propval *val)
-{
- s32 ret;
- enum bq20z75_battery_mode mode = BATTERY_MODE_WATTS;
-
- if (power_supply_is_amp_property(psp))
- mode = BATTERY_MODE_AMPS;
-
- mode = bq20z75_set_battery_mode(client, mode);
- if (mode < 0)
- return mode;
-
- ret = bq20z75_read_word_data(client, bq20z75_data[reg_offset].addr);
- if (ret < 0)
- return ret;
-
- if (psp == POWER_SUPPLY_PROP_CAPACITY) {
- /* bq20z75 spec says that this can be >100 %
- * even if max value is 100 % */
- val->intval = min(ret, 100);
- } else
- val->intval = ret;
-
- ret = bq20z75_set_battery_mode(client, mode);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-static char bq20z75_serial[5];
-static int bq20z75_get_battery_serial_number(struct i2c_client *client,
- union power_supply_propval *val)
-{
- int ret;
-
- ret = bq20z75_read_word_data(client,
- bq20z75_data[REG_SERIAL_NUMBER].addr);
- if (ret < 0)
- return ret;
-
- ret = sprintf(bq20z75_serial, "%04x", ret);
- val->strval = bq20z75_serial;
-
- return 0;
-}
-
-static int bq20z75_get_property_index(struct i2c_client *client,
- enum power_supply_property psp)
-{
- int count;
- for (count = 0; count < ARRAY_SIZE(bq20z75_data); count++)
- if (psp == bq20z75_data[count].psp)
- return count;
-
- dev_warn(&client->dev,
- "%s: Invalid Property - %d\n", __func__, psp);
-
- return -EINVAL;
-}
-
-static int bq20z75_get_property(struct power_supply *psy,
- enum power_supply_property psp,
- union power_supply_propval *val)
-{
- int ret = 0;
- struct bq20z75_info *bq20z75_device = container_of(psy,
- struct bq20z75_info, power_supply);
- struct i2c_client *client = bq20z75_device->client;
-
- switch (psp) {
- case POWER_SUPPLY_PROP_PRESENT:
- case POWER_SUPPLY_PROP_HEALTH:
- ret = bq20z75_get_battery_presence_and_health(client, psp, val);
- if (psp == POWER_SUPPLY_PROP_PRESENT)
- return 0;
- break;
-
- case POWER_SUPPLY_PROP_TECHNOLOGY:
- val->intval = POWER_SUPPLY_TECHNOLOGY_LION;
- break;
-
- case POWER_SUPPLY_PROP_ENERGY_NOW:
- case POWER_SUPPLY_PROP_ENERGY_FULL:
- case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN:
- case POWER_SUPPLY_PROP_CHARGE_NOW:
- case POWER_SUPPLY_PROP_CHARGE_FULL:
- case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
- case POWER_SUPPLY_PROP_CAPACITY:
- ret = bq20z75_get_property_index(client, psp);
- if (ret < 0)
- break;
-
- ret = bq20z75_get_battery_capacity(client, ret, psp, val);
- break;
-
- case POWER_SUPPLY_PROP_SERIAL_NUMBER:
- ret = bq20z75_get_battery_serial_number(client, val);
- break;
-
- case POWER_SUPPLY_PROP_STATUS:
- case POWER_SUPPLY_PROP_CYCLE_COUNT:
- case POWER_SUPPLY_PROP_VOLTAGE_NOW:
- case POWER_SUPPLY_PROP_CURRENT_NOW:
- case POWER_SUPPLY_PROP_TEMP:
- case POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG:
- case POWER_SUPPLY_PROP_TIME_TO_FULL_AVG:
- case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
- ret = bq20z75_get_property_index(client, psp);
- if (ret < 0)
- break;
-
- ret = bq20z75_get_battery_property(client, ret, psp, val);
- break;
-
- default:
- dev_err(&client->dev,
- "%s: INVALID property\n", __func__);
- return -EINVAL;
- }
-
- if (!bq20z75_device->enable_detection)
- goto done;
-
- if (!bq20z75_device->gpio_detect &&
- bq20z75_device->is_present != (ret >= 0)) {
- bq20z75_device->is_present = (ret >= 0);
- power_supply_changed(&bq20z75_device->power_supply);
- }
-
-done:
- if (!ret) {
- /* Convert units to match requirements for power supply class */
- bq20z75_unit_adjustment(client, psp, val);
- }
-
- dev_dbg(&client->dev,
- "%s: property = %d, value = %x\n", __func__, psp, val->intval);
-
- if (ret && bq20z75_device->is_present)
- return ret;
-
- /* battery not present, so return NODATA for properties */
- if (ret)
- return -ENODATA;
-
- return 0;
-}
-
-static irqreturn_t bq20z75_irq(int irq, void *devid)
-{
- struct power_supply *battery = devid;
-
- power_supply_changed(battery);
-
- return IRQ_HANDLED;
-}
-
-static void bq20z75_external_power_changed(struct power_supply *psy)
-{
- struct bq20z75_info *bq20z75_device;
-
- bq20z75_device = container_of(psy, struct bq20z75_info, power_supply);
-
- if (bq20z75_device->ignore_changes > 0) {
- bq20z75_device->ignore_changes--;
- return;
- }
-
- /* cancel outstanding work */
- cancel_delayed_work_sync(&bq20z75_device->work);
-
- schedule_delayed_work(&bq20z75_device->work, HZ);
- bq20z75_device->poll_time = bq20z75_device->pdata->poll_retry_count;
-}
-
-static void bq20z75_delayed_work(struct work_struct *work)
-{
- struct bq20z75_info *bq20z75_device;
- s32 ret;
-
- bq20z75_device = container_of(work, struct bq20z75_info, work.work);
-
- ret = bq20z75_read_word_data(bq20z75_device->client,
- bq20z75_data[REG_STATUS].addr);
- /* if the read failed, give up on this work */
- if (ret < 0) {
- bq20z75_device->poll_time = 0;
- return;
- }
-
- if (ret & BATTERY_FULL_CHARGED)
- ret = POWER_SUPPLY_STATUS_FULL;
- else if (ret & BATTERY_FULL_DISCHARGED)
- ret = POWER_SUPPLY_STATUS_NOT_CHARGING;
- else if (ret & BATTERY_DISCHARGING)
- ret = POWER_SUPPLY_STATUS_DISCHARGING;
- else
- ret = POWER_SUPPLY_STATUS_CHARGING;
-
- if (bq20z75_device->last_state != ret) {
- bq20z75_device->poll_time = 0;
- power_supply_changed(&bq20z75_device->power_supply);
- return;
- }
- if (bq20z75_device->poll_time > 0) {
- schedule_delayed_work(&bq20z75_device->work, HZ);
- bq20z75_device->poll_time--;
- return;
- }
-}
-
-static int __devinit bq20z75_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- struct bq20z75_info *bq20z75_device;
- struct bq20z75_platform_data *pdata = client->dev.platform_data;
- int rc;
- int irq;
-
- bq20z75_device = kzalloc(sizeof(struct bq20z75_info), GFP_KERNEL);
- if (!bq20z75_device)
- return -ENOMEM;
-
- bq20z75_device->client = client;
- bq20z75_device->enable_detection = false;
- bq20z75_device->gpio_detect = false;
- bq20z75_device->power_supply.name = "battery";
- bq20z75_device->power_supply.type = POWER_SUPPLY_TYPE_BATTERY;
- bq20z75_device->power_supply.properties = bq20z75_properties;
- bq20z75_device->power_supply.num_properties =
- ARRAY_SIZE(bq20z75_properties);
- bq20z75_device->power_supply.get_property = bq20z75_get_property;
- /* ignore first notification of external change, it is generated
- * from the power_supply_register call back
- */
- bq20z75_device->ignore_changes = 1;
- bq20z75_device->last_state = POWER_SUPPLY_STATUS_UNKNOWN;
- bq20z75_device->power_supply.external_power_changed =
- bq20z75_external_power_changed;
-
- if (pdata) {
- bq20z75_device->gpio_detect =
- gpio_is_valid(pdata->battery_detect);
- bq20z75_device->pdata = pdata;
- }
-
- i2c_set_clientdata(client, bq20z75_device);
-
- if (!bq20z75_device->gpio_detect)
- goto skip_gpio;
-
- rc = gpio_request(pdata->battery_detect, dev_name(&client->dev));
- if (rc) {
- dev_warn(&client->dev, "Failed to request gpio: %d\n", rc);
- bq20z75_device->gpio_detect = false;
- goto skip_gpio;
- }
-
- rc = gpio_direction_input(pdata->battery_detect);
- if (rc) {
- dev_warn(&client->dev, "Failed to get gpio as input: %d\n", rc);
- gpio_free(pdata->battery_detect);
- bq20z75_device->gpio_detect = false;
- goto skip_gpio;
- }
-
- irq = gpio_to_irq(pdata->battery_detect);
- if (irq <= 0) {
- dev_warn(&client->dev, "Failed to get gpio as irq: %d\n", irq);
- gpio_free(pdata->battery_detect);
- bq20z75_device->gpio_detect = false;
- goto skip_gpio;
- }
-
- rc = request_irq(irq, bq20z75_irq,
- IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
- dev_name(&client->dev), &bq20z75_device->power_supply);
- if (rc) {
- dev_warn(&client->dev, "Failed to request irq: %d\n", rc);
- gpio_free(pdata->battery_detect);
- bq20z75_device->gpio_detect = false;
- goto skip_gpio;
- }
-
- bq20z75_device->irq = irq;
-
-skip_gpio:
-
- rc = power_supply_register(&client->dev, &bq20z75_device->power_supply);
- if (rc) {
- dev_err(&client->dev,
- "%s: Failed to register power supply\n", __func__);
- goto exit_psupply;
- }
-
- dev_info(&client->dev,
- "%s: battery gas gauge device registered\n", client->name);
-
- INIT_DELAYED_WORK(&bq20z75_device->work, bq20z75_delayed_work);
-
- bq20z75_device->enable_detection = true;
-
- return 0;
-
-exit_psupply:
- if (bq20z75_device->irq)
- free_irq(bq20z75_device->irq, &bq20z75_device->power_supply);
- if (bq20z75_device->gpio_detect)
- gpio_free(pdata->battery_detect);
-
- kfree(bq20z75_device);
-
- return rc;
-}
-
-static int __devexit bq20z75_remove(struct i2c_client *client)
-{
- struct bq20z75_info *bq20z75_device = i2c_get_clientdata(client);
-
- if (bq20z75_device->irq)
- free_irq(bq20z75_device->irq, &bq20z75_device->power_supply);
- if (bq20z75_device->gpio_detect)
- gpio_free(bq20z75_device->pdata->battery_detect);
-
- power_supply_unregister(&bq20z75_device->power_supply);
-
- cancel_delayed_work_sync(&bq20z75_device->work);
-
- kfree(bq20z75_device);
- bq20z75_device = NULL;
-
- return 0;
-}
-
-#if defined CONFIG_PM
-static int bq20z75_suspend(struct i2c_client *client,
- pm_message_t state)
-{
- struct bq20z75_info *bq20z75_device = i2c_get_clientdata(client);
- s32 ret;
-
- if (bq20z75_device->poll_time > 0)
- cancel_delayed_work_sync(&bq20z75_device->work);
-
- /* write to manufacturer access with sleep command */
- ret = bq20z75_write_word_data(client,
- bq20z75_data[REG_MANUFACTURER_DATA].addr,
- MANUFACTURER_ACCESS_SLEEP);
- if (bq20z75_device->is_present && ret < 0)
- return ret;
-
- return 0;
-}
-#else
-#define bq20z75_suspend NULL
-#endif
-/* any smbus transaction will wake up bq20z75 */
-#define bq20z75_resume NULL
-
-static const struct i2c_device_id bq20z75_id[] = {
- { "bq20z75", 0 },
- {}
-};
-MODULE_DEVICE_TABLE(i2c, bq20z75_id);
-
-static struct i2c_driver bq20z75_battery_driver = {
- .probe = bq20z75_probe,
- .remove = __devexit_p(bq20z75_remove),
- .suspend = bq20z75_suspend,
- .resume = bq20z75_resume,
- .id_table = bq20z75_id,
- .driver = {
- .name = "bq20z75-battery",
- },
-};
-
-static int __init bq20z75_battery_init(void)
-{
- return i2c_add_driver(&bq20z75_battery_driver);
-}
-module_init(bq20z75_battery_init);
-
-static void __exit bq20z75_battery_exit(void)
-{
- i2c_del_driver(&bq20z75_battery_driver);
-}
-module_exit(bq20z75_battery_exit);
-
-MODULE_DESCRIPTION("BQ20z75 battery monitor driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/power/bq27x00_battery.c b/drivers/power/bq27x00_battery.c
index bb16f5b..98bf567 100644
--- a/drivers/power/bq27x00_battery.c
+++ b/drivers/power/bq27x00_battery.c
@@ -54,13 +54,19 @@
#define BQ27000_REG_RSOC 0x0B /* Relative State-of-Charge */
#define BQ27000_REG_ILMD 0x76 /* Initial last measured discharge */
-#define BQ27000_FLAG_CHGS BIT(7)
+#define BQ27000_FLAG_EDVF BIT(0) /* Final End-of-Discharge-Voltage flag */
+#define BQ27000_FLAG_EDV1 BIT(1) /* First End-of-Discharge-Voltage flag */
+#define BQ27000_FLAG_CI BIT(4) /* Capacity Inaccurate flag */
#define BQ27000_FLAG_FC BIT(5)
+#define BQ27000_FLAG_CHGS BIT(7) /* Charge state flag */
#define BQ27500_REG_SOC 0x2C
#define BQ27500_REG_DCAP 0x3C /* Design capacity */
-#define BQ27500_FLAG_DSC BIT(0)
-#define BQ27500_FLAG_FC BIT(9)
+#define BQ27500_FLAG_DSG BIT(0) /* Discharging */
+#define BQ27500_FLAG_SOCF BIT(1) /* State-of-Charge threshold final */
+#define BQ27500_FLAG_SOC1 BIT(2) /* State-of-Charge threshold 1 */
+#define BQ27500_FLAG_CHG BIT(8) /* Charging */
+#define BQ27500_FLAG_FC BIT(9) /* Fully charged */
#define BQ27000_RS 20 /* Resistor sense */
@@ -79,9 +85,8 @@
int charge_full;
int cycle_count;
int capacity;
+ int energy;
int flags;
-
- int current_now;
};
struct bq27x00_device_info {
@@ -108,6 +113,7 @@
POWER_SUPPLY_PROP_VOLTAGE_NOW,
POWER_SUPPLY_PROP_CURRENT_NOW,
POWER_SUPPLY_PROP_CAPACITY,
+ POWER_SUPPLY_PROP_CAPACITY_LEVEL,
POWER_SUPPLY_PROP_TEMP,
POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW,
POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG,
@@ -149,7 +155,7 @@
rsoc = bq27x00_read(di, BQ27000_REG_RSOC, true);
if (rsoc < 0)
- dev_err(di->dev, "error reading relative State-of-Charge\n");
+ dev_dbg(di->dev, "error reading relative State-of-Charge\n");
return rsoc;
}
@@ -164,7 +170,8 @@
charge = bq27x00_read(di, reg, false);
if (charge < 0) {
- dev_err(di->dev, "error reading nominal available capacity\n");
+ dev_dbg(di->dev, "error reading charge register %02x: %d\n",
+ reg, charge);
return charge;
}
@@ -208,7 +215,7 @@
ilmd = bq27x00_read(di, BQ27000_REG_ILMD, true);
if (ilmd < 0) {
- dev_err(di->dev, "error reading initial last measured discharge\n");
+ dev_dbg(di->dev, "error reading initial last measured discharge\n");
return ilmd;
}
@@ -221,6 +228,50 @@
}
/*
+ * Return the battery Available energy in µWh
+ * Or < 0 if something fails.
+ */
+static int bq27x00_battery_read_energy(struct bq27x00_device_info *di)
+{
+ int ae;
+
+ ae = bq27x00_read(di, BQ27x00_REG_AE, false);
+ if (ae < 0) {
+ dev_dbg(di->dev, "error reading available energy\n");
+ return ae;
+ }
+
+ if (di->chip == BQ27500)
+ ae *= 1000;
+ else
+ ae = ae * 29200 / BQ27000_RS;
+
+ return ae;
+}
+
+/*
+ * Return the battery temperature in tenths of degree Celsius
+ * Or < 0 if something fails.
+ */
+static int bq27x00_battery_read_temperature(struct bq27x00_device_info *di)
+{
+ int temp;
+
+ temp = bq27x00_read(di, BQ27x00_REG_TEMP, false);
+ if (temp < 0) {
+ dev_err(di->dev, "error reading temperature\n");
+ return temp;
+ }
+
+ if (di->chip == BQ27500)
+ temp -= 2731;
+ else
+ temp = ((temp * 5) - 5463) / 2;
+
+ return temp;
+}
+
+/*
* Return the battery Cycle count total
* Or < 0 if something fails.
*/
@@ -245,7 +296,8 @@
tval = bq27x00_read(di, reg, false);
if (tval < 0) {
- dev_err(di->dev, "error reading register %02x: %d\n", reg, tval);
+ dev_dbg(di->dev, "error reading time register %02x: %d\n",
+ reg, tval);
return tval;
}
@@ -262,25 +314,31 @@
cache.flags = bq27x00_read(di, BQ27x00_REG_FLAGS, is_bq27500);
if (cache.flags >= 0) {
- cache.capacity = bq27x00_battery_read_rsoc(di);
- cache.temperature = bq27x00_read(di, BQ27x00_REG_TEMP, false);
- cache.time_to_empty = bq27x00_battery_read_time(di, BQ27x00_REG_TTE);
- cache.time_to_empty_avg = bq27x00_battery_read_time(di, BQ27x00_REG_TTECP);
- cache.time_to_full = bq27x00_battery_read_time(di, BQ27x00_REG_TTF);
- cache.charge_full = bq27x00_battery_read_lmd(di);
+ if (!is_bq27500 && (cache.flags & BQ27000_FLAG_CI)) {
+ dev_info(di->dev, "battery is not calibrated! ignoring capacity values\n");
+ cache.capacity = -ENODATA;
+ cache.energy = -ENODATA;
+ cache.time_to_empty = -ENODATA;
+ cache.time_to_empty_avg = -ENODATA;
+ cache.time_to_full = -ENODATA;
+ cache.charge_full = -ENODATA;
+ } else {
+ cache.capacity = bq27x00_battery_read_rsoc(di);
+ cache.energy = bq27x00_battery_read_energy(di);
+ cache.time_to_empty = bq27x00_battery_read_time(di, BQ27x00_REG_TTE);
+ cache.time_to_empty_avg = bq27x00_battery_read_time(di, BQ27x00_REG_TTECP);
+ cache.time_to_full = bq27x00_battery_read_time(di, BQ27x00_REG_TTF);
+ cache.charge_full = bq27x00_battery_read_lmd(di);
+ }
+ cache.temperature = bq27x00_battery_read_temperature(di);
cache.cycle_count = bq27x00_battery_read_cyct(di);
- if (!is_bq27500)
- cache.current_now = bq27x00_read(di, BQ27x00_REG_AI, false);
-
/* We only have to read charge design full once */
if (di->charge_design_full <= 0)
di->charge_design_full = bq27x00_battery_read_ilmd(di);
}
- /* Ignore current_now which is a snapshot of the current battery state
- * and is likely to be different even between two consecutive reads */
- if (memcmp(&di->cache, &cache, sizeof(cache) - sizeof(int)) != 0) {
+ if (memcmp(&di->cache, &cache, sizeof(cache)) != 0) {
di->cache = cache;
power_supply_changed(&di->bat);
}
@@ -302,25 +360,6 @@
}
}
-
-/*
- * Return the battery temperature in tenths of degree Celsius
- * Or < 0 if something fails.
- */
-static int bq27x00_battery_temperature(struct bq27x00_device_info *di,
- union power_supply_propval *val)
-{
- if (di->cache.temperature < 0)
- return di->cache.temperature;
-
- if (di->chip == BQ27500)
- val->intval = di->cache.temperature - 2731;
- else
- val->intval = ((di->cache.temperature * 5) - 5463) / 2;
-
- return 0;
-}
-
/*
* Return the battery average current in µA
* Note that current can be negative signed as well
@@ -330,20 +369,20 @@
union power_supply_propval *val)
{
int curr;
+ int flags;
- if (di->chip == BQ27500)
- curr = bq27x00_read(di, BQ27x00_REG_AI, false);
- else
- curr = di->cache.current_now;
-
- if (curr < 0)
+ curr = bq27x00_read(di, BQ27x00_REG_AI, false);
+ if (curr < 0) {
+ dev_err(di->dev, "error reading current\n");
return curr;
+ }
if (di->chip == BQ27500) {
/* bq27500 returns signed value */
val->intval = (int)((s16)curr) * 1000;
} else {
- if (di->cache.flags & BQ27000_FLAG_CHGS) {
+ flags = bq27x00_read(di, BQ27x00_REG_FLAGS, false);
+ if (flags & BQ27000_FLAG_CHGS) {
dev_dbg(di->dev, "negative current!\n");
curr = -curr;
}
@@ -362,10 +401,14 @@
if (di->chip == BQ27500) {
if (di->cache.flags & BQ27500_FLAG_FC)
status = POWER_SUPPLY_STATUS_FULL;
- else if (di->cache.flags & BQ27500_FLAG_DSC)
+ else if (di->cache.flags & BQ27500_FLAG_DSG)
status = POWER_SUPPLY_STATUS_DISCHARGING;
- else
+ else if (di->cache.flags & BQ27500_FLAG_CHG)
status = POWER_SUPPLY_STATUS_CHARGING;
+ else if (power_supply_am_i_supplied(&di->bat))
+ status = POWER_SUPPLY_STATUS_NOT_CHARGING;
+ else
+ status = POWER_SUPPLY_STATUS_UNKNOWN;
} else {
if (di->cache.flags & BQ27000_FLAG_FC)
status = POWER_SUPPLY_STATUS_FULL;
@@ -382,6 +425,36 @@
return 0;
}
+static int bq27x00_battery_capacity_level(struct bq27x00_device_info *di,
+ union power_supply_propval *val)
+{
+ int level;
+
+ if (di->chip == BQ27500) {
+ if (di->cache.flags & BQ27500_FLAG_FC)
+ level = POWER_SUPPLY_CAPACITY_LEVEL_FULL;
+ else if (di->cache.flags & BQ27500_FLAG_SOC1)
+ level = POWER_SUPPLY_CAPACITY_LEVEL_LOW;
+ else if (di->cache.flags & BQ27500_FLAG_SOCF)
+ level = POWER_SUPPLY_CAPACITY_LEVEL_CRITICAL;
+ else
+ level = POWER_SUPPLY_CAPACITY_LEVEL_NORMAL;
+ } else {
+ if (di->cache.flags & BQ27000_FLAG_FC)
+ level = POWER_SUPPLY_CAPACITY_LEVEL_FULL;
+ else if (di->cache.flags & BQ27000_FLAG_EDV1)
+ level = POWER_SUPPLY_CAPACITY_LEVEL_LOW;
+ else if (di->cache.flags & BQ27000_FLAG_EDVF)
+ level = POWER_SUPPLY_CAPACITY_LEVEL_CRITICAL;
+ else
+ level = POWER_SUPPLY_CAPACITY_LEVEL_NORMAL;
+ }
+
+ val->intval = level;
+
+ return 0;
+}
+
/*
* Return the battery Voltage in milivolts
* Or < 0 if something fails.
@@ -392,40 +465,16 @@
int volt;
volt = bq27x00_read(di, BQ27x00_REG_VOLT, false);
- if (volt < 0)
+ if (volt < 0) {
+ dev_err(di->dev, "error reading voltage\n");
return volt;
+ }
val->intval = volt * 1000;
return 0;
}
-/*
- * Return the battery Available energy in µWh
- * Or < 0 if something fails.
- */
-static int bq27x00_battery_energy(struct bq27x00_device_info *di,
- union power_supply_propval *val)
-{
- int ae;
-
- ae = bq27x00_read(di, BQ27x00_REG_AE, false);
- if (ae < 0) {
- dev_err(di->dev, "error reading available energy\n");
- return ae;
- }
-
- if (di->chip == BQ27500)
- ae *= 1000;
- else
- ae = ae * 29200 / BQ27000_RS;
-
- val->intval = ae;
-
- return 0;
-}
-
-
static int bq27x00_simple_value(int value,
union power_supply_propval *val)
{
@@ -473,8 +522,11 @@
case POWER_SUPPLY_PROP_CAPACITY:
ret = bq27x00_simple_value(di->cache.capacity, val);
break;
+ case POWER_SUPPLY_PROP_CAPACITY_LEVEL:
+ ret = bq27x00_battery_capacity_level(di, val);
+ break;
case POWER_SUPPLY_PROP_TEMP:
- ret = bq27x00_battery_temperature(di, val);
+ ret = bq27x00_simple_value(di->cache.temperature, val);
break;
case POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW:
ret = bq27x00_simple_value(di->cache.time_to_empty, val);
@@ -501,7 +553,7 @@
ret = bq27x00_simple_value(di->cache.cycle_count, val);
break;
case POWER_SUPPLY_PROP_ENERGY_NOW:
- ret = bq27x00_battery_energy(di, val);
+ ret = bq27x00_simple_value(di->cache.energy, val);
break;
default:
return -EINVAL;
@@ -546,6 +598,14 @@
static void bq27x00_powersupply_unregister(struct bq27x00_device_info *di)
{
+ /*
+ * power_supply_unregister call bq27x00_battery_get_property which
+ * call bq27x00_battery_poll.
+ * Make sure that bq27x00_battery_poll will not call
+ * schedule_delayed_work again after unregister (which cause OOPS).
+ */
+ poll_interval = 0;
+
cancel_delayed_work_sync(&di->work);
power_supply_unregister(&di->bat);
diff --git a/drivers/power/charger-manager.c b/drivers/power/charger-manager.c
new file mode 100644
index 0000000..0378d01
--- /dev/null
+++ b/drivers/power/charger-manager.c
@@ -0,0 +1,1072 @@
+/*
+ * Copyright (C) 2011 Samsung Electronics Co., Ltd.
+ * MyungJoo Ham <myungjoo.ham@samsung.com>
+ *
+ * This driver enables to monitor battery health and control charger
+ * during suspend-to-mem.
+ * Charger manager depends on other devices. register this later than
+ * the depending devices.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+**/
+
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/rtc.h>
+#include <linux/slab.h>
+#include <linux/workqueue.h>
+#include <linux/platform_device.h>
+#include <linux/power/charger-manager.h>
+#include <linux/regulator/consumer.h>
+
+/*
+ * Regard CM_JIFFIES_SMALL jiffies is small enough to ignore for
+ * delayed works so that we can run delayed works with CM_JIFFIES_SMALL
+ * without any delays.
+ */
+#define CM_JIFFIES_SMALL (2)
+
+/* If y is valid (> 0) and smaller than x, do x = y */
+#define CM_MIN_VALID(x, y) x = (((y > 0) && ((x) > (y))) ? (y) : (x))
+
+/*
+ * Regard CM_RTC_SMALL (sec) is small enough to ignore error in invoking
+ * rtc alarm. It should be 2 or larger
+ */
+#define CM_RTC_SMALL (2)
+
+#define UEVENT_BUF_SIZE 32
+
+static LIST_HEAD(cm_list);
+static DEFINE_MUTEX(cm_list_mtx);
+
+/* About in-suspend (suspend-again) monitoring */
+static struct rtc_device *rtc_dev;
+/*
+ * Backup RTC alarm
+ * Save the wakeup alarm before entering suspend-to-RAM
+ */
+static struct rtc_wkalrm rtc_wkalarm_save;
+/* Backup RTC alarm time in terms of seconds since 01-01-1970 00:00:00 */
+static unsigned long rtc_wkalarm_save_time;
+static bool cm_suspended;
+static bool cm_rtc_set;
+static unsigned long cm_suspend_duration_ms;
+
+/* Global charger-manager description */
+static struct charger_global_desc *g_desc; /* init with setup_charger_manager */
+
+/**
+ * is_batt_present - See if the battery presents in place.
+ * @cm: the Charger Manager representing the battery.
+ */
+static bool is_batt_present(struct charger_manager *cm)
+{
+ union power_supply_propval val;
+ bool present = false;
+ int i, ret;
+
+ switch (cm->desc->battery_present) {
+ case CM_FUEL_GAUGE:
+ ret = cm->fuel_gauge->get_property(cm->fuel_gauge,
+ POWER_SUPPLY_PROP_PRESENT, &val);
+ if (ret == 0 && val.intval)
+ present = true;
+ break;
+ case CM_CHARGER_STAT:
+ for (i = 0; cm->charger_stat[i]; i++) {
+ ret = cm->charger_stat[i]->get_property(
+ cm->charger_stat[i],
+ POWER_SUPPLY_PROP_PRESENT, &val);
+ if (ret == 0 && val.intval) {
+ present = true;
+ break;
+ }
+ }
+ break;
+ }
+
+ return present;
+}
+
+/**
+ * is_ext_pwr_online - See if an external power source is attached to charge
+ * @cm: the Charger Manager representing the battery.
+ *
+ * Returns true if at least one of the chargers of the battery has an external
+ * power source attached to charge the battery regardless of whether it is
+ * actually charging or not.
+ */
+static bool is_ext_pwr_online(struct charger_manager *cm)
+{
+ union power_supply_propval val;
+ bool online = false;
+ int i, ret;
+
+ /* If at least one of them has one, it's yes. */
+ for (i = 0; cm->charger_stat[i]; i++) {
+ ret = cm->charger_stat[i]->get_property(
+ cm->charger_stat[i],
+ POWER_SUPPLY_PROP_ONLINE, &val);
+ if (ret == 0 && val.intval) {
+ online = true;
+ break;
+ }
+ }
+
+ return online;
+}
+
+/**
+ * get_batt_uV - Get the voltage level of the battery
+ * @cm: the Charger Manager representing the battery.
+ * @uV: the voltage level returned.
+ *
+ * Returns 0 if there is no error.
+ * Returns a negative value on error.
+ */
+static int get_batt_uV(struct charger_manager *cm, int *uV)
+{
+ union power_supply_propval val;
+ int ret;
+
+ if (cm->fuel_gauge)
+ ret = cm->fuel_gauge->get_property(cm->fuel_gauge,
+ POWER_SUPPLY_PROP_VOLTAGE_NOW, &val);
+ else
+ return -ENODEV;
+
+ if (ret)
+ return ret;
+
+ *uV = val.intval;
+ return 0;
+}
+
+/**
+ * is_charging - Returns true if the battery is being charged.
+ * @cm: the Charger Manager representing the battery.
+ */
+static bool is_charging(struct charger_manager *cm)
+{
+ int i, ret;
+ bool charging = false;
+ union power_supply_propval val;
+
+ /* If there is no battery, it cannot be charged */
+ if (!is_batt_present(cm))
+ return false;
+
+ /* If at least one of the charger is charging, return yes */
+ for (i = 0; cm->charger_stat[i]; i++) {
+ /* 1. The charger sholuld not be DISABLED */
+ if (cm->emergency_stop)
+ continue;
+ if (!cm->charger_enabled)
+ continue;
+
+ /* 2. The charger should be online (ext-power) */
+ ret = cm->charger_stat[i]->get_property(
+ cm->charger_stat[i],
+ POWER_SUPPLY_PROP_ONLINE, &val);
+ if (ret) {
+ dev_warn(cm->dev, "Cannot read ONLINE value from %s.\n",
+ cm->desc->psy_charger_stat[i]);
+ continue;
+ }
+ if (val.intval == 0)
+ continue;
+
+ /*
+ * 3. The charger should not be FULL, DISCHARGING,
+ * or NOT_CHARGING.
+ */
+ ret = cm->charger_stat[i]->get_property(
+ cm->charger_stat[i],
+ POWER_SUPPLY_PROP_STATUS, &val);
+ if (ret) {
+ dev_warn(cm->dev, "Cannot read STATUS value from %s.\n",
+ cm->desc->psy_charger_stat[i]);
+ continue;
+ }
+ if (val.intval == POWER_SUPPLY_STATUS_FULL ||
+ val.intval == POWER_SUPPLY_STATUS_DISCHARGING ||
+ val.intval == POWER_SUPPLY_STATUS_NOT_CHARGING)
+ continue;
+
+ /* Then, this is charging. */
+ charging = true;
+ break;
+ }
+
+ return charging;
+}
+
+/**
+ * is_polling_required - Return true if need to continue polling for this CM.
+ * @cm: the Charger Manager representing the battery.
+ */
+static bool is_polling_required(struct charger_manager *cm)
+{
+ switch (cm->desc->polling_mode) {
+ case CM_POLL_DISABLE:
+ return false;
+ case CM_POLL_ALWAYS:
+ return true;
+ case CM_POLL_EXTERNAL_POWER_ONLY:
+ return is_ext_pwr_online(cm);
+ case CM_POLL_CHARGING_ONLY:
+ return is_charging(cm);
+ default:
+ dev_warn(cm->dev, "Incorrect polling_mode (%d)\n",
+ cm->desc->polling_mode);
+ }
+
+ return false;
+}
+
+/**
+ * try_charger_enable - Enable/Disable chargers altogether
+ * @cm: the Charger Manager representing the battery.
+ * @enable: true: enable / false: disable
+ *
+ * Note that Charger Manager keeps the charger enabled regardless whether
+ * the charger is charging or not (because battery is full or no external
+ * power source exists) except when CM needs to disable chargers forcibly
+ * bacause of emergency causes; when the battery is overheated or too cold.
+ */
+static int try_charger_enable(struct charger_manager *cm, bool enable)
+{
+ int err = 0, i;
+ struct charger_desc *desc = cm->desc;
+
+ /* Ignore if it's redundent command */
+ if (enable && cm->charger_enabled)
+ return 0;
+ if (!enable && !cm->charger_enabled)
+ return 0;
+
+ if (enable) {
+ if (cm->emergency_stop)
+ return -EAGAIN;
+ err = regulator_bulk_enable(desc->num_charger_regulators,
+ desc->charger_regulators);
+ } else {
+ /*
+ * Abnormal battery state - Stop charging forcibly,
+ * even if charger was enabled at the other places
+ */
+ err = regulator_bulk_disable(desc->num_charger_regulators,
+ desc->charger_regulators);
+
+ for (i = 0; i < desc->num_charger_regulators; i++) {
+ if (regulator_is_enabled(
+ desc->charger_regulators[i].consumer)) {
+ regulator_force_disable(
+ desc->charger_regulators[i].consumer);
+ dev_warn(cm->dev,
+ "Disable regulator(%s) forcibly.\n",
+ desc->charger_regulators[i].supply);
+ }
+ }
+ }
+
+ if (!err)
+ cm->charger_enabled = enable;
+
+ return err;
+}
+
+/**
+ * uevent_notify - Let users know something has changed.
+ * @cm: the Charger Manager representing the battery.
+ * @event: the event string.
+ *
+ * If @event is null, it implies that uevent_notify is called
+ * by resume function. When called in the resume function, cm_suspended
+ * should be already reset to false in order to let uevent_notify
+ * notify the recent event during the suspend to users. While
+ * suspended, uevent_notify does not notify users, but tracks
+ * events so that uevent_notify can notify users later after resumed.
+ */
+static void uevent_notify(struct charger_manager *cm, const char *event)
+{
+ static char env_str[UEVENT_BUF_SIZE + 1] = "";
+ static char env_str_save[UEVENT_BUF_SIZE + 1] = "";
+
+ if (cm_suspended) {
+ /* Nothing in suspended-event buffer */
+ if (env_str_save[0] == 0) {
+ if (!strncmp(env_str, event, UEVENT_BUF_SIZE))
+ return; /* status not changed */
+ strncpy(env_str_save, event, UEVENT_BUF_SIZE);
+ return;
+ }
+
+ if (!strncmp(env_str_save, event, UEVENT_BUF_SIZE))
+ return; /* Duplicated. */
+ else
+ strncpy(env_str_save, event, UEVENT_BUF_SIZE);
+
+ return;
+ }
+
+ if (event == NULL) {
+ /* No messages pending */
+ if (!env_str_save[0])
+ return;
+
+ strncpy(env_str, env_str_save, UEVENT_BUF_SIZE);
+ kobject_uevent(&cm->dev->kobj, KOBJ_CHANGE);
+ env_str_save[0] = 0;
+
+ return;
+ }
+
+ /* status not changed */
+ if (!strncmp(env_str, event, UEVENT_BUF_SIZE))
+ return;
+
+ /* save the status and notify the update */
+ strncpy(env_str, event, UEVENT_BUF_SIZE);
+ kobject_uevent(&cm->dev->kobj, KOBJ_CHANGE);
+
+ dev_info(cm->dev, event);
+}
+
+/**
+ * _cm_monitor - Monitor the temperature and return true for exceptions.
+ * @cm: the Charger Manager representing the battery.
+ *
+ * Returns true if there is an event to notify for the battery.
+ * (True if the status of "emergency_stop" changes)
+ */
+static bool _cm_monitor(struct charger_manager *cm)
+{
+ struct charger_desc *desc = cm->desc;
+ int temp = desc->temperature_out_of_range(&cm->last_temp_mC);
+
+ dev_dbg(cm->dev, "monitoring (%2.2d.%3.3dC)\n",
+ cm->last_temp_mC / 1000, cm->last_temp_mC % 1000);
+
+ /* It has been stopped or charging already */
+ if (!!temp == !!cm->emergency_stop)
+ return false;
+
+ if (temp) {
+ cm->emergency_stop = temp;
+ if (!try_charger_enable(cm, false)) {
+ if (temp > 0)
+ uevent_notify(cm, "OVERHEAT");
+ else
+ uevent_notify(cm, "COLD");
+ }
+ } else {
+ cm->emergency_stop = 0;
+ if (!try_charger_enable(cm, true))
+ uevent_notify(cm, "CHARGING");
+ }
+
+ return true;
+}
+
+/**
+ * cm_monitor - Monitor every battery.
+ *
+ * Returns true if there is an event to notify from any of the batteries.
+ * (True if the status of "emergency_stop" changes)
+ */
+static bool cm_monitor(void)
+{
+ bool stop = false;
+ struct charger_manager *cm;
+
+ mutex_lock(&cm_list_mtx);
+
+ list_for_each_entry(cm, &cm_list, entry)
+ stop = stop || _cm_monitor(cm);
+
+ mutex_unlock(&cm_list_mtx);
+
+ return stop;
+}
+
+static int charger_get_property(struct power_supply *psy,
+ enum power_supply_property psp,
+ union power_supply_propval *val)
+{
+ struct charger_manager *cm = container_of(psy,
+ struct charger_manager, charger_psy);
+ struct charger_desc *desc = cm->desc;
+ int i, ret = 0, uV;
+
+ switch (psp) {
+ case POWER_SUPPLY_PROP_STATUS:
+ if (is_charging(cm))
+ val->intval = POWER_SUPPLY_STATUS_CHARGING;
+ else if (is_ext_pwr_online(cm))
+ val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
+ else
+ val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
+ break;
+ case POWER_SUPPLY_PROP_HEALTH:
+ if (cm->emergency_stop > 0)
+ val->intval = POWER_SUPPLY_HEALTH_OVERHEAT;
+ else if (cm->emergency_stop < 0)
+ val->intval = POWER_SUPPLY_HEALTH_COLD;
+ else
+ val->intval = POWER_SUPPLY_HEALTH_GOOD;
+ break;
+ case POWER_SUPPLY_PROP_PRESENT:
+ if (is_batt_present(cm))
+ val->intval = 1;
+ else
+ val->intval = 0;
+ break;
+ case POWER_SUPPLY_PROP_VOLTAGE_NOW:
+ ret = get_batt_uV(cm, &i);
+ val->intval = i;
+ break;
+ case POWER_SUPPLY_PROP_CURRENT_NOW:
+ ret = cm->fuel_gauge->get_property(cm->fuel_gauge,
+ POWER_SUPPLY_PROP_CURRENT_NOW, val);
+ break;
+ case POWER_SUPPLY_PROP_TEMP:
+ /* in thenth of centigrade */
+ if (cm->last_temp_mC == INT_MIN)
+ desc->temperature_out_of_range(&cm->last_temp_mC);
+ val->intval = cm->last_temp_mC / 100;
+ if (!desc->measure_battery_temp)
+ ret = -ENODEV;
+ break;
+ case POWER_SUPPLY_PROP_TEMP_AMBIENT:
+ /* in thenth of centigrade */
+ if (cm->last_temp_mC == INT_MIN)
+ desc->temperature_out_of_range(&cm->last_temp_mC);
+ val->intval = cm->last_temp_mC / 100;
+ if (desc->measure_battery_temp)
+ ret = -ENODEV;
+ break;
+ case POWER_SUPPLY_PROP_CAPACITY:
+ if (!cm->fuel_gauge) {
+ ret = -ENODEV;
+ break;
+ }
+
+ if (!is_batt_present(cm)) {
+ /* There is no battery. Assume 100% */
+ val->intval = 100;
+ break;
+ }
+
+ ret = cm->fuel_gauge->get_property(cm->fuel_gauge,
+ POWER_SUPPLY_PROP_CAPACITY, val);
+ if (ret)
+ break;
+
+ if (val->intval > 100) {
+ val->intval = 100;
+ break;
+ }
+ if (val->intval < 0)
+ val->intval = 0;
+
+ /* Do not adjust SOC when charging: voltage is overrated */
+ if (is_charging(cm))
+ break;
+
+ /*
+ * If the capacity value is inconsistent, calibrate it base on
+ * the battery voltage values and the thresholds given as desc
+ */
+ ret = get_batt_uV(cm, &uV);
+ if (ret) {
+ /* Voltage information not available. No calibration */
+ ret = 0;
+ break;
+ }
+
+ if (desc->fullbatt_uV > 0 && uV >= desc->fullbatt_uV &&
+ !is_charging(cm)) {
+ val->intval = 100;
+ break;
+ }
+
+ break;
+ case POWER_SUPPLY_PROP_ONLINE:
+ if (is_ext_pwr_online(cm))
+ val->intval = 1;
+ else
+ val->intval = 0;
+ break;
+ case POWER_SUPPLY_PROP_CHARGE_FULL:
+ if (cm->fuel_gauge) {
+ if (cm->fuel_gauge->get_property(cm->fuel_gauge,
+ POWER_SUPPLY_PROP_CHARGE_FULL, val) == 0)
+ break;
+ }
+
+ if (is_ext_pwr_online(cm)) {
+ /* Not full if it's charging. */
+ if (is_charging(cm)) {
+ val->intval = 0;
+ break;
+ }
+ /*
+ * Full if it's powered but not charging andi
+ * not forced stop by emergency
+ */
+ if (!cm->emergency_stop) {
+ val->intval = 1;
+ break;
+ }
+ }
+
+ /* Full if it's over the fullbatt voltage */
+ ret = get_batt_uV(cm, &uV);
+ if (!ret && desc->fullbatt_uV > 0 && uV >= desc->fullbatt_uV &&
+ !is_charging(cm)) {
+ val->intval = 1;
+ break;
+ }
+
+ /* Full if the cap is 100 */
+ if (cm->fuel_gauge) {
+ ret = cm->fuel_gauge->get_property(cm->fuel_gauge,
+ POWER_SUPPLY_PROP_CAPACITY, val);
+ if (!ret && val->intval >= 100 && !is_charging(cm)) {
+ val->intval = 1;
+ break;
+ }
+ }
+
+ val->intval = 0;
+ ret = 0;
+ break;
+ case POWER_SUPPLY_PROP_CHARGE_NOW:
+ if (is_charging(cm)) {
+ ret = cm->fuel_gauge->get_property(cm->fuel_gauge,
+ POWER_SUPPLY_PROP_CHARGE_NOW,
+ val);
+ if (ret) {
+ val->intval = 1;
+ ret = 0;
+ } else {
+ /* If CHARGE_NOW is supplied, use it */
+ val->intval = (val->intval > 0) ?
+ val->intval : 1;
+ }
+ } else {
+ val->intval = 0;
+ }
+ break;
+ default:
+ return -EINVAL;
+ }
+ return ret;
+}
+
+#define NUM_CHARGER_PSY_OPTIONAL (4)
+static enum power_supply_property default_charger_props[] = {
+ /* Guaranteed to provide */
+ POWER_SUPPLY_PROP_STATUS,
+ POWER_SUPPLY_PROP_HEALTH,
+ POWER_SUPPLY_PROP_PRESENT,
+ POWER_SUPPLY_PROP_VOLTAGE_NOW,
+ POWER_SUPPLY_PROP_CAPACITY,
+ POWER_SUPPLY_PROP_ONLINE,
+ POWER_SUPPLY_PROP_CHARGE_FULL,
+ /*
+ * Optional properties are:
+ * POWER_SUPPLY_PROP_CHARGE_NOW,
+ * POWER_SUPPLY_PROP_CURRENT_NOW,
+ * POWER_SUPPLY_PROP_TEMP, and
+ * POWER_SUPPLY_PROP_TEMP_AMBIENT,
+ */
+};
+
+static struct power_supply psy_default = {
+ .name = "battery",
+ .type = POWER_SUPPLY_TYPE_BATTERY,
+ .properties = default_charger_props,
+ .num_properties = ARRAY_SIZE(default_charger_props),
+ .get_property = charger_get_property,
+};
+
+/**
+ * cm_setup_timer - For in-suspend monitoring setup wakeup alarm
+ * for suspend_again.
+ *
+ * Returns true if the alarm is set for Charger Manager to use.
+ * Returns false if
+ * cm_setup_timer fails to set an alarm,
+ * cm_setup_timer does not need to set an alarm for Charger Manager,
+ * or an alarm previously configured is to be used.
+ */
+static bool cm_setup_timer(void)
+{
+ struct charger_manager *cm;
+ unsigned int wakeup_ms = UINT_MAX;
+ bool ret = false;
+
+ mutex_lock(&cm_list_mtx);
+
+ list_for_each_entry(cm, &cm_list, entry) {
+ /* Skip if polling is not required for this CM */
+ if (!is_polling_required(cm) && !cm->emergency_stop)
+ continue;
+ if (cm->desc->polling_interval_ms == 0)
+ continue;
+ CM_MIN_VALID(wakeup_ms, cm->desc->polling_interval_ms);
+ }
+
+ mutex_unlock(&cm_list_mtx);
+
+ if (wakeup_ms < UINT_MAX && wakeup_ms > 0) {
+ pr_info("Charger Manager wakeup timer: %u ms.\n", wakeup_ms);
+ if (rtc_dev) {
+ struct rtc_wkalrm tmp;
+ unsigned long time, now;
+ unsigned long add = DIV_ROUND_UP(wakeup_ms, 1000);
+
+ /*
+ * Set alarm with the polling interval (wakeup_ms)
+ * except when rtc_wkalarm_save comes first.
+ * However, the alarm time should be NOW +
+ * CM_RTC_SMALL or later.
+ */
+ tmp.enabled = 1;
+ rtc_read_time(rtc_dev, &tmp.time);
+ rtc_tm_to_time(&tmp.time, &now);
+ if (add < CM_RTC_SMALL)
+ add = CM_RTC_SMALL;
+ time = now + add;
+
+ ret = true;
+
+ if (rtc_wkalarm_save.enabled &&
+ rtc_wkalarm_save_time &&
+ rtc_wkalarm_save_time < time) {
+ if (rtc_wkalarm_save_time < now + CM_RTC_SMALL)
+ time = now + CM_RTC_SMALL;
+ else
+ time = rtc_wkalarm_save_time;
+
+ /* The timer is not appointed by CM */
+ ret = false;
+ }
+
+ pr_info("Waking up after %lu secs.\n",
+ time - now);
+
+ rtc_time_to_tm(time, &tmp.time);
+ rtc_set_alarm(rtc_dev, &tmp);
+ cm_suspend_duration_ms += wakeup_ms;
+ return ret;
+ }
+ }
+
+ if (rtc_dev)
+ rtc_set_alarm(rtc_dev, &rtc_wkalarm_save);
+ return false;
+}
+
+/**
+ * cm_suspend_again - Determine whether suspend again or not
+ *
+ * Returns true if the system should be suspended again
+ * Returns false if the system should be woken up
+ */
+bool cm_suspend_again(void)
+{
+ struct charger_manager *cm;
+ bool ret = false;
+
+ if (!g_desc || !g_desc->rtc_only_wakeup || !g_desc->rtc_only_wakeup() ||
+ !cm_rtc_set)
+ return false;
+
+ if (cm_monitor())
+ goto out;
+
+ ret = true;
+ mutex_lock(&cm_list_mtx);
+ list_for_each_entry(cm, &cm_list, entry) {
+ if (cm->status_save_ext_pwr_inserted != is_ext_pwr_online(cm) ||
+ cm->status_save_batt != is_batt_present(cm))
+ ret = false;
+ }
+ mutex_unlock(&cm_list_mtx);
+
+ cm_rtc_set = cm_setup_timer();
+out:
+ /* It's about the time when the non-CM appointed timer goes off */
+ if (rtc_wkalarm_save.enabled) {
+ unsigned long now;
+ struct rtc_time tmp;
+
+ rtc_read_time(rtc_dev, &tmp);
+ rtc_tm_to_time(&tmp, &now);
+
+ if (rtc_wkalarm_save_time &&
+ now + CM_RTC_SMALL >= rtc_wkalarm_save_time)
+ return false;
+ }
+ return ret;
+}
+EXPORT_SYMBOL_GPL(cm_suspend_again);
+
+/**
+ * setup_charger_manager - initialize charger_global_desc data
+ * @gd: pointer to instance of charger_global_desc
+ */
+int setup_charger_manager(struct charger_global_desc *gd)
+{
+ if (!gd)
+ return -EINVAL;
+
+ if (rtc_dev)
+ rtc_class_close(rtc_dev);
+ rtc_dev = NULL;
+ g_desc = NULL;
+
+ if (!gd->rtc_only_wakeup) {
+ pr_err("The callback rtc_only_wakeup is not given.\n");
+ return -EINVAL;
+ }
+
+ if (gd->rtc_name) {
+ rtc_dev = rtc_class_open(gd->rtc_name);
+ if (IS_ERR_OR_NULL(rtc_dev)) {
+ rtc_dev = NULL;
+ /* Retry at probe. RTC may be not registered yet */
+ }
+ } else {
+ pr_warn("No wakeup timer is given for charger manager."
+ "In-suspend monitoring won't work.\n");
+ }
+
+ g_desc = gd;
+ return 0;
+}
+EXPORT_SYMBOL_GPL(setup_charger_manager);
+
+static int charger_manager_probe(struct platform_device *pdev)
+{
+ struct charger_desc *desc = dev_get_platdata(&pdev->dev);
+ struct charger_manager *cm;
+ int ret = 0, i = 0;
+ union power_supply_propval val;
+
+ if (g_desc && !rtc_dev && g_desc->rtc_name) {
+ rtc_dev = rtc_class_open(g_desc->rtc_name);
+ if (IS_ERR_OR_NULL(rtc_dev)) {
+ rtc_dev = NULL;
+ dev_err(&pdev->dev, "Cannot get RTC %s.\n",
+ g_desc->rtc_name);
+ ret = -ENODEV;
+ goto err_alloc;
+ }
+ }
+
+ if (!desc) {
+ dev_err(&pdev->dev, "No platform data (desc) found.\n");
+ ret = -ENODEV;
+ goto err_alloc;
+ }
+
+ cm = kzalloc(sizeof(struct charger_manager), GFP_KERNEL);
+ if (!cm) {
+ dev_err(&pdev->dev, "Cannot allocate memory.\n");
+ ret = -ENOMEM;
+ goto err_alloc;
+ }
+
+ /* Basic Values. Unspecified are Null or 0 */
+ cm->dev = &pdev->dev;
+ cm->desc = kzalloc(sizeof(struct charger_desc), GFP_KERNEL);
+ if (!cm->desc) {
+ dev_err(&pdev->dev, "Cannot allocate memory.\n");
+ ret = -ENOMEM;
+ goto err_alloc_desc;
+ }
+ memcpy(cm->desc, desc, sizeof(struct charger_desc));
+ cm->last_temp_mC = INT_MIN; /* denotes "unmeasured, yet" */
+
+ if (!desc->charger_regulators || desc->num_charger_regulators < 1) {
+ ret = -EINVAL;
+ dev_err(&pdev->dev, "charger_regulators undefined.\n");
+ goto err_no_charger;
+ }
+
+ if (!desc->psy_charger_stat || !desc->psy_charger_stat[0]) {
+ dev_err(&pdev->dev, "No power supply defined.\n");
+ ret = -EINVAL;
+ goto err_no_charger_stat;
+ }
+
+ /* Counting index only */
+ while (desc->psy_charger_stat[i])
+ i++;
+
+ cm->charger_stat = kzalloc(sizeof(struct power_supply *) * (i + 1),
+ GFP_KERNEL);
+ if (!cm->charger_stat) {
+ ret = -ENOMEM;
+ goto err_no_charger_stat;
+ }
+
+ for (i = 0; desc->psy_charger_stat[i]; i++) {
+ cm->charger_stat[i] = power_supply_get_by_name(
+ desc->psy_charger_stat[i]);
+ if (!cm->charger_stat[i]) {
+ dev_err(&pdev->dev, "Cannot find power supply "
+ "\"%s\"\n",
+ desc->psy_charger_stat[i]);
+ ret = -ENODEV;
+ goto err_chg_stat;
+ }
+ }
+
+ cm->fuel_gauge = power_supply_get_by_name(desc->psy_fuel_gauge);
+ if (!cm->fuel_gauge) {
+ dev_err(&pdev->dev, "Cannot find power supply \"%s\"\n",
+ desc->psy_fuel_gauge);
+ ret = -ENODEV;
+ goto err_chg_stat;
+ }
+
+ if (desc->polling_interval_ms == 0 ||
+ msecs_to_jiffies(desc->polling_interval_ms) <= CM_JIFFIES_SMALL) {
+ dev_err(&pdev->dev, "polling_interval_ms is too small\n");
+ ret = -EINVAL;
+ goto err_chg_stat;
+ }
+
+ if (!desc->temperature_out_of_range) {
+ dev_err(&pdev->dev, "there is no temperature_out_of_range\n");
+ ret = -EINVAL;
+ goto err_chg_stat;
+ }
+
+ platform_set_drvdata(pdev, cm);
+
+ memcpy(&cm->charger_psy, &psy_default,
+ sizeof(psy_default));
+ if (!desc->psy_name) {
+ strncpy(cm->psy_name_buf, psy_default.name,
+ PSY_NAME_MAX);
+ } else {
+ strncpy(cm->psy_name_buf, desc->psy_name, PSY_NAME_MAX);
+ }
+ cm->charger_psy.name = cm->psy_name_buf;
+
+ /* Allocate for psy properties because they may vary */
+ cm->charger_psy.properties = kzalloc(sizeof(enum power_supply_property)
+ * (ARRAY_SIZE(default_charger_props) +
+ NUM_CHARGER_PSY_OPTIONAL),
+ GFP_KERNEL);
+ if (!cm->charger_psy.properties) {
+ dev_err(&pdev->dev, "Cannot allocate for psy properties.\n");
+ ret = -ENOMEM;
+ goto err_chg_stat;
+ }
+ memcpy(cm->charger_psy.properties, default_charger_props,
+ sizeof(enum power_supply_property) *
+ ARRAY_SIZE(default_charger_props));
+ cm->charger_psy.num_properties = psy_default.num_properties;
+
+ /* Find which optional psy-properties are available */
+ if (!cm->fuel_gauge->get_property(cm->fuel_gauge,
+ POWER_SUPPLY_PROP_CHARGE_NOW, &val)) {
+ cm->charger_psy.properties[cm->charger_psy.num_properties] =
+ POWER_SUPPLY_PROP_CHARGE_NOW;
+ cm->charger_psy.num_properties++;
+ }
+ if (!cm->fuel_gauge->get_property(cm->fuel_gauge,
+ POWER_SUPPLY_PROP_CURRENT_NOW,
+ &val)) {
+ cm->charger_psy.properties[cm->charger_psy.num_properties] =
+ POWER_SUPPLY_PROP_CURRENT_NOW;
+ cm->charger_psy.num_properties++;
+ }
+ if (!desc->measure_battery_temp) {
+ cm->charger_psy.properties[cm->charger_psy.num_properties] =
+ POWER_SUPPLY_PROP_TEMP_AMBIENT;
+ cm->charger_psy.num_properties++;
+ }
+ if (desc->measure_battery_temp) {
+ cm->charger_psy.properties[cm->charger_psy.num_properties] =
+ POWER_SUPPLY_PROP_TEMP;
+ cm->charger_psy.num_properties++;
+ }
+
+ ret = power_supply_register(NULL, &cm->charger_psy);
+ if (ret) {
+ dev_err(&pdev->dev, "Cannot register charger-manager with"
+ " name \"%s\".\n", cm->charger_psy.name);
+ goto err_register;
+ }
+
+ ret = regulator_bulk_get(&pdev->dev, desc->num_charger_regulators,
+ desc->charger_regulators);
+ if (ret) {
+ dev_err(&pdev->dev, "Cannot get charger regulators.\n");
+ goto err_bulk_get;
+ }
+
+ ret = try_charger_enable(cm, true);
+ if (ret) {
+ dev_err(&pdev->dev, "Cannot enable charger regulators\n");
+ goto err_chg_enable;
+ }
+
+ /* Add to the list */
+ mutex_lock(&cm_list_mtx);
+ list_add(&cm->entry, &cm_list);
+ mutex_unlock(&cm_list_mtx);
+
+ return 0;
+
+err_chg_enable:
+ if (desc->charger_regulators)
+ regulator_bulk_free(desc->num_charger_regulators,
+ desc->charger_regulators);
+err_bulk_get:
+ power_supply_unregister(&cm->charger_psy);
+err_register:
+ kfree(cm->charger_psy.properties);
+err_chg_stat:
+ kfree(cm->charger_stat);
+err_no_charger_stat:
+err_no_charger:
+ kfree(cm->desc);
+err_alloc_desc:
+ kfree(cm);
+err_alloc:
+ return ret;
+}
+
+static int __devexit charger_manager_remove(struct platform_device *pdev)
+{
+ struct charger_manager *cm = platform_get_drvdata(pdev);
+ struct charger_desc *desc = cm->desc;
+
+ /* Remove from the list */
+ mutex_lock(&cm_list_mtx);
+ list_del(&cm->entry);
+ mutex_unlock(&cm_list_mtx);
+
+ if (desc->charger_regulators)
+ regulator_bulk_free(desc->num_charger_regulators,
+ desc->charger_regulators);
+
+ power_supply_unregister(&cm->charger_psy);
+ kfree(cm->charger_psy.properties);
+ kfree(cm->charger_stat);
+ kfree(cm->desc);
+ kfree(cm);
+
+ return 0;
+}
+
+const struct platform_device_id charger_manager_id[] = {
+ { "charger-manager", 0 },
+ { },
+};
+
+static int cm_suspend_prepare(struct device *dev)
+{
+ struct platform_device *pdev = container_of(dev, struct platform_device,
+ dev);
+ struct charger_manager *cm = platform_get_drvdata(pdev);
+
+ if (!cm_suspended) {
+ if (rtc_dev) {
+ struct rtc_time tmp;
+ unsigned long now;
+
+ rtc_read_alarm(rtc_dev, &rtc_wkalarm_save);
+ rtc_read_time(rtc_dev, &tmp);
+
+ if (rtc_wkalarm_save.enabled) {
+ rtc_tm_to_time(&rtc_wkalarm_save.time,
+ &rtc_wkalarm_save_time);
+ rtc_tm_to_time(&tmp, &now);
+ if (now > rtc_wkalarm_save_time)
+ rtc_wkalarm_save_time = 0;
+ } else {
+ rtc_wkalarm_save_time = 0;
+ }
+ }
+ cm_suspended = true;
+ }
+
+ cm->status_save_ext_pwr_inserted = is_ext_pwr_online(cm);
+ cm->status_save_batt = is_batt_present(cm);
+
+ if (!cm_rtc_set) {
+ cm_suspend_duration_ms = 0;
+ cm_rtc_set = cm_setup_timer();
+ }
+
+ return 0;
+}
+
+static void cm_suspend_complete(struct device *dev)
+{
+ struct platform_device *pdev = container_of(dev, struct platform_device,
+ dev);
+ struct charger_manager *cm = platform_get_drvdata(pdev);
+
+ if (cm_suspended) {
+ if (rtc_dev) {
+ struct rtc_wkalrm tmp;
+
+ rtc_read_alarm(rtc_dev, &tmp);
+ rtc_wkalarm_save.pending = tmp.pending;
+ rtc_set_alarm(rtc_dev, &rtc_wkalarm_save);
+ }
+ cm_suspended = false;
+ cm_rtc_set = false;
+ }
+
+ uevent_notify(cm, NULL);
+}
+
+static const struct dev_pm_ops charger_manager_pm = {
+ .prepare = cm_suspend_prepare,
+ .complete = cm_suspend_complete,
+};
+
+static struct platform_driver charger_manager_driver = {
+ .driver = {
+ .name = "charger-manager",
+ .owner = THIS_MODULE,
+ .pm = &charger_manager_pm,
+ },
+ .probe = charger_manager_probe,
+ .remove = __devexit_p(charger_manager_remove),
+ .id_table = charger_manager_id,
+};
+
+static int __init charger_manager_init(void)
+{
+ return platform_driver_register(&charger_manager_driver);
+}
+late_initcall(charger_manager_init);
+
+static void __exit charger_manager_cleanup(void)
+{
+ platform_driver_unregister(&charger_manager_driver);
+}
+module_exit(charger_manager_cleanup);
+
+MODULE_AUTHOR("MyungJoo Ham <myungjoo.ham@samsung.com>");
+MODULE_DESCRIPTION("Charger Manager");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("charger-manager");
diff --git a/drivers/power/collie_battery.c b/drivers/power/collie_battery.c
index 548d263..74c6b23 100644
--- a/drivers/power/collie_battery.c
+++ b/drivers/power/collie_battery.c
@@ -146,7 +146,7 @@
static irqreturn_t collie_bat_gpio_isr(int irq, void *data)
{
- pr_info("collie_bat_gpio irq: %d\n", gpio_get_value(irq_to_gpio(irq)));
+ pr_info("collie_bat_gpio irq\n");
schedule_work(&bat_work);
return IRQ_HANDLED;
}
@@ -277,18 +277,13 @@
.adc_temp_divider = -1,
};
-static struct {
- int gpio;
- char *name;
- bool output;
- int value;
-} gpios[] = {
- { COLLIE_GPIO_CO, "main battery full", 0, 0 },
- { COLLIE_GPIO_MAIN_BAT_LOW, "main battery low", 0, 0 },
- { COLLIE_GPIO_CHARGE_ON, "main charge on", 1, 0 },
- { COLLIE_GPIO_MBAT_ON, "main battery", 1, 0 },
- { COLLIE_GPIO_TMP_ON, "main battery temp", 1, 0 },
- { COLLIE_GPIO_BBAT_ON, "backup battery", 1, 0 },
+static struct gpio collie_batt_gpios[] = {
+ { COLLIE_GPIO_CO, GPIOF_IN, "main battery full" },
+ { COLLIE_GPIO_MAIN_BAT_LOW, GPIOF_IN, "main battery low" },
+ { COLLIE_GPIO_CHARGE_ON, GPIOF_OUT_INIT_LOW, "main charge on" },
+ { COLLIE_GPIO_MBAT_ON, GPIOF_OUT_INIT_LOW, "main battery" },
+ { COLLIE_GPIO_TMP_ON, GPIOF_OUT_INIT_LOW, "main battery temp" },
+ { COLLIE_GPIO_BBAT_ON, GPIOF_OUT_INIT_LOW, "backup battery" },
};
#ifdef CONFIG_PM
@@ -313,29 +308,16 @@
static int __devinit collie_bat_probe(struct ucb1x00_dev *dev)
{
int ret;
- int i;
if (!machine_is_collie())
return -ENODEV;
ucb = dev->ucb;
- for (i = 0; i < ARRAY_SIZE(gpios); i++) {
- ret = gpio_request(gpios[i].gpio, gpios[i].name);
- if (ret) {
- i--;
- goto err_gpio;
- }
-
- if (gpios[i].output)
- ret = gpio_direction_output(gpios[i].gpio,
- gpios[i].value);
- else
- ret = gpio_direction_input(gpios[i].gpio);
-
- if (ret)
- goto err_gpio;
- }
+ ret = gpio_request_array(collie_batt_gpios,
+ ARRAY_SIZE(collie_batt_gpios));
+ if (ret)
+ return ret;
mutex_init(&collie_bat_main.work_lock);
@@ -363,19 +345,12 @@
/* see comment in collie_bat_remove */
cancel_work_sync(&bat_work);
-
- i--;
-err_gpio:
- for (; i >= 0; i--)
- gpio_free(gpios[i].gpio);
-
+ gpio_free_array(collie_batt_gpios, ARRAY_SIZE(collie_batt_gpios));
return ret;
}
static void __devexit collie_bat_remove(struct ucb1x00_dev *dev)
{
- int i;
-
free_irq(gpio_to_irq(COLLIE_GPIO_CO), &collie_bat_main);
power_supply_unregister(&collie_bat_bu.psy);
@@ -387,9 +362,7 @@
* unregistered now.
*/
cancel_work_sync(&bat_work);
-
- for (i = ARRAY_SIZE(gpios) - 1; i >= 0; i--)
- gpio_free(gpios[i].gpio);
+ gpio_free_array(collie_batt_gpios, ARRAY_SIZE(collie_batt_gpios));
}
static struct ucb1x00_driver collie_bat_driver = {
diff --git a/drivers/power/da9030_battery.c b/drivers/power/da9030_battery.c
index d2c793cf..3fd3e95 100644
--- a/drivers/power/da9030_battery.c
+++ b/drivers/power/da9030_battery.c
@@ -588,18 +588,7 @@
.remove = da9030_battery_remove,
};
-static int da903x_battery_init(void)
-{
- return platform_driver_register(&da903x_battery_driver);
-}
-
-static void da903x_battery_exit(void)
-{
- platform_driver_unregister(&da903x_battery_driver);
-}
-
-module_init(da903x_battery_init);
-module_exit(da903x_battery_exit);
+module_platform_driver(da903x_battery_driver);
MODULE_DESCRIPTION("DA9030 battery charger driver");
MODULE_AUTHOR("Mike Rapoport, CompuLab");
diff --git a/drivers/power/da9052-battery.c b/drivers/power/da9052-battery.c
new file mode 100644
index 0000000..e8ea47a
--- /dev/null
+++ b/drivers/power/da9052-battery.c
@@ -0,0 +1,664 @@
+/*
+ * Batttery Driver for Dialog DA9052 PMICs
+ *
+ * Copyright(c) 2011 Dialog Semiconductor Ltd.
+ *
+ * Author: David Dajun Chen <dchen@diasemi.com>
+ *
+ * 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.
+ */
+
+#include <linux/delay.h>
+#include <linux/freezer.h>
+#include <linux/fs.h>
+#include <linux/jiffies.h>
+#include <linux/module.h>
+#include <linux/timer.h>
+#include <linux/uaccess.h>
+#include <linux/platform_device.h>
+#include <linux/power_supply.h>
+
+#include <linux/mfd/da9052/da9052.h>
+#include <linux/mfd/da9052/pdata.h>
+#include <linux/mfd/da9052/reg.h>
+
+/* STATIC CONFIGURATION */
+#define DA9052_BAT_CUTOFF_VOLT 2800
+#define DA9052_BAT_TSH 62000
+#define DA9052_BAT_LOW_CAP 4
+#define DA9052_AVG_SZ 4
+#define DA9052_VC_TBL_SZ 68
+#define DA9052_VC_TBL_REF_SZ 3
+
+#define DA9052_ISET_USB_MASK 0x0F
+#define DA9052_CHG_USB_ILIM_MASK 0x40
+#define DA9052_CHG_LIM_COLS 16
+
+#define DA9052_MEAN(x, y) ((x + y) / 2)
+
+enum charger_type_enum {
+ DA9052_NOCHARGER = 1,
+ DA9052_CHARGER,
+};
+
+static const u16 da9052_chg_current_lim[2][DA9052_CHG_LIM_COLS] = {
+ {70, 80, 90, 100, 110, 120, 400, 450,
+ 500, 550, 600, 650, 700, 900, 1100, 1300},
+ {80, 90, 100, 110, 120, 400, 450, 500,
+ 550, 600, 800, 1000, 1200, 1400, 1600, 1800},
+};
+
+static const u16 vc_tbl_ref[3] = {10, 25, 40};
+/* Lookup table for voltage vs capacity */
+static u32 const vc_tbl[3][68][2] = {
+ /* For temperature 10 degree Celsius */
+ {
+ {4082, 100}, {4036, 98},
+ {4020, 96}, {4008, 95},
+ {3997, 93}, {3983, 91},
+ {3964, 90}, {3943, 88},
+ {3926, 87}, {3912, 85},
+ {3900, 84}, {3890, 82},
+ {3881, 80}, {3873, 79},
+ {3865, 77}, {3857, 76},
+ {3848, 74}, {3839, 73},
+ {3829, 71}, {3820, 70},
+ {3811, 68}, {3802, 67},
+ {3794, 65}, {3785, 64},
+ {3778, 62}, {3770, 61},
+ {3763, 59}, {3756, 58},
+ {3750, 56}, {3744, 55},
+ {3738, 53}, {3732, 52},
+ {3727, 50}, {3722, 49},
+ {3717, 47}, {3712, 46},
+ {3708, 44}, {3703, 43},
+ {3700, 41}, {3696, 40},
+ {3693, 38}, {3691, 37},
+ {3688, 35}, {3686, 34},
+ {3683, 32}, {3681, 31},
+ {3678, 29}, {3675, 28},
+ {3672, 26}, {3669, 25},
+ {3665, 23}, {3661, 22},
+ {3656, 21}, {3651, 19},
+ {3645, 18}, {3639, 16},
+ {3631, 15}, {3622, 13},
+ {3611, 12}, {3600, 10},
+ {3587, 9}, {3572, 7},
+ {3548, 6}, {3503, 5},
+ {3420, 3}, {3268, 2},
+ {2992, 1}, {2746, 0}
+ },
+ /* For temperature 25 degree Celsius */
+ {
+ {4102, 100}, {4065, 98},
+ {4048, 96}, {4034, 95},
+ {4021, 93}, {4011, 92},
+ {4001, 90}, {3986, 88},
+ {3968, 87}, {3952, 85},
+ {3938, 84}, {3926, 82},
+ {3916, 81}, {3908, 79},
+ {3900, 77}, {3892, 76},
+ {3883, 74}, {3874, 73},
+ {3864, 71}, {3855, 70},
+ {3846, 68}, {3836, 67},
+ {3827, 65}, {3819, 64},
+ {3810, 62}, {3801, 61},
+ {3793, 59}, {3786, 58},
+ {3778, 56}, {3772, 55},
+ {3765, 53}, {3759, 52},
+ {3754, 50}, {3748, 49},
+ {3743, 47}, {3738, 46},
+ {3733, 44}, {3728, 43},
+ {3724, 41}, {3720, 40},
+ {3716, 38}, {3712, 37},
+ {3709, 35}, {3706, 34},
+ {3703, 33}, {3701, 31},
+ {3698, 30}, {3696, 28},
+ {3693, 27}, {3690, 25},
+ {3687, 24}, {3683, 22},
+ {3680, 21}, {3675, 19},
+ {3671, 18}, {3666, 17},
+ {3660, 15}, {3654, 14},
+ {3647, 12}, {3639, 11},
+ {3630, 9}, {3621, 8},
+ {3613, 6}, {3606, 5},
+ {3597, 4}, {3582, 2},
+ {3546, 1}, {2747, 0}
+ },
+ /* For temperature 40 degree Celsius */
+ {
+ {4114, 100}, {4081, 98},
+ {4065, 96}, {4050, 95},
+ {4036, 93}, {4024, 92},
+ {4013, 90}, {4002, 88},
+ {3990, 87}, {3976, 85},
+ {3962, 84}, {3950, 82},
+ {3939, 81}, {3930, 79},
+ {3921, 77}, {3912, 76},
+ {3902, 74}, {3893, 73},
+ {3883, 71}, {3874, 70},
+ {3865, 68}, {3856, 67},
+ {3847, 65}, {3838, 64},
+ {3829, 62}, {3820, 61},
+ {3812, 59}, {3803, 58},
+ {3795, 56}, {3787, 55},
+ {3780, 53}, {3773, 52},
+ {3767, 50}, {3761, 49},
+ {3756, 47}, {3751, 46},
+ {3746, 44}, {3741, 43},
+ {3736, 41}, {3732, 40},
+ {3728, 38}, {3724, 37},
+ {3720, 35}, {3716, 34},
+ {3713, 33}, {3710, 31},
+ {3707, 30}, {3704, 28},
+ {3701, 27}, {3698, 25},
+ {3695, 24}, {3691, 22},
+ {3686, 21}, {3681, 19},
+ {3676, 18}, {3671, 17},
+ {3666, 15}, {3661, 14},
+ {3655, 12}, {3648, 11},
+ {3640, 9}, {3632, 8},
+ {3622, 6}, {3616, 5},
+ {3611, 4}, {3604, 2},
+ {3594, 1}, {2747, 0}
+ }
+};
+
+struct da9052_battery {
+ struct da9052 *da9052;
+ struct power_supply psy;
+ struct notifier_block nb;
+ int charger_type;
+ int status;
+ int health;
+};
+
+static inline int volt_reg_to_mV(int value)
+{
+ return ((value * 1000) / 512) + 2500;
+}
+
+static inline int ichg_reg_to_mA(int value)
+{
+ return (value * 3900) / 1000;
+}
+
+static int da9052_read_chgend_current(struct da9052_battery *bat,
+ int *current_mA)
+{
+ int ret;
+
+ if (bat->status == POWER_SUPPLY_STATUS_DISCHARGING)
+ return -EINVAL;
+
+ ret = da9052_reg_read(bat->da9052, DA9052_ICHG_END_REG);
+ if (ret < 0)
+ return ret;
+
+ *current_mA = ichg_reg_to_mA(ret & DA9052_ICHGEND_ICHGEND);
+
+ return 0;
+}
+
+static int da9052_read_chg_current(struct da9052_battery *bat, int *current_mA)
+{
+ int ret;
+
+ if (bat->status == POWER_SUPPLY_STATUS_DISCHARGING)
+ return -EINVAL;
+
+ ret = da9052_reg_read(bat->da9052, DA9052_ICHG_AV_REG);
+ if (ret < 0)
+ return ret;
+
+ *current_mA = ichg_reg_to_mA(ret & DA9052_ICHGAV_ICHGAV);
+
+ return 0;
+}
+
+static int da9052_bat_check_status(struct da9052_battery *bat, int *status)
+{
+ u8 v[2] = {0, 0};
+ u8 bat_status;
+ u8 chg_end;
+ int ret;
+ int chg_current;
+ int chg_end_current;
+ bool dcinsel;
+ bool dcindet;
+ bool vbussel;
+ bool vbusdet;
+ bool dc;
+ bool vbus;
+
+ ret = da9052_group_read(bat->da9052, DA9052_STATUS_A_REG, 2, v);
+ if (ret < 0)
+ return ret;
+
+ bat_status = v[0];
+ chg_end = v[1];
+
+ dcinsel = bat_status & DA9052_STATUSA_DCINSEL;
+ dcindet = bat_status & DA9052_STATUSA_DCINDET;
+ vbussel = bat_status & DA9052_STATUSA_VBUSSEL;
+ vbusdet = bat_status & DA9052_STATUSA_VBUSDET;
+ dc = dcinsel && dcindet;
+ vbus = vbussel && vbusdet;
+
+ /* Preference to WALL(DCIN) charger unit */
+ if (dc || vbus) {
+ bat->charger_type = DA9052_CHARGER;
+
+ /* If charging end flag is set and Charging current is greater
+ * than charging end limit then battery is charging
+ */
+ if ((chg_end & DA9052_STATUSB_CHGEND) != 0) {
+ ret = da9052_read_chg_current(bat, &chg_current);
+ if (ret < 0)
+ return ret;
+ ret = da9052_read_chgend_current(bat, &chg_end_current);
+ if (ret < 0)
+ return ret;
+
+ if (chg_current >= chg_end_current)
+ bat->status = POWER_SUPPLY_STATUS_CHARGING;
+ else
+ bat->status = POWER_SUPPLY_STATUS_NOT_CHARGING;
+ } else {
+ /* If Charging end flag is cleared then battery is
+ * charging
+ */
+ bat->status = POWER_SUPPLY_STATUS_CHARGING;
+ }
+ } else if (dcindet || vbusdet) {
+ bat->charger_type = DA9052_CHARGER;
+ bat->status = POWER_SUPPLY_STATUS_NOT_CHARGING;
+ } else {
+ bat->charger_type = DA9052_NOCHARGER;
+ bat->status = POWER_SUPPLY_STATUS_DISCHARGING;
+ }
+
+ if (status != NULL)
+ *status = bat->status;
+ return 0;
+}
+
+static int da9052_bat_read_volt(struct da9052_battery *bat, int *volt_mV)
+{
+ int volt;
+
+ volt = da9052_adc_manual_read(bat->da9052, DA9052_ADC_MAN_MUXSEL_VBAT);
+ if (volt < 0)
+ return volt;
+
+ *volt_mV = volt_reg_to_mV(volt);
+
+ return 0;
+}
+
+static int da9052_bat_check_presence(struct da9052_battery *bat, int *illegal)
+{
+ int bat_temp;
+
+ bat_temp = da9052_adc_read_temp(bat->da9052);
+ if (bat_temp < 0)
+ return bat_temp;
+
+ if (bat_temp > DA9052_BAT_TSH)
+ *illegal = 1;
+ else
+ *illegal = 0;
+
+ return 0;
+}
+
+static int da9052_bat_interpolate(int vbat_lower, int vbat_upper,
+ int level_lower, int level_upper,
+ int bat_voltage)
+{
+ int tmp;
+
+ tmp = ((level_upper - level_lower) * 1000) / (vbat_upper - vbat_lower);
+ tmp = level_lower + (((bat_voltage - vbat_lower) * tmp) / 1000);
+
+ return tmp;
+}
+
+unsigned char da9052_determine_vc_tbl_index(unsigned char adc_temp)
+{
+ int i;
+
+ if (adc_temp <= vc_tbl_ref[0])
+ return 0;
+
+ if (adc_temp > vc_tbl_ref[DA9052_VC_TBL_REF_SZ - 1])
+ return DA9052_VC_TBL_REF_SZ - 1;
+
+ for (i = 0; i < DA9052_VC_TBL_REF_SZ; i++) {
+ if ((adc_temp > vc_tbl_ref[i]) &&
+ (adc_temp <= DA9052_MEAN(vc_tbl_ref[i], vc_tbl_ref[i + 1])))
+ return i;
+ if ((adc_temp > DA9052_MEAN(vc_tbl_ref[i], vc_tbl_ref[i + 1]))
+ && (adc_temp <= vc_tbl_ref[i]))
+ return i + 1;
+ }
+}
+
+static int da9052_bat_read_capacity(struct da9052_battery *bat, int *capacity)
+{
+ int adc_temp;
+ int bat_voltage;
+ int vbat_lower;
+ int vbat_upper;
+ int level_upper;
+ int level_lower;
+ int ret;
+ int flag;
+ int i = 0;
+ int j;
+
+ ret = da9052_bat_read_volt(bat, &bat_voltage);
+ if (ret < 0)
+ return ret;
+
+ adc_temp = da9052_adc_read_temp(bat->da9052);
+ if (adc_temp < 0)
+ return adc_temp;
+
+ i = da9052_determine_vc_tbl_index(adc_temp);
+
+ if (bat_voltage >= vc_tbl[i][0][0]) {
+ *capacity = 100;
+ return 0;
+ }
+ if (bat_voltage <= vc_tbl[i][DA9052_VC_TBL_SZ - 1][0]) {
+ *capacity = 0;
+ return 0;
+ }
+ flag = 0;
+
+ for (j = 0; j < (DA9052_VC_TBL_SZ-1); j++) {
+ if ((bat_voltage <= vc_tbl[i][j][0]) &&
+ (bat_voltage >= vc_tbl[i][j + 1][0])) {
+ vbat_upper = vc_tbl[i][j][0];
+ vbat_lower = vc_tbl[i][j + 1][0];
+ level_upper = vc_tbl[i][j][1];
+ level_lower = vc_tbl[i][j + 1][1];
+ flag = 1;
+ break;
+ }
+ }
+ if (!flag)
+ return -EIO;
+
+ *capacity = da9052_bat_interpolate(vbat_lower, vbat_upper, level_lower,
+ level_upper, bat_voltage);
+
+ return 0;
+}
+
+static int da9052_bat_check_health(struct da9052_battery *bat, int *health)
+{
+ int ret;
+ int bat_illegal;
+ int capacity;
+
+ ret = da9052_bat_check_presence(bat, &bat_illegal);
+ if (ret < 0)
+ return ret;
+
+ if (bat_illegal) {
+ bat->health = POWER_SUPPLY_HEALTH_UNKNOWN;
+ return 0;
+ }
+
+ if (bat->health != POWER_SUPPLY_HEALTH_OVERHEAT) {
+ ret = da9052_bat_read_capacity(bat, &capacity);
+ if (ret < 0)
+ return ret;
+ if (capacity < DA9052_BAT_LOW_CAP)
+ bat->health = POWER_SUPPLY_HEALTH_DEAD;
+ else
+ bat->health = POWER_SUPPLY_HEALTH_GOOD;
+ }
+
+ *health = bat->health;
+
+ return 0;
+}
+
+static irqreturn_t da9052_bat_irq(int irq, void *data)
+{
+ struct da9052_battery *bat = data;
+
+ irq -= bat->da9052->irq_base;
+
+ if (irq == DA9052_IRQ_CHGEND)
+ bat->status = POWER_SUPPLY_STATUS_FULL;
+ else
+ da9052_bat_check_status(bat, NULL);
+
+ if (irq == DA9052_IRQ_CHGEND || irq == DA9052_IRQ_DCIN ||
+ irq == DA9052_IRQ_VBUS || irq == DA9052_IRQ_TBAT) {
+ power_supply_changed(&bat->psy);
+ }
+
+ return IRQ_HANDLED;
+}
+
+static int da9052_USB_current_notifier(struct notifier_block *nb,
+ unsigned long events, void *data)
+{
+ u8 row;
+ u8 col;
+ int *current_mA = data;
+ int ret;
+ struct da9052_battery *bat = container_of(nb, struct da9052_battery,
+ nb);
+
+ if (bat->status == POWER_SUPPLY_STATUS_DISCHARGING)
+ return -EPERM;
+
+ ret = da9052_reg_read(bat->da9052, DA9052_CHGBUCK_REG);
+ if (ret & DA9052_CHG_USB_ILIM_MASK)
+ return -EPERM;
+
+ if (bat->da9052->chip_id == DA9052)
+ row = 0;
+ else
+ row = 1;
+
+ if (*current_mA < da9052_chg_current_lim[row][0] ||
+ *current_mA > da9052_chg_current_lim[row][DA9052_CHG_LIM_COLS - 1])
+ return -EINVAL;
+
+ for (col = 0; col <= DA9052_CHG_LIM_COLS - 1 ; col++) {
+ if (*current_mA <= da9052_chg_current_lim[row][col])
+ break;
+ }
+
+ return da9052_reg_update(bat->da9052, DA9052_ISET_REG,
+ DA9052_ISET_USB_MASK, col);
+}
+
+static int da9052_bat_get_property(struct power_supply *psy,
+ enum power_supply_property psp,
+ union power_supply_propval *val)
+{
+ int ret;
+ int illegal;
+ struct da9052_battery *bat = container_of(psy, struct da9052_battery,
+ psy);
+
+ ret = da9052_bat_check_presence(bat, &illegal);
+ if (ret < 0)
+ return ret;
+
+ if (illegal && psp != POWER_SUPPLY_PROP_PRESENT)
+ return -ENODEV;
+
+ switch (psp) {
+ case POWER_SUPPLY_PROP_STATUS:
+ ret = da9052_bat_check_status(bat, &val->intval);
+ break;
+ case POWER_SUPPLY_PROP_ONLINE:
+ val->intval =
+ (bat->charger_type == DA9052_NOCHARGER) ? 0 : 1;
+ break;
+ case POWER_SUPPLY_PROP_PRESENT:
+ ret = da9052_bat_check_presence(bat, &val->intval);
+ break;
+ case POWER_SUPPLY_PROP_HEALTH:
+ ret = da9052_bat_check_health(bat, &val->intval);
+ break;
+ case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
+ val->intval = DA9052_BAT_CUTOFF_VOLT * 1000;
+ break;
+ case POWER_SUPPLY_PROP_VOLTAGE_AVG:
+ ret = da9052_bat_read_volt(bat, &val->intval);
+ break;
+ case POWER_SUPPLY_PROP_CURRENT_AVG:
+ ret = da9052_read_chg_current(bat, &val->intval);
+ break;
+ case POWER_SUPPLY_PROP_CAPACITY:
+ ret = da9052_bat_read_capacity(bat, &val->intval);
+ break;
+ case POWER_SUPPLY_PROP_TEMP:
+ val->intval = da9052_adc_read_temp(bat->da9052);
+ ret = val->intval;
+ break;
+ case POWER_SUPPLY_PROP_TECHNOLOGY:
+ val->intval = POWER_SUPPLY_TECHNOLOGY_LION;
+ break;
+ default:
+ return -EINVAL;
+ }
+ return ret;
+}
+
+static enum power_supply_property da9052_bat_props[] = {
+ POWER_SUPPLY_PROP_STATUS,
+ POWER_SUPPLY_PROP_ONLINE,
+ POWER_SUPPLY_PROP_PRESENT,
+ POWER_SUPPLY_PROP_HEALTH,
+ POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
+ POWER_SUPPLY_PROP_VOLTAGE_AVG,
+ POWER_SUPPLY_PROP_CURRENT_AVG,
+ POWER_SUPPLY_PROP_CAPACITY,
+ POWER_SUPPLY_PROP_TEMP,
+ POWER_SUPPLY_PROP_TECHNOLOGY,
+};
+
+static struct power_supply template_battery = {
+ .name = "da9052-bat",
+ .type = POWER_SUPPLY_TYPE_BATTERY,
+ .properties = da9052_bat_props,
+ .num_properties = ARRAY_SIZE(da9052_bat_props),
+ .get_property = da9052_bat_get_property,
+};
+
+static const char *const da9052_bat_irqs[] = {
+ "BATT TEMP",
+ "DCIN DET",
+ "DCIN REM",
+ "VBUS DET",
+ "VBUS REM",
+ "CHG END",
+};
+
+static s32 __devinit da9052_bat_probe(struct platform_device *pdev)
+{
+ struct da9052_pdata *pdata;
+ struct da9052_battery *bat;
+ int ret;
+ int irq;
+ int i;
+
+ bat = kzalloc(sizeof(struct da9052_battery), GFP_KERNEL);
+ if (!bat)
+ return -ENOMEM;
+
+ bat->da9052 = dev_get_drvdata(pdev->dev.parent);
+ bat->psy = template_battery;
+ bat->charger_type = DA9052_NOCHARGER;
+ bat->status = POWER_SUPPLY_STATUS_UNKNOWN;
+ bat->health = POWER_SUPPLY_HEALTH_UNKNOWN;
+ bat->nb.notifier_call = da9052_USB_current_notifier;
+
+ pdata = bat->da9052->dev->platform_data;
+ if (pdata != NULL && pdata->use_for_apm)
+ bat->psy.use_for_apm = pdata->use_for_apm;
+ else
+ bat->psy.use_for_apm = 1;
+
+ for (i = 0; i < ARRAY_SIZE(da9052_bat_irqs); i++) {
+ irq = platform_get_irq_byname(pdev, da9052_bat_irqs[i]);
+ ret = request_threaded_irq(bat->da9052->irq_base + irq,
+ NULL, da9052_bat_irq,
+ IRQF_TRIGGER_LOW | IRQF_ONESHOT,
+ da9052_bat_irqs[i], bat);
+ if (ret != 0) {
+ dev_err(bat->da9052->dev,
+ "DA9052 failed to request %s IRQ %d: %d\n",
+ da9052_bat_irqs[i], irq, ret);
+ goto err;
+ }
+ }
+
+ ret = power_supply_register(&pdev->dev, &bat->psy);
+ if (ret)
+ goto err;
+
+ return 0;
+
+err:
+ for (; i >= 0; i--) {
+ irq = platform_get_irq_byname(pdev, da9052_bat_irqs[i]);
+ free_irq(bat->da9052->irq_base + irq, bat);
+ }
+ kfree(bat);
+ return ret;
+}
+static int __devexit da9052_bat_remove(struct platform_device *pdev)
+{
+ int i;
+ int irq;
+ struct da9052_battery *bat = platform_get_drvdata(pdev);
+
+ for (i = 0; i < ARRAY_SIZE(da9052_bat_irqs); i++) {
+ irq = platform_get_irq_byname(pdev, da9052_bat_irqs[i]);
+ free_irq(bat->da9052->irq_base + irq, bat);
+ }
+ power_supply_unregister(&bat->psy);
+
+ return 0;
+}
+
+static struct platform_driver da9052_bat_driver = {
+ .probe = da9052_bat_probe,
+ .remove = __devexit_p(da9052_bat_remove),
+ .driver = {
+ .name = "da9052-bat",
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init da9052_bat_init(void)
+{
+ return platform_driver_register(&da9052_bat_driver);
+}
+module_init(da9052_bat_init);
+
+static void __exit da9052_bat_exit(void)
+{
+ platform_driver_unregister(&da9052_bat_driver);
+}
+module_exit(da9052_bat_exit);
+
+MODULE_DESCRIPTION("DA9052 BAT Device Driver");
+MODULE_AUTHOR("David Dajun Chen <dchen@diasemi.com>");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:da9052-bat");
diff --git a/drivers/power/ds2760_battery.c b/drivers/power/ds2760_battery.c
index f2c9cc3..545874b 100644
--- a/drivers/power/ds2760_battery.c
+++ b/drivers/power/ds2760_battery.c
@@ -95,7 +95,11 @@
2880, /* Samsung */
2880, /* BYD */
2880, /* Lishen */
- 2880 /* NEC */
+ 2880, /* NEC */
+#ifdef CONFIG_MACH_H4700
+ 0,
+ 3600, /* HP iPAQ hx4700 3.7V 3600mAh (359114-001) */
+#endif
};
/* array is level at temps 0°C, 10°C, 20°C, 30°C, 40°C
@@ -637,18 +641,7 @@
.resume = ds2760_battery_resume,
};
-static int __init ds2760_battery_init(void)
-{
- return platform_driver_register(&ds2760_battery_driver);
-}
-
-static void __exit ds2760_battery_exit(void)
-{
- platform_driver_unregister(&ds2760_battery_driver);
-}
-
-module_init(ds2760_battery_init);
-module_exit(ds2760_battery_exit);
+module_platform_driver(ds2760_battery_driver);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Szabolcs Gyurko <szabolcs.gyurko@tlt.hu>, "
diff --git a/drivers/power/ds2780_battery.c b/drivers/power/ds2780_battery.c
index 91a783d..de31cae 100644
--- a/drivers/power/ds2780_battery.c
+++ b/drivers/power/ds2780_battery.c
@@ -841,29 +841,17 @@
return 0;
}
-MODULE_ALIAS("platform:ds2780-battery");
-
static struct platform_driver ds2780_battery_driver = {
.driver = {
.name = "ds2780-battery",
},
.probe = ds2780_battery_probe,
- .remove = ds2780_battery_remove,
+ .remove = __devexit_p(ds2780_battery_remove),
};
-static int __init ds2780_battery_init(void)
-{
- return platform_driver_register(&ds2780_battery_driver);
-}
-
-static void __exit ds2780_battery_exit(void)
-{
- platform_driver_unregister(&ds2780_battery_driver);
-}
-
-module_init(ds2780_battery_init);
-module_exit(ds2780_battery_exit);
+module_platform_driver(ds2780_battery_driver);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Clifton Barnes <cabarnes@indesign-llc.com>");
MODULE_DESCRIPTION("Maxim/Dallas DS2780 Stand-Alone Fuel Gauage IC driver");
+MODULE_ALIAS("platform:ds2780-battery");
diff --git a/drivers/power/gpio-charger.c b/drivers/power/gpio-charger.c
index a64b885..8672c91 100644
--- a/drivers/power/gpio-charger.c
+++ b/drivers/power/gpio-charger.c
@@ -185,17 +185,7 @@
},
};
-static int __init gpio_charger_init(void)
-{
- return platform_driver_register(&gpio_charger_driver);
-}
-module_init(gpio_charger_init);
-
-static void __exit gpio_charger_exit(void)
-{
- platform_driver_unregister(&gpio_charger_driver);
-}
-module_exit(gpio_charger_exit);
+module_platform_driver(gpio_charger_driver);
MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
MODULE_DESCRIPTION("Driver for chargers which report their online status through a GPIO");
diff --git a/drivers/power/intel_mid_battery.c b/drivers/power/intel_mid_battery.c
index 01fa671..d096497 100644
--- a/drivers/power/intel_mid_battery.c
+++ b/drivers/power/intel_mid_battery.c
@@ -779,18 +779,7 @@
.remove = __devexit_p(platform_pmic_battery_remove),
};
-static int __init platform_pmic_battery_module_init(void)
-{
- return platform_driver_register(&platform_pmic_battery_driver);
-}
-
-static void __exit platform_pmic_battery_module_exit(void)
-{
- platform_driver_unregister(&platform_pmic_battery_driver);
-}
-
-module_init(platform_pmic_battery_module_init);
-module_exit(platform_pmic_battery_module_exit);
+module_platform_driver(platform_pmic_battery_driver);
MODULE_AUTHOR("Nithish Mahalingam <nithish.mahalingam@intel.com>");
MODULE_DESCRIPTION("Intel Moorestown PMIC Battery Driver");
diff --git a/drivers/power/isp1704_charger.c b/drivers/power/isp1704_charger.c
index f6d72b4..b806667 100644
--- a/drivers/power/isp1704_charger.c
+++ b/drivers/power/isp1704_charger.c
@@ -79,7 +79,7 @@
{
struct isp1704_charger_data *board = isp->dev->platform_data;
- if (board->set_power)
+ if (board && board->set_power)
board->set_power(on);
}
@@ -494,17 +494,7 @@
.remove = __devexit_p(isp1704_charger_remove),
};
-static int __init isp1704_charger_init(void)
-{
- return platform_driver_register(&isp1704_charger_driver);
-}
-module_init(isp1704_charger_init);
-
-static void __exit isp1704_charger_exit(void)
-{
- platform_driver_unregister(&isp1704_charger_driver);
-}
-module_exit(isp1704_charger_exit);
+module_platform_driver(isp1704_charger_driver);
MODULE_ALIAS("platform:isp1704_charger");
MODULE_AUTHOR("Nokia Corporation");
diff --git a/drivers/power/jz4740-battery.c b/drivers/power/jz4740-battery.c
index 763f894..8dbc7bf 100644
--- a/drivers/power/jz4740-battery.c
+++ b/drivers/power/jz4740-battery.c
@@ -67,7 +67,7 @@
static long jz_battery_read_voltage(struct jz_battery *battery)
{
- unsigned long t;
+ long t;
unsigned long val;
long voltage;
@@ -441,17 +441,7 @@
},
};
-static int __init jz_battery_init(void)
-{
- return platform_driver_register(&jz_battery_driver);
-}
-module_init(jz_battery_init);
-
-static void __exit jz_battery_exit(void)
-{
- platform_driver_unregister(&jz_battery_driver);
-}
-module_exit(jz_battery_exit);
+module_platform_driver(jz_battery_driver);
MODULE_ALIAS("platform:jz4740-battery");
MODULE_LICENSE("GPL");
diff --git a/drivers/power/lp8727_charger.c b/drivers/power/lp8727_charger.c
new file mode 100644
index 0000000..b15b575
--- /dev/null
+++ b/drivers/power/lp8727_charger.c
@@ -0,0 +1,494 @@
+/*
+ * Driver for LP8727 Micro/Mini USB IC with intergrated charger
+ *
+ * Copyright (C) 2011 National Semiconductor
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/i2c.h>
+#include <linux/power_supply.h>
+#include <linux/lp8727.h>
+
+#define DEBOUNCE_MSEC 270
+
+/* Registers */
+#define CTRL1 0x1
+#define CTRL2 0x2
+#define SWCTRL 0x3
+#define INT1 0x4
+#define INT2 0x5
+#define STATUS1 0x6
+#define STATUS2 0x7
+#define CHGCTRL2 0x9
+
+/* CTRL1 register */
+#define CP_EN (1 << 0)
+#define ADC_EN (1 << 1)
+#define ID200_EN (1 << 4)
+
+/* CTRL2 register */
+#define CHGDET_EN (1 << 1)
+#define INT_EN (1 << 6)
+
+/* SWCTRL register */
+#define SW_DM1_DM (0x0 << 0)
+#define SW_DM1_U1 (0x1 << 0)
+#define SW_DM1_HiZ (0x7 << 0)
+#define SW_DP2_DP (0x0 << 3)
+#define SW_DP2_U2 (0x1 << 3)
+#define SW_DP2_HiZ (0x7 << 3)
+
+/* INT1 register */
+#define IDNO (0xF << 0)
+#define VBUS (1 << 4)
+
+/* STATUS1 register */
+#define CHGSTAT (3 << 4)
+#define CHPORT (1 << 6)
+#define DCPORT (1 << 7)
+
+/* STATUS2 register */
+#define TEMP_STAT (3 << 5)
+
+enum lp8727_dev_id {
+ ID_NONE,
+ ID_TA,
+ ID_DEDICATED_CHG,
+ ID_USB_CHG,
+ ID_USB_DS,
+ ID_MAX,
+};
+
+enum lp8727_chg_stat {
+ PRECHG,
+ CC,
+ CV,
+ EOC,
+};
+
+struct lp8727_psy {
+ struct power_supply ac;
+ struct power_supply usb;
+ struct power_supply batt;
+};
+
+struct lp8727_chg {
+ struct device *dev;
+ struct i2c_client *client;
+ struct mutex xfer_lock;
+ struct delayed_work work;
+ struct workqueue_struct *irqthread;
+ struct lp8727_platform_data *pdata;
+ struct lp8727_psy *psy;
+ struct lp8727_chg_param *chg_parm;
+ enum lp8727_dev_id devid;
+};
+
+static int lp8727_i2c_read(struct lp8727_chg *pchg, u8 reg, u8 *data, u8 len)
+{
+ s32 ret;
+
+ mutex_lock(&pchg->xfer_lock);
+ ret = i2c_smbus_read_i2c_block_data(pchg->client, reg, len, data);
+ mutex_unlock(&pchg->xfer_lock);
+
+ return (ret != len) ? -EIO : 0;
+}
+
+static int lp8727_i2c_write(struct lp8727_chg *pchg, u8 reg, u8 *data, u8 len)
+{
+ s32 ret;
+
+ mutex_lock(&pchg->xfer_lock);
+ ret = i2c_smbus_write_i2c_block_data(pchg->client, reg, len, data);
+ mutex_unlock(&pchg->xfer_lock);
+
+ return ret;
+}
+
+static inline int lp8727_i2c_read_byte(struct lp8727_chg *pchg, u8 reg,
+ u8 *data)
+{
+ return lp8727_i2c_read(pchg, reg, data, 1);
+}
+
+static inline int lp8727_i2c_write_byte(struct lp8727_chg *pchg, u8 reg,
+ u8 *data)
+{
+ return lp8727_i2c_write(pchg, reg, data, 1);
+}
+
+static int lp8727_is_charger_attached(const char *name, int id)
+{
+ if (name) {
+ if (!strcmp(name, "ac"))
+ return (id == ID_TA || id == ID_DEDICATED_CHG) ? 1 : 0;
+ else if (!strcmp(name, "usb"))
+ return (id == ID_USB_CHG) ? 1 : 0;
+ }
+
+ return (id >= ID_TA && id <= ID_USB_CHG) ? 1 : 0;
+}
+
+static void lp8727_init_device(struct lp8727_chg *pchg)
+{
+ u8 val;
+
+ val = ID200_EN | ADC_EN | CP_EN;
+ if (lp8727_i2c_write_byte(pchg, CTRL1, &val))
+ dev_err(pchg->dev, "i2c write err : addr=0x%.2x\n", CTRL1);
+
+ val = INT_EN | CHGDET_EN;
+ if (lp8727_i2c_write_byte(pchg, CTRL2, &val))
+ dev_err(pchg->dev, "i2c write err : addr=0x%.2x\n", CTRL2);
+}
+
+static int lp8727_is_dedicated_charger(struct lp8727_chg *pchg)
+{
+ u8 val;
+ lp8727_i2c_read_byte(pchg, STATUS1, &val);
+ return (val & DCPORT);
+}
+
+static int lp8727_is_usb_charger(struct lp8727_chg *pchg)
+{
+ u8 val;
+ lp8727_i2c_read_byte(pchg, STATUS1, &val);
+ return (val & CHPORT);
+}
+
+static void lp8727_ctrl_switch(struct lp8727_chg *pchg, u8 sw)
+{
+ u8 val = sw;
+ lp8727_i2c_write_byte(pchg, SWCTRL, &val);
+}
+
+static void lp8727_id_detection(struct lp8727_chg *pchg, u8 id, int vbusin)
+{
+ u8 devid = ID_NONE;
+ u8 swctrl = SW_DM1_HiZ | SW_DP2_HiZ;
+
+ switch (id) {
+ case 0x5:
+ devid = ID_TA;
+ pchg->chg_parm = &pchg->pdata->ac;
+ break;
+ case 0xB:
+ if (lp8727_is_dedicated_charger(pchg)) {
+ pchg->chg_parm = &pchg->pdata->ac;
+ devid = ID_DEDICATED_CHG;
+ } else if (lp8727_is_usb_charger(pchg)) {
+ pchg->chg_parm = &pchg->pdata->usb;
+ devid = ID_USB_CHG;
+ swctrl = SW_DM1_DM | SW_DP2_DP;
+ } else if (vbusin) {
+ devid = ID_USB_DS;
+ swctrl = SW_DM1_DM | SW_DP2_DP;
+ }
+ break;
+ default:
+ devid = ID_NONE;
+ pchg->chg_parm = NULL;
+ break;
+ }
+
+ pchg->devid = devid;
+ lp8727_ctrl_switch(pchg, swctrl);
+}
+
+static void lp8727_enable_chgdet(struct lp8727_chg *pchg)
+{
+ u8 val;
+
+ lp8727_i2c_read_byte(pchg, CTRL2, &val);
+ val |= CHGDET_EN;
+ lp8727_i2c_write_byte(pchg, CTRL2, &val);
+}
+
+static void lp8727_delayed_func(struct work_struct *_work)
+{
+ u8 intstat[2], idno, vbus;
+ struct lp8727_chg *pchg =
+ container_of(_work, struct lp8727_chg, work.work);
+
+ if (lp8727_i2c_read(pchg, INT1, intstat, 2)) {
+ dev_err(pchg->dev, "can not read INT registers\n");
+ return;
+ }
+
+ idno = intstat[0] & IDNO;
+ vbus = intstat[0] & VBUS;
+
+ lp8727_id_detection(pchg, idno, vbus);
+ lp8727_enable_chgdet(pchg);
+
+ power_supply_changed(&pchg->psy->ac);
+ power_supply_changed(&pchg->psy->usb);
+ power_supply_changed(&pchg->psy->batt);
+}
+
+static irqreturn_t lp8727_isr_func(int irq, void *ptr)
+{
+ struct lp8727_chg *pchg = ptr;
+ unsigned long delay = msecs_to_jiffies(DEBOUNCE_MSEC);
+
+ queue_delayed_work(pchg->irqthread, &pchg->work, delay);
+
+ return IRQ_HANDLED;
+}
+
+static void lp8727_intr_config(struct lp8727_chg *pchg)
+{
+ INIT_DELAYED_WORK(&pchg->work, lp8727_delayed_func);
+
+ pchg->irqthread = create_singlethread_workqueue("lp8727-irqthd");
+ if (!pchg->irqthread)
+ dev_err(pchg->dev, "can not create thread for lp8727\n");
+
+ if (request_threaded_irq(pchg->client->irq,
+ NULL,
+ lp8727_isr_func,
+ IRQF_TRIGGER_FALLING, "lp8727_irq", pchg)) {
+ dev_err(pchg->dev, "lp8727 irq can not be registered\n");
+ }
+}
+
+static enum power_supply_property lp8727_charger_prop[] = {
+ POWER_SUPPLY_PROP_ONLINE,
+};
+
+static enum power_supply_property lp8727_battery_prop[] = {
+ POWER_SUPPLY_PROP_STATUS,
+ POWER_SUPPLY_PROP_HEALTH,
+ POWER_SUPPLY_PROP_PRESENT,
+ POWER_SUPPLY_PROP_VOLTAGE_NOW,
+ POWER_SUPPLY_PROP_CAPACITY,
+ POWER_SUPPLY_PROP_TEMP,
+};
+
+static char *battery_supplied_to[] = {
+ "main_batt",
+};
+
+static int lp8727_charger_get_property(struct power_supply *psy,
+ enum power_supply_property psp,
+ union power_supply_propval *val)
+{
+ struct lp8727_chg *pchg = dev_get_drvdata(psy->dev->parent);
+
+ if (psp == POWER_SUPPLY_PROP_ONLINE)
+ val->intval = lp8727_is_charger_attached(psy->name,
+ pchg->devid);
+
+ return 0;
+}
+
+static int lp8727_battery_get_property(struct power_supply *psy,
+ enum power_supply_property psp,
+ union power_supply_propval *val)
+{
+ struct lp8727_chg *pchg = dev_get_drvdata(psy->dev->parent);
+ u8 read;
+
+ switch (psp) {
+ case POWER_SUPPLY_PROP_STATUS:
+ if (lp8727_is_charger_attached(psy->name, pchg->devid)) {
+ lp8727_i2c_read_byte(pchg, STATUS1, &read);
+ if (((read & CHGSTAT) >> 4) == EOC)
+ val->intval = POWER_SUPPLY_STATUS_FULL;
+ else
+ val->intval = POWER_SUPPLY_STATUS_CHARGING;
+ } else {
+ val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
+ }
+ break;
+ case POWER_SUPPLY_PROP_HEALTH:
+ lp8727_i2c_read_byte(pchg, STATUS2, &read);
+ read = (read & TEMP_STAT) >> 5;
+ if (read >= 0x1 && read <= 0x3)
+ val->intval = POWER_SUPPLY_HEALTH_OVERHEAT;
+ else
+ val->intval = POWER_SUPPLY_HEALTH_GOOD;
+ break;
+ case POWER_SUPPLY_PROP_PRESENT:
+ if (pchg->pdata->get_batt_present)
+ val->intval = pchg->pdata->get_batt_present();
+ break;
+ case POWER_SUPPLY_PROP_VOLTAGE_NOW:
+ if (pchg->pdata->get_batt_level)
+ val->intval = pchg->pdata->get_batt_level();
+ break;
+ case POWER_SUPPLY_PROP_CAPACITY:
+ if (pchg->pdata->get_batt_capacity)
+ val->intval = pchg->pdata->get_batt_capacity();
+ break;
+ case POWER_SUPPLY_PROP_TEMP:
+ if (pchg->pdata->get_batt_temp)
+ val->intval = pchg->pdata->get_batt_temp();
+ break;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+static void lp8727_charger_changed(struct power_supply *psy)
+{
+ struct lp8727_chg *pchg = dev_get_drvdata(psy->dev->parent);
+ u8 val;
+ u8 eoc_level, ichg;
+
+ if (lp8727_is_charger_attached(psy->name, pchg->devid)) {
+ if (pchg->chg_parm) {
+ eoc_level = pchg->chg_parm->eoc_level;
+ ichg = pchg->chg_parm->ichg;
+ val = (ichg << 4) | eoc_level;
+ lp8727_i2c_write_byte(pchg, CHGCTRL2, &val);
+ }
+ }
+}
+
+static int lp8727_register_psy(struct lp8727_chg *pchg)
+{
+ struct lp8727_psy *psy;
+
+ psy = kzalloc(sizeof(*psy), GFP_KERNEL);
+ if (!psy)
+ goto err_mem;
+
+ pchg->psy = psy;
+
+ psy->ac.name = "ac";
+ psy->ac.type = POWER_SUPPLY_TYPE_MAINS;
+ psy->ac.properties = lp8727_charger_prop;
+ psy->ac.num_properties = ARRAY_SIZE(lp8727_charger_prop);
+ psy->ac.get_property = lp8727_charger_get_property;
+ psy->ac.supplied_to = battery_supplied_to;
+ psy->ac.num_supplicants = ARRAY_SIZE(battery_supplied_to);
+
+ if (power_supply_register(pchg->dev, &psy->ac))
+ goto err_psy;
+
+ psy->usb.name = "usb";
+ psy->usb.type = POWER_SUPPLY_TYPE_USB;
+ psy->usb.properties = lp8727_charger_prop;
+ psy->usb.num_properties = ARRAY_SIZE(lp8727_charger_prop);
+ psy->usb.get_property = lp8727_charger_get_property;
+ psy->usb.supplied_to = battery_supplied_to;
+ psy->usb.num_supplicants = ARRAY_SIZE(battery_supplied_to);
+
+ if (power_supply_register(pchg->dev, &psy->usb))
+ goto err_psy;
+
+ psy->batt.name = "main_batt";
+ psy->batt.type = POWER_SUPPLY_TYPE_BATTERY;
+ psy->batt.properties = lp8727_battery_prop;
+ psy->batt.num_properties = ARRAY_SIZE(lp8727_battery_prop);
+ psy->batt.get_property = lp8727_battery_get_property;
+ psy->batt.external_power_changed = lp8727_charger_changed;
+
+ if (power_supply_register(pchg->dev, &psy->batt))
+ goto err_psy;
+
+ return 0;
+
+err_mem:
+ return -ENOMEM;
+err_psy:
+ kfree(psy);
+ return -EPERM;
+}
+
+static void lp8727_unregister_psy(struct lp8727_chg *pchg)
+{
+ struct lp8727_psy *psy = pchg->psy;
+
+ if (!psy)
+ return;
+
+ power_supply_unregister(&psy->ac);
+ power_supply_unregister(&psy->usb);
+ power_supply_unregister(&psy->batt);
+ kfree(psy);
+}
+
+static int lp8727_probe(struct i2c_client *cl, const struct i2c_device_id *id)
+{
+ struct lp8727_chg *pchg;
+ int ret;
+
+ if (!i2c_check_functionality(cl->adapter, I2C_FUNC_SMBUS_I2C_BLOCK))
+ return -EIO;
+
+ pchg = kzalloc(sizeof(*pchg), GFP_KERNEL);
+ if (!pchg)
+ return -ENOMEM;
+
+ pchg->client = cl;
+ pchg->dev = &cl->dev;
+ pchg->pdata = cl->dev.platform_data;
+ i2c_set_clientdata(cl, pchg);
+
+ mutex_init(&pchg->xfer_lock);
+
+ lp8727_init_device(pchg);
+ lp8727_intr_config(pchg);
+
+ ret = lp8727_register_psy(pchg);
+ if (ret)
+ dev_err(pchg->dev,
+ "can not register power supplies. err=%d", ret);
+
+ return 0;
+}
+
+static int __devexit lp8727_remove(struct i2c_client *cl)
+{
+ struct lp8727_chg *pchg = i2c_get_clientdata(cl);
+
+ lp8727_unregister_psy(pchg);
+ free_irq(pchg->client->irq, pchg);
+ flush_workqueue(pchg->irqthread);
+ destroy_workqueue(pchg->irqthread);
+ kfree(pchg);
+ return 0;
+}
+
+static const struct i2c_device_id lp8727_ids[] = {
+ {"lp8727", 0},
+};
+
+static struct i2c_driver lp8727_driver = {
+ .driver = {
+ .name = "lp8727",
+ },
+ .probe = lp8727_probe,
+ .remove = __devexit_p(lp8727_remove),
+ .id_table = lp8727_ids,
+};
+
+static int __init lp8727_init(void)
+{
+ return i2c_add_driver(&lp8727_driver);
+}
+
+static void __exit lp8727_exit(void)
+{
+ i2c_del_driver(&lp8727_driver);
+}
+
+module_init(lp8727_init);
+module_exit(lp8727_exit);
+
+MODULE_DESCRIPTION("National Semiconductor LP8727 charger driver");
+MODULE_AUTHOR
+ ("Woogyom Kim <milo.kim@ti.com>, Daniel Jeong <daniel.jeong@ti.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/power/max17042_battery.c b/drivers/power/max17042_battery.c
index 9f0183c..86acee2 100644
--- a/drivers/power/max17042_battery.c
+++ b/drivers/power/max17042_battery.c
@@ -85,55 +85,79 @@
{
struct max17042_chip *chip = container_of(psy,
struct max17042_chip, battery);
+ int ret;
switch (psp) {
case POWER_SUPPLY_PROP_PRESENT:
- val->intval = max17042_read_reg(chip->client,
- MAX17042_STATUS);
- if (val->intval & MAX17042_STATUS_BattAbsent)
+ ret = max17042_read_reg(chip->client, MAX17042_STATUS);
+ if (ret < 0)
+ return ret;
+
+ if (ret & MAX17042_STATUS_BattAbsent)
val->intval = 0;
else
val->intval = 1;
break;
case POWER_SUPPLY_PROP_CYCLE_COUNT:
- val->intval = max17042_read_reg(chip->client,
- MAX17042_Cycles);
+ ret = max17042_read_reg(chip->client, MAX17042_Cycles);
+ if (ret < 0)
+ return ret;
+
+ val->intval = ret;
break;
case POWER_SUPPLY_PROP_VOLTAGE_MAX:
- val->intval = max17042_read_reg(chip->client,
- MAX17042_MinMaxVolt);
- val->intval >>= 8;
+ ret = max17042_read_reg(chip->client, MAX17042_MinMaxVolt);
+ if (ret < 0)
+ return ret;
+
+ val->intval = ret >> 8;
val->intval *= 20000; /* Units of LSB = 20mV */
break;
case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
- val->intval = max17042_read_reg(chip->client,
- MAX17042_V_empty);
- val->intval >>= 7;
+ ret = max17042_read_reg(chip->client, MAX17042_V_empty);
+ if (ret < 0)
+ return ret;
+
+ val->intval = ret >> 7;
val->intval *= 10000; /* Units of LSB = 10mV */
break;
case POWER_SUPPLY_PROP_VOLTAGE_NOW:
- val->intval = max17042_read_reg(chip->client,
- MAX17042_VCELL) * 83; /* 1000 / 12 = 83 */
+ ret = max17042_read_reg(chip->client, MAX17042_VCELL);
+ if (ret < 0)
+ return ret;
+
+ val->intval = ret * 625 / 8;
break;
case POWER_SUPPLY_PROP_VOLTAGE_AVG:
- val->intval = max17042_read_reg(chip->client,
- MAX17042_AvgVCELL) * 83;
+ ret = max17042_read_reg(chip->client, MAX17042_AvgVCELL);
+ if (ret < 0)
+ return ret;
+
+ val->intval = ret * 625 / 8;
break;
case POWER_SUPPLY_PROP_CAPACITY:
- val->intval = max17042_read_reg(chip->client,
- MAX17042_SOC) / 256;
+ ret = max17042_read_reg(chip->client, MAX17042_SOC);
+ if (ret < 0)
+ return ret;
+
+ val->intval = ret >> 8;
break;
case POWER_SUPPLY_PROP_CHARGE_FULL:
- val->intval = max17042_read_reg(chip->client,
- MAX17042_RepSOC);
- if ((val->intval / 256) >= MAX17042_BATTERY_FULL)
+ ret = max17042_read_reg(chip->client, MAX17042_RepSOC);
+ if (ret < 0)
+ return ret;
+
+ if ((ret >> 8) >= MAX17042_BATTERY_FULL)
val->intval = 1;
- else if (val->intval >= 0)
+ else if (ret >= 0)
val->intval = 0;
break;
case POWER_SUPPLY_PROP_TEMP:
- val->intval = max17042_read_reg(chip->client,
- MAX17042_TEMP);
+ ret = max17042_read_reg(chip->client, MAX17042_TEMP);
+ if (ret < 0)
+ return ret;
+
+ val->intval = ret;
/* The value is signed. */
if (val->intval & 0x8000) {
val->intval = (0x7fff & ~val->intval) + 1;
@@ -145,24 +169,30 @@
break;
case POWER_SUPPLY_PROP_CURRENT_NOW:
if (chip->pdata->enable_current_sense) {
- val->intval = max17042_read_reg(chip->client,
- MAX17042_Current);
+ ret = max17042_read_reg(chip->client, MAX17042_Current);
+ if (ret < 0)
+ return ret;
+
+ val->intval = ret;
if (val->intval & 0x8000) {
/* Negative */
val->intval = ~val->intval & 0x7fff;
val->intval++;
val->intval *= -1;
}
- val->intval >>= 4;
- val->intval *= 1000000 * 25 / chip->pdata->r_sns;
+ val->intval *= 1562500 / chip->pdata->r_sns;
} else {
return -EINVAL;
}
break;
case POWER_SUPPLY_PROP_CURRENT_AVG:
if (chip->pdata->enable_current_sense) {
- val->intval = max17042_read_reg(chip->client,
- MAX17042_AvgCurrent);
+ ret = max17042_read_reg(chip->client,
+ MAX17042_AvgCurrent);
+ if (ret < 0)
+ return ret;
+
+ val->intval = ret;
if (val->intval & 0x8000) {
/* Negative */
val->intval = ~val->intval & 0x7fff;
@@ -210,6 +240,9 @@
if (!chip->pdata->enable_current_sense)
chip->battery.num_properties -= 2;
+ if (chip->pdata->r_sns == 0)
+ chip->pdata->r_sns = MAX17042_DEFAULT_SNS_RESISTOR;
+
ret = power_supply_register(&client->dev, &chip->battery);
if (ret) {
dev_err(&client->dev, "failed: power supply register\n");
@@ -226,9 +259,6 @@
max17042_write_reg(client, MAX17042_CGAIN, 0x0000);
max17042_write_reg(client, MAX17042_MiscCFG, 0x0003);
max17042_write_reg(client, MAX17042_LearnCFG, 0x0007);
- } else {
- if (chip->pdata->r_sns == 0)
- chip->pdata->r_sns = MAX17042_DEFAULT_SNS_RESISTOR;
}
return 0;
diff --git a/drivers/power/max8903_charger.c b/drivers/power/max8903_charger.c
index 2595145..3e23f43 100644
--- a/drivers/power/max8903_charger.c
+++ b/drivers/power/max8903_charger.c
@@ -374,19 +374,9 @@
},
};
-static int __init max8903_init(void)
-{
- return platform_driver_register(&max8903_driver);
-}
-module_init(max8903_init);
-
-static void __exit max8903_exit(void)
-{
- platform_driver_unregister(&max8903_driver);
-}
-module_exit(max8903_exit);
+module_platform_driver(max8903_driver);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("MAX8903 Charger Driver");
MODULE_AUTHOR("MyungJoo Ham <myungjoo.ham@samsung.com>");
-MODULE_ALIAS("max8903-charger");
+MODULE_ALIAS("platform:max8903-charger");
diff --git a/drivers/power/max8925_power.c b/drivers/power/max8925_power.c
index a70e16d..daa333b 100644
--- a/drivers/power/max8925_power.c
+++ b/drivers/power/max8925_power.c
@@ -78,6 +78,8 @@
unsigned batt_detect:1; /* detecing MB by ID pin */
unsigned topoff_threshold:2;
unsigned fast_charge:3;
+ unsigned no_temp_support:1;
+ unsigned no_insert_detect:1;
int (*set_charger) (int);
};
@@ -116,17 +118,7 @@
case MAX8925_IRQ_VCHG_DC_F:
info->ac_online = 0;
__set_charger(info, 0);
- dev_dbg(chip->dev, "Adapter is removal\n");
- break;
- case MAX8925_IRQ_VCHG_USB_R:
- info->usb_online = 1;
- __set_charger(info, 1);
- dev_dbg(chip->dev, "USB inserted\n");
- break;
- case MAX8925_IRQ_VCHG_USB_F:
- info->usb_online = 0;
- __set_charger(info, 0);
- dev_dbg(chip->dev, "USB is removal\n");
+ dev_dbg(chip->dev, "Adapter removed\n");
break;
case MAX8925_IRQ_VCHG_THM_OK_F:
/* Battery is not ready yet */
@@ -168,27 +160,33 @@
static int start_measure(struct max8925_power_info *info, int type)
{
unsigned char buf[2] = {0, 0};
+ int meas_cmd;
int meas_reg = 0, ret;
switch (type) {
case MEASURE_VCHG:
+ meas_cmd = MAX8925_CMD_VCHG;
meas_reg = MAX8925_ADC_VCHG;
break;
case MEASURE_VBBATT:
+ meas_cmd = MAX8925_CMD_VBBATT;
meas_reg = MAX8925_ADC_VBBATT;
break;
case MEASURE_VMBATT:
+ meas_cmd = MAX8925_CMD_VMBATT;
meas_reg = MAX8925_ADC_VMBATT;
break;
case MEASURE_ISNS:
+ meas_cmd = MAX8925_CMD_ISNS;
meas_reg = MAX8925_ADC_ISNS;
break;
default:
return -EINVAL;
}
+ max8925_reg_write(info->adc, meas_cmd, 0);
max8925_bulk_read(info->adc, meas_reg, 2, buf);
- ret = (buf[0] << 4) | (buf[1] >> 4);
+ ret = ((buf[0]<<8) | buf[1]) >> 4;
return ret;
}
@@ -208,7 +206,7 @@
if (info->ac_online) {
ret = start_measure(info, MEASURE_VCHG);
if (ret >= 0) {
- val->intval = ret << 1; /* unit is mV */
+ val->intval = ret * 2000; /* unit is uV */
goto out;
}
}
@@ -242,7 +240,7 @@
if (info->usb_online) {
ret = start_measure(info, MEASURE_VCHG);
if (ret >= 0) {
- val->intval = ret << 1; /* unit is mV */
+ val->intval = ret * 2000; /* unit is uV */
goto out;
}
}
@@ -266,7 +264,6 @@
union power_supply_propval *val)
{
struct max8925_power_info *info = dev_get_drvdata(psy->dev->parent);
- long long int tmp = 0;
int ret = 0;
switch (psp) {
@@ -277,7 +274,7 @@
if (info->bat_online) {
ret = start_measure(info, MEASURE_VMBATT);
if (ret >= 0) {
- val->intval = ret << 1; /* unit is mV */
+ val->intval = ret * 2000; /* unit is uV */
ret = 0;
break;
}
@@ -288,8 +285,8 @@
if (info->bat_online) {
ret = start_measure(info, MEASURE_ISNS);
if (ret >= 0) {
- tmp = (long long int)ret * 6250 / 4096 - 3125;
- ret = (int)tmp;
+ /* assume r_sns is 0.02 */
+ ret = ((ret * 6250) - 3125) /* uA */;
val->intval = 0;
if (ret > 0)
val->intval = ret; /* unit is mA */
@@ -365,13 +362,14 @@
int ret;
REQUEST_IRQ(MAX8925_IRQ_VCHG_DC_OVP, "ac-ovp");
- REQUEST_IRQ(MAX8925_IRQ_VCHG_DC_F, "ac-remove");
- REQUEST_IRQ(MAX8925_IRQ_VCHG_DC_R, "ac-insert");
- REQUEST_IRQ(MAX8925_IRQ_VCHG_USB_OVP, "usb-ovp");
- REQUEST_IRQ(MAX8925_IRQ_VCHG_USB_F, "usb-remove");
- REQUEST_IRQ(MAX8925_IRQ_VCHG_USB_R, "usb-insert");
- REQUEST_IRQ(MAX8925_IRQ_VCHG_THM_OK_R, "batt-temp-in-range");
- REQUEST_IRQ(MAX8925_IRQ_VCHG_THM_OK_F, "batt-temp-out-range");
+ if (!info->no_insert_detect) {
+ REQUEST_IRQ(MAX8925_IRQ_VCHG_DC_F, "ac-remove");
+ REQUEST_IRQ(MAX8925_IRQ_VCHG_DC_R, "ac-insert");
+ }
+ if (!info->no_temp_support) {
+ REQUEST_IRQ(MAX8925_IRQ_VCHG_THM_OK_R, "batt-temp-in-range");
+ REQUEST_IRQ(MAX8925_IRQ_VCHG_THM_OK_F, "batt-temp-out-range");
+ }
REQUEST_IRQ(MAX8925_IRQ_VCHG_SYSLOW_F, "vsys-high");
REQUEST_IRQ(MAX8925_IRQ_VCHG_SYSLOW_R, "vsys-low");
REQUEST_IRQ(MAX8925_IRQ_VCHG_RST, "charger-reset");
@@ -379,9 +377,15 @@
REQUEST_IRQ(MAX8925_IRQ_VCHG_TOPOFF, "charger-topoff");
REQUEST_IRQ(MAX8925_IRQ_VCHG_TMR_FAULT, "charger-timer-expire");
- info->ac_online = 0;
info->usb_online = 0;
info->bat_online = 0;
+
+ /* check for power - can miss interrupt at boot time */
+ if (start_measure(info, MEASURE_VCHG) * 2000 > 500000)
+ info->ac_online = 1;
+ else
+ info->ac_online = 0;
+
ret = max8925_reg_read(info->gpm, MAX8925_CHG_STATUS);
if (ret >= 0) {
/*
@@ -449,6 +453,8 @@
info->ac.properties = max8925_ac_props;
info->ac.num_properties = ARRAY_SIZE(max8925_ac_props);
info->ac.get_property = max8925_ac_get_prop;
+ info->ac.supplied_to = pdata->supplied_to;
+ info->ac.num_supplicants = pdata->num_supplicants;
ret = power_supply_register(&pdev->dev, &info->ac);
if (ret)
goto out;
@@ -459,6 +465,9 @@
info->usb.properties = max8925_usb_props;
info->usb.num_properties = ARRAY_SIZE(max8925_usb_props);
info->usb.get_property = max8925_usb_get_prop;
+ info->usb.supplied_to = pdata->supplied_to;
+ info->usb.num_supplicants = pdata->num_supplicants;
+
ret = power_supply_register(&pdev->dev, &info->usb);
if (ret)
goto out_usb;
@@ -478,6 +487,8 @@
info->topoff_threshold = pdata->topoff_threshold;
info->fast_charge = pdata->fast_charge;
info->set_charger = pdata->set_charger;
+ info->no_temp_support = pdata->no_temp_support;
+ info->no_insert_detect = pdata->no_insert_detect;
max8925_init_charger(chip, info);
return 0;
@@ -512,17 +523,7 @@
},
};
-static int __init max8925_power_init(void)
-{
- return platform_driver_register(&max8925_power_driver);
-}
-module_init(max8925_power_init);
-
-static void __exit max8925_power_exit(void)
-{
- platform_driver_unregister(&max8925_power_driver);
-}
-module_exit(max8925_power_exit);
+module_platform_driver(max8925_power_driver);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Power supply driver for MAX8925");
diff --git a/drivers/power/max8997_charger.c b/drivers/power/max8997_charger.c
index a23317d..6e88c5d 100644
--- a/drivers/power/max8997_charger.c
+++ b/drivers/power/max8997_charger.c
@@ -19,7 +19,6 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include <linux/module.h>
#include <linux/err.h>
#include <linux/module.h>
#include <linux/slab.h>
@@ -98,7 +97,7 @@
return -EINVAL;
if (pdata->eoc_mA) {
- u8 val = (pdata->eoc_mA - 50) / 10;
+ int val = (pdata->eoc_mA - 50) / 10;
if (val < 0)
val = 0;
if (val > 0xf)
@@ -179,6 +178,7 @@
static const struct platform_device_id max8997_battery_id[] = {
{ "max8997-battery", 0 },
+ { }
};
static struct platform_driver max8997_battery_driver = {
diff --git a/drivers/power/max8998_charger.c b/drivers/power/max8998_charger.c
index 93e3bb4..9b3f2bf5 100644
--- a/drivers/power/max8998_charger.c
+++ b/drivers/power/max8998_charger.c
@@ -154,6 +154,7 @@
case 0:
dev_dbg(max8998->dev,
"Full Timeout not set: leave it unchanged.\n");
+ break;
default:
dev_err(max8998->dev, "Invalid Full Timeout value\n");
ret = -EINVAL;
@@ -190,6 +191,7 @@
static const struct platform_device_id max8998_battery_id[] = {
{ "max8998-battery", TYPE_MAX8998 },
+ { }
};
static struct platform_driver max8998_battery_driver = {
@@ -202,17 +204,7 @@
.id_table = max8998_battery_id,
};
-static int __init max8998_battery_init(void)
-{
- return platform_driver_register(&max8998_battery_driver);
-}
-module_init(max8998_battery_init);
-
-static void __exit max8998_battery_cleanup(void)
-{
- platform_driver_unregister(&max8998_battery_driver);
-}
-module_exit(max8998_battery_cleanup);
+module_platform_driver(max8998_battery_driver);
MODULE_DESCRIPTION("MAXIM 8998 battery control driver");
MODULE_AUTHOR("MyungJoo Ham <myungjoo.ham@samsung.com>");
diff --git a/drivers/power/olpc_battery.c b/drivers/power/olpc_battery.c
index 0b0ff3a..7385092 100644
--- a/drivers/power/olpc_battery.c
+++ b/drivers/power/olpc_battery.c
@@ -519,29 +519,35 @@
* Initialisation
*********************************************************************/
-static struct platform_device *bat_pdev;
-
static struct power_supply olpc_bat = {
+ .name = "olpc-battery",
.get_property = olpc_bat_get_property,
.use_for_apm = 1,
};
-void olpc_battery_trigger_uevent(unsigned long cause)
+static int olpc_battery_suspend(struct platform_device *pdev,
+ pm_message_t state)
{
- if (cause & EC_SCI_SRC_ACPWR)
- kobject_uevent(&olpc_ac.dev->kobj, KOBJ_CHANGE);
- if (cause & (EC_SCI_SRC_BATERR|EC_SCI_SRC_BATSOC|EC_SCI_SRC_BATTERY))
- kobject_uevent(&olpc_bat.dev->kobj, KOBJ_CHANGE);
+ if (device_may_wakeup(olpc_ac.dev))
+ olpc_ec_wakeup_set(EC_SCI_SRC_ACPWR);
+ else
+ olpc_ec_wakeup_clear(EC_SCI_SRC_ACPWR);
+
+ if (device_may_wakeup(olpc_bat.dev))
+ olpc_ec_wakeup_set(EC_SCI_SRC_BATTERY | EC_SCI_SRC_BATSOC
+ | EC_SCI_SRC_BATERR);
+ else
+ olpc_ec_wakeup_clear(EC_SCI_SRC_BATTERY | EC_SCI_SRC_BATSOC
+ | EC_SCI_SRC_BATERR);
+
+ return 0;
}
-static int __init olpc_bat_init(void)
+static int __devinit olpc_battery_probe(struct platform_device *pdev)
{
- int ret = 0;
+ int ret;
uint8_t status;
- if (!olpc_platform_info.ecver)
- return -ENXIO;
-
/*
* We've seen a number of EC protocol changes; this driver requires
* the latest EC protocol, supported by 0x44 and above.
@@ -558,15 +564,10 @@
/* Ignore the status. It doesn't actually matter */
- bat_pdev = platform_device_register_simple("olpc-battery", 0, NULL, 0);
- if (IS_ERR(bat_pdev))
- return PTR_ERR(bat_pdev);
-
- ret = power_supply_register(&bat_pdev->dev, &olpc_ac);
+ ret = power_supply_register(&pdev->dev, &olpc_ac);
if (ret)
- goto ac_failed;
+ return ret;
- olpc_bat.name = bat_pdev->name;
if (olpc_board_at_least(olpc_board_pre(0xd0))) { /* XO-1.5 */
olpc_bat.properties = olpc_xo15_bat_props;
olpc_bat.num_properties = ARRAY_SIZE(olpc_xo15_bat_props);
@@ -575,7 +576,7 @@
olpc_bat.num_properties = ARRAY_SIZE(olpc_xo1_bat_props);
}
- ret = power_supply_register(&bat_pdev->dev, &olpc_bat);
+ ret = power_supply_register(&pdev->dev, &olpc_bat);
if (ret)
goto battery_failed;
@@ -587,7 +588,12 @@
if (ret)
goto error_failed;
- goto success;
+ if (olpc_ec_wakeup_available()) {
+ device_set_wakeup_capable(olpc_ac.dev, true);
+ device_set_wakeup_capable(olpc_bat.dev, true);
+ }
+
+ return 0;
error_failed:
device_remove_bin_file(olpc_bat.dev, &olpc_bat_eeprom);
@@ -595,23 +601,36 @@
power_supply_unregister(&olpc_bat);
battery_failed:
power_supply_unregister(&olpc_ac);
-ac_failed:
- platform_device_unregister(bat_pdev);
-success:
return ret;
}
-static void __exit olpc_bat_exit(void)
+static int __devexit olpc_battery_remove(struct platform_device *pdev)
{
device_remove_file(olpc_bat.dev, &olpc_bat_error);
device_remove_bin_file(olpc_bat.dev, &olpc_bat_eeprom);
power_supply_unregister(&olpc_bat);
power_supply_unregister(&olpc_ac);
- platform_device_unregister(bat_pdev);
+ return 0;
}
-module_init(olpc_bat_init);
-module_exit(olpc_bat_exit);
+static const struct of_device_id olpc_battery_ids[] __devinitconst = {
+ { .compatible = "olpc,xo1-battery" },
+ {}
+};
+MODULE_DEVICE_TABLE(of, olpc_battery_ids);
+
+static struct platform_driver olpc_battery_driver = {
+ .driver = {
+ .name = "olpc-battery",
+ .owner = THIS_MODULE,
+ .of_match_table = olpc_battery_ids,
+ },
+ .probe = olpc_battery_probe,
+ .remove = __devexit_p(olpc_battery_remove),
+ .suspend = olpc_battery_suspend,
+};
+
+module_platform_driver(olpc_battery_driver);
MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>");
MODULE_LICENSE("GPL");
diff --git a/drivers/power/pcf50633-charger.c b/drivers/power/pcf50633-charger.c
index 4fa52e1..3d1e9ef 100644
--- a/drivers/power/pcf50633-charger.c
+++ b/drivers/power/pcf50633-charger.c
@@ -474,17 +474,7 @@
.remove = __devexit_p(pcf50633_mbc_remove),
};
-static int __init pcf50633_mbc_init(void)
-{
- return platform_driver_register(&pcf50633_mbc_driver);
-}
-module_init(pcf50633_mbc_init);
-
-static void __exit pcf50633_mbc_exit(void)
-{
- platform_driver_unregister(&pcf50633_mbc_driver);
-}
-module_exit(pcf50633_mbc_exit);
+module_platform_driver(pcf50633_mbc_driver);
MODULE_AUTHOR("Balaji Rao <balajirrao@openmoko.org>");
MODULE_DESCRIPTION("PCF50633 mbc driver");
diff --git a/drivers/power/pda_power.c b/drivers/power/pda_power.c
index 69f8aa3..fd49689 100644
--- a/drivers/power/pda_power.c
+++ b/drivers/power/pda_power.c
@@ -14,6 +14,7 @@
#include <linux/platform_device.h>
#include <linux/err.h>
#include <linux/interrupt.h>
+#include <linux/notifier.h>
#include <linux/power_supply.h>
#include <linux/pda_power.h>
#include <linux/regulator/consumer.h>
@@ -40,7 +41,9 @@
#ifdef CONFIG_USB_OTG_UTILS
static struct otg_transceiver *transceiver;
+static struct notifier_block otg_nb;
#endif
+
static struct regulator *ac_draw;
enum {
@@ -222,7 +225,42 @@
#ifdef CONFIG_USB_OTG_UTILS
static int otg_is_usb_online(void)
{
- return (transceiver->state == OTG_STATE_B_PERIPHERAL);
+ return (transceiver->last_event == USB_EVENT_VBUS ||
+ transceiver->last_event == USB_EVENT_ENUMERATED);
+}
+
+static int otg_is_ac_online(void)
+{
+ return (transceiver->last_event == USB_EVENT_CHARGER);
+}
+
+static int otg_handle_notification(struct notifier_block *nb,
+ unsigned long event, void *unused)
+{
+ switch (event) {
+ case USB_EVENT_CHARGER:
+ ac_status = PDA_PSY_TO_CHANGE;
+ break;
+ case USB_EVENT_VBUS:
+ case USB_EVENT_ENUMERATED:
+ usb_status = PDA_PSY_TO_CHANGE;
+ break;
+ case USB_EVENT_NONE:
+ ac_status = PDA_PSY_TO_CHANGE;
+ usb_status = PDA_PSY_TO_CHANGE;
+ break;
+ default:
+ return NOTIFY_OK;
+ }
+
+ /*
+ * Wait a bit before reading ac/usb line status and setting charger,
+ * because ac/usb status readings may lag from irq.
+ */
+ mod_timer(&charger_timer,
+ jiffies + msecs_to_jiffies(pdata->wait_for_status));
+
+ return NOTIFY_OK;
}
#endif
@@ -282,6 +320,16 @@
ret = PTR_ERR(ac_draw);
}
+#ifdef CONFIG_USB_OTG_UTILS
+ transceiver = otg_get_transceiver();
+ if (transceiver && !pdata->is_usb_online) {
+ pdata->is_usb_online = otg_is_usb_online;
+ }
+ if (transceiver && !pdata->is_ac_online) {
+ pdata->is_ac_online = otg_is_ac_online;
+ }
+#endif
+
if (pdata->is_ac_online) {
ret = power_supply_register(&pdev->dev, &pda_psy_ac);
if (ret) {
@@ -303,13 +351,6 @@
}
}
-#ifdef CONFIG_USB_OTG_UTILS
- transceiver = otg_get_transceiver();
- if (transceiver && !pdata->is_usb_online) {
- pdata->is_usb_online = otg_is_usb_online;
- }
-#endif
-
if (pdata->is_usb_online) {
ret = power_supply_register(&pdev->dev, &pda_psy_usb);
if (ret) {
@@ -331,6 +372,18 @@
}
}
+#ifdef CONFIG_USB_OTG_UTILS
+ if (transceiver && pdata->use_otg_notifier) {
+ otg_nb.notifier_call = otg_handle_notification;
+ ret = otg_register_notifier(transceiver, &otg_nb);
+ if (ret) {
+ dev_err(dev, "failure to register otg notifier\n");
+ goto otg_reg_notifier_failed;
+ }
+ polling = 0;
+ }
+#endif
+
if (polling) {
dev_dbg(dev, "will poll for status\n");
setup_timer(&polling_timer, polling_timer_func, 0);
@@ -343,6 +396,11 @@
return 0;
+#ifdef CONFIG_USB_OTG_UTILS
+otg_reg_notifier_failed:
+ if (pdata->is_usb_online && usb_irq)
+ free_irq(usb_irq->start, &pda_psy_usb);
+#endif
usb_irq_failed:
if (pdata->is_usb_online)
power_supply_unregister(&pda_psy_usb);
@@ -440,8 +498,6 @@
#define pda_power_resume NULL
#endif /* CONFIG_PM */
-MODULE_ALIAS("platform:pda-power");
-
static struct platform_driver pda_power_pdrv = {
.driver = {
.name = "pda-power",
@@ -452,17 +508,8 @@
.resume = pda_power_resume,
};
-static int __init pda_power_init(void)
-{
- return platform_driver_register(&pda_power_pdrv);
-}
+module_platform_driver(pda_power_pdrv);
-static void __exit pda_power_exit(void)
-{
- platform_driver_unregister(&pda_power_pdrv);
-}
-
-module_init(pda_power_init);
-module_exit(pda_power_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Anton Vorontsov <cbou@mail.ru>");
+MODULE_ALIAS("platform:pda-power");
diff --git a/drivers/power/power_supply_core.c b/drivers/power/power_supply_core.c
index 329b46b..6ad6127 100644
--- a/drivers/power/power_supply_core.c
+++ b/drivers/power/power_supply_core.c
@@ -98,7 +98,9 @@
{
union power_supply_propval ret = {0,};
struct power_supply *psy = dev_get_drvdata(dev);
+ unsigned int *count = data;
+ (*count)++;
if (psy->type != POWER_SUPPLY_TYPE_BATTERY) {
if (psy->get_property(psy, POWER_SUPPLY_PROP_ONLINE, &ret))
return 0;
@@ -111,10 +113,18 @@
int power_supply_is_system_supplied(void)
{
int error;
+ unsigned int count = 0;
- error = class_for_each_device(power_supply_class, NULL, NULL,
+ error = class_for_each_device(power_supply_class, NULL, &count,
__power_supply_is_system_supplied);
+ /*
+ * If no power class device was found at all, most probably we are
+ * running on a desktop system, so assume we are on mains power.
+ */
+ if (count == 0)
+ return 1;
+
return error;
}
EXPORT_SYMBOL_GPL(power_supply_is_system_supplied);
@@ -147,6 +157,12 @@
}
EXPORT_SYMBOL_GPL(power_supply_get_by_name);
+int power_supply_powers(struct power_supply *psy, struct device *dev)
+{
+ return sysfs_create_link(&psy->dev->kobj, &dev->kobj, "powers");
+}
+EXPORT_SYMBOL_GPL(power_supply_powers);
+
static void power_supply_dev_release(struct device *dev)
{
pr_debug("device: '%s': %s\n", dev_name(dev), __func__);
@@ -202,6 +218,7 @@
void power_supply_unregister(struct power_supply *psy)
{
cancel_work_sync(&psy->changed_work);
+ sysfs_remove_link(&psy->dev->kobj, "powers");
power_supply_remove_triggers(psy);
device_unregister(psy->dev);
}
diff --git a/drivers/power/power_supply_sysfs.c b/drivers/power/power_supply_sysfs.c
index e95cd65..b52b57c 100644
--- a/drivers/power/power_supply_sysfs.c
+++ b/drivers/power/power_supply_sysfs.c
@@ -43,7 +43,7 @@
struct device_attribute *attr,
char *buf) {
static char *type_text[] = {
- "Battery", "UPS", "Mains", "USB",
+ "Unknown", "Battery", "UPS", "Mains", "USB",
"USB_DCP", "USB_CDP", "USB_ACA"
};
static char *status_text[] = {
@@ -63,6 +63,9 @@
static char *capacity_level_text[] = {
"Unknown", "Critical", "Low", "Normal", "High", "Full"
};
+ static char *scope_text[] = {
+ "Unknown", "System", "Device"
+ };
ssize_t ret = 0;
struct power_supply *psy = dev_get_drvdata(dev);
const ptrdiff_t off = attr - power_supply_attrs;
@@ -78,8 +81,8 @@
dev_dbg(dev, "driver has no data for `%s' property\n",
attr->attr.name);
else if (ret != -ENODEV)
- dev_err(dev, "driver failed to report `%s' property\n",
- attr->attr.name);
+ dev_err(dev, "driver failed to report `%s' property: %zd\n",
+ attr->attr.name, ret);
return ret;
}
@@ -95,6 +98,8 @@
return sprintf(buf, "%s\n", capacity_level_text[value.intval]);
else if (off == POWER_SUPPLY_PROP_TYPE)
return sprintf(buf, "%s\n", type_text[value.intval]);
+ else if (off == POWER_SUPPLY_PROP_SCOPE)
+ return sprintf(buf, "%s\n", scope_text[value.intval]);
else if (off >= POWER_SUPPLY_PROP_MODEL_NAME)
return sprintf(buf, "%s\n", value.strval);
@@ -167,6 +172,7 @@
POWER_SUPPLY_ATTR(time_to_full_now),
POWER_SUPPLY_ATTR(time_to_full_avg),
POWER_SUPPLY_ATTR(type),
+ POWER_SUPPLY_ATTR(scope),
/* Properties of type `const char *' */
POWER_SUPPLY_ATTR(model_name),
POWER_SUPPLY_ATTR(manufacturer),
diff --git a/drivers/power/s3c_adc_battery.c b/drivers/power/s3c_adc_battery.c
index d32d0d7..8b804a5 100644
--- a/drivers/power/s3c_adc_battery.c
+++ b/drivers/power/s3c_adc_battery.c
@@ -47,6 +47,22 @@
msecs_to_jiffies(JITTER_DELAY));
}
+static int gather_samples(struct s3c_adc_client *client, int num, int channel)
+{
+ int value, i;
+
+ /* default to 1 if nothing is set */
+ if (num < 1)
+ num = 1;
+
+ value = 0;
+ for (i = 0; i < num; i++)
+ value += s3c_adc_read(client, channel);
+ value /= num;
+
+ return value;
+}
+
static enum power_supply_property s3c_adc_backup_bat_props[] = {
POWER_SUPPLY_PROP_VOLTAGE_NOW,
POWER_SUPPLY_PROP_VOLTAGE_MIN,
@@ -67,7 +83,8 @@
if (bat->volt_value < 0 ||
jiffies_to_msecs(jiffies - bat->timestamp) >
BAT_POLL_INTERVAL) {
- bat->volt_value = s3c_adc_read(bat->client,
+ bat->volt_value = gather_samples(bat->client,
+ bat->pdata->backup_volt_samples,
bat->pdata->backup_volt_channel);
bat->volt_value *= bat->pdata->backup_volt_mult;
bat->timestamp = jiffies;
@@ -139,9 +156,11 @@
if (bat->volt_value < 0 || bat->cur_value < 0 ||
jiffies_to_msecs(jiffies - bat->timestamp) >
BAT_POLL_INTERVAL) {
- bat->volt_value = s3c_adc_read(bat->client,
+ bat->volt_value = gather_samples(bat->client,
+ bat->pdata->volt_samples,
bat->pdata->volt_channel) * bat->pdata->volt_mult;
- bat->cur_value = s3c_adc_read(bat->client,
+ bat->cur_value = gather_samples(bat->client,
+ bat->pdata->current_samples,
bat->pdata->current_channel) * bat->pdata->current_mult;
bat->timestamp = jiffies;
}
@@ -421,17 +440,7 @@
.resume = s3c_adc_bat_resume,
};
-static int __init s3c_adc_bat_init(void)
-{
- return platform_driver_register(&s3c_adc_bat_driver);
-}
-module_init(s3c_adc_bat_init);
-
-static void __exit s3c_adc_bat_exit(void)
-{
- platform_driver_unregister(&s3c_adc_bat_driver);
-}
-module_exit(s3c_adc_bat_exit);
+module_platform_driver(s3c_adc_bat_driver);
MODULE_AUTHOR("Vasily Khoruzhick <anarsoul@gmail.com>");
MODULE_DESCRIPTION("iPAQ H1930/H1940/RX1950 battery controller driver");
diff --git a/drivers/power/sbs-battery.c b/drivers/power/sbs-battery.c
new file mode 100644
index 0000000..9ff8af0
--- /dev/null
+++ b/drivers/power/sbs-battery.c
@@ -0,0 +1,869 @@
+/*
+ * Gas Gauge driver for SBS Compliant Batteries
+ *
+ * Copyright (c) 2010, NVIDIA Corporation.
+ *
+ * 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 Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/err.h>
+#include <linux/power_supply.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/gpio.h>
+
+#include <linux/power/sbs-battery.h>
+
+enum {
+ REG_MANUFACTURER_DATA,
+ REG_TEMPERATURE,
+ REG_VOLTAGE,
+ REG_CURRENT,
+ REG_CAPACITY,
+ REG_TIME_TO_EMPTY,
+ REG_TIME_TO_FULL,
+ REG_STATUS,
+ REG_CYCLE_COUNT,
+ REG_SERIAL_NUMBER,
+ REG_REMAINING_CAPACITY,
+ REG_REMAINING_CAPACITY_CHARGE,
+ REG_FULL_CHARGE_CAPACITY,
+ REG_FULL_CHARGE_CAPACITY_CHARGE,
+ REG_DESIGN_CAPACITY,
+ REG_DESIGN_CAPACITY_CHARGE,
+ REG_DESIGN_VOLTAGE,
+};
+
+/* Battery Mode defines */
+#define BATTERY_MODE_OFFSET 0x03
+#define BATTERY_MODE_MASK 0x8000
+enum sbs_battery_mode {
+ BATTERY_MODE_AMPS,
+ BATTERY_MODE_WATTS
+};
+
+/* manufacturer access defines */
+#define MANUFACTURER_ACCESS_STATUS 0x0006
+#define MANUFACTURER_ACCESS_SLEEP 0x0011
+
+/* battery status value bits */
+#define BATTERY_DISCHARGING 0x40
+#define BATTERY_FULL_CHARGED 0x20
+#define BATTERY_FULL_DISCHARGED 0x10
+
+#define SBS_DATA(_psp, _addr, _min_value, _max_value) { \
+ .psp = _psp, \
+ .addr = _addr, \
+ .min_value = _min_value, \
+ .max_value = _max_value, \
+}
+
+static const struct chip_data {
+ enum power_supply_property psp;
+ u8 addr;
+ int min_value;
+ int max_value;
+} sbs_data[] = {
+ [REG_MANUFACTURER_DATA] =
+ SBS_DATA(POWER_SUPPLY_PROP_PRESENT, 0x00, 0, 65535),
+ [REG_TEMPERATURE] =
+ SBS_DATA(POWER_SUPPLY_PROP_TEMP, 0x08, 0, 65535),
+ [REG_VOLTAGE] =
+ SBS_DATA(POWER_SUPPLY_PROP_VOLTAGE_NOW, 0x09, 0, 20000),
+ [REG_CURRENT] =
+ SBS_DATA(POWER_SUPPLY_PROP_CURRENT_NOW, 0x0A, -32768, 32767),
+ [REG_CAPACITY] =
+ SBS_DATA(POWER_SUPPLY_PROP_CAPACITY, 0x0E, 0, 100),
+ [REG_REMAINING_CAPACITY] =
+ SBS_DATA(POWER_SUPPLY_PROP_ENERGY_NOW, 0x0F, 0, 65535),
+ [REG_REMAINING_CAPACITY_CHARGE] =
+ SBS_DATA(POWER_SUPPLY_PROP_CHARGE_NOW, 0x0F, 0, 65535),
+ [REG_FULL_CHARGE_CAPACITY] =
+ SBS_DATA(POWER_SUPPLY_PROP_ENERGY_FULL, 0x10, 0, 65535),
+ [REG_FULL_CHARGE_CAPACITY_CHARGE] =
+ SBS_DATA(POWER_SUPPLY_PROP_CHARGE_FULL, 0x10, 0, 65535),
+ [REG_TIME_TO_EMPTY] =
+ SBS_DATA(POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG, 0x12, 0, 65535),
+ [REG_TIME_TO_FULL] =
+ SBS_DATA(POWER_SUPPLY_PROP_TIME_TO_FULL_AVG, 0x13, 0, 65535),
+ [REG_STATUS] =
+ SBS_DATA(POWER_SUPPLY_PROP_STATUS, 0x16, 0, 65535),
+ [REG_CYCLE_COUNT] =
+ SBS_DATA(POWER_SUPPLY_PROP_CYCLE_COUNT, 0x17, 0, 65535),
+ [REG_DESIGN_CAPACITY] =
+ SBS_DATA(POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN, 0x18, 0, 65535),
+ [REG_DESIGN_CAPACITY_CHARGE] =
+ SBS_DATA(POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN, 0x18, 0, 65535),
+ [REG_DESIGN_VOLTAGE] =
+ SBS_DATA(POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN, 0x19, 0, 65535),
+ [REG_SERIAL_NUMBER] =
+ SBS_DATA(POWER_SUPPLY_PROP_SERIAL_NUMBER, 0x1C, 0, 65535),
+};
+
+static enum power_supply_property sbs_properties[] = {
+ POWER_SUPPLY_PROP_STATUS,
+ POWER_SUPPLY_PROP_HEALTH,
+ POWER_SUPPLY_PROP_PRESENT,
+ POWER_SUPPLY_PROP_TECHNOLOGY,
+ POWER_SUPPLY_PROP_CYCLE_COUNT,
+ POWER_SUPPLY_PROP_VOLTAGE_NOW,
+ POWER_SUPPLY_PROP_CURRENT_NOW,
+ POWER_SUPPLY_PROP_CAPACITY,
+ POWER_SUPPLY_PROP_TEMP,
+ POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG,
+ POWER_SUPPLY_PROP_TIME_TO_FULL_AVG,
+ POWER_SUPPLY_PROP_SERIAL_NUMBER,
+ POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN,
+ POWER_SUPPLY_PROP_ENERGY_NOW,
+ POWER_SUPPLY_PROP_ENERGY_FULL,
+ POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN,
+ POWER_SUPPLY_PROP_CHARGE_NOW,
+ POWER_SUPPLY_PROP_CHARGE_FULL,
+ POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
+};
+
+struct sbs_info {
+ struct i2c_client *client;
+ struct power_supply power_supply;
+ struct sbs_platform_data *pdata;
+ bool is_present;
+ bool gpio_detect;
+ bool enable_detection;
+ int irq;
+ int last_state;
+ int poll_time;
+ struct delayed_work work;
+ int ignore_changes;
+};
+
+static int sbs_read_word_data(struct i2c_client *client, u8 address)
+{
+ struct sbs_info *chip = i2c_get_clientdata(client);
+ s32 ret = 0;
+ int retries = 1;
+
+ if (chip->pdata)
+ retries = max(chip->pdata->i2c_retry_count + 1, 1);
+
+ while (retries > 0) {
+ ret = i2c_smbus_read_word_data(client, address);
+ if (ret >= 0)
+ break;
+ retries--;
+ }
+
+ if (ret < 0) {
+ dev_dbg(&client->dev,
+ "%s: i2c read at address 0x%x failed\n",
+ __func__, address);
+ return ret;
+ }
+
+ return le16_to_cpu(ret);
+}
+
+static int sbs_write_word_data(struct i2c_client *client, u8 address,
+ u16 value)
+{
+ struct sbs_info *chip = i2c_get_clientdata(client);
+ s32 ret = 0;
+ int retries = 1;
+
+ if (chip->pdata)
+ retries = max(chip->pdata->i2c_retry_count + 1, 1);
+
+ while (retries > 0) {
+ ret = i2c_smbus_write_word_data(client, address,
+ le16_to_cpu(value));
+ if (ret >= 0)
+ break;
+ retries--;
+ }
+
+ if (ret < 0) {
+ dev_dbg(&client->dev,
+ "%s: i2c write to address 0x%x failed\n",
+ __func__, address);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int sbs_get_battery_presence_and_health(
+ struct i2c_client *client, enum power_supply_property psp,
+ union power_supply_propval *val)
+{
+ s32 ret;
+ struct sbs_info *chip = i2c_get_clientdata(client);
+
+ if (psp == POWER_SUPPLY_PROP_PRESENT &&
+ chip->gpio_detect) {
+ ret = gpio_get_value(chip->pdata->battery_detect);
+ if (ret == chip->pdata->battery_detect_present)
+ val->intval = 1;
+ else
+ val->intval = 0;
+ chip->is_present = val->intval;
+ return ret;
+ }
+
+ /* Write to ManufacturerAccess with
+ * ManufacturerAccess command and then
+ * read the status */
+ ret = sbs_write_word_data(client, sbs_data[REG_MANUFACTURER_DATA].addr,
+ MANUFACTURER_ACCESS_STATUS);
+ if (ret < 0) {
+ if (psp == POWER_SUPPLY_PROP_PRESENT)
+ val->intval = 0; /* battery removed */
+ return ret;
+ }
+
+ ret = sbs_read_word_data(client, sbs_data[REG_MANUFACTURER_DATA].addr);
+ if (ret < 0)
+ return ret;
+
+ if (ret < sbs_data[REG_MANUFACTURER_DATA].min_value ||
+ ret > sbs_data[REG_MANUFACTURER_DATA].max_value) {
+ val->intval = 0;
+ return 0;
+ }
+
+ /* Mask the upper nibble of 2nd byte and
+ * lower byte of response then
+ * shift the result by 8 to get status*/
+ ret &= 0x0F00;
+ ret >>= 8;
+ if (psp == POWER_SUPPLY_PROP_PRESENT) {
+ if (ret == 0x0F)
+ /* battery removed */
+ val->intval = 0;
+ else
+ val->intval = 1;
+ } else if (psp == POWER_SUPPLY_PROP_HEALTH) {
+ if (ret == 0x09)
+ val->intval = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE;
+ else if (ret == 0x0B)
+ val->intval = POWER_SUPPLY_HEALTH_OVERHEAT;
+ else if (ret == 0x0C)
+ val->intval = POWER_SUPPLY_HEALTH_DEAD;
+ else
+ val->intval = POWER_SUPPLY_HEALTH_GOOD;
+ }
+
+ return 0;
+}
+
+static int sbs_get_battery_property(struct i2c_client *client,
+ int reg_offset, enum power_supply_property psp,
+ union power_supply_propval *val)
+{
+ struct sbs_info *chip = i2c_get_clientdata(client);
+ s32 ret;
+
+ ret = sbs_read_word_data(client, sbs_data[reg_offset].addr);
+ if (ret < 0)
+ return ret;
+
+ /* returned values are 16 bit */
+ if (sbs_data[reg_offset].min_value < 0)
+ ret = (s16)ret;
+
+ if (ret >= sbs_data[reg_offset].min_value &&
+ ret <= sbs_data[reg_offset].max_value) {
+ val->intval = ret;
+ if (psp != POWER_SUPPLY_PROP_STATUS)
+ return 0;
+
+ if (ret & BATTERY_FULL_CHARGED)
+ val->intval = POWER_SUPPLY_STATUS_FULL;
+ else if (ret & BATTERY_FULL_DISCHARGED)
+ val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
+ else if (ret & BATTERY_DISCHARGING)
+ val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
+ else
+ val->intval = POWER_SUPPLY_STATUS_CHARGING;
+
+ if (chip->poll_time == 0)
+ chip->last_state = val->intval;
+ else if (chip->last_state != val->intval) {
+ cancel_delayed_work_sync(&chip->work);
+ power_supply_changed(&chip->power_supply);
+ chip->poll_time = 0;
+ }
+ } else {
+ if (psp == POWER_SUPPLY_PROP_STATUS)
+ val->intval = POWER_SUPPLY_STATUS_UNKNOWN;
+ else
+ val->intval = 0;
+ }
+
+ return 0;
+}
+
+static void sbs_unit_adjustment(struct i2c_client *client,
+ enum power_supply_property psp, union power_supply_propval *val)
+{
+#define BASE_UNIT_CONVERSION 1000
+#define BATTERY_MODE_CAP_MULT_WATT (10 * BASE_UNIT_CONVERSION)
+#define TIME_UNIT_CONVERSION 60
+#define TEMP_KELVIN_TO_CELSIUS 2731
+ switch (psp) {
+ case POWER_SUPPLY_PROP_ENERGY_NOW:
+ case POWER_SUPPLY_PROP_ENERGY_FULL:
+ case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN:
+ /* sbs provides energy in units of 10mWh.
+ * Convert to µWh
+ */
+ val->intval *= BATTERY_MODE_CAP_MULT_WATT;
+ break;
+
+ case POWER_SUPPLY_PROP_VOLTAGE_NOW:
+ case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
+ case POWER_SUPPLY_PROP_CURRENT_NOW:
+ case POWER_SUPPLY_PROP_CHARGE_NOW:
+ case POWER_SUPPLY_PROP_CHARGE_FULL:
+ case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
+ val->intval *= BASE_UNIT_CONVERSION;
+ break;
+
+ case POWER_SUPPLY_PROP_TEMP:
+ /* sbs provides battery temperature in 0.1K
+ * so convert it to 0.1°C
+ */
+ val->intval -= TEMP_KELVIN_TO_CELSIUS;
+ break;
+
+ case POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG:
+ case POWER_SUPPLY_PROP_TIME_TO_FULL_AVG:
+ /* sbs provides time to empty and time to full in minutes.
+ * Convert to seconds
+ */
+ val->intval *= TIME_UNIT_CONVERSION;
+ break;
+
+ default:
+ dev_dbg(&client->dev,
+ "%s: no need for unit conversion %d\n", __func__, psp);
+ }
+}
+
+static enum sbs_battery_mode sbs_set_battery_mode(struct i2c_client *client,
+ enum sbs_battery_mode mode)
+{
+ int ret, original_val;
+
+ original_val = sbs_read_word_data(client, BATTERY_MODE_OFFSET);
+ if (original_val < 0)
+ return original_val;
+
+ if ((original_val & BATTERY_MODE_MASK) == mode)
+ return mode;
+
+ if (mode == BATTERY_MODE_AMPS)
+ ret = original_val & ~BATTERY_MODE_MASK;
+ else
+ ret = original_val | BATTERY_MODE_MASK;
+
+ ret = sbs_write_word_data(client, BATTERY_MODE_OFFSET, ret);
+ if (ret < 0)
+ return ret;
+
+ return original_val & BATTERY_MODE_MASK;
+}
+
+static int sbs_get_battery_capacity(struct i2c_client *client,
+ int reg_offset, enum power_supply_property psp,
+ union power_supply_propval *val)
+{
+ s32 ret;
+ enum sbs_battery_mode mode = BATTERY_MODE_WATTS;
+
+ if (power_supply_is_amp_property(psp))
+ mode = BATTERY_MODE_AMPS;
+
+ mode = sbs_set_battery_mode(client, mode);
+ if (mode < 0)
+ return mode;
+
+ ret = sbs_read_word_data(client, sbs_data[reg_offset].addr);
+ if (ret < 0)
+ return ret;
+
+ if (psp == POWER_SUPPLY_PROP_CAPACITY) {
+ /* sbs spec says that this can be >100 %
+ * even if max value is 100 % */
+ val->intval = min(ret, 100);
+ } else
+ val->intval = ret;
+
+ ret = sbs_set_battery_mode(client, mode);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+static char sbs_serial[5];
+static int sbs_get_battery_serial_number(struct i2c_client *client,
+ union power_supply_propval *val)
+{
+ int ret;
+
+ ret = sbs_read_word_data(client, sbs_data[REG_SERIAL_NUMBER].addr);
+ if (ret < 0)
+ return ret;
+
+ ret = sprintf(sbs_serial, "%04x", ret);
+ val->strval = sbs_serial;
+
+ return 0;
+}
+
+static int sbs_get_property_index(struct i2c_client *client,
+ enum power_supply_property psp)
+{
+ int count;
+ for (count = 0; count < ARRAY_SIZE(sbs_data); count++)
+ if (psp == sbs_data[count].psp)
+ return count;
+
+ dev_warn(&client->dev,
+ "%s: Invalid Property - %d\n", __func__, psp);
+
+ return -EINVAL;
+}
+
+static int sbs_get_property(struct power_supply *psy,
+ enum power_supply_property psp,
+ union power_supply_propval *val)
+{
+ int ret = 0;
+ struct sbs_info *chip = container_of(psy,
+ struct sbs_info, power_supply);
+ struct i2c_client *client = chip->client;
+
+ switch (psp) {
+ case POWER_SUPPLY_PROP_PRESENT:
+ case POWER_SUPPLY_PROP_HEALTH:
+ ret = sbs_get_battery_presence_and_health(client, psp, val);
+ if (psp == POWER_SUPPLY_PROP_PRESENT)
+ return 0;
+ break;
+
+ case POWER_SUPPLY_PROP_TECHNOLOGY:
+ val->intval = POWER_SUPPLY_TECHNOLOGY_LION;
+ break;
+
+ case POWER_SUPPLY_PROP_ENERGY_NOW:
+ case POWER_SUPPLY_PROP_ENERGY_FULL:
+ case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN:
+ case POWER_SUPPLY_PROP_CHARGE_NOW:
+ case POWER_SUPPLY_PROP_CHARGE_FULL:
+ case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
+ case POWER_SUPPLY_PROP_CAPACITY:
+ ret = sbs_get_property_index(client, psp);
+ if (ret < 0)
+ break;
+
+ ret = sbs_get_battery_capacity(client, ret, psp, val);
+ break;
+
+ case POWER_SUPPLY_PROP_SERIAL_NUMBER:
+ ret = sbs_get_battery_serial_number(client, val);
+ break;
+
+ case POWER_SUPPLY_PROP_STATUS:
+ case POWER_SUPPLY_PROP_CYCLE_COUNT:
+ case POWER_SUPPLY_PROP_VOLTAGE_NOW:
+ case POWER_SUPPLY_PROP_CURRENT_NOW:
+ case POWER_SUPPLY_PROP_TEMP:
+ case POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG:
+ case POWER_SUPPLY_PROP_TIME_TO_FULL_AVG:
+ case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
+ ret = sbs_get_property_index(client, psp);
+ if (ret < 0)
+ break;
+
+ ret = sbs_get_battery_property(client, ret, psp, val);
+ break;
+
+ default:
+ dev_err(&client->dev,
+ "%s: INVALID property\n", __func__);
+ return -EINVAL;
+ }
+
+ if (!chip->enable_detection)
+ goto done;
+
+ if (!chip->gpio_detect &&
+ chip->is_present != (ret >= 0)) {
+ chip->is_present = (ret >= 0);
+ power_supply_changed(&chip->power_supply);
+ }
+
+done:
+ if (!ret) {
+ /* Convert units to match requirements for power supply class */
+ sbs_unit_adjustment(client, psp, val);
+ }
+
+ dev_dbg(&client->dev,
+ "%s: property = %d, value = %x\n", __func__, psp, val->intval);
+
+ if (ret && chip->is_present)
+ return ret;
+
+ /* battery not present, so return NODATA for properties */
+ if (ret)
+ return -ENODATA;
+
+ return 0;
+}
+
+static irqreturn_t sbs_irq(int irq, void *devid)
+{
+ struct power_supply *battery = devid;
+
+ power_supply_changed(battery);
+
+ return IRQ_HANDLED;
+}
+
+static void sbs_external_power_changed(struct power_supply *psy)
+{
+ struct sbs_info *chip;
+
+ chip = container_of(psy, struct sbs_info, power_supply);
+
+ if (chip->ignore_changes > 0) {
+ chip->ignore_changes--;
+ return;
+ }
+
+ /* cancel outstanding work */
+ cancel_delayed_work_sync(&chip->work);
+
+ schedule_delayed_work(&chip->work, HZ);
+ chip->poll_time = chip->pdata->poll_retry_count;
+}
+
+static void sbs_delayed_work(struct work_struct *work)
+{
+ struct sbs_info *chip;
+ s32 ret;
+
+ chip = container_of(work, struct sbs_info, work.work);
+
+ ret = sbs_read_word_data(chip->client, sbs_data[REG_STATUS].addr);
+ /* if the read failed, give up on this work */
+ if (ret < 0) {
+ chip->poll_time = 0;
+ return;
+ }
+
+ if (ret & BATTERY_FULL_CHARGED)
+ ret = POWER_SUPPLY_STATUS_FULL;
+ else if (ret & BATTERY_FULL_DISCHARGED)
+ ret = POWER_SUPPLY_STATUS_NOT_CHARGING;
+ else if (ret & BATTERY_DISCHARGING)
+ ret = POWER_SUPPLY_STATUS_DISCHARGING;
+ else
+ ret = POWER_SUPPLY_STATUS_CHARGING;
+
+ if (chip->last_state != ret) {
+ chip->poll_time = 0;
+ power_supply_changed(&chip->power_supply);
+ return;
+ }
+ if (chip->poll_time > 0) {
+ schedule_delayed_work(&chip->work, HZ);
+ chip->poll_time--;
+ return;
+ }
+}
+
+#if defined(CONFIG_OF)
+
+#include <linux/of_device.h>
+#include <linux/of_gpio.h>
+
+static const struct of_device_id sbs_dt_ids[] = {
+ { .compatible = "sbs,sbs-battery" },
+ { .compatible = "ti,bq20z75" },
+ { }
+};
+MODULE_DEVICE_TABLE(of, sbs_dt_ids);
+
+static struct sbs_platform_data *sbs_of_populate_pdata(
+ struct i2c_client *client)
+{
+ struct device_node *of_node = client->dev.of_node;
+ struct sbs_platform_data *pdata = client->dev.platform_data;
+ enum of_gpio_flags gpio_flags;
+ int rc;
+ u32 prop;
+
+ /* verify this driver matches this device */
+ if (!of_node)
+ return NULL;
+
+ /* if platform data is set, honor it */
+ if (pdata)
+ return pdata;
+
+ /* first make sure at least one property is set, otherwise
+ * it won't change behavior from running without pdata.
+ */
+ if (!of_get_property(of_node, "sbs,i2c-retry-count", NULL) &&
+ !of_get_property(of_node, "sbs,poll-retry-count", NULL) &&
+ !of_get_property(of_node, "sbs,battery-detect-gpios", NULL))
+ goto of_out;
+
+ pdata = devm_kzalloc(&client->dev, sizeof(struct sbs_platform_data),
+ GFP_KERNEL);
+ if (!pdata)
+ goto of_out;
+
+ rc = of_property_read_u32(of_node, "sbs,i2c-retry-count", &prop);
+ if (!rc)
+ pdata->i2c_retry_count = prop;
+
+ rc = of_property_read_u32(of_node, "sbs,poll-retry-count", &prop);
+ if (!rc)
+ pdata->poll_retry_count = prop;
+
+ if (!of_get_property(of_node, "sbs,battery-detect-gpios", NULL)) {
+ pdata->battery_detect = -1;
+ goto of_out;
+ }
+
+ pdata->battery_detect = of_get_named_gpio_flags(of_node,
+ "sbs,battery-detect-gpios", 0, &gpio_flags);
+
+ if (gpio_flags & OF_GPIO_ACTIVE_LOW)
+ pdata->battery_detect_present = 0;
+ else
+ pdata->battery_detect_present = 1;
+
+of_out:
+ return pdata;
+}
+#else
+#define sbs_dt_ids NULL
+static struct sbs_platform_data *sbs_of_populate_pdata(
+ struct i2c_client *client)
+{
+ return client->dev.platform_data;
+}
+#endif
+
+static int __devinit sbs_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct sbs_info *chip;
+ struct sbs_platform_data *pdata = client->dev.platform_data;
+ int rc;
+ int irq;
+ char *name;
+
+ name = kasprintf(GFP_KERNEL, "sbs-%s", dev_name(&client->dev));
+ if (!name) {
+ dev_err(&client->dev, "Failed to allocate device name\n");
+ return -ENOMEM;
+ }
+
+ chip = kzalloc(sizeof(struct sbs_info), GFP_KERNEL);
+ if (!chip) {
+ rc = -ENOMEM;
+ goto exit_free_name;
+ }
+
+ chip->client = client;
+ chip->enable_detection = false;
+ chip->gpio_detect = false;
+ chip->power_supply.name = name;
+ chip->power_supply.type = POWER_SUPPLY_TYPE_BATTERY;
+ chip->power_supply.properties = sbs_properties;
+ chip->power_supply.num_properties = ARRAY_SIZE(sbs_properties);
+ chip->power_supply.get_property = sbs_get_property;
+ /* ignore first notification of external change, it is generated
+ * from the power_supply_register call back
+ */
+ chip->ignore_changes = 1;
+ chip->last_state = POWER_SUPPLY_STATUS_UNKNOWN;
+ chip->power_supply.external_power_changed = sbs_external_power_changed;
+
+ pdata = sbs_of_populate_pdata(client);
+
+ if (pdata) {
+ chip->gpio_detect = gpio_is_valid(pdata->battery_detect);
+ chip->pdata = pdata;
+ }
+
+ i2c_set_clientdata(client, chip);
+
+ if (!chip->gpio_detect)
+ goto skip_gpio;
+
+ rc = gpio_request(pdata->battery_detect, dev_name(&client->dev));
+ if (rc) {
+ dev_warn(&client->dev, "Failed to request gpio: %d\n", rc);
+ chip->gpio_detect = false;
+ goto skip_gpio;
+ }
+
+ rc = gpio_direction_input(pdata->battery_detect);
+ if (rc) {
+ dev_warn(&client->dev, "Failed to get gpio as input: %d\n", rc);
+ gpio_free(pdata->battery_detect);
+ chip->gpio_detect = false;
+ goto skip_gpio;
+ }
+
+ irq = gpio_to_irq(pdata->battery_detect);
+ if (irq <= 0) {
+ dev_warn(&client->dev, "Failed to get gpio as irq: %d\n", irq);
+ gpio_free(pdata->battery_detect);
+ chip->gpio_detect = false;
+ goto skip_gpio;
+ }
+
+ rc = request_irq(irq, sbs_irq,
+ IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
+ dev_name(&client->dev), &chip->power_supply);
+ if (rc) {
+ dev_warn(&client->dev, "Failed to request irq: %d\n", rc);
+ gpio_free(pdata->battery_detect);
+ chip->gpio_detect = false;
+ goto skip_gpio;
+ }
+
+ chip->irq = irq;
+
+skip_gpio:
+
+ rc = power_supply_register(&client->dev, &chip->power_supply);
+ if (rc) {
+ dev_err(&client->dev,
+ "%s: Failed to register power supply\n", __func__);
+ goto exit_psupply;
+ }
+
+ dev_info(&client->dev,
+ "%s: battery gas gauge device registered\n", client->name);
+
+ INIT_DELAYED_WORK(&chip->work, sbs_delayed_work);
+
+ chip->enable_detection = true;
+
+ return 0;
+
+exit_psupply:
+ if (chip->irq)
+ free_irq(chip->irq, &chip->power_supply);
+ if (chip->gpio_detect)
+ gpio_free(pdata->battery_detect);
+
+ kfree(chip);
+
+exit_free_name:
+ kfree(name);
+
+ return rc;
+}
+
+static int __devexit sbs_remove(struct i2c_client *client)
+{
+ struct sbs_info *chip = i2c_get_clientdata(client);
+
+ if (chip->irq)
+ free_irq(chip->irq, &chip->power_supply);
+ if (chip->gpio_detect)
+ gpio_free(chip->pdata->battery_detect);
+
+ power_supply_unregister(&chip->power_supply);
+
+ cancel_delayed_work_sync(&chip->work);
+
+ kfree(chip->power_supply.name);
+ kfree(chip);
+ chip = NULL;
+
+ return 0;
+}
+
+#if defined CONFIG_PM
+static int sbs_suspend(struct i2c_client *client,
+ pm_message_t state)
+{
+ struct sbs_info *chip = i2c_get_clientdata(client);
+ s32 ret;
+
+ if (chip->poll_time > 0)
+ cancel_delayed_work_sync(&chip->work);
+
+ /* write to manufacturer access with sleep command */
+ ret = sbs_write_word_data(client, sbs_data[REG_MANUFACTURER_DATA].addr,
+ MANUFACTURER_ACCESS_SLEEP);
+ if (chip->is_present && ret < 0)
+ return ret;
+
+ return 0;
+}
+#else
+#define sbs_suspend NULL
+#endif
+/* any smbus transaction will wake up sbs */
+#define sbs_resume NULL
+
+static const struct i2c_device_id sbs_id[] = {
+ { "bq20z75", 0 },
+ { "sbs-battery", 1 },
+ {}
+};
+MODULE_DEVICE_TABLE(i2c, sbs_id);
+
+static struct i2c_driver sbs_battery_driver = {
+ .probe = sbs_probe,
+ .remove = __devexit_p(sbs_remove),
+ .suspend = sbs_suspend,
+ .resume = sbs_resume,
+ .id_table = sbs_id,
+ .driver = {
+ .name = "sbs-battery",
+ .of_match_table = sbs_dt_ids,
+ },
+};
+
+static int __init sbs_battery_init(void)
+{
+ return i2c_add_driver(&sbs_battery_driver);
+}
+module_init(sbs_battery_init);
+
+static void __exit sbs_battery_exit(void)
+{
+ i2c_del_driver(&sbs_battery_driver);
+}
+module_exit(sbs_battery_exit);
+
+MODULE_DESCRIPTION("SBS battery monitor driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/power/tosa_battery.c b/drivers/power/tosa_battery.c
index 53f0d35..28bbe7e 100644
--- a/drivers/power/tosa_battery.c
+++ b/drivers/power/tosa_battery.c
@@ -307,25 +307,20 @@
.adc_temp_divider = -1,
};
-static struct {
- int gpio;
- char *name;
- bool output;
- int value;
-} gpios[] = {
- { TOSA_GPIO_CHARGE_OFF, "main charge off", 1, 1 },
- { TOSA_GPIO_CHARGE_OFF_JC, "jacket charge off", 1, 1 },
- { TOSA_GPIO_BAT_SW_ON, "battery switch", 1, 0 },
- { TOSA_GPIO_BAT0_V_ON, "main battery", 1, 0 },
- { TOSA_GPIO_BAT1_V_ON, "jacket battery", 1, 0 },
- { TOSA_GPIO_BAT1_TH_ON, "main battery temp", 1, 0 },
- { TOSA_GPIO_BAT0_TH_ON, "jacket battery temp", 1, 0 },
- { TOSA_GPIO_BU_CHRG_ON, "backup battery", 1, 0 },
- { TOSA_GPIO_BAT0_CRG, "main battery full", 0, 0 },
- { TOSA_GPIO_BAT1_CRG, "jacket battery full", 0, 0 },
- { TOSA_GPIO_BAT0_LOW, "main battery low", 0, 0 },
- { TOSA_GPIO_BAT1_LOW, "jacket battery low", 0, 0 },
- { TOSA_GPIO_JACKET_DETECT, "jacket detect", 0, 0 },
+static struct gpio tosa_bat_gpios[] = {
+ { TOSA_GPIO_CHARGE_OFF, GPIOF_OUT_INIT_HIGH, "main charge off" },
+ { TOSA_GPIO_CHARGE_OFF_JC, GPIOF_OUT_INIT_HIGH, "jacket charge off" },
+ { TOSA_GPIO_BAT_SW_ON, GPIOF_OUT_INIT_LOW, "battery switch" },
+ { TOSA_GPIO_BAT0_V_ON, GPIOF_OUT_INIT_LOW, "main battery" },
+ { TOSA_GPIO_BAT1_V_ON, GPIOF_OUT_INIT_LOW, "jacket battery" },
+ { TOSA_GPIO_BAT1_TH_ON, GPIOF_OUT_INIT_LOW, "main battery temp" },
+ { TOSA_GPIO_BAT0_TH_ON, GPIOF_OUT_INIT_LOW, "jacket battery temp" },
+ { TOSA_GPIO_BU_CHRG_ON, GPIOF_OUT_INIT_LOW, "backup battery" },
+ { TOSA_GPIO_BAT0_CRG, GPIOF_IN, "main battery full" },
+ { TOSA_GPIO_BAT1_CRG, GPIOF_IN, "jacket battery full" },
+ { TOSA_GPIO_BAT0_LOW, GPIOF_IN, "main battery low" },
+ { TOSA_GPIO_BAT1_LOW, GPIOF_IN, "jacket battery low" },
+ { TOSA_GPIO_JACKET_DETECT, GPIOF_IN, "jacket detect" },
};
#ifdef CONFIG_PM
@@ -350,27 +345,13 @@
static int __devinit tosa_bat_probe(struct platform_device *dev)
{
int ret;
- int i;
if (!machine_is_tosa())
return -ENODEV;
- for (i = 0; i < ARRAY_SIZE(gpios); i++) {
- ret = gpio_request(gpios[i].gpio, gpios[i].name);
- if (ret) {
- i--;
- goto err_gpio;
- }
-
- if (gpios[i].output)
- ret = gpio_direction_output(gpios[i].gpio,
- gpios[i].value);
- else
- ret = gpio_direction_input(gpios[i].gpio);
-
- if (ret)
- goto err_gpio;
- }
+ ret = gpio_request_array(tosa_bat_gpios, ARRAY_SIZE(tosa_bat_gpios));
+ if (ret)
+ return ret;
mutex_init(&tosa_bat_main.work_lock);
mutex_init(&tosa_bat_jacket.work_lock);
@@ -424,18 +405,12 @@
/* see comment in tosa_bat_remove */
cancel_work_sync(&bat_work);
- i--;
-err_gpio:
- for (; i >= 0; i--)
- gpio_free(gpios[i].gpio);
-
+ gpio_free_array(tosa_bat_gpios, ARRAY_SIZE(tosa_bat_gpios));
return ret;
}
static int __devexit tosa_bat_remove(struct platform_device *dev)
{
- int i;
-
free_irq(gpio_to_irq(TOSA_GPIO_JACKET_DETECT), &tosa_bat_jacket);
free_irq(gpio_to_irq(TOSA_GPIO_BAT1_CRG), &tosa_bat_jacket);
free_irq(gpio_to_irq(TOSA_GPIO_BAT0_CRG), &tosa_bat_main);
@@ -450,10 +425,7 @@
* unregistered now.
*/
cancel_work_sync(&bat_work);
-
- for (i = ARRAY_SIZE(gpios) - 1; i >= 0; i--)
- gpio_free(gpios[i].gpio);
-
+ gpio_free_array(tosa_bat_gpios, ARRAY_SIZE(tosa_bat_gpios));
return 0;
}
@@ -466,18 +438,7 @@
.resume = tosa_bat_resume,
};
-static int __init tosa_bat_init(void)
-{
- return platform_driver_register(&tosa_bat_driver);
-}
-
-static void __exit tosa_bat_exit(void)
-{
- platform_driver_unregister(&tosa_bat_driver);
-}
-
-module_init(tosa_bat_init);
-module_exit(tosa_bat_exit);
+module_platform_driver(tosa_bat_driver);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Dmitry Baryshkov");
diff --git a/drivers/power/wm831x_backup.c b/drivers/power/wm831x_backup.c
index e648cbe..6243e69 100644
--- a/drivers/power/wm831x_backup.c
+++ b/drivers/power/wm831x_backup.c
@@ -226,17 +226,7 @@
},
};
-static int __init wm831x_backup_init(void)
-{
- return platform_driver_register(&wm831x_backup_driver);
-}
-module_init(wm831x_backup_init);
-
-static void __exit wm831x_backup_exit(void)
-{
- platform_driver_unregister(&wm831x_backup_driver);
-}
-module_exit(wm831x_backup_exit);
+module_platform_driver(wm831x_backup_driver);
MODULE_DESCRIPTION("Backup battery charger driver for WM831x PMICs");
MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
diff --git a/drivers/power/wm831x_power.c b/drivers/power/wm831x_power.c
index 6cc2ca6..987332b 100644
--- a/drivers/power/wm831x_power.c
+++ b/drivers/power/wm831x_power.c
@@ -27,6 +27,7 @@
char wall_name[20];
char usb_name[20];
char battery_name[20];
+ bool have_battery;
};
static int wm831x_power_check_online(struct wm831x *wm831x, int supply,
@@ -449,7 +450,8 @@
/* The battery charger is autonomous so we don't need to do
* anything except kick user space */
- power_supply_changed(&wm831x_power->battery);
+ if (wm831x_power->have_battery)
+ power_supply_changed(&wm831x_power->battery);
return IRQ_HANDLED;
}
@@ -479,7 +481,8 @@
dev_dbg(wm831x->dev, "Power source changed\n");
/* Just notify for everything - little harm in overnotifying. */
- power_supply_changed(&wm831x_power->battery);
+ if (wm831x_power->have_battery)
+ power_supply_changed(&wm831x_power->battery);
power_supply_changed(&wm831x_power->usb);
power_supply_changed(&wm831x_power->wall);
@@ -537,15 +540,6 @@
if (ret)
goto err_kmalloc;
- battery->name = power->battery_name;
- battery->properties = wm831x_bat_props;
- battery->num_properties = ARRAY_SIZE(wm831x_bat_props);
- battery->get_property = wm831x_bat_get_prop;
- battery->use_for_apm = 1;
- ret = power_supply_register(&pdev->dev, battery);
- if (ret)
- goto err_wall;
-
usb->name = power->usb_name,
usb->type = POWER_SUPPLY_TYPE_USB;
usb->properties = wm831x_usb_props;
@@ -553,7 +547,23 @@
usb->get_property = wm831x_usb_get_prop;
ret = power_supply_register(&pdev->dev, usb);
if (ret)
- goto err_battery;
+ goto err_wall;
+
+ ret = wm831x_reg_read(wm831x, WM831X_CHARGER_CONTROL_1);
+ if (ret < 0)
+ goto err_wall;
+ power->have_battery = ret & WM831X_CHG_ENA;
+
+ if (power->have_battery) {
+ battery->name = power->battery_name;
+ battery->properties = wm831x_bat_props;
+ battery->num_properties = ARRAY_SIZE(wm831x_bat_props);
+ battery->get_property = wm831x_bat_get_prop;
+ battery->use_for_apm = 1;
+ ret = power_supply_register(&pdev->dev, battery);
+ if (ret)
+ goto err_usb;
+ }
irq = platform_get_irq_byname(pdev, "SYSLO");
ret = request_threaded_irq(irq, NULL, wm831x_syslo_irq,
@@ -562,7 +572,7 @@
if (ret != 0) {
dev_err(&pdev->dev, "Failed to request SYSLO IRQ %d: %d\n",
irq, ret);
- goto err_usb;
+ goto err_battery;
}
irq = platform_get_irq_byname(pdev, "PWR SRC");
@@ -601,10 +611,11 @@
err_syslo:
irq = platform_get_irq_byname(pdev, "SYSLO");
free_irq(irq, power);
+err_battery:
+ if (power->have_battery)
+ power_supply_unregister(battery);
err_usb:
power_supply_unregister(usb);
-err_battery:
- power_supply_unregister(battery);
err_wall:
power_supply_unregister(wall);
err_kmalloc:
@@ -628,7 +639,8 @@
irq = platform_get_irq_byname(pdev, "SYSLO");
free_irq(irq, wm831x_power);
- power_supply_unregister(&wm831x_power->battery);
+ if (wm831x_power->have_battery)
+ power_supply_unregister(&wm831x_power->battery);
power_supply_unregister(&wm831x_power->wall);
power_supply_unregister(&wm831x_power->usb);
kfree(wm831x_power);
@@ -643,17 +655,7 @@
},
};
-static int __init wm831x_power_init(void)
-{
- return platform_driver_register(&wm831x_power_driver);
-}
-module_init(wm831x_power_init);
-
-static void __exit wm831x_power_exit(void)
-{
- platform_driver_unregister(&wm831x_power_driver);
-}
-module_exit(wm831x_power_exit);
+module_platform_driver(wm831x_power_driver);
MODULE_DESCRIPTION("Power supply driver for WM831x PMICs");
MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
diff --git a/drivers/power/wm8350_power.c b/drivers/power/wm8350_power.c
index 0693902..fae04d3 100644
--- a/drivers/power/wm8350_power.c
+++ b/drivers/power/wm8350_power.c
@@ -522,17 +522,7 @@
},
};
-static int __init wm8350_power_init(void)
-{
- return platform_driver_register(&wm8350_power_driver);
-}
-module_init(wm8350_power_init);
-
-static void __exit wm8350_power_exit(void)
-{
- platform_driver_unregister(&wm8350_power_driver);
-}
-module_exit(wm8350_power_exit);
+module_platform_driver(wm8350_power_driver);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Power supply driver for WM8350");
diff --git a/drivers/power/wm97xx_battery.c b/drivers/power/wm97xx_battery.c
index 156559e..d2d4c08 100644
--- a/drivers/power/wm97xx_battery.c
+++ b/drivers/power/wm97xx_battery.c
@@ -25,9 +25,8 @@
#include <linux/irq.h>
#include <linux/slab.h>
-static DEFINE_MUTEX(bat_lock);
static struct work_struct bat_work;
-static struct mutex work_lock;
+static DEFINE_MUTEX(work_lock);
static int bat_status = POWER_SUPPLY_STATUS_UNKNOWN;
static enum power_supply_property *prop;
@@ -181,8 +180,6 @@
if (dev->id != -1)
return -EINVAL;
- mutex_init(&work_lock);
-
if (!pdata) {
dev_err(&dev->dev, "No platform_data supplied\n");
return -EINVAL;
@@ -196,7 +193,7 @@
if (ret)
goto err2;
ret = request_irq(gpio_to_irq(pdata->charge_gpio),
- wm97xx_chrg_irq, IRQF_DISABLED,
+ wm97xx_chrg_irq, 0,
"AC Detect", dev);
if (ret)
goto err2;
@@ -291,18 +288,7 @@
.remove = __devexit_p(wm97xx_bat_remove),
};
-static int __init wm97xx_bat_init(void)
-{
- return platform_driver_register(&wm97xx_bat_driver);
-}
-
-static void __exit wm97xx_bat_exit(void)
-{
- platform_driver_unregister(&wm97xx_bat_driver);
-}
-
-module_init(wm97xx_bat_init);
-module_exit(wm97xx_bat_exit);
+module_platform_driver(wm97xx_bat_driver);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Marek Vasut <marek.vasut@gmail.com>");
diff --git a/drivers/power/z2_battery.c b/drivers/power/z2_battery.c
index d119c38..636ebb2 100644
--- a/drivers/power/z2_battery.c
+++ b/drivers/power/z2_battery.c
@@ -218,7 +218,7 @@
irq_set_irq_type(gpio_to_irq(info->charge_gpio),
IRQ_TYPE_EDGE_BOTH);
ret = request_irq(gpio_to_irq(info->charge_gpio),
- z2_charge_switch_irq, IRQF_DISABLED,
+ z2_charge_switch_irq, 0,
"AC Detect", charger);
if (ret)
goto err3;
@@ -313,7 +313,7 @@
.pm = Z2_BATTERY_PM_OPS
},
.probe = z2_batt_probe,
- .remove = z2_batt_remove,
+ .remove = __devexit_p(z2_batt_remove),
.id_table = z2_batt_id,
};
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 877cf6f..e19a403 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -498,9 +498,9 @@
will be called rtc-cmos.
config RTC_DRV_VRTC
- tristate "Virtual RTC for Moorestown platforms"
- depends on X86_MRST
- default y if X86_MRST
+ tristate "Virtual RTC for Intel MID platforms"
+ depends on X86_INTEL_MID
+ default y if X86_INTEL_MID
help
Say "yes" here to get direct support for the real time clock
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
index fd860d9..67b169b 100644
--- a/drivers/scsi/ipr.c
+++ b/drivers/scsi/ipr.c
@@ -7638,8 +7638,12 @@
**/
static int ipr_reset_bist_done(struct ipr_cmnd *ipr_cmd)
{
+ struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
+
ENTER;
- pci_unblock_user_cfg_access(ipr_cmd->ioa_cfg->pdev);
+ if (ioa_cfg->cfg_locked)
+ pci_cfg_access_unlock(ioa_cfg->pdev);
+ ioa_cfg->cfg_locked = 0;
ipr_cmd->job_step = ipr_reset_restore_cfg_space;
LEAVE;
return IPR_RC_JOB_CONTINUE;
@@ -7660,8 +7664,6 @@
int rc = PCIBIOS_SUCCESSFUL;
ENTER;
- pci_block_user_cfg_access(ioa_cfg->pdev);
-
if (ioa_cfg->ipr_chip->bist_method == IPR_MMIO)
writel(IPR_UPROCI_SIS64_START_BIST,
ioa_cfg->regs.set_uproc_interrupt_reg32);
@@ -7673,7 +7675,9 @@
ipr_reset_start_timer(ipr_cmd, IPR_WAIT_FOR_BIST_TIMEOUT);
rc = IPR_RC_JOB_RETURN;
} else {
- pci_unblock_user_cfg_access(ipr_cmd->ioa_cfg->pdev);
+ if (ioa_cfg->cfg_locked)
+ pci_cfg_access_unlock(ipr_cmd->ioa_cfg->pdev);
+ ioa_cfg->cfg_locked = 0;
ipr_cmd->s.ioasa.hdr.ioasc = cpu_to_be32(IPR_IOASC_PCI_ACCESS_ERROR);
rc = IPR_RC_JOB_CONTINUE;
}
@@ -7716,7 +7720,6 @@
struct pci_dev *pdev = ioa_cfg->pdev;
ENTER;
- pci_block_user_cfg_access(pdev);
pci_set_pcie_reset_state(pdev, pcie_warm_reset);
ipr_cmd->job_step = ipr_reset_slot_reset_done;
ipr_reset_start_timer(ipr_cmd, IPR_PCI_RESET_TIMEOUT);
@@ -7725,6 +7728,56 @@
}
/**
+ * ipr_reset_block_config_access_wait - Wait for permission to block config access
+ * @ipr_cmd: ipr command struct
+ *
+ * Description: This attempts to block config access to the IOA.
+ *
+ * Return value:
+ * IPR_RC_JOB_CONTINUE / IPR_RC_JOB_RETURN
+ **/
+static int ipr_reset_block_config_access_wait(struct ipr_cmnd *ipr_cmd)
+{
+ struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
+ int rc = IPR_RC_JOB_CONTINUE;
+
+ if (pci_cfg_access_trylock(ioa_cfg->pdev)) {
+ ioa_cfg->cfg_locked = 1;
+ ipr_cmd->job_step = ioa_cfg->reset;
+ } else {
+ if (ipr_cmd->u.time_left) {
+ rc = IPR_RC_JOB_RETURN;
+ ipr_cmd->u.time_left -= IPR_CHECK_FOR_RESET_TIMEOUT;
+ ipr_reset_start_timer(ipr_cmd,
+ IPR_CHECK_FOR_RESET_TIMEOUT);
+ } else {
+ ipr_cmd->job_step = ioa_cfg->reset;
+ dev_err(&ioa_cfg->pdev->dev,
+ "Timed out waiting to lock config access. Resetting anyway.\n");
+ }
+ }
+
+ return rc;
+}
+
+/**
+ * ipr_reset_block_config_access - Block config access to the IOA
+ * @ipr_cmd: ipr command struct
+ *
+ * Description: This attempts to block config access to the IOA
+ *
+ * Return value:
+ * IPR_RC_JOB_CONTINUE
+ **/
+static int ipr_reset_block_config_access(struct ipr_cmnd *ipr_cmd)
+{
+ ipr_cmd->ioa_cfg->cfg_locked = 0;
+ ipr_cmd->job_step = ipr_reset_block_config_access_wait;
+ ipr_cmd->u.time_left = IPR_WAIT_FOR_RESET_TIMEOUT;
+ return IPR_RC_JOB_CONTINUE;
+}
+
+/**
* ipr_reset_allowed - Query whether or not IOA can be reset
* @ioa_cfg: ioa config struct
*
@@ -7763,7 +7816,7 @@
ipr_cmd->u.time_left -= IPR_CHECK_FOR_RESET_TIMEOUT;
ipr_reset_start_timer(ipr_cmd, IPR_CHECK_FOR_RESET_TIMEOUT);
} else {
- ipr_cmd->job_step = ioa_cfg->reset;
+ ipr_cmd->job_step = ipr_reset_block_config_access;
rc = IPR_RC_JOB_CONTINUE;
}
@@ -7796,7 +7849,7 @@
writel(IPR_UPROCI_RESET_ALERT, ioa_cfg->regs.set_uproc_interrupt_reg32);
ipr_cmd->job_step = ipr_reset_wait_to_start_bist;
} else {
- ipr_cmd->job_step = ioa_cfg->reset;
+ ipr_cmd->job_step = ipr_reset_block_config_access;
}
ipr_cmd->u.time_left = IPR_WAIT_FOR_RESET_TIMEOUT;
diff --git a/drivers/scsi/ipr.h b/drivers/scsi/ipr.h
index ac84736..b13f9cc 100644
--- a/drivers/scsi/ipr.h
+++ b/drivers/scsi/ipr.h
@@ -1387,6 +1387,7 @@
u8 msi_received:1;
u8 sis64:1;
u8 dump_timeout:1;
+ u8 cfg_locked:1;
u8 revid;
diff --git a/drivers/sh/Makefile b/drivers/sh/Makefile
index 67e272a..7139ad2 100644
--- a/drivers/sh/Makefile
+++ b/drivers/sh/Makefile
@@ -7,11 +7,4 @@
obj-$(CONFIG_MAPLE) += maple/
obj-$(CONFIG_SUPERHYWAY) += superhyway/
obj-$(CONFIG_GENERIC_GPIO) += pfc.o
-
-#
-# For the moment we only use this framework for ARM-based SH/R-Mobile
-# platforms and generic SH. SH-based SH-Mobile platforms are still using
-# an older framework that is pending up-porting, at which point this
-# special casing can go away.
-#
-obj-$(CONFIG_SUPERH)$(CONFIG_ARCH_SHMOBILE) += pm_runtime.o
+obj-y += pm_runtime.o
diff --git a/drivers/sh/clk/core.c b/drivers/sh/clk/core.c
index db257a3..7715de2 100644
--- a/drivers/sh/clk/core.c
+++ b/drivers/sh/clk/core.c
@@ -355,7 +355,7 @@
*/
if (!clk->parent) {
clk->mapping = &dummy_mapping;
- return 0;
+ goto out;
}
/*
@@ -384,6 +384,9 @@
}
clk->mapping = mapping;
+out:
+ clk->mapped_reg = clk->mapping->base;
+ clk->mapped_reg += (phys_addr_t)clk->enable_reg - clk->mapping->phys;
return 0;
}
@@ -402,10 +405,12 @@
/* Nothing to do */
if (mapping == &dummy_mapping)
- return;
+ goto out;
kref_put(&mapping->ref, clk_destroy_mapping);
clk->mapping = NULL;
+out:
+ clk->mapped_reg = NULL;
}
int clk_register(struct clk *clk)
diff --git a/drivers/sh/clk/cpg.c b/drivers/sh/clk/cpg.c
index 82dd6fb..45fee36 100644
--- a/drivers/sh/clk/cpg.c
+++ b/drivers/sh/clk/cpg.c
@@ -15,15 +15,15 @@
static int sh_clk_mstp32_enable(struct clk *clk)
{
- __raw_writel(__raw_readl(clk->enable_reg) & ~(1 << clk->enable_bit),
- clk->enable_reg);
+ iowrite32(ioread32(clk->mapped_reg) & ~(1 << clk->enable_bit),
+ clk->mapped_reg);
return 0;
}
static void sh_clk_mstp32_disable(struct clk *clk)
{
- __raw_writel(__raw_readl(clk->enable_reg) | (1 << clk->enable_bit),
- clk->enable_reg);
+ iowrite32(ioread32(clk->mapped_reg) | (1 << clk->enable_bit),
+ clk->mapped_reg);
}
static struct clk_ops sh_clk_mstp32_clk_ops = {
@@ -72,7 +72,7 @@
clk_rate_table_build(clk, clk->freq_table, table->nr_divisors,
table, NULL);
- idx = __raw_readl(clk->enable_reg) & 0x003f;
+ idx = ioread32(clk->mapped_reg) & 0x003f;
return clk->freq_table[idx].frequency;
}
@@ -98,10 +98,10 @@
if (ret < 0)
return ret;
- value = __raw_readl(clk->enable_reg) &
+ value = ioread32(clk->mapped_reg) &
~(((1 << clk->src_width) - 1) << clk->src_shift);
- __raw_writel(value | (i << clk->src_shift), clk->enable_reg);
+ iowrite32(value | (i << clk->src_shift), clk->mapped_reg);
/* Rebuild the frequency table */
clk_rate_table_build(clk, clk->freq_table, table->nr_divisors,
@@ -119,10 +119,10 @@
if (idx < 0)
return idx;
- value = __raw_readl(clk->enable_reg);
+ value = ioread32(clk->mapped_reg);
value &= ~0x3f;
value |= idx;
- __raw_writel(value, clk->enable_reg);
+ iowrite32(value, clk->mapped_reg);
return 0;
}
@@ -133,9 +133,9 @@
ret = sh_clk_div6_set_rate(clk, clk->rate);
if (ret == 0) {
- value = __raw_readl(clk->enable_reg);
+ value = ioread32(clk->mapped_reg);
value &= ~0x100; /* clear stop bit to enable clock */
- __raw_writel(value, clk->enable_reg);
+ iowrite32(value, clk->mapped_reg);
}
return ret;
}
@@ -144,10 +144,10 @@
{
unsigned long value;
- value = __raw_readl(clk->enable_reg);
+ value = ioread32(clk->mapped_reg);
value |= 0x100; /* stop clock */
value |= 0x3f; /* VDIV bits must be non-zero, overwrite divider */
- __raw_writel(value, clk->enable_reg);
+ iowrite32(value, clk->mapped_reg);
}
static struct clk_ops sh_clk_div6_clk_ops = {
@@ -167,6 +167,38 @@
.set_parent = sh_clk_div6_set_parent,
};
+static int __init sh_clk_init_parent(struct clk *clk)
+{
+ u32 val;
+
+ if (clk->parent)
+ return 0;
+
+ if (!clk->parent_table || !clk->parent_num)
+ return 0;
+
+ if (!clk->src_width) {
+ pr_err("sh_clk_init_parent: cannot select parent clock\n");
+ return -EINVAL;
+ }
+
+ val = (ioread32(clk->mapped_reg) >> clk->src_shift);
+ val &= (1 << clk->src_width) - 1;
+
+ if (val >= clk->parent_num) {
+ pr_err("sh_clk_init_parent: parent table size failed\n");
+ return -EINVAL;
+ }
+
+ clk->parent = clk->parent_table[val];
+ if (!clk->parent) {
+ pr_err("sh_clk_init_parent: unable to set parent");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
static int __init sh_clk_div6_register_ops(struct clk *clks, int nr,
struct clk_ops *ops)
{
@@ -190,8 +222,11 @@
clkp->ops = ops;
clkp->freq_table = freq_table + (k * freq_table_size);
clkp->freq_table[nr_divs].frequency = CPUFREQ_TABLE_END;
-
ret = clk_register(clkp);
+ if (ret < 0)
+ break;
+
+ ret = sh_clk_init_parent(clkp);
}
return ret;
@@ -217,7 +252,7 @@
clk_rate_table_build(clk, clk->freq_table, table->nr_divisors,
table, &clk->arch_flags);
- idx = (__raw_readl(clk->enable_reg) >> clk->enable_bit) & 0x000f;
+ idx = (ioread32(clk->mapped_reg) >> clk->enable_bit) & 0x000f;
return clk->freq_table[idx].frequency;
}
@@ -235,15 +270,15 @@
*/
if (parent->flags & CLK_ENABLE_ON_INIT)
- value = __raw_readl(clk->enable_reg) & ~(1 << 7);
+ value = ioread32(clk->mapped_reg) & ~(1 << 7);
else
- value = __raw_readl(clk->enable_reg) | (1 << 7);
+ value = ioread32(clk->mapped_reg) | (1 << 7);
ret = clk_reparent(clk, parent);
if (ret < 0)
return ret;
- __raw_writel(value, clk->enable_reg);
+ iowrite32(value, clk->mapped_reg);
/* Rebiuld the frequency table */
clk_rate_table_build(clk, clk->freq_table, table->nr_divisors,
@@ -260,10 +295,10 @@
if (idx < 0)
return idx;
- value = __raw_readl(clk->enable_reg);
+ value = ioread32(clk->mapped_reg);
value &= ~(0xf << clk->enable_bit);
value |= (idx << clk->enable_bit);
- __raw_writel(value, clk->enable_reg);
+ iowrite32(value, clk->mapped_reg);
if (d4t->kick)
d4t->kick(clk);
@@ -273,13 +308,13 @@
static int sh_clk_div4_enable(struct clk *clk)
{
- __raw_writel(__raw_readl(clk->enable_reg) & ~(1 << 8), clk->enable_reg);
+ iowrite32(ioread32(clk->mapped_reg) & ~(1 << 8), clk->mapped_reg);
return 0;
}
static void sh_clk_div4_disable(struct clk *clk)
{
- __raw_writel(__raw_readl(clk->enable_reg) | (1 << 8), clk->enable_reg);
+ iowrite32(ioread32(clk->mapped_reg) | (1 << 8), clk->mapped_reg);
}
static struct clk_ops sh_clk_div4_clk_ops = {
diff --git a/drivers/sh/pfc.c b/drivers/sh/pfc.c
index e67fe17..522c6c4 100644
--- a/drivers/sh/pfc.c
+++ b/drivers/sh/pfc.c
@@ -19,6 +19,75 @@
#include <linux/irq.h>
#include <linux/bitops.h>
#include <linux/gpio.h>
+#include <linux/slab.h>
+#include <linux/ioport.h>
+
+static void pfc_iounmap(struct pinmux_info *pip)
+{
+ int k;
+
+ for (k = 0; k < pip->num_resources; k++)
+ if (pip->window[k].virt)
+ iounmap(pip->window[k].virt);
+
+ kfree(pip->window);
+ pip->window = NULL;
+}
+
+static int pfc_ioremap(struct pinmux_info *pip)
+{
+ struct resource *res;
+ int k;
+
+ if (!pip->num_resources)
+ return 0;
+
+ pip->window = kzalloc(pip->num_resources * sizeof(*pip->window),
+ GFP_NOWAIT);
+ if (!pip->window)
+ goto err1;
+
+ for (k = 0; k < pip->num_resources; k++) {
+ res = pip->resource + k;
+ WARN_ON(resource_type(res) != IORESOURCE_MEM);
+ pip->window[k].phys = res->start;
+ pip->window[k].size = resource_size(res);
+ pip->window[k].virt = ioremap_nocache(res->start,
+ resource_size(res));
+ if (!pip->window[k].virt)
+ goto err2;
+ }
+
+ return 0;
+
+err2:
+ pfc_iounmap(pip);
+err1:
+ return -1;
+}
+
+static void __iomem *pfc_phys_to_virt(struct pinmux_info *pip,
+ unsigned long address)
+{
+ struct pfc_window *window;
+ int k;
+
+ /* scan through physical windows and convert address */
+ for (k = 0; k < pip->num_resources; k++) {
+ window = pip->window + k;
+
+ if (address < window->phys)
+ continue;
+
+ if (address >= (window->phys + window->size))
+ continue;
+
+ return window->virt + (address - window->phys);
+ }
+
+ /* no windows defined, register must be 1:1 mapped virt:phys */
+ return (void __iomem *)address;
+}
static int enum_in_range(pinmux_enum_t enum_id, struct pinmux_range *r)
{
@@ -31,41 +100,54 @@
return 1;
}
-static unsigned long gpio_read_raw_reg(unsigned long reg,
+static unsigned long gpio_read_raw_reg(void __iomem *mapped_reg,
unsigned long reg_width)
{
switch (reg_width) {
case 8:
- return __raw_readb(reg);
+ return ioread8(mapped_reg);
case 16:
- return __raw_readw(reg);
+ return ioread16(mapped_reg);
case 32:
- return __raw_readl(reg);
+ return ioread32(mapped_reg);
}
BUG();
return 0;
}
-static void gpio_write_raw_reg(unsigned long reg,
+static void gpio_write_raw_reg(void __iomem *mapped_reg,
unsigned long reg_width,
unsigned long data)
{
switch (reg_width) {
case 8:
- __raw_writeb(data, reg);
+ iowrite8(data, mapped_reg);
return;
case 16:
- __raw_writew(data, reg);
+ iowrite16(data, mapped_reg);
return;
case 32:
- __raw_writel(data, reg);
+ iowrite32(data, mapped_reg);
return;
}
BUG();
}
+static int gpio_read_bit(struct pinmux_data_reg *dr,
+ unsigned long in_pos)
+{
+ unsigned long pos;
+
+ pos = dr->reg_width - (in_pos + 1);
+
+ pr_debug("read_bit: addr = %lx, pos = %ld, "
+ "r_width = %ld\n", dr->reg, pos, dr->reg_width);
+
+ return (gpio_read_raw_reg(dr->mapped_reg, dr->reg_width) >> pos) & 1;
+}
+
static void gpio_write_bit(struct pinmux_data_reg *dr,
unsigned long in_pos, unsigned long value)
{
@@ -82,53 +164,72 @@
else
clear_bit(pos, &dr->reg_shadow);
- gpio_write_raw_reg(dr->reg, dr->reg_width, dr->reg_shadow);
+ gpio_write_raw_reg(dr->mapped_reg, dr->reg_width, dr->reg_shadow);
}
-static int gpio_read_reg(unsigned long reg, unsigned long reg_width,
- unsigned long field_width, unsigned long in_pos)
+static void config_reg_helper(struct pinmux_info *gpioc,
+ struct pinmux_cfg_reg *crp,
+ unsigned long in_pos,
+ void __iomem **mapped_regp,
+ unsigned long *maskp,
+ unsigned long *posp)
{
- unsigned long data, mask, pos;
+ int k;
- data = 0;
- mask = (1 << field_width) - 1;
- pos = reg_width - ((in_pos + 1) * field_width);
+ *mapped_regp = pfc_phys_to_virt(gpioc, crp->reg);
- pr_debug("read_reg: addr = %lx, pos = %ld, "
- "r_width = %ld, f_width = %ld\n",
- reg, pos, reg_width, field_width);
-
- data = gpio_read_raw_reg(reg, reg_width);
- return (data >> pos) & mask;
+ if (crp->field_width) {
+ *maskp = (1 << crp->field_width) - 1;
+ *posp = crp->reg_width - ((in_pos + 1) * crp->field_width);
+ } else {
+ *maskp = (1 << crp->var_field_width[in_pos]) - 1;
+ *posp = crp->reg_width;
+ for (k = 0; k <= in_pos; k++)
+ *posp -= crp->var_field_width[k];
+ }
}
-static void gpio_write_reg(unsigned long reg, unsigned long reg_width,
- unsigned long field_width, unsigned long in_pos,
- unsigned long value)
+static int read_config_reg(struct pinmux_info *gpioc,
+ struct pinmux_cfg_reg *crp,
+ unsigned long field)
{
+ void __iomem *mapped_reg;
unsigned long mask, pos;
- mask = (1 << field_width) - 1;
- pos = reg_width - ((in_pos + 1) * field_width);
+ config_reg_helper(gpioc, crp, field, &mapped_reg, &mask, &pos);
- pr_debug("write_reg addr = %lx, value = %ld, pos = %ld, "
+ pr_debug("read_reg: addr = %lx, field = %ld, "
"r_width = %ld, f_width = %ld\n",
- reg, value, pos, reg_width, field_width);
+ crp->reg, field, crp->reg_width, crp->field_width);
+
+ return (gpio_read_raw_reg(mapped_reg, crp->reg_width) >> pos) & mask;
+}
+
+static void write_config_reg(struct pinmux_info *gpioc,
+ struct pinmux_cfg_reg *crp,
+ unsigned long field, unsigned long value)
+{
+ void __iomem *mapped_reg;
+ unsigned long mask, pos, data;
+
+ config_reg_helper(gpioc, crp, field, &mapped_reg, &mask, &pos);
+
+ pr_debug("write_reg addr = %lx, value = %ld, field = %ld, "
+ "r_width = %ld, f_width = %ld\n",
+ crp->reg, value, field, crp->reg_width, crp->field_width);
mask = ~(mask << pos);
value = value << pos;
- switch (reg_width) {
- case 8:
- __raw_writeb((__raw_readb(reg) & mask) | value, reg);
- break;
- case 16:
- __raw_writew((__raw_readw(reg) & mask) | value, reg);
- break;
- case 32:
- __raw_writel((__raw_readl(reg) & mask) | value, reg);
- break;
- }
+ data = gpio_read_raw_reg(mapped_reg, crp->reg_width);
+ data &= mask;
+ data |= value;
+
+ if (gpioc->unlock_reg)
+ gpio_write_raw_reg(pfc_phys_to_virt(gpioc, gpioc->unlock_reg),
+ 32, ~data);
+
+ gpio_write_raw_reg(mapped_reg, crp->reg_width, data);
}
static int setup_data_reg(struct pinmux_info *gpioc, unsigned gpio)
@@ -147,6 +248,8 @@
if (!data_reg->reg_width)
break;
+ data_reg->mapped_reg = pfc_phys_to_virt(gpioc, data_reg->reg);
+
for (n = 0; n < data_reg->reg_width; n++) {
if (data_reg->enum_ids[n] == gpiop->enum_id) {
gpiop->flags &= ~PINMUX_FLAG_DREG;
@@ -179,7 +282,8 @@
if (!drp->reg_width)
break;
- drp->reg_shadow = gpio_read_raw_reg(drp->reg, drp->reg_width);
+ drp->reg_shadow = gpio_read_raw_reg(drp->mapped_reg,
+ drp->reg_width);
k++;
}
}
@@ -201,12 +305,13 @@
}
static int get_config_reg(struct pinmux_info *gpioc, pinmux_enum_t enum_id,
- struct pinmux_cfg_reg **crp, int *indexp,
+ struct pinmux_cfg_reg **crp,
+ int *fieldp, int *valuep,
unsigned long **cntp)
{
struct pinmux_cfg_reg *config_reg;
- unsigned long r_width, f_width;
- int k, n;
+ unsigned long r_width, f_width, curr_width, ncomb;
+ int k, m, n, pos, bit_pos;
k = 0;
while (1) {
@@ -217,13 +322,27 @@
if (!r_width)
break;
- for (n = 0; n < (r_width / f_width) * (1 << f_width); n++) {
- if (config_reg->enum_ids[n] == enum_id) {
- *crp = config_reg;
- *indexp = n;
- *cntp = &config_reg->cnt[n / (1 << f_width)];
- return 0;
+
+ pos = 0;
+ m = 0;
+ for (bit_pos = 0; bit_pos < r_width; bit_pos += curr_width) {
+ if (f_width)
+ curr_width = f_width;
+ else
+ curr_width = config_reg->var_field_width[m];
+
+ ncomb = 1 << curr_width;
+ for (n = 0; n < ncomb; n++) {
+ if (config_reg->enum_ids[pos + n] == enum_id) {
+ *crp = config_reg;
+ *fieldp = m;
+ *valuep = n;
+ *cntp = &config_reg->cnt[m];
+ return 0;
+ }
}
+ pos += ncomb;
+ m++;
}
k++;
}
@@ -261,36 +380,6 @@
return -1;
}
-static void write_config_reg(struct pinmux_info *gpioc,
- struct pinmux_cfg_reg *crp,
- int index)
-{
- unsigned long ncomb, pos, value;
-
- ncomb = 1 << crp->field_width;
- pos = index / ncomb;
- value = index % ncomb;
-
- gpio_write_reg(crp->reg, crp->reg_width, crp->field_width, pos, value);
-}
-
-static int check_config_reg(struct pinmux_info *gpioc,
- struct pinmux_cfg_reg *crp,
- int index)
-{
- unsigned long ncomb, pos, value;
-
- ncomb = 1 << crp->field_width;
- pos = index / ncomb;
- value = index % ncomb;
-
- if (gpio_read_reg(crp->reg, crp->reg_width,
- crp->field_width, pos) == value)
- return 0;
-
- return -1;
-}
-
enum { GPIO_CFG_DRYRUN, GPIO_CFG_REQ, GPIO_CFG_FREE };
static int pinmux_config_gpio(struct pinmux_info *gpioc, unsigned gpio,
@@ -299,7 +388,7 @@
struct pinmux_cfg_reg *cr = NULL;
pinmux_enum_t enum_id;
struct pinmux_range *range;
- int in_range, pos, index;
+ int in_range, pos, field, value;
unsigned long *cntp;
switch (pinmux_type) {
@@ -330,7 +419,8 @@
pos = 0;
enum_id = 0;
- index = 0;
+ field = 0;
+ value = 0;
while (1) {
pos = get_gpio_enum_id(gpioc, gpio, pos, &enum_id);
if (pos <= 0)
@@ -377,17 +467,19 @@
if (!in_range)
continue;
- if (get_config_reg(gpioc, enum_id, &cr, &index, &cntp) != 0)
+ if (get_config_reg(gpioc, enum_id, &cr,
+ &field, &value, &cntp) != 0)
goto out_err;
switch (cfg_mode) {
case GPIO_CFG_DRYRUN:
- if (!*cntp || !check_config_reg(gpioc, cr, index))
+ if (!*cntp ||
+ (read_config_reg(gpioc, cr, field) != value))
continue;
break;
case GPIO_CFG_REQ:
- write_config_reg(gpioc, cr, index);
+ write_config_reg(gpioc, cr, field, value);
*cntp = *cntp + 1;
break;
@@ -564,7 +656,7 @@
if (!gpioc || get_data_reg(gpioc, gpio, &dr, &bit) != 0)
return -EINVAL;
- return gpio_read_reg(dr->reg, dr->reg_width, 1, bit);
+ return gpio_read_bit(dr, bit);
}
static int sh_gpio_get(struct gpio_chip *chip, unsigned offset)
@@ -606,10 +698,15 @@
int register_pinmux(struct pinmux_info *pip)
{
struct gpio_chip *chip = &pip->chip;
+ int ret;
pr_info("%s handling gpio %d -> %d\n",
pip->name, pip->first_gpio, pip->last_gpio);
+ ret = pfc_ioremap(pip);
+ if (ret < 0)
+ return ret;
+
setup_data_regs(pip);
chip->request = sh_gpio_request;
@@ -627,12 +724,16 @@
chip->base = pip->first_gpio;
chip->ngpio = (pip->last_gpio - pip->first_gpio) + 1;
- return gpiochip_add(chip);
+ ret = gpiochip_add(chip);
+ if (ret < 0)
+ pfc_iounmap(pip);
+
+ return ret;
}
int unregister_pinmux(struct pinmux_info *pip)
{
pr_info("%s deregistering\n", pip->name);
-
+ pfc_iounmap(pip);
return gpiochip_remove(&pip->chip);
}
diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index aff9d61..9e62349 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -50,6 +50,7 @@
#include <linux/dma-mapping.h>
#include <linux/scatterlist.h>
#include <linux/slab.h>
+#include <linux/gpio.h>
#ifdef CONFIG_SUPERH
#include <asm/sh_bios.h>
@@ -73,6 +74,7 @@
struct clk *fclk;
char *irqstr[SCIx_NR_IRQS];
+ char *gpiostr[SCIx_NR_FNS];
struct dma_chan *chan_tx;
struct dma_chan *chan_rx;
@@ -474,8 +476,15 @@
if (!reg->size)
return;
- if (!(cflag & CRTSCTS))
- sci_out(port, SCSPTR, 0x0080); /* Set RTS = 1 */
+ if ((s->cfg->capabilities & SCIx_HAVE_RTSCTS) &&
+ ((!(cflag & CRTSCTS)))) {
+ unsigned short status;
+
+ status = sci_in(port, SCSPTR);
+ status &= ~SCSPTR_CTSIO;
+ status |= SCSPTR_RTSIO;
+ sci_out(port, SCSPTR, status); /* Set RTS = 1 */
+ }
}
static int sci_txfill(struct uart_port *port)
@@ -621,6 +630,7 @@
} else {
for (i = 0; i < count; i++) {
char c = sci_in(port, SCxRDR);
+
status = sci_in(port, SCxSR);
#if defined(CONFIG_CPU_SH3)
/* Skip "chars" during break */
@@ -649,9 +659,11 @@
/* Store data and status */
if (status & SCxSR_FER(port)) {
flag = TTY_FRAME;
+ port->icount.frame++;
dev_notice(port->dev, "frame error\n");
} else if (status & SCxSR_PER(port)) {
flag = TTY_PARITY;
+ port->icount.parity++;
dev_notice(port->dev, "parity error\n");
} else
flag = TTY_NORMAL;
@@ -723,6 +735,8 @@
*/
if (s->cfg->overrun_bit != SCIx_NOT_SUPPORTED) {
if (status & (1 << s->cfg->overrun_bit)) {
+ port->icount.overrun++;
+
/* overrun error */
if (tty_insert_flip_char(tty, 0, TTY_OVERRUN))
copied++;
@@ -737,6 +751,8 @@
struct sci_port *sci_port = to_sci_port(port);
if (!sci_port->break_flag) {
+ port->icount.brk++;
+
sci_port->break_flag = 1;
sci_schedule_break_timer(sci_port);
@@ -752,6 +768,8 @@
} else {
/* frame error */
+ port->icount.frame++;
+
if (tty_insert_flip_char(tty, 0, TTY_FRAME))
copied++;
@@ -761,6 +779,8 @@
if (status & SCxSR_PER(port)) {
/* parity error */
+ port->icount.parity++;
+
if (tty_insert_flip_char(tty, 0, TTY_PARITY))
copied++;
@@ -787,6 +807,8 @@
if ((sci_in(port, SCLSR) & (1 << s->cfg->overrun_bit))) {
sci_out(port, SCLSR, 0);
+ port->icount.overrun++;
+
tty_insert_flip_char(tty, 0, TTY_OVERRUN);
tty_flip_buffer_push(tty);
@@ -812,6 +834,9 @@
/* Debounce break */
s->break_flag = 1;
#endif
+
+ port->icount.brk++;
+
/* Notify of BREAK */
if (tty_insert_flip_char(tty, 0, TTY_BREAK))
copied++;
@@ -1082,6 +1107,67 @@
}
}
+static const char *sci_gpio_names[SCIx_NR_FNS] = {
+ "sck", "rxd", "txd", "cts", "rts",
+};
+
+static const char *sci_gpio_str(unsigned int index)
+{
+ return sci_gpio_names[index];
+}
+
+static void __devinit sci_init_gpios(struct sci_port *port)
+{
+ struct uart_port *up = &port->port;
+ int i;
+
+ if (!port->cfg)
+ return;
+
+ for (i = 0; i < SCIx_NR_FNS; i++) {
+ const char *desc;
+ int ret;
+
+ if (!port->cfg->gpios[i])
+ continue;
+
+ desc = sci_gpio_str(i);
+
+ port->gpiostr[i] = kasprintf(GFP_KERNEL, "%s:%s",
+ dev_name(up->dev), desc);
+
+ /*
+ * If we've failed the allocation, we can still continue
+ * on with a NULL string.
+ */
+ if (!port->gpiostr[i])
+ dev_notice(up->dev, "%s string allocation failure\n",
+ desc);
+
+ ret = gpio_request(port->cfg->gpios[i], port->gpiostr[i]);
+ if (unlikely(ret != 0)) {
+ dev_notice(up->dev, "failed %s gpio request\n", desc);
+
+ /*
+ * If we can't get the GPIO for whatever reason,
+ * no point in keeping the verbose string around.
+ */
+ kfree(port->gpiostr[i]);
+ }
+ }
+}
+
+static void sci_free_gpios(struct sci_port *port)
+{
+ int i;
+
+ for (i = 0; i < SCIx_NR_FNS; i++)
+ if (port->cfg->gpios[i]) {
+ gpio_free(port->cfg->gpios[i]);
+ kfree(port->gpiostr[i]);
+ }
+}
+
static unsigned int sci_tx_empty(struct uart_port *port)
{
unsigned short status = sci_in(port, SCxSR);
@@ -1090,19 +1176,39 @@
return (status & SCxSR_TEND(port)) && !in_tx_fifo ? TIOCSER_TEMT : 0;
}
+/*
+ * Modem control is a bit of a mixed bag for SCI(F) ports. Generally
+ * CTS/RTS is supported in hardware by at least one port and controlled
+ * via SCSPTR (SCxPCR for SCIFA/B parts), or external pins (presently
+ * handled via the ->init_pins() op, which is a bit of a one-way street,
+ * lacking any ability to defer pin control -- this will later be
+ * converted over to the GPIO framework).
+ *
+ * Other modes (such as loopback) are supported generically on certain
+ * port types, but not others. For these it's sufficient to test for the
+ * existence of the support register and simply ignore the port type.
+ */
static void sci_set_mctrl(struct uart_port *port, unsigned int mctrl)
{
- /* This routine is used for seting signals of: DTR, DCD, CTS/RTS */
- /* We use SCIF's hardware for CTS/RTS, so don't need any for that. */
- /* If you have signals for DTR and DCD, please implement here. */
+ if (mctrl & TIOCM_LOOP) {
+ struct plat_sci_reg *reg;
+
+ /*
+ * Standard loopback mode for SCFCR ports.
+ */
+ reg = sci_getreg(port, SCFCR);
+ if (reg->size)
+ sci_out(port, SCFCR, sci_in(port, SCFCR) | 1);
+ }
}
static unsigned int sci_get_mctrl(struct uart_port *port)
{
- /* This routine is used for getting signals of: DTR, DCD, DSR, RI,
- and CTS/RTS */
-
- return TIOCM_DTR | TIOCM_RTS | TIOCM_CTS | TIOCM_DSR;
+ /*
+ * CTS/RTS is handled in hardware when supported, while nothing
+ * else is wired up. Keep it simple and simply assert DSR/CAR.
+ */
+ return TIOCM_DSR | TIOCM_CAR;
}
#ifdef CONFIG_SERIAL_SH_SCI_DMA
@@ -1449,12 +1555,17 @@
static void sci_enable_ms(struct uart_port *port)
{
- /* Nothing here yet .. */
+ /*
+ * Not supported by hardware, always a nop.
+ */
}
static void sci_break_ctl(struct uart_port *port, int break_state)
{
- /* Nothing here yet .. */
+ /*
+ * Not supported by hardware. Most parts couple break and rx
+ * interrupts together, with break detection always enabled.
+ */
}
#ifdef CONFIG_SERIAL_SH_SCI_DMA
@@ -1652,6 +1763,7 @@
static void sci_reset(struct uart_port *port)
{
+ struct plat_sci_reg *reg;
unsigned int status;
do {
@@ -1660,7 +1772,8 @@
sci_out(port, SCSCR, 0x00); /* TE=0, RE=0, CKE1=0 */
- if (port->type != PORT_SCI)
+ reg = sci_getreg(port, SCFCR);
+ if (reg->size)
sci_out(port, SCFCR, SCFCR_RFRST | SCFCR_TFRST);
}
@@ -1668,9 +1781,9 @@
struct ktermios *old)
{
struct sci_port *s = to_sci_port(port);
+ struct plat_sci_reg *reg;
unsigned int baud, smr_val, max_baud;
int t = -1;
- u16 scfcr = 0;
/*
* earlyprintk comes here early on with port->uartclk set to zero.
@@ -1720,7 +1833,27 @@
}
sci_init_pins(port, termios->c_cflag);
- sci_out(port, SCFCR, scfcr | ((termios->c_cflag & CRTSCTS) ? SCFCR_MCE : 0));
+
+ reg = sci_getreg(port, SCFCR);
+ if (reg->size) {
+ unsigned short ctrl = sci_in(port, SCFCR);
+
+ if (s->cfg->capabilities & SCIx_HAVE_RTSCTS) {
+ if (termios->c_cflag & CRTSCTS)
+ ctrl |= SCFCR_MCE;
+ else
+ ctrl &= ~SCFCR_MCE;
+ }
+
+ /*
+ * As we've done a sci_reset() above, ensure we don't
+ * interfere with the FIFOs while toggling MCE. As the
+ * reset values could still be set, simply mask them out.
+ */
+ ctrl &= ~(SCFCR_RFRST | SCFCR_TFRST);
+
+ sci_out(port, SCFCR, ctrl);
+ }
sci_out(port, SCSCR, s->cfg->scscr);
@@ -1892,6 +2025,8 @@
struct uart_port *port = &sci_port->port;
int ret;
+ sci_port->cfg = p;
+
port->ops = &sci_uart_ops;
port->iotype = UPIO_MEM;
port->line = index;
@@ -1937,6 +2072,8 @@
port->dev = &dev->dev;
+ sci_init_gpios(sci_port);
+
pm_runtime_irq_safe(&dev->dev);
pm_runtime_enable(&dev->dev);
}
@@ -1971,8 +2108,6 @@
p->error_mask |= (1 << p->overrun_bit);
}
- sci_port->cfg = p;
-
port->mapbase = p->mapbase;
port->type = p->type;
port->flags = p->flags;
@@ -2113,9 +2248,16 @@
struct uart_port *port = &sci_port->port;
if (uart_console(port)) {
+ struct plat_sci_reg *reg;
+
sci_port->saved_smr = sci_in(port, SCSMR);
sci_port->saved_brr = sci_in(port, SCBRR);
- sci_port->saved_fcr = sci_in(port, SCFCR);
+
+ reg = sci_getreg(port, SCFCR);
+ if (reg->size)
+ sci_port->saved_fcr = sci_in(port, SCFCR);
+ else
+ sci_port->saved_fcr = 0;
}
return 0;
}
@@ -2129,7 +2271,10 @@
sci_reset(port);
sci_out(port, SCSMR, sci_port->saved_smr);
sci_out(port, SCBRR, sci_port->saved_brr);
- sci_out(port, SCFCR, sci_port->saved_fcr);
+
+ if (sci_port->saved_fcr)
+ sci_out(port, SCFCR, sci_port->saved_fcr);
+
sci_out(port, SCSCR, sci_port->cfg->scscr);
}
return 0;
@@ -2169,6 +2314,8 @@
cpufreq_unregister_notifier(&port->freq_transition,
CPUFREQ_TRANSITION_NOTIFIER);
+ sci_free_gpios(port);
+
uart_remove_one_port(&sci_uart_driver, &port->port);
clk_put(port->iclk);
diff --git a/drivers/tty/serial/sh-sci.h b/drivers/tty/serial/sh-sci.h
index e9bed03..a1a2d36 100644
--- a/drivers/tty/serial/sh-sci.h
+++ b/drivers/tty/serial/sh-sci.h
@@ -17,7 +17,9 @@
defined(CONFIG_ARCH_SH73A0) || \
defined(CONFIG_ARCH_SH7367) || \
defined(CONFIG_ARCH_SH7377) || \
- defined(CONFIG_ARCH_SH7372)
+ defined(CONFIG_ARCH_SH7372) || \
+ defined(CONFIG_ARCH_R8A7740)
+
# define SCxSR_RDxF_CLEAR(port) (sci_in(port, SCxSR) & 0xfffc)
# define SCxSR_ERROR_CLEAR(port) (sci_in(port, SCxSR) & 0xfd73)
# define SCxSR_TDxE_CLEAR(port) (sci_in(port, SCxSR) & 0xffdf)
diff --git a/drivers/uio/uio_pci_generic.c b/drivers/uio/uio_pci_generic.c
index 02bd47b..0bd08ef 100644
--- a/drivers/uio/uio_pci_generic.c
+++ b/drivers/uio/uio_pci_generic.c
@@ -45,77 +45,12 @@
static irqreturn_t irqhandler(int irq, struct uio_info *info)
{
struct uio_pci_generic_dev *gdev = to_uio_pci_generic_dev(info);
- struct pci_dev *pdev = gdev->pdev;
- irqreturn_t ret = IRQ_NONE;
- u32 cmd_status_dword;
- u16 origcmd, newcmd, status;
- /* We do a single dword read to retrieve both command and status.
- * Document assumptions that make this possible. */
- BUILD_BUG_ON(PCI_COMMAND % 4);
- BUILD_BUG_ON(PCI_COMMAND + 2 != PCI_STATUS);
-
- pci_block_user_cfg_access(pdev);
-
- /* Read both command and status registers in a single 32-bit operation.
- * Note: we could cache the value for command and move the status read
- * out of the lock if there was a way to get notified of user changes
- * to command register through sysfs. Should be good for shared irqs. */
- pci_read_config_dword(pdev, PCI_COMMAND, &cmd_status_dword);
- origcmd = cmd_status_dword;
- status = cmd_status_dword >> 16;
-
- /* Check interrupt status register to see whether our device
- * triggered the interrupt. */
- if (!(status & PCI_STATUS_INTERRUPT))
- goto done;
-
- /* We triggered the interrupt, disable it. */
- newcmd = origcmd | PCI_COMMAND_INTX_DISABLE;
- if (newcmd != origcmd)
- pci_write_config_word(pdev, PCI_COMMAND, newcmd);
+ if (!pci_check_and_mask_intx(gdev->pdev))
+ return IRQ_NONE;
/* UIO core will signal the user process. */
- ret = IRQ_HANDLED;
-done:
-
- pci_unblock_user_cfg_access(pdev);
- return ret;
-}
-
-/* Verify that the device supports Interrupt Disable bit in command register,
- * per PCI 2.3, by flipping this bit and reading it back: this bit was readonly
- * in PCI 2.2. */
-static int __devinit verify_pci_2_3(struct pci_dev *pdev)
-{
- u16 orig, new;
- int err = 0;
-
- pci_block_user_cfg_access(pdev);
- pci_read_config_word(pdev, PCI_COMMAND, &orig);
- pci_write_config_word(pdev, PCI_COMMAND,
- orig ^ PCI_COMMAND_INTX_DISABLE);
- pci_read_config_word(pdev, PCI_COMMAND, &new);
- /* There's no way to protect against
- * hardware bugs or detect them reliably, but as long as we know
- * what the value should be, let's go ahead and check it. */
- if ((new ^ orig) & ~PCI_COMMAND_INTX_DISABLE) {
- err = -EBUSY;
- dev_err(&pdev->dev, "Command changed from 0x%x to 0x%x: "
- "driver or HW bug?\n", orig, new);
- goto err;
- }
- if (!((new ^ orig) & PCI_COMMAND_INTX_DISABLE)) {
- dev_warn(&pdev->dev, "Device does not support "
- "disabling interrupts: unable to bind.\n");
- err = -ENODEV;
- goto err;
- }
- /* Now restore the original value. */
- pci_write_config_word(pdev, PCI_COMMAND, orig);
-err:
- pci_unblock_user_cfg_access(pdev);
- return err;
+ return IRQ_HANDLED;
}
static int __devinit probe(struct pci_dev *pdev,
@@ -138,9 +73,10 @@
return -ENODEV;
}
- err = verify_pci_2_3(pdev);
- if (err)
+ if (!pci_intx_mask_supported(pdev)) {
+ err = -ENODEV;
goto err_verify;
+ }
gdev = kzalloc(sizeof(struct uio_pci_generic_dev), GFP_KERNEL);
if (!gdev) {
diff --git a/fs/autofs4/autofs_i.h b/fs/autofs4/autofs_i.h
index 5869d4e..d8d8e7b 100644
--- a/fs/autofs4/autofs_i.h
+++ b/fs/autofs4/autofs_i.h
@@ -116,6 +116,7 @@
int needs_reghost;
struct super_block *sb;
struct mutex wq_mutex;
+ struct mutex pipe_mutex;
spinlock_t fs_lock;
struct autofs_wait_queue *queues; /* Wait queue pointer */
spinlock_t lookup_lock;
diff --git a/fs/autofs4/inode.c b/fs/autofs4/inode.c
index 2ba44c7..e16980b 100644
--- a/fs/autofs4/inode.c
+++ b/fs/autofs4/inode.c
@@ -225,6 +225,7 @@
sbi->min_proto = 0;
sbi->max_proto = 0;
mutex_init(&sbi->wq_mutex);
+ mutex_init(&sbi->pipe_mutex);
spin_lock_init(&sbi->fs_lock);
sbi->queues = NULL;
spin_lock_init(&sbi->lookup_lock);
diff --git a/fs/autofs4/waitq.c b/fs/autofs4/waitq.c
index e1fbdee..9ef5b29 100644
--- a/fs/autofs4/waitq.c
+++ b/fs/autofs4/waitq.c
@@ -56,26 +56,27 @@
mutex_unlock(&sbi->wq_mutex);
}
-static int autofs4_write(struct file *file, const void *addr, int bytes)
+static int autofs4_write(struct autofs_sb_info *sbi,
+ struct file *file, const void *addr, int bytes)
{
unsigned long sigpipe, flags;
mm_segment_t fs;
const char *data = (const char *)addr;
ssize_t wr = 0;
- /** WARNING: this is not safe for writing more than PIPE_BUF bytes! **/
-
sigpipe = sigismember(¤t->pending.signal, SIGPIPE);
/* Save pointer to user space and point back to kernel space */
fs = get_fs();
set_fs(KERNEL_DS);
+ mutex_lock(&sbi->pipe_mutex);
while (bytes &&
(wr = file->f_op->write(file,data,bytes,&file->f_pos)) > 0) {
data += wr;
bytes -= wr;
}
+ mutex_lock(&sbi->pipe_mutex);
set_fs(fs);
@@ -110,6 +111,13 @@
pkt.hdr.proto_version = sbi->version;
pkt.hdr.type = type;
+ mutex_lock(&sbi->wq_mutex);
+
+ /* Check if we have become catatonic */
+ if (sbi->catatonic) {
+ mutex_unlock(&sbi->wq_mutex);
+ return;
+ }
switch (type) {
/* Kernel protocol v4 missing and expire packets */
case autofs_ptype_missing:
@@ -163,22 +171,18 @@
}
default:
printk("autofs4_notify_daemon: bad type %d!\n", type);
+ mutex_unlock(&sbi->wq_mutex);
return;
}
- /* Check if we have become catatonic */
- mutex_lock(&sbi->wq_mutex);
- if (!sbi->catatonic) {
- pipe = sbi->pipe;
- get_file(pipe);
- }
+ pipe = sbi->pipe;
+ get_file(pipe);
+
mutex_unlock(&sbi->wq_mutex);
- if (pipe) {
- if (autofs4_write(pipe, &pkt, pktsz))
- autofs4_catatonic_mode(sbi);
- fput(pipe);
- }
+ if (autofs4_write(sbi, pipe, &pkt, pktsz))
+ autofs4_catatonic_mode(sbi);
+ fput(pipe);
}
static int autofs4_getpath(struct autofs_sb_info *sbi,
@@ -257,6 +261,9 @@
struct autofs_wait_queue *wq;
struct autofs_info *ino;
+ if (sbi->catatonic)
+ return -ENOENT;
+
/* Wait in progress, continue; */
wq = autofs4_find_wait(sbi, qstr);
if (wq) {
@@ -289,6 +296,9 @@
if (mutex_lock_interruptible(&sbi->wq_mutex))
return -EINTR;
+ if (sbi->catatonic)
+ return -ENOENT;
+
wq = autofs4_find_wait(sbi, qstr);
if (wq) {
*wait = wq;
@@ -389,7 +399,7 @@
ret = validate_request(&wq, sbi, &qstr, dentry, notify);
if (ret <= 0) {
- if (ret == 0)
+ if (ret != -EINTR)
mutex_unlock(&sbi->wq_mutex);
kfree(qstr.name);
return ret;
diff --git a/fs/block_dev.c b/fs/block_dev.c
index 69a5b6f..afe74dd 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -25,7 +25,6 @@
#include <linux/uio.h>
#include <linux/namei.h>
#include <linux/log2.h>
-#include <linux/kmemleak.h>
#include <linux/cleancache.h>
#include <asm/uaccess.h>
#include "internal.h"
@@ -521,7 +520,7 @@
void __init bdev_cache_init(void)
{
int err;
- struct vfsmount *bd_mnt;
+ static struct vfsmount *bd_mnt;
bdev_cachep = kmem_cache_create("bdev_cache", sizeof(struct bdev_inode),
0, (SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT|
@@ -533,12 +532,7 @@
bd_mnt = kern_mount(&bd_type);
if (IS_ERR(bd_mnt))
panic("Cannot create bdev pseudo-fs");
- /*
- * This vfsmount structure is only used to obtain the
- * blockdev_superblock, so tell kmemleak not to report it.
- */
- kmemleak_not_leak(bd_mnt);
- blockdev_superblock = bd_mnt->mnt_sb; /* For writeback */
+ blockdev_superblock = bd_mnt->mnt_sb; /* For writeback */
}
/*
diff --git a/fs/coda/cnode.c b/fs/coda/cnode.c
index 6475877..911cf30 100644
--- a/fs/coda/cnode.c
+++ b/fs/coda/cnode.c
@@ -88,24 +88,21 @@
- link the two up if this is needed
- fill in the attributes
*/
-int coda_cnode_make(struct inode **inode, struct CodaFid *fid, struct super_block *sb)
+struct inode *coda_cnode_make(struct CodaFid *fid, struct super_block *sb)
{
struct coda_vattr attr;
+ struct inode *inode;
int error;
/* We get inode numbers from Venus -- see venus source */
error = venus_getattr(sb, fid, &attr);
- if ( error ) {
- *inode = NULL;
- return error;
- }
+ if (error)
+ return ERR_PTR(error);
- *inode = coda_iget(sb, fid, &attr);
- if ( IS_ERR(*inode) ) {
+ inode = coda_iget(sb, fid, &attr);
+ if (IS_ERR(inode))
printk("coda_cnode_make: coda_iget failed\n");
- return PTR_ERR(*inode);
- }
- return 0;
+ return inode;
}
@@ -156,19 +153,16 @@
}
/* the CONTROL inode is made without asking attributes from Venus */
-int coda_cnode_makectl(struct inode **inode, struct super_block *sb)
+struct inode *coda_cnode_makectl(struct super_block *sb)
{
- int error = -ENOMEM;
-
- *inode = new_inode(sb);
- if (*inode) {
- (*inode)->i_ino = CTL_INO;
- (*inode)->i_op = &coda_ioctl_inode_operations;
- (*inode)->i_fop = &coda_ioctl_operations;
- (*inode)->i_mode = 0444;
- error = 0;
+ struct inode *inode = new_inode(sb);
+ if (inode) {
+ inode->i_ino = CTL_INO;
+ inode->i_op = &coda_ioctl_inode_operations;
+ inode->i_fop = &coda_ioctl_operations;
+ inode->i_mode = 0444;
+ return inode;
}
-
- return error;
+ return ERR_PTR(-ENOMEM);
}
diff --git a/fs/coda/coda_fs_i.h b/fs/coda/coda_fs_i.h
index e35071b..b24fdfd 100644
--- a/fs/coda/coda_fs_i.h
+++ b/fs/coda/coda_fs_i.h
@@ -49,9 +49,9 @@
#define C_DYING 0x4 /* from venus (which died) */
#define C_PURGE 0x8
-int coda_cnode_make(struct inode **, struct CodaFid *, struct super_block *);
+struct inode *coda_cnode_make(struct CodaFid *, struct super_block *);
struct inode *coda_iget(struct super_block *sb, struct CodaFid *fid, struct coda_vattr *attr);
-int coda_cnode_makectl(struct inode **inode, struct super_block *sb);
+struct inode *coda_cnode_makectl(struct super_block *sb);
struct inode *coda_fid_to_inode(struct CodaFid *fid, struct super_block *sb);
void coda_replace_fid(struct inode *, struct CodaFid *, struct CodaFid *);
diff --git a/fs/coda/dir.c b/fs/coda/dir.c
index 83d2fd8..1775158 100644
--- a/fs/coda/dir.c
+++ b/fs/coda/dir.c
@@ -96,12 +96,11 @@
/* access routines: lookup, readlink, permission */
static struct dentry *coda_lookup(struct inode *dir, struct dentry *entry, struct nameidata *nd)
{
- struct inode *inode = NULL;
- struct CodaFid resfid = { { 0, } };
- int type = 0;
- int error = 0;
+ struct super_block *sb = dir->i_sb;
const char *name = entry->d_name.name;
size_t length = entry->d_name.len;
+ struct inode *inode;
+ int type = 0;
if (length > CODA_MAXNAMLEN) {
printk(KERN_ERR "name too long: lookup, %s (%*s)\n",
@@ -111,23 +110,21 @@
/* control object, create inode on the fly */
if (coda_isroot(dir) && coda_iscontrol(name, length)) {
- error = coda_cnode_makectl(&inode, dir->i_sb);
+ inode = coda_cnode_makectl(sb);
type = CODA_NOCACHE;
- goto exit;
+ } else {
+ struct CodaFid fid = { { 0, } };
+ int error = venus_lookup(sb, coda_i2f(dir), name, length,
+ &type, &fid);
+ inode = !error ? coda_cnode_make(&fid, sb) : ERR_PTR(error);
}
- error = venus_lookup(dir->i_sb, coda_i2f(dir), name, length,
- &type, &resfid);
- if (!error)
- error = coda_cnode_make(&inode, &resfid, dir->i_sb);
-
- if (error && error != -ENOENT)
- return ERR_PTR(error);
-
-exit:
- if (inode && (type & CODA_NOCACHE))
+ if (!IS_ERR(inode) && (type & CODA_NOCACHE))
coda_flag_inode(inode, C_VATTR | C_PURGE);
+ if (inode == ERR_PTR(-ENOENT))
+ inode = NULL;
+
return d_splice_alias(inode, entry);
}
diff --git a/fs/coda/inode.c b/fs/coda/inode.c
index 1c08a8c..5e2e1b3 100644
--- a/fs/coda/inode.c
+++ b/fs/coda/inode.c
@@ -204,10 +204,12 @@
printk("coda_read_super: rootfid is %s\n", coda_f2s(&fid));
/* make root inode */
- error = coda_cnode_make(&root, &fid, sb);
- if ( error || !root ) {
- printk("Failure of coda_cnode_make for root: error %d\n", error);
- goto error;
+ root = coda_cnode_make(&fid, sb);
+ if (IS_ERR(root)) {
+ error = PTR_ERR(root);
+ printk("Failure of coda_cnode_make for root: error %d\n", error);
+ root = NULL;
+ goto error;
}
printk("coda_read_super: rootinode is %ld dev %s\n",
diff --git a/fs/dcache.c b/fs/dcache.c
index 3c6d311..616fedf 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -243,6 +243,7 @@
static void __dentry_lru_del(struct dentry *dentry)
{
list_del_init(&dentry->d_lru);
+ dentry->d_flags &= ~DCACHE_SHRINK_LIST;
dentry->d_sb->s_nr_dentry_unused--;
dentry_stat.nr_unused--;
}
@@ -806,6 +807,7 @@
spin_unlock(&dentry->d_lock);
} else {
list_move_tail(&dentry->d_lru, &tmp);
+ dentry->d_flags |= DCACHE_SHRINK_LIST;
spin_unlock(&dentry->d_lock);
if (!--count)
break;
@@ -1097,14 +1099,19 @@
/*
* move only zero ref count dentries to the dispose list.
+ *
+ * Those which are presently on the shrink list, being processed
+ * by shrink_dentry_list(), shouldn't be moved. Otherwise the
+ * loop in shrink_dcache_parent() might not make any progress
+ * and loop forever.
*/
- if (!dentry->d_count) {
- dentry_lru_move_list(dentry, dispose);
- found++;
- } else {
+ if (dentry->d_count) {
dentry_lru_del(dentry);
+ } else if (!(dentry->d_flags & DCACHE_SHRINK_LIST)) {
+ dentry_lru_move_list(dentry, dispose);
+ dentry->d_flags |= DCACHE_SHRINK_LIST;
+ found++;
}
-
/*
* We can return to the caller if we have found some (this
* ensures forward progress). We'll be coming back to find
diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c
index edf0a80..427682c 100644
--- a/fs/hfsplus/super.c
+++ b/fs/hfsplus/super.c
@@ -499,9 +499,16 @@
if (!sbi->hidden_dir) {
mutex_lock(&sbi->vh_mutex);
sbi->hidden_dir = hfsplus_new_inode(sb, S_IFDIR);
- hfsplus_create_cat(sbi->hidden_dir->i_ino, root, &str,
- sbi->hidden_dir);
+ if (!sbi->hidden_dir) {
+ mutex_unlock(&sbi->vh_mutex);
+ err = -ENOMEM;
+ goto out_put_root;
+ }
+ err = hfsplus_create_cat(sbi->hidden_dir->i_ino, root,
+ &str, sbi->hidden_dir);
mutex_unlock(&sbi->vh_mutex);
+ if (err)
+ goto out_put_hidden_dir;
hfsplus_mark_inode_dirty(sbi->hidden_dir,
HFSPLUS_I_CAT_DIRTY);
diff --git a/include/crypto/algapi.h b/include/crypto/algapi.h
index ecc721d..418d270 100644
--- a/include/crypto/algapi.h
+++ b/include/crypto/algapi.h
@@ -134,6 +134,7 @@
int crypto_register_instance(struct crypto_template *tmpl,
struct crypto_instance *inst);
+int crypto_unregister_instance(struct crypto_alg *alg);
int crypto_init_spawn(struct crypto_spawn *spawn, struct crypto_alg *alg,
struct crypto_instance *inst, u32 mask);
diff --git a/include/crypto/lrw.h b/include/crypto/lrw.h
new file mode 100644
index 0000000..25a2c87
--- /dev/null
+++ b/include/crypto/lrw.h
@@ -0,0 +1,43 @@
+#ifndef _CRYPTO_LRW_H
+#define _CRYPTO_LRW_H
+
+#include <crypto/b128ops.h>
+
+struct scatterlist;
+struct gf128mul_64k;
+struct blkcipher_desc;
+
+#define LRW_BLOCK_SIZE 16
+
+struct lrw_table_ctx {
+ /* optimizes multiplying a random (non incrementing, as at the
+ * start of a new sector) value with key2, we could also have
+ * used 4k optimization tables or no optimization at all. In the
+ * latter case we would have to store key2 here */
+ struct gf128mul_64k *table;
+ /* stores:
+ * key2*{ 0,0,...0,0,0,0,1 }, key2*{ 0,0,...0,0,0,1,1 },
+ * key2*{ 0,0,...0,0,1,1,1 }, key2*{ 0,0,...0,1,1,1,1 }
+ * key2*{ 0,0,...1,1,1,1,1 }, etc
+ * needed for optimized multiplication of incrementing values
+ * with key2 */
+ be128 mulinc[128];
+};
+
+int lrw_init_table(struct lrw_table_ctx *ctx, const u8 *tweak);
+void lrw_free_table(struct lrw_table_ctx *ctx);
+
+struct lrw_crypt_req {
+ be128 *tbuf;
+ unsigned int tbuflen;
+
+ struct lrw_table_ctx *table_ctx;
+ void *crypt_ctx;
+ void (*crypt_fn)(void *ctx, u8 *blks, unsigned int nbytes);
+};
+
+int lrw_crypt(struct blkcipher_desc *desc, struct scatterlist *dst,
+ struct scatterlist *src, unsigned int nbytes,
+ struct lrw_crypt_req *req);
+
+#endif /* _CRYPTO_LRW_H */
diff --git a/include/crypto/serpent.h b/include/crypto/serpent.h
new file mode 100644
index 0000000..b7e0941
--- /dev/null
+++ b/include/crypto/serpent.h
@@ -0,0 +1,27 @@
+/*
+ * Common values for serpent algorithms
+ */
+
+#ifndef _CRYPTO_SERPENT_H
+#define _CRYPTO_SERPENT_H
+
+#include <linux/types.h>
+#include <linux/crypto.h>
+
+#define SERPENT_MIN_KEY_SIZE 0
+#define SERPENT_MAX_KEY_SIZE 32
+#define SERPENT_EXPKEY_WORDS 132
+#define SERPENT_BLOCK_SIZE 16
+
+struct serpent_ctx {
+ u32 expkey[SERPENT_EXPKEY_WORDS];
+};
+
+int __serpent_setkey(struct serpent_ctx *ctx, const u8 *key,
+ unsigned int keylen);
+int serpent_setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen);
+
+void __serpent_encrypt(struct serpent_ctx *ctx, u8 *dst, const u8 *src);
+void __serpent_decrypt(struct serpent_ctx *ctx, u8 *dst, const u8 *src);
+
+#endif
diff --git a/include/crypto/twofish.h b/include/crypto/twofish.h
index c408522..095c901 100644
--- a/include/crypto/twofish.h
+++ b/include/crypto/twofish.h
@@ -17,6 +17,8 @@
u32 s[4][256], w[8], k[32];
};
+int __twofish_setkey(struct twofish_ctx *ctx, const u8 *key,
+ unsigned int key_len, u32 *flags);
int twofish_setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int key_len);
#endif
diff --git a/include/crypto/xts.h b/include/crypto/xts.h
new file mode 100644
index 0000000..72c09eb
--- /dev/null
+++ b/include/crypto/xts.h
@@ -0,0 +1,27 @@
+#ifndef _CRYPTO_XTS_H
+#define _CRYPTO_XTS_H
+
+#include <crypto/b128ops.h>
+
+struct scatterlist;
+struct blkcipher_desc;
+
+#define XTS_BLOCK_SIZE 16
+
+struct xts_crypt_req {
+ be128 *tbuf;
+ unsigned int tbuflen;
+
+ void *tweak_ctx;
+ void (*tweak_fn)(void *ctx, u8* dst, const u8* src);
+ void *crypt_ctx;
+ void (*crypt_fn)(void *ctx, u8 *blks, unsigned int nbytes);
+};
+
+#define XTS_TWEAK_CAST(x) ((void (*)(void *, u8*, const u8*))(x))
+
+int xts_crypt(struct blkcipher_desc *desc, struct scatterlist *dst,
+ struct scatterlist *src, unsigned int nbytes,
+ struct xts_crypt_req *req);
+
+#endif /* _CRYPTO_XTS_H */
diff --git a/include/linux/dcache.h b/include/linux/dcache.h
index a47bda5..31f7322 100644
--- a/include/linux/dcache.h
+++ b/include/linux/dcache.h
@@ -203,6 +203,7 @@
#define DCACHE_CANT_MOUNT 0x0100
#define DCACHE_GENOCIDE 0x0200
+#define DCACHE_SHRINK_LIST 0x0400
#define DCACHE_NFSFS_RENAMED 0x1000
/* this dentry has been "silly renamed" and has to be deleted on the last
diff --git a/include/linux/digsig.h b/include/linux/digsig.h
new file mode 100644
index 0000000..efae755
--- /dev/null
+++ b/include/linux/digsig.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2011 Nokia Corporation
+ * Copyright (C) 2011 Intel Corporation
+ *
+ * Author:
+ * Dmitry Kasatkin <dmitry.kasatkin@nokia.com>
+ * <dmitry.kasatkin@intel.com>
+ *
+ * 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, version 2 of the License.
+ *
+ */
+
+#ifndef _DIGSIG_H
+#define _DIGSIG_H
+
+#include <linux/key.h>
+
+enum pubkey_algo {
+ PUBKEY_ALGO_RSA,
+ PUBKEY_ALGO_MAX,
+};
+
+enum digest_algo {
+ DIGEST_ALGO_SHA1,
+ DIGEST_ALGO_SHA256,
+ DIGEST_ALGO_MAX
+};
+
+struct pubkey_hdr {
+ uint8_t version; /* key format version */
+ time_t timestamp; /* key made, always 0 for now */
+ uint8_t algo;
+ uint8_t nmpi;
+ char mpi[0];
+} __packed;
+
+struct signature_hdr {
+ uint8_t version; /* signature format version */
+ time_t timestamp; /* signature made */
+ uint8_t algo;
+ uint8_t hash;
+ uint8_t keyid[8];
+ uint8_t nmpi;
+ char mpi[0];
+} __packed;
+
+#if defined(CONFIG_DIGSIG) || defined(CONFIG_DIGSIG_MODULE)
+
+int digsig_verify(struct key *keyring, const char *sig, int siglen,
+ const char *digest, int digestlen);
+
+#else
+
+static inline int digsig_verify(struct key *keyring, const char *sig,
+ int siglen, const char *digest, int digestlen)
+{
+ return -EOPNOTSUPP;
+}
+
+#endif /* CONFIG_DIGSIG */
+
+#endif /* _DIGSIG_H */
diff --git a/include/linux/efi.h b/include/linux/efi.h
index 2362a0b..37c3007 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -109,6 +109,14 @@
u32 imagesize;
} efi_capsule_header_t;
+/*
+ * Allocation types for calls to boottime->allocate_pages.
+ */
+#define EFI_ALLOCATE_ANY_PAGES 0
+#define EFI_ALLOCATE_MAX_ADDRESS 1
+#define EFI_ALLOCATE_ADDRESS 2
+#define EFI_MAX_ALLOCATE_TYPE 3
+
typedef int (*efi_freemem_callback_t) (u64 start, u64 end, void *arg);
/*
@@ -139,6 +147,57 @@
} efi_time_cap_t;
/*
+ * EFI Boot Services table
+ */
+typedef struct {
+ efi_table_hdr_t hdr;
+ void *raise_tpl;
+ void *restore_tpl;
+ void *allocate_pages;
+ void *free_pages;
+ void *get_memory_map;
+ void *allocate_pool;
+ void *free_pool;
+ void *create_event;
+ void *set_timer;
+ void *wait_for_event;
+ void *signal_event;
+ void *close_event;
+ void *check_event;
+ void *install_protocol_interface;
+ void *reinstall_protocol_interface;
+ void *uninstall_protocol_interface;
+ void *handle_protocol;
+ void *__reserved;
+ void *register_protocol_notify;
+ void *locate_handle;
+ void *locate_device_path;
+ void *install_configuration_table;
+ void *load_image;
+ void *start_image;
+ void *exit;
+ void *unload_image;
+ void *exit_boot_services;
+ void *get_next_monotonic_count;
+ void *stall;
+ void *set_watchdog_timer;
+ void *connect_controller;
+ void *disconnect_controller;
+ void *open_protocol;
+ void *close_protocol;
+ void *open_protocol_information;
+ void *protocols_per_handle;
+ void *locate_handle_buffer;
+ void *locate_protocol;
+ void *install_multiple_protocol_interfaces;
+ void *uninstall_multiple_protocol_interfaces;
+ void *calculate_crc32;
+ void *copy_mem;
+ void *set_mem;
+ void *create_event_ex;
+} efi_boot_services_t;
+
+/*
* Types and defines for EFI ResetSystem
*/
#define EFI_RESET_COLD 0
@@ -236,6 +295,24 @@
#define LINUX_EFI_CRASH_GUID \
EFI_GUID( 0xcfc8fc79, 0xbe2e, 0x4ddc, 0x97, 0xf0, 0x9f, 0x98, 0xbf, 0xe2, 0x98, 0xa0 )
+#define LOADED_IMAGE_PROTOCOL_GUID \
+ EFI_GUID( 0x5b1b31a1, 0x9562, 0x11d2, 0x8e, 0x3f, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b )
+
+#define EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID \
+ EFI_GUID( 0x9042a9de, 0x23dc, 0x4a38, 0x96, 0xfb, 0x7a, 0xde, 0xd0, 0x80, 0x51, 0x6a )
+
+#define EFI_UGA_PROTOCOL_GUID \
+ EFI_GUID( 0x982c298b, 0xf4fa, 0x41cb, 0xb8, 0x38, 0x77, 0xaa, 0x68, 0x8f, 0xb8, 0x39 )
+
+#define EFI_PCI_IO_PROTOCOL_GUID \
+ EFI_GUID( 0x4cf5b200, 0x68b8, 0x4ca5, 0x9e, 0xec, 0xb2, 0x3e, 0x3f, 0x50, 0x2, 0x9a )
+
+#define EFI_FILE_INFO_ID \
+ EFI_GUID( 0x9576e92, 0x6d3f, 0x11d2, 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b )
+
+#define EFI_FILE_SYSTEM_GUID \
+ EFI_GUID( 0x964e5b22, 0x6459, 0x11d2, 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b )
+
typedef struct {
efi_guid_t guid;
unsigned long table;
@@ -261,7 +338,7 @@
unsigned long stderr_handle;
unsigned long stderr;
efi_runtime_services_t *runtime;
- unsigned long boottime;
+ efi_boot_services_t *boottime;
unsigned long nr_tables;
unsigned long tables;
} efi_system_table_t;
@@ -275,6 +352,56 @@
unsigned long desc_size;
};
+typedef struct {
+ u32 revision;
+ void *parent_handle;
+ efi_system_table_t *system_table;
+ void *device_handle;
+ void *file_path;
+ void *reserved;
+ u32 load_options_size;
+ void *load_options;
+ void *image_base;
+ __aligned_u64 image_size;
+ unsigned int image_code_type;
+ unsigned int image_data_type;
+ unsigned long unload;
+} efi_loaded_image_t;
+
+typedef struct {
+ u64 revision;
+ void *open_volume;
+} efi_file_io_interface_t;
+
+typedef struct {
+ u64 size;
+ u64 file_size;
+ u64 phys_size;
+ efi_time_t create_time;
+ efi_time_t last_access_time;
+ efi_time_t modification_time;
+ __aligned_u64 attribute;
+ efi_char16_t filename[1];
+} efi_file_info_t;
+
+typedef struct {
+ u64 revision;
+ void *open;
+ void *close;
+ void *delete;
+ void *read;
+ void *write;
+ void *get_position;
+ void *set_position;
+ void *get_info;
+ void *set_info;
+ void *flush;
+} efi_file_handle_t;
+
+#define EFI_FILE_MODE_READ 0x0000000000000001
+#define EFI_FILE_MODE_WRITE 0x0000000000000002
+#define EFI_FILE_MODE_CREATE 0x8000000000000000
+
#define EFI_INVALID_TABLE_ADDR (~0UL)
/*
@@ -385,6 +512,13 @@
#define EFI_VARIABLE_RUNTIME_ACCESS 0x0000000000000004
/*
+ * The type of search to perform when calling boottime->locate_handle
+ */
+#define EFI_LOCATE_ALL_HANDLES 0
+#define EFI_LOCATE_BY_REGISTER_NOTIFY 1
+#define EFI_LOCATE_BY_PROTOCOL 2
+
+/*
* EFI Device Path information
*/
#define EFI_DEV_HW 0x01
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index f48e8a5..d0a7a0c 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -341,6 +341,7 @@
extern int panic_on_oops;
extern int panic_on_unrecovered_nmi;
extern int panic_on_io_nmi;
+extern int sysctl_panic_on_stackoverflow;
extern const char *print_tainted(void);
extern void add_taint(unsigned flag);
extern int test_taint(unsigned flag);
diff --git a/include/linux/key-type.h b/include/linux/key-type.h
index 9efd081..39e3c08 100644
--- a/include/linux/key-type.h
+++ b/include/linux/key-type.h
@@ -92,6 +92,7 @@
/* internal fields */
struct list_head link; /* link in types list */
+ struct lock_class_key lock_class; /* key->sem lock class */
};
extern struct key_type key_type_keyring;
diff --git a/include/linux/lp8727.h b/include/linux/lp8727.h
new file mode 100755
index 0000000..d21fa28
--- /dev/null
+++ b/include/linux/lp8727.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2011 National Semiconductor
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef _LP8727_H
+#define _LP8727_H
+
+enum lp8727_eoc_level {
+ EOC_5P,
+ EOC_10P,
+ EOC_16P,
+ EOC_20P,
+ EOC_25P,
+ EOC_33P,
+ EOC_50P,
+};
+
+enum lp8727_ichg {
+ ICHG_90mA,
+ ICHG_100mA,
+ ICHG_400mA,
+ ICHG_450mA,
+ ICHG_500mA,
+ ICHG_600mA,
+ ICHG_700mA,
+ ICHG_800mA,
+ ICHG_900mA,
+ ICHG_1000mA,
+};
+
+struct lp8727_chg_param {
+ /* end of charge level setting */
+ enum lp8727_eoc_level eoc_level;
+ /* charging current */
+ enum lp8727_ichg ichg;
+};
+
+struct lp8727_platform_data {
+ u8 (*get_batt_present)(void);
+ u16 (*get_batt_level)(void);
+ u8 (*get_batt_capacity)(void);
+ u8 (*get_batt_temp)(void);
+ struct lp8727_chg_param ac;
+ struct lp8727_chg_param usb;
+};
+
+#endif
diff --git a/include/linux/mfd/max8925.h b/include/linux/mfd/max8925.h
index 5259dfe..b8e6d94 100644
--- a/include/linux/mfd/max8925.h
+++ b/include/linux/mfd/max8925.h
@@ -167,9 +167,6 @@
MAX8925_IRQ_VCHG_DC_OVP,
MAX8925_IRQ_VCHG_DC_F,
MAX8925_IRQ_VCHG_DC_R,
- MAX8925_IRQ_VCHG_USB_OVP,
- MAX8925_IRQ_VCHG_USB_F,
- MAX8925_IRQ_VCHG_USB_R,
MAX8925_IRQ_VCHG_THM_OK_R,
MAX8925_IRQ_VCHG_THM_OK_F,
MAX8925_IRQ_VCHG_SYSLOW_F,
@@ -223,6 +220,10 @@
unsigned batt_detect:1;
unsigned topoff_threshold:2;
unsigned fast_charge:3; /* charge current */
+ unsigned no_temp_support:1; /* set if no temperature detect */
+ unsigned no_insert_detect:1; /* set if no ac insert detect */
+ char **supplied_to;
+ int num_supplicants;
};
/*
diff --git a/include/linux/mfd/wm8994/core.h b/include/linux/mfd/wm8994/core.h
index f44bdb7..9eff2a3 100644
--- a/include/linux/mfd/wm8994/core.h
+++ b/include/linux/mfd/wm8994/core.h
@@ -15,6 +15,7 @@
#ifndef __MFD_WM8994_CORE_H__
#define __MFD_WM8994_CORE_H__
+#include <linux/mutex.h>
#include <linux/interrupt.h>
enum wm8994_type {
@@ -55,6 +56,7 @@
struct mutex irq_lock;
enum wm8994_type type;
+ int revision;
struct device *dev;
struct regmap *regmap;
@@ -65,13 +67,10 @@
int irq_base;
int irq;
- u16 irq_masks_cur[WM8994_NUM_IRQ_REGS];
- u16 irq_masks_cache[WM8994_NUM_IRQ_REGS];
+ struct regmap_irq_chip_data *irq_data;
/* Used over suspend/resume */
bool suspended;
- u16 ldo_regs[WM8994_NUM_LDO_REGS];
- u16 gpio_regs[WM8994_NUM_GPIO_REGS];
struct regulator_dev *dbvdd;
int num_supplies;
diff --git a/include/linux/mfd/wm8994/pdata.h b/include/linux/mfd/wm8994/pdata.h
index ea32f30..3fb1f407 100644
--- a/include/linux/mfd/wm8994/pdata.h
+++ b/include/linux/mfd/wm8994/pdata.h
@@ -23,7 +23,7 @@
int enable;
const char *supply;
- struct regulator_init_data *init_data;
+ const struct regulator_init_data *init_data;
};
#define WM8994_CONFIGURE_GPIO 0x10000
@@ -113,6 +113,23 @@
u16 regs[WM8958_ENH_EQ_REGS];
};
+/**
+ * Microphone detection rates, used to tune response rates and power
+ * consumption for WM8958/WM1811 microphone detection.
+ *
+ * @sysclk: System clock rate to use this configuration for.
+ * @idle: True if this configuration should use when no accessory is detected,
+ * false otherwise.
+ * @start: Value for MICD_BIAS_START_TIME register field (not shifted).
+ * @rate: Value for MICD_RATE register field (not shifted).
+ */
+struct wm8958_micd_rate {
+ int sysclk;
+ bool idle;
+ int start;
+ int rate;
+};
+
struct wm8994_pdata {
int gpio_base;
@@ -144,6 +161,9 @@
int num_enh_eq_cfgs;
struct wm8958_enh_eq_cfg *enh_eq_cfgs;
+ int num_micd_rates;
+ struct wm8958_micd_rate *micd_rates;
+
/* LINEOUT can be differential or single ended */
unsigned int lineout1_diff:1;
unsigned int lineout2_diff:1;
@@ -168,12 +188,21 @@
/* WM8958 microphone bias configuration */
int micbias[2];
+ /* WM8958 microphone detection ranges */
+ u16 micd_lvl_sel;
+
/* Disable the internal pull downs on the LDOs if they are
* always driven (eg, connected to an always on supply or
* GPIO that always drives an output. If they float power
* consumption will rise.
*/
bool ldo_ena_always_driven;
+
+ /*
+ * SPKMODE must be pulled internally by the device on this
+ * system.
+ */
+ bool spkmode_pu;
};
#endif
diff --git a/include/linux/mfd/wm8994/registers.h b/include/linux/mfd/wm8994/registers.h
index 83a9cae..86e6a03 100644
--- a/include/linux/mfd/wm8994/registers.h
+++ b/include/linux/mfd/wm8994/registers.h
@@ -95,11 +95,15 @@
#define WM8994_FLL1_CONTROL_3 0x222
#define WM8994_FLL1_CONTROL_4 0x223
#define WM8994_FLL1_CONTROL_5 0x224
+#define WM8958_FLL1_EFS_1 0x226
+#define WM8958_FLL1_EFS_2 0x227
#define WM8994_FLL2_CONTROL_1 0x240
#define WM8994_FLL2_CONTROL_2 0x241
#define WM8994_FLL2_CONTROL_3 0x242
#define WM8994_FLL2_CONTROL_4 0x243
#define WM8994_FLL2_CONTROL_5 0x244
+#define WM8958_FLL2_EFS_1 0x246
+#define WM8958_FLL2_EFS_2 0x247
#define WM8994_AIF1_CONTROL_1 0x300
#define WM8994_AIF1_CONTROL_2 0x301
#define WM8994_AIF1_MASTER_SLAVE 0x302
@@ -116,6 +120,7 @@
#define WM8994_AIF2DAC_LRCLK 0x315
#define WM8994_AIF2DAC_DATA 0x316
#define WM8994_AIF2ADC_DATA 0x317
+#define WM1811_AIF2TX_CONTROL 0x318
#define WM8958_AIF3_CONTROL_1 0x320
#define WM8958_AIF3_CONTROL_2 0x321
#define WM8958_AIF3DAC_DATA 0x322
@@ -166,6 +171,7 @@
#define WM8994_AIF1_DAC1_EQ_BAND_5_A 0x491
#define WM8994_AIF1_DAC1_EQ_BAND_5_B 0x492
#define WM8994_AIF1_DAC1_EQ_BAND_5_PG 0x493
+#define WM8994_AIF1_DAC1_EQ_BAND_1_C 0x494
#define WM8994_AIF1_DAC2_EQ_GAINS_1 0x4A0
#define WM8994_AIF1_DAC2_EQ_GAINS_2 0x4A1
#define WM8994_AIF1_DAC2_EQ_BAND_1_A 0x4A2
@@ -186,6 +192,7 @@
#define WM8994_AIF1_DAC2_EQ_BAND_5_A 0x4B1
#define WM8994_AIF1_DAC2_EQ_BAND_5_B 0x4B2
#define WM8994_AIF1_DAC2_EQ_BAND_5_PG 0x4B3
+#define WM8994_AIF1_DAC2_EQ_BAND_1_C 0x4B4
#define WM8994_AIF2_ADC_LEFT_VOLUME 0x500
#define WM8994_AIF2_ADC_RIGHT_VOLUME 0x501
#define WM8994_AIF2_DAC_LEFT_VOLUME 0x502
@@ -219,6 +226,7 @@
#define WM8994_AIF2_EQ_BAND_5_A 0x591
#define WM8994_AIF2_EQ_BAND_5_B 0x592
#define WM8994_AIF2_EQ_BAND_5_PG 0x593
+#define WM8994_AIF2_EQ_BAND_1_C 0x594
#define WM8994_DAC1_MIXER_VOLUMES 0x600
#define WM8994_DAC1_LEFT_MIXER_ROUTING 0x601
#define WM8994_DAC1_RIGHT_MIXER_ROUTING 0x602
@@ -242,6 +250,7 @@
#define WM8994_GPIO_4 0x703
#define WM8994_GPIO_5 0x704
#define WM8994_GPIO_6 0x705
+#define WM1811_JACKDET_CTRL 0x705
#define WM8994_GPIO_7 0x706
#define WM8994_GPIO_8 0x707
#define WM8994_GPIO_9 0x708
@@ -264,7 +273,43 @@
#define WM8958_DSP2_RELEASETIME 0xA03
#define WM8958_DSP2_VERMAJMIN 0xA04
#define WM8958_DSP2_VERBUILD 0xA05
+#define WM8958_DSP2_TESTREG 0xA06
+#define WM8958_DSP2_XORREG 0xA07
+#define WM8958_DSP2_SHIFTMAXX 0xA08
+#define WM8958_DSP2_SHIFTMAXY 0xA09
+#define WM8958_DSP2_SHIFTMAXZ 0xA0A
+#define WM8958_DSP2_SHIFTMAXEXTLO 0xA0B
+#define WM8958_DSP2_AESSELECT 0xA0C
#define WM8958_DSP2_EXECCONTROL 0xA0D
+#define WM8958_DSP2_SAMPLEBREAK 0xA0E
+#define WM8958_DSP2_COUNTBREAK 0xA0F
+#define WM8958_DSP2_INTSTATUS 0xA10
+#define WM8958_DSP2_EVENTSTATUS 0xA11
+#define WM8958_DSP2_INTMASK 0xA12
+#define WM8958_DSP2_CONFIGDWIDTH 0xA13
+#define WM8958_DSP2_CONFIGINSTR 0xA14
+#define WM8958_DSP2_CONFIGDMEM 0xA15
+#define WM8958_DSP2_CONFIGDELAYS 0xA16
+#define WM8958_DSP2_CONFIGNUMIO 0xA17
+#define WM8958_DSP2_CONFIGEXTDEPTH 0xA18
+#define WM8958_DSP2_CONFIGMULTIPLIER 0xA19
+#define WM8958_DSP2_CONFIGCTRLDWIDTH 0xA1A
+#define WM8958_DSP2_CONFIGPIPELINE 0xA1B
+#define WM8958_DSP2_SHIFTMAXEXTHI 0xA1C
+#define WM8958_DSP2_SWVERSIONREG 0xA1D
+#define WM8958_DSP2_CONFIGXMEM 0xA1E
+#define WM8958_DSP2_CONFIGYMEM 0xA1F
+#define WM8958_DSP2_CONFIGZMEM 0xA20
+#define WM8958_FW_BUILD_1 0x2000
+#define WM8958_FW_BUILD_0 0x2001
+#define WM8958_FW_ID_1 0x2002
+#define WM8958_FW_ID_0 0x2003
+#define WM8958_FW_MAJOR_1 0x2004
+#define WM8958_FW_MAJOR_0 0x2005
+#define WM8958_FW_MINOR_1 0x2006
+#define WM8958_FW_MINOR_0 0x2007
+#define WM8958_FW_PATCH_1 0x2008
+#define WM8958_FW_PATCH_0 0x2009
#define WM8958_MBC_BAND_2_LOWER_CUTOFF_C1_1 0x2200
#define WM8958_MBC_BAND_2_LOWER_CUTOFF_C1_2 0x2201
#define WM8958_MBC_BAND_2_LOWER_CUTOFF_C2_1 0x2202
@@ -333,6 +378,14 @@
#define WM8958_MBC_B2_PG2_2 0x242D
#define WM8958_MBC_B1_PG2_1 0x242E
#define WM8958_MBC_B1_PG2_2 0x242F
+#define WM8958_MBC_CROSSOVER_1 0x2600
+#define WM8958_MBC_CROSSOVER_2 0x2601
+#define WM8958_MBC_HPF_1 0x2602
+#define WM8958_MBC_HPF_2 0x2603
+#define WM8958_MBC_LPF_1 0x2606
+#define WM8958_MBC_LPF_2 0x2607
+#define WM8958_MBC_RMS_LIMIT_1 0x260A
+#define WM8958_MBC_RMS_LIMIT_2 0x260B
#define WM8994_WRITE_SEQUENCER_0 0x3000
#define WM8994_WRITE_SEQUENCER_1 0x3001
#define WM8994_WRITE_SEQUENCER_2 0x3002
@@ -1852,6 +1905,9 @@
/*
* R57 (0x39) - AntiPOP (2)
*/
+#define WM1811_JACKDET_MODE_MASK 0x0180 /* JACKDET_MODE - [8:7] */
+#define WM1811_JACKDET_MODE_SHIFT 7 /* JACKDET_MODE - [8:7] */
+#define WM1811_JACKDET_MODE_WIDTH 2 /* JACKDET_MODE - [8:7] */
#define WM8994_MICB2_DISCH 0x0100 /* MICB2_DISCH */
#define WM8994_MICB2_DISCH_MASK 0x0100 /* MICB2_DISCH */
#define WM8994_MICB2_DISCH_SHIFT 8 /* MICB2_DISCH */
@@ -2389,6 +2445,10 @@
/*
* R548 (0x224) - FLL1 Control (5)
*/
+#define WM8958_FLL1_BYP 0x8000 /* FLL1_BYP */
+#define WM8958_FLL1_BYP_MASK 0x8000 /* FLL1_BYP */
+#define WM8958_FLL1_BYP_SHIFT 15 /* FLL1_BYP */
+#define WM8958_FLL1_BYP_WIDTH 1 /* FLL1_BYP */
#define WM8994_FLL1_FRC_NCO_VAL_MASK 0x1F80 /* FLL1_FRC_NCO_VAL - [12:7] */
#define WM8994_FLL1_FRC_NCO_VAL_SHIFT 7 /* FLL1_FRC_NCO_VAL - [12:7] */
#define WM8994_FLL1_FRC_NCO_VAL_WIDTH 6 /* FLL1_FRC_NCO_VAL - [12:7] */
@@ -2404,6 +2464,24 @@
#define WM8994_FLL1_REFCLK_SRC_WIDTH 2 /* FLL1_REFCLK_SRC - [1:0] */
/*
+ * R550 (0x226) - FLL1 EFS 1
+ */
+#define WM8958_FLL1_LAMBDA_MASK 0xFFFF /* FLL1_LAMBDA - [15:0] */
+#define WM8958_FLL1_LAMBDA_SHIFT 0 /* FLL1_LAMBDA - [15:0] */
+#define WM8958_FLL1_LAMBDA_WIDTH 16 /* FLL1_LAMBDA - [15:0] */
+
+/*
+ * R551 (0x227) - FLL1 EFS 2
+ */
+#define WM8958_FLL1_LFSR_SEL_MASK 0x0006 /* FLL1_LFSR_SEL - [2:1] */
+#define WM8958_FLL1_LFSR_SEL_SHIFT 1 /* FLL1_LFSR_SEL - [2:1] */
+#define WM8958_FLL1_LFSR_SEL_WIDTH 2 /* FLL1_LFSR_SEL - [2:1] */
+#define WM8958_FLL1_EFS_ENA 0x0001 /* FLL1_EFS_ENA */
+#define WM8958_FLL1_EFS_ENA_MASK 0x0001 /* FLL1_EFS_ENA */
+#define WM8958_FLL1_EFS_ENA_SHIFT 0 /* FLL1_EFS_ENA */
+#define WM8958_FLL1_EFS_ENA_WIDTH 1 /* FLL1_EFS_ENA */
+
+/*
* R576 (0x240) - FLL2 Control (1)
*/
#define WM8994_FLL2_FRAC 0x0004 /* FLL2_FRAC */
@@ -2452,6 +2530,10 @@
/*
* R580 (0x244) - FLL2 Control (5)
*/
+#define WM8958_FLL2_BYP 0x8000 /* FLL2_BYP */
+#define WM8958_FLL2_BYP_MASK 0x8000 /* FLL2_BYP */
+#define WM8958_FLL2_BYP_SHIFT 15 /* FLL2_BYP */
+#define WM8958_FLL2_BYP_WIDTH 1 /* FLL2_BYP */
#define WM8994_FLL2_FRC_NCO_VAL_MASK 0x1F80 /* FLL2_FRC_NCO_VAL - [12:7] */
#define WM8994_FLL2_FRC_NCO_VAL_SHIFT 7 /* FLL2_FRC_NCO_VAL - [12:7] */
#define WM8994_FLL2_FRC_NCO_VAL_WIDTH 6 /* FLL2_FRC_NCO_VAL - [12:7] */
@@ -2467,6 +2549,24 @@
#define WM8994_FLL2_REFCLK_SRC_WIDTH 2 /* FLL2_REFCLK_SRC - [1:0] */
/*
+ * R582 (0x246) - FLL2 EFS 1
+ */
+#define WM8958_FLL2_LAMBDA_MASK 0xFFFF /* FLL2_LAMBDA - [15:0] */
+#define WM8958_FLL2_LAMBDA_SHIFT 0 /* FLL2_LAMBDA - [15:0] */
+#define WM8958_FLL2_LAMBDA_WIDTH 16 /* FLL2_LAMBDA - [15:0] */
+
+/*
+ * R583 (0x247) - FLL2 EFS 2
+ */
+#define WM8958_FLL2_LFSR_SEL_MASK 0x0006 /* FLL2_LFSR_SEL - [2:1] */
+#define WM8958_FLL2_LFSR_SEL_SHIFT 1 /* FLL2_LFSR_SEL - [2:1] */
+#define WM8958_FLL2_LFSR_SEL_WIDTH 2 /* FLL2_LFSR_SEL - [2:1] */
+#define WM8958_FLL2_EFS_ENA 0x0001 /* FLL2_EFS_ENA */
+#define WM8958_FLL2_EFS_ENA_MASK 0x0001 /* FLL2_EFS_ENA */
+#define WM8958_FLL2_EFS_ENA_SHIFT 0 /* FLL2_EFS_ENA */
+#define WM8958_FLL2_EFS_ENA_WIDTH 1 /* FLL2_EFS_ENA */
+
+/*
* R768 (0x300) - AIF1 Control (1)
*/
#define WM8994_AIF1ADCL_SRC 0x8000 /* AIF1ADCL_SRC */
@@ -4187,6 +4287,18 @@
#define WM8994_STL_SEL_WIDTH 1 /* STL_SEL */
/*
+ * R1797 (0x705) - JACKDET Ctrl
+ */
+#define WM1811_JACKDET_DB 0x0100 /* JACKDET_DB */
+#define WM1811_JACKDET_DB_MASK 0x0100 /* JACKDET_DB */
+#define WM1811_JACKDET_DB_SHIFT 8 /* JACKDET_DB */
+#define WM1811_JACKDET_DB_WIDTH 1 /* JACKDET_DB */
+#define WM1811_JACKDET_LVL 0x0040 /* JACKDET_LVL */
+#define WM1811_JACKDET_LVL_MASK 0x0040 /* JACKDET_LVL */
+#define WM1811_JACKDET_LVL_SHIFT 6 /* JACKDET_LVL */
+#define WM1811_JACKDET_LVL_WIDTH 1 /* JACKDET_LVL */
+
+/*
* R1824 (0x720) - Pull Control (1)
*/
#define WM8994_DMICDAT2_PU 0x0800 /* DMICDAT2_PU */
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 6eba2cc..17b27cd 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -1540,23 +1540,13 @@
#endif /* CONFIG_PROC_FS */
#ifdef CONFIG_DEBUG_PAGEALLOC
-extern int debug_pagealloc_enabled;
-
extern void kernel_map_pages(struct page *page, int numpages, int enable);
-
-static inline void enable_debug_pagealloc(void)
-{
- debug_pagealloc_enabled = 1;
-}
#ifdef CONFIG_HIBERNATION
extern bool kernel_page_present(struct page *page);
#endif /* CONFIG_HIBERNATION */
#else
static inline void
kernel_map_pages(struct page *page, int numpages, int enable) {}
-static inline void enable_debug_pagealloc(void)
-{
-}
#ifdef CONFIG_HIBERNATION
static inline bool kernel_page_present(struct page *page) { return true; }
#endif /* CONFIG_HIBERNATION */
diff --git a/include/linux/mpi.h b/include/linux/mpi.h
new file mode 100644
index 0000000..06f8899
--- /dev/null
+++ b/include/linux/mpi.h
@@ -0,0 +1,146 @@
+/* mpi.h - Multi Precision Integers
+ * Copyright (C) 1994, 1996, 1998, 1999,
+ * 2000, 2001 Free Software Foundation, Inc.
+ *
+ * This file is part of GNUPG.
+ *
+ * GNUPG 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.
+ *
+ * GNUPG 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ * The GNU MP Library itself is published under the LGPL;
+ * however I decided to publish this code under the plain GPL.
+ */
+
+#ifndef G10_MPI_H
+#define G10_MPI_H
+
+#include <linux/types.h>
+
+/* DSI defines */
+
+#define SHA1_DIGEST_LENGTH 20
+
+/*end of DSI defines */
+
+#define BYTES_PER_MPI_LIMB (BITS_PER_LONG / 8)
+#define BITS_PER_MPI_LIMB BITS_PER_LONG
+
+typedef unsigned long int mpi_limb_t;
+typedef signed long int mpi_limb_signed_t;
+
+struct gcry_mpi {
+ int alloced; /* array size (# of allocated limbs) */
+ int nlimbs; /* number of valid limbs */
+ int nbits; /* the real number of valid bits (info only) */
+ int sign; /* indicates a negative number */
+ unsigned flags; /* bit 0: array must be allocated in secure memory space */
+ /* bit 1: not used */
+ /* bit 2: the limb is a pointer to some m_alloced data */
+ mpi_limb_t *d; /* array with the limbs */
+};
+
+typedef struct gcry_mpi *MPI;
+
+#define MPI_NULL NULL
+
+#define mpi_get_nlimbs(a) ((a)->nlimbs)
+#define mpi_is_neg(a) ((a)->sign)
+
+/*-- mpiutil.c --*/
+MPI mpi_alloc(unsigned nlimbs);
+MPI mpi_alloc_secure(unsigned nlimbs);
+MPI mpi_alloc_like(MPI a);
+void mpi_free(MPI a);
+int mpi_resize(MPI a, unsigned nlimbs);
+int mpi_copy(MPI *copy, const MPI a);
+void mpi_clear(MPI a);
+int mpi_set(MPI w, MPI u);
+int mpi_set_ui(MPI w, ulong u);
+MPI mpi_alloc_set_ui(unsigned long u);
+void mpi_m_check(MPI a);
+void mpi_swap(MPI a, MPI b);
+
+/*-- mpicoder.c --*/
+MPI do_encode_md(const void *sha_buffer, unsigned nbits);
+MPI mpi_read_from_buffer(const void *buffer, unsigned *ret_nread);
+int mpi_fromstr(MPI val, const char *str);
+u32 mpi_get_keyid(MPI a, u32 *keyid);
+void *mpi_get_buffer(MPI a, unsigned *nbytes, int *sign);
+void *mpi_get_secure_buffer(MPI a, unsigned *nbytes, int *sign);
+int mpi_set_buffer(MPI a, const void *buffer, unsigned nbytes, int sign);
+
+#define log_mpidump g10_log_mpidump
+
+/*-- mpi-add.c --*/
+int mpi_add_ui(MPI w, MPI u, ulong v);
+int mpi_add(MPI w, MPI u, MPI v);
+int mpi_addm(MPI w, MPI u, MPI v, MPI m);
+int mpi_sub_ui(MPI w, MPI u, ulong v);
+int mpi_sub(MPI w, MPI u, MPI v);
+int mpi_subm(MPI w, MPI u, MPI v, MPI m);
+
+/*-- mpi-mul.c --*/
+int mpi_mul_ui(MPI w, MPI u, ulong v);
+int mpi_mul_2exp(MPI w, MPI u, ulong cnt);
+int mpi_mul(MPI w, MPI u, MPI v);
+int mpi_mulm(MPI w, MPI u, MPI v, MPI m);
+
+/*-- mpi-div.c --*/
+ulong mpi_fdiv_r_ui(MPI rem, MPI dividend, ulong divisor);
+int mpi_fdiv_r(MPI rem, MPI dividend, MPI divisor);
+int mpi_fdiv_q(MPI quot, MPI dividend, MPI divisor);
+int mpi_fdiv_qr(MPI quot, MPI rem, MPI dividend, MPI divisor);
+int mpi_tdiv_r(MPI rem, MPI num, MPI den);
+int mpi_tdiv_qr(MPI quot, MPI rem, MPI num, MPI den);
+int mpi_tdiv_q_2exp(MPI w, MPI u, unsigned count);
+int mpi_divisible_ui(const MPI dividend, ulong divisor);
+
+/*-- mpi-gcd.c --*/
+int mpi_gcd(MPI g, const MPI a, const MPI b);
+
+/*-- mpi-pow.c --*/
+int mpi_pow(MPI w, MPI u, MPI v);
+int mpi_powm(MPI res, MPI base, MPI exp, MPI mod);
+
+/*-- mpi-mpow.c --*/
+int mpi_mulpowm(MPI res, MPI *basearray, MPI *exparray, MPI mod);
+
+/*-- mpi-cmp.c --*/
+int mpi_cmp_ui(MPI u, ulong v);
+int mpi_cmp(MPI u, MPI v);
+
+/*-- mpi-scan.c --*/
+int mpi_getbyte(MPI a, unsigned idx);
+void mpi_putbyte(MPI a, unsigned idx, int value);
+unsigned mpi_trailing_zeros(MPI a);
+
+/*-- mpi-bit.c --*/
+void mpi_normalize(MPI a);
+unsigned mpi_get_nbits(MPI a);
+int mpi_test_bit(MPI a, unsigned n);
+int mpi_set_bit(MPI a, unsigned n);
+int mpi_set_highbit(MPI a, unsigned n);
+void mpi_clear_highbit(MPI a, unsigned n);
+void mpi_clear_bit(MPI a, unsigned n);
+int mpi_rshift(MPI x, MPI a, unsigned n);
+
+/*-- mpi-inv.c --*/
+int mpi_invm(MPI x, MPI u, MPI v);
+
+#endif /*G10_MPI_H */
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 84225c7..a16b1df 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -111,7 +111,7 @@
PCI_NUM_RESOURCES,
/* preserve this for compatibility */
- DEVICE_COUNT_RESOURCE
+ DEVICE_COUNT_RESOURCE = PCI_NUM_RESOURCES,
};
typedef int __bitwise pci_power_t;
@@ -308,7 +308,7 @@
unsigned int is_added:1;
unsigned int is_busmaster:1; /* device is busmaster */
unsigned int no_msi:1; /* device may not use msi */
- unsigned int block_ucfg_access:1; /* userspace config space access is blocked */
+ unsigned int block_cfg_access:1; /* config space access is blocked */
unsigned int broken_parity_status:1; /* Device generates false positive parity */
unsigned int irq_reroute_variant:2; /* device needs IRQ rerouting variant */
unsigned int msi_enabled:1;
@@ -661,17 +661,13 @@
void pci_bus_add_devices(const struct pci_bus *bus);
struct pci_bus *pci_scan_bus_parented(struct device *parent, int bus,
struct pci_ops *ops, void *sysdata);
-static inline struct pci_bus * __devinit pci_scan_bus(int bus, struct pci_ops *ops,
- void *sysdata)
-{
- struct pci_bus *root_bus;
- root_bus = pci_scan_bus_parented(NULL, bus, ops, sysdata);
- if (root_bus)
- pci_bus_add_devices(root_bus);
- return root_bus;
-}
-struct pci_bus *pci_create_bus(struct device *parent, int bus,
- struct pci_ops *ops, void *sysdata);
+struct pci_bus *pci_scan_bus(int bus, struct pci_ops *ops, void *sysdata);
+struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
+ struct pci_ops *ops, void *sysdata,
+ struct list_head *resources);
+struct pci_bus * __devinit pci_scan_root_bus(struct device *parent, int bus,
+ struct pci_ops *ops, void *sysdata,
+ struct list_head *resources);
struct pci_bus *pci_add_new_bus(struct pci_bus *parent, struct pci_dev *dev,
int busnr);
void pcie_update_link_speed(struct pci_bus *bus, u16 link_status);
@@ -795,8 +791,11 @@
}
void pci_disable_device(struct pci_dev *dev);
+
+extern unsigned int pcibios_max_latency;
void pci_set_master(struct pci_dev *dev);
void pci_clear_master(struct pci_dev *dev);
+
int pci_set_pcie_reset_state(struct pci_dev *dev, enum pcie_reset_state state);
int pci_set_cacheline_size(struct pci_dev *dev);
#define HAVE_PCI_SET_MWI
@@ -804,6 +803,9 @@
int pci_try_set_mwi(struct pci_dev *dev);
void pci_clear_mwi(struct pci_dev *dev);
void pci_intx(struct pci_dev *dev, int enable);
+bool pci_intx_mask_supported(struct pci_dev *dev);
+bool pci_check_and_mask_intx(struct pci_dev *dev);
+bool pci_check_and_unmask_intx(struct pci_dev *dev);
void pci_msi_off(struct pci_dev *dev);
int pci_set_dma_max_seg_size(struct pci_dev *dev, unsigned int size);
int pci_set_dma_seg_boundary(struct pci_dev *dev, unsigned long mask);
@@ -911,6 +913,8 @@
void pci_release_selected_regions(struct pci_dev *, int);
/* drivers/pci/bus.c */
+void pci_add_resource(struct list_head *resources, struct resource *res);
+void pci_free_resource_list(struct list_head *resources);
void pci_bus_add_resource(struct pci_bus *bus, struct resource *res, unsigned int flags);
struct resource *pci_bus_resource_n(const struct pci_bus *bus, int n);
void pci_bus_remove_resources(struct pci_bus *bus);
@@ -1085,8 +1089,9 @@
void ht_destroy_irq(unsigned int irq);
#endif /* CONFIG_HT_IRQ */
-extern void pci_block_user_cfg_access(struct pci_dev *dev);
-extern void pci_unblock_user_cfg_access(struct pci_dev *dev);
+extern void pci_cfg_access_lock(struct pci_dev *dev);
+extern bool pci_cfg_access_trylock(struct pci_dev *dev);
+extern void pci_cfg_access_unlock(struct pci_dev *dev);
/*
* PCI domain support. Sometimes called PCI segment (eg by ACPI),
@@ -1283,10 +1288,13 @@
#define pci_dma_burst_advice(pdev, strat, strategy_parameter) do { } while (0)
-static inline void pci_block_user_cfg_access(struct pci_dev *dev)
+static inline void pci_block_cfg_access(struct pci_dev *dev)
{ }
-static inline void pci_unblock_user_cfg_access(struct pci_dev *dev)
+static inline int pci_block_cfg_access_in_atomic(struct pci_dev *dev)
+{ return 0; }
+
+static inline void pci_unblock_cfg_access(struct pci_dev *dev)
{ }
static inline struct pci_bus *pci_find_next_bus(const struct pci_bus *from)
@@ -1424,10 +1432,10 @@
void __iomem *pcim_iomap(struct pci_dev *pdev, int bar, unsigned long maxlen);
void pcim_iounmap(struct pci_dev *pdev, void __iomem *addr);
void __iomem * const *pcim_iomap_table(struct pci_dev *pdev);
-int pcim_iomap_regions(struct pci_dev *pdev, u16 mask, const char *name);
-int pcim_iomap_regions_request_all(struct pci_dev *pdev, u16 mask,
+int pcim_iomap_regions(struct pci_dev *pdev, int mask, const char *name);
+int pcim_iomap_regions_request_all(struct pci_dev *pdev, int mask,
const char *name);
-void pcim_iounmap_regions(struct pci_dev *pdev, u16 mask);
+void pcim_iounmap_regions(struct pci_dev *pdev, int mask);
extern int pci_pci_problems;
#define PCIPCI_FAIL 1 /* No PCI PCI DMA */
@@ -1446,8 +1454,10 @@
extern unsigned long pci_hotplug_io_size;
extern unsigned long pci_hotplug_mem_size;
+/* Architecture specific versions may override these (weak) */
int pcibios_add_platform_entries(struct pci_dev *dev);
void pcibios_disable_device(struct pci_dev *dev);
+void pcibios_set_master(struct pci_dev *dev);
int pcibios_set_pcie_reset_state(struct pci_dev *dev,
enum pcie_reset_state state);
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index 2aaee0c..31d77af 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -776,6 +776,29 @@
#define PCI_DEVICE_ID_ELSA_QS3000 0x3000
#define PCI_VENDOR_ID_STMICRO 0x104A
+#define PCI_DEVICE_ID_STMICRO_USB_HOST 0xCC00
+#define PCI_DEVICE_ID_STMICRO_USB_OHCI 0xCC01
+#define PCI_DEVICE_ID_STMICRO_USB_OTG 0xCC02
+#define PCI_DEVICE_ID_STMICRO_UART_HWFC 0xCC03
+#define PCI_DEVICE_ID_STMICRO_UART_NO_HWFC 0xCC04
+#define PCI_DEVICE_ID_STMICRO_SOC_DMA 0xCC05
+#define PCI_DEVICE_ID_STMICRO_SATA 0xCC06
+#define PCI_DEVICE_ID_STMICRO_I2C 0xCC07
+#define PCI_DEVICE_ID_STMICRO_SPI_HS 0xCC08
+#define PCI_DEVICE_ID_STMICRO_MAC 0xCC09
+#define PCI_DEVICE_ID_STMICRO_SDIO_EMMC 0xCC0A
+#define PCI_DEVICE_ID_STMICRO_SDIO 0xCC0B
+#define PCI_DEVICE_ID_STMICRO_GPIO 0xCC0C
+#define PCI_DEVICE_ID_STMICRO_VIP 0xCC0D
+#define PCI_DEVICE_ID_STMICRO_AUDIO_ROUTER_DMA 0xCC0E
+#define PCI_DEVICE_ID_STMICRO_AUDIO_ROUTER_SRCS 0xCC0F
+#define PCI_DEVICE_ID_STMICRO_AUDIO_ROUTER_MSPS 0xCC10
+#define PCI_DEVICE_ID_STMICRO_CAN 0xCC11
+#define PCI_DEVICE_ID_STMICRO_MLB 0xCC12
+#define PCI_DEVICE_ID_STMICRO_DBP 0xCC13
+#define PCI_DEVICE_ID_STMICRO_SATA_PHY 0xCC14
+#define PCI_DEVICE_ID_STMICRO_ESRAM 0xCC15
+#define PCI_DEVICE_ID_STMICRO_VIC 0xCC16
#define PCI_VENDOR_ID_BUSLOGIC 0x104B
#define PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER_NC 0x0140
diff --git a/include/linux/pci_regs.h b/include/linux/pci_regs.h
index 28fe380..e41a10f 100644
--- a/include/linux/pci_regs.h
+++ b/include/linux/pci_regs.h
@@ -392,7 +392,7 @@
#define PCI_EXP_TYPE_DOWNSTREAM 0x6 /* Downstream Port */
#define PCI_EXP_TYPE_PCI_BRIDGE 0x7 /* PCI/PCI-X Bridge */
#define PCI_EXP_TYPE_RC_END 0x9 /* Root Complex Integrated Endpoint */
-#define PCI_EXP_TYPE_RC_EC 0x10 /* Root Complex Event Collector */
+#define PCI_EXP_TYPE_RC_EC 0xa /* Root Complex Event Collector */
#define PCI_EXP_FLAGS_SLOT 0x0100 /* Slot implemented */
#define PCI_EXP_FLAGS_IRQ 0x3e00 /* Interrupt message number */
#define PCI_EXP_DEVCAP 4 /* Device capabilities */
diff --git a/include/linux/pda_power.h b/include/linux/pda_power.h
index c9e4d81..2bb62bf 100644
--- a/include/linux/pda_power.h
+++ b/include/linux/pda_power.h
@@ -35,6 +35,8 @@
unsigned int polling_interval; /* msecs, default is 2000 */
unsigned long ac_max_uA; /* current to draw when on AC */
+
+ bool use_otg_notifier;
};
#endif /* __PDA_POWER_H__ */
diff --git a/include/linux/power/charger-manager.h b/include/linux/power/charger-manager.h
new file mode 100644
index 0000000..4f75e53
--- /dev/null
+++ b/include/linux/power/charger-manager.h
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2011 Samsung Electronics Co., Ltd.
+ * MyungJoo.Ham <myungjoo.ham@samsung.com>
+ *
+ * Charger Manager.
+ * This framework enables to control and multiple chargers and to
+ * monitor charging even in the context of suspend-to-RAM with
+ * an interface combining the chargers.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+**/
+
+#ifndef _CHARGER_MANAGER_H
+#define _CHARGER_MANAGER_H
+
+#include <linux/power_supply.h>
+
+enum data_source {
+ CM_FUEL_GAUGE,
+ CM_CHARGER_STAT,
+};
+
+enum polling_modes {
+ CM_POLL_DISABLE = 0,
+ CM_POLL_ALWAYS,
+ CM_POLL_EXTERNAL_POWER_ONLY,
+ CM_POLL_CHARGING_ONLY,
+};
+
+/**
+ * struct charger_global_desc
+ * @rtc_name: the name of RTC used to wake up the system from suspend.
+ * @rtc_only_wakeup:
+ * If the system is woken up by waekup-sources other than the RTC or
+ * callbacks, Charger Manager should recognize with
+ * rtc_only_wakeup() returning false.
+ * If the RTC given to CM is the only wakeup reason,
+ * rtc_only_wakeup should return true.
+ */
+struct charger_global_desc {
+ char *rtc_name;
+
+ bool (*rtc_only_wakeup)(void);
+};
+
+/**
+ * struct charger_desc
+ * @psy_name: the name of power-supply-class for charger manager
+ * @polling_mode:
+ * Determine which polling mode will be used
+ * @fullbatt_uV: voltage in microvolt
+ * If it is not being charged and VBATT >= fullbatt_uV,
+ * it is assumed to be full.
+ * @polling_interval_ms: interval in millisecond at which
+ * charger manager will monitor battery health
+ * @battery_present:
+ * Specify where information for existance of battery can be obtained
+ * @psy_charger_stat: the names of power-supply for chargers
+ * @num_charger_regulator: the number of entries in charger_regulators
+ * @charger_regulators: array of regulator_bulk_data for chargers
+ * @psy_fuel_gauge: the name of power-supply for fuel gauge
+ * @temperature_out_of_range:
+ * Determine whether the status is overheat or cold or normal.
+ * return_value > 0: overheat
+ * return_value == 0: normal
+ * return_value < 0: cold
+ * @measure_battery_temp:
+ * true: measure battery temperature
+ * false: measure ambient temperature
+ */
+struct charger_desc {
+ char *psy_name;
+
+ enum polling_modes polling_mode;
+ unsigned int polling_interval_ms;
+
+ unsigned int fullbatt_uV;
+
+ enum data_source battery_present;
+
+ char **psy_charger_stat;
+
+ int num_charger_regulators;
+ struct regulator_bulk_data *charger_regulators;
+
+ char *psy_fuel_gauge;
+
+ int (*temperature_out_of_range)(int *mC);
+ bool measure_battery_temp;
+};
+
+#define PSY_NAME_MAX 30
+
+/**
+ * struct charger_manager
+ * @entry: entry for list
+ * @dev: device pointer
+ * @desc: instance of charger_desc
+ * @fuel_gauge: power_supply for fuel gauge
+ * @charger_stat: array of power_supply for chargers
+ * @charger_enabled: the state of charger
+ * @emergency_stop:
+ * When setting true, stop charging
+ * @last_temp_mC: the measured temperature in milli-Celsius
+ * @psy_name_buf: the name of power-supply-class for charger manager
+ * @charger_psy: power_supply for charger manager
+ * @status_save_ext_pwr_inserted:
+ * saved status of external power before entering suspend-to-RAM
+ * @status_save_batt:
+ * saved status of battery before entering suspend-to-RAM
+ */
+struct charger_manager {
+ struct list_head entry;
+ struct device *dev;
+ struct charger_desc *desc;
+
+ struct power_supply *fuel_gauge;
+ struct power_supply **charger_stat;
+
+ bool charger_enabled;
+
+ int emergency_stop;
+ int last_temp_mC;
+
+ char psy_name_buf[PSY_NAME_MAX + 1];
+ struct power_supply charger_psy;
+
+ bool status_save_ext_pwr_inserted;
+ bool status_save_batt;
+};
+
+#ifdef CONFIG_CHARGER_MANAGER
+extern int setup_charger_manager(struct charger_global_desc *gd);
+extern bool cm_suspend_again(void);
+#else
+static void __maybe_unused setup_charger_manager(struct charger_global_desc *gd)
+{ }
+
+static bool __maybe_unused cm_suspend_again(void)
+{
+ return false;
+}
+#endif
+
+#endif /* _CHARGER_MANAGER_H */
diff --git a/include/linux/power/bq20z75.h b/include/linux/power/sbs-battery.h
similarity index 85%
rename from include/linux/power/bq20z75.h
rename to include/linux/power/sbs-battery.h
index 1398eb0..2b0a9d9 100644
--- a/include/linux/power/bq20z75.h
+++ b/include/linux/power/sbs-battery.h
@@ -1,5 +1,5 @@
/*
- * Gas Gauge driver for TI's BQ20Z75
+ * Gas Gauge driver for SBS Compliant Gas Gauges
*
* Copyright (c) 2010, NVIDIA Corporation.
*
@@ -18,21 +18,21 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __LINUX_POWER_BQ20Z75_H_
-#define __LINUX_POWER_BQ20Z75_H_
+#ifndef __LINUX_POWER_SBS_BATTERY_H_
+#define __LINUX_POWER_SBS_BATTERY_H_
#include <linux/power_supply.h>
#include <linux/types.h>
/**
- * struct bq20z75_platform_data - platform data for bq20z75 devices
+ * struct sbs_platform_data - platform data for sbs devices
* @battery_detect: GPIO which is used to detect battery presence
* @battery_detect_present: gpio state when battery is present (0 / 1)
* @i2c_retry_count: # of times to retry on i2c IO failure
* @poll_retry_count: # of times to retry looking for new status after
* external change notification
*/
-struct bq20z75_platform_data {
+struct sbs_platform_data {
int battery_detect;
int battery_detect_present;
int i2c_retry_count;
diff --git a/include/linux/power_supply.h b/include/linux/power_supply.h
index 204c18d..fa9b962 100644
--- a/include/linux/power_supply.h
+++ b/include/linux/power_supply.h
@@ -74,6 +74,12 @@
POWER_SUPPLY_CAPACITY_LEVEL_FULL,
};
+enum {
+ POWER_SUPPLY_SCOPE_UNKNOWN = 0,
+ POWER_SUPPLY_SCOPE_SYSTEM,
+ POWER_SUPPLY_SCOPE_DEVICE,
+};
+
enum power_supply_property {
/* Properties of type `int' */
POWER_SUPPLY_PROP_STATUS = 0,
@@ -116,6 +122,7 @@
POWER_SUPPLY_PROP_TIME_TO_FULL_NOW,
POWER_SUPPLY_PROP_TIME_TO_FULL_AVG,
POWER_SUPPLY_PROP_TYPE, /* use power_supply.type instead */
+ POWER_SUPPLY_PROP_SCOPE,
/* Properties of type `const char *' */
POWER_SUPPLY_PROP_MODEL_NAME,
POWER_SUPPLY_PROP_MANUFACTURER,
@@ -123,7 +130,8 @@
};
enum power_supply_type {
- POWER_SUPPLY_TYPE_BATTERY = 0,
+ POWER_SUPPLY_TYPE_UNKNOWN = 0,
+ POWER_SUPPLY_TYPE_BATTERY,
POWER_SUPPLY_TYPE_UPS,
POWER_SUPPLY_TYPE_MAINS,
POWER_SUPPLY_TYPE_USB, /* Standard Downstream Port */
@@ -211,6 +219,7 @@
extern int power_supply_register(struct device *parent,
struct power_supply *psy);
extern void power_supply_unregister(struct power_supply *psy);
+extern int power_supply_powers(struct power_supply *psy, struct device *dev);
/* For APM emulation, think legacy userspace. */
extern struct class *power_supply_class;
diff --git a/include/linux/s3c_adc_battery.h b/include/linux/s3c_adc_battery.h
index fbe58b7..99dadbf 100644
--- a/include/linux/s3c_adc_battery.h
+++ b/include/linux/s3c_adc_battery.h
@@ -25,6 +25,10 @@
const unsigned int current_channel;
const unsigned int backup_volt_channel;
+ const unsigned int volt_samples;
+ const unsigned int current_samples;
+ const unsigned int backup_volt_samples;
+
const unsigned int volt_mult;
const unsigned int current_mult;
const unsigned int backup_volt_mult;
diff --git a/include/linux/security.h b/include/linux/security.h
index 98112cf..0ccceb9 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -590,6 +590,8 @@
* @reqprot contains the protection requested by the application.
* @prot contains the protection that will be applied by the kernel.
* @flags contains the operational flags.
+ * @addr contains virtual address that will be used for the operation.
+ * @addr_only contains a boolean: 0 if file-backed VMA, otherwise 1.
* Return 0 if permission is granted.
* @file_mprotect:
* Check permissions before changing memory access permissions.
@@ -2043,7 +2045,7 @@
static inline int security_inode_init_security(struct inode *inode,
struct inode *dir,
const struct qstr *qstr,
- initxattrs initxattrs,
+ const initxattrs initxattrs,
void *fs_data)
{
return 0;
diff --git a/include/linux/serial_sci.h b/include/linux/serial_sci.h
index 369273a..7877907 100644
--- a/include/linux/serial_sci.h
+++ b/include/linux/serial_sci.h
@@ -49,6 +49,10 @@
#define SCIF_DEFAULT_ERROR_MASK (SCIF_PER | SCIF_FER | SCIF_ER | SCIF_BRK)
+/* SCSPTR, optional */
+#define SCSPTR_RTSIO (1 << 7)
+#define SCSPTR_CTSIO (1 << 5)
+
/* Offsets into the sci_port->irqs array */
enum {
SCIx_ERI_IRQ,
@@ -60,6 +64,17 @@
SCIx_MUX_IRQ = SCIx_NR_IRQS, /* special case */
};
+/* Offsets into the sci_port->gpios array */
+enum {
+ SCIx_SCK,
+ SCIx_RXD,
+ SCIx_TXD,
+ SCIx_CTS,
+ SCIx_RTS,
+
+ SCIx_NR_FNS,
+};
+
enum {
SCIx_PROBE_REGTYPE,
@@ -109,13 +124,20 @@
};
/*
+ * Port-specific capabilities
+ */
+#define SCIx_HAVE_RTSCTS (1 << 0)
+
+/*
* Platform device specific platform_data struct
*/
struct plat_sci_port {
unsigned long mapbase; /* resource base */
unsigned int irqs[SCIx_NR_IRQS]; /* ERI, RXI, TXI, BRI */
+ unsigned int gpios[SCIx_NR_FNS]; /* SCK, RXD, TXD, CTS, RTS */
unsigned int type; /* SCI / SCIF / IRDA */
upf_t flags; /* UPF_* flags */
+ unsigned long capabilities; /* Port features/capabilities */
unsigned int scbrr_algo_id; /* SCBRR calculation algo */
unsigned int scscr; /* SCSCR initialization */
diff --git a/include/linux/sh_clk.h b/include/linux/sh_clk.h
index a20831c..54341d8 100644
--- a/include/linux/sh_clk.h
+++ b/include/linux/sh_clk.h
@@ -49,6 +49,7 @@
void __iomem *enable_reg;
unsigned int enable_bit;
+ void __iomem *mapped_reg;
unsigned long arch_flags;
void *priv;
@@ -131,10 +132,9 @@
int sh_clk_div4_reparent_register(struct clk *clks, int nr,
struct clk_div4_table *table);
-#define SH_CLK_DIV6_EXT(_parent, _reg, _flags, _parents, \
+#define SH_CLK_DIV6_EXT(_reg, _flags, _parents, \
_num_parents, _src_shift, _src_width) \
{ \
- .parent = _parent, \
.enable_reg = (void __iomem *)_reg, \
.flags = _flags, \
.parent_table = _parents, \
@@ -144,7 +144,11 @@
}
#define SH_CLK_DIV6(_parent, _reg, _flags) \
- SH_CLK_DIV6_EXT(_parent, _reg, _flags, NULL, 0, 0, 0)
+{ \
+ .parent = _parent, \
+ .enable_reg = (void __iomem *)_reg, \
+ .flags = _flags, \
+}
int sh_clk_div6_register(struct clk *clks, int nr);
int sh_clk_div6_reparent_register(struct clk *clks, int nr);
diff --git a/include/linux/sh_pfc.h b/include/linux/sh_pfc.h
index 8446789..5c15aed 100644
--- a/include/linux/sh_pfc.h
+++ b/include/linux/sh_pfc.h
@@ -45,16 +45,24 @@
unsigned long reg, reg_width, field_width;
unsigned long *cnt;
pinmux_enum_t *enum_ids;
+ unsigned long *var_field_width;
};
#define PINMUX_CFG_REG(name, r, r_width, f_width) \
.reg = r, .reg_width = r_width, .field_width = f_width, \
.cnt = (unsigned long [r_width / f_width]) {}, \
- .enum_ids = (pinmux_enum_t [(r_width / f_width) * (1 << f_width)]) \
+ .enum_ids = (pinmux_enum_t [(r_width / f_width) * (1 << f_width)])
+
+#define PINMUX_CFG_REG_VAR(name, r, r_width, var_fw0, var_fwn...) \
+ .reg = r, .reg_width = r_width, \
+ .cnt = (unsigned long [r_width]) {}, \
+ .var_field_width = (unsigned long [r_width]) { var_fw0, var_fwn, 0 }, \
+ .enum_ids = (pinmux_enum_t [])
struct pinmux_data_reg {
unsigned long reg, reg_width, reg_shadow;
pinmux_enum_t *enum_ids;
+ void __iomem *mapped_reg;
};
#define PINMUX_DATA_REG(name, r, r_width) \
@@ -75,6 +83,12 @@
pinmux_enum_t force;
};
+struct pfc_window {
+ phys_addr_t phys;
+ void __iomem *virt;
+ unsigned long size;
+};
+
struct pinmux_info {
char *name;
pinmux_enum_t reserved_id;
@@ -98,6 +112,12 @@
struct pinmux_irq *gpio_irq;
unsigned int gpio_irq_size;
+ struct resource *resource;
+ unsigned int num_resources;
+ struct pfc_window *window;
+
+ unsigned long unlock_reg;
+
struct gpio_chip chip;
};
diff --git a/include/linux/sigma.h b/include/linux/sigma.h
deleted file mode 100644
index d0de882..0000000
--- a/include/linux/sigma.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Load firmware files from Analog Devices SigmaStudio
- *
- * Copyright 2009-2011 Analog Devices Inc.
- *
- * Licensed under the GPL-2 or later.
- */
-
-#ifndef __SIGMA_FIRMWARE_H__
-#define __SIGMA_FIRMWARE_H__
-
-#include <linux/firmware.h>
-#include <linux/types.h>
-
-struct i2c_client;
-
-#define SIGMA_MAGIC "ADISIGM"
-
-struct sigma_firmware {
- const struct firmware *fw;
- size_t pos;
-};
-
-struct sigma_firmware_header {
- unsigned char magic[7];
- u8 version;
- __le32 crc;
-};
-
-enum {
- SIGMA_ACTION_WRITEXBYTES = 0,
- SIGMA_ACTION_WRITESINGLE,
- SIGMA_ACTION_WRITESAFELOAD,
- SIGMA_ACTION_DELAY,
- SIGMA_ACTION_PLLWAIT,
- SIGMA_ACTION_NOOP,
- SIGMA_ACTION_END,
-};
-
-struct sigma_action {
- u8 instr;
- u8 len_hi;
- __le16 len;
- __be16 addr;
- unsigned char payload[];
-};
-
-static inline u32 sigma_action_len(struct sigma_action *sa)
-{
- return (sa->len_hi << 16) | le16_to_cpu(sa->len);
-}
-
-extern int process_sigma_firmware(struct i2c_client *client, const char *name);
-
-#endif
diff --git a/include/sound/Kbuild b/include/sound/Kbuild
index 802947f..6df30ed 100644
--- a/include/sound/Kbuild
+++ b/include/sound/Kbuild
@@ -6,3 +6,5 @@
header-y += hdspm.h
header-y += sb16_csp.h
header-y += sfnt_info.h
+header-y += compress_params.h
+header-y += compress_offload.h
diff --git a/include/sound/compress_driver.h b/include/sound/compress_driver.h
new file mode 100644
index 0000000..48f2a1f
--- /dev/null
+++ b/include/sound/compress_driver.h
@@ -0,0 +1,167 @@
+/*
+ * compress_driver.h - compress offload driver definations
+ *
+ * Copyright (C) 2011 Intel Corporation
+ * Authors: Vinod Koul <vinod.koul@linux.intel.com>
+ * Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ * 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; version 2 of the License.
+ *
+ * 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.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ */
+#ifndef __COMPRESS_DRIVER_H
+#define __COMPRESS_DRIVER_H
+
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <sound/compress_offload.h>
+#include <sound/asound.h>
+#include <sound/pcm.h>
+
+struct snd_compr_ops;
+
+/**
+ * struct snd_compr_runtime: runtime stream description
+ * @state: stream state
+ * @ops: pointer to DSP callbacks
+ * @buffer: pointer to kernel buffer, valid only when not in mmap mode or
+ * DSP doesn't implement copy
+ * @buffer_size: size of the above buffer
+ * @fragment_size: size of buffer fragment in bytes
+ * @fragments: number of such fragments
+ * @hw_pointer: offset of last location in buffer where DSP copied data
+ * @app_pointer: offset of last location in buffer where app wrote data
+ * @total_bytes_available: cumulative number of bytes made available in
+ * the ring buffer
+ * @total_bytes_transferred: cumulative bytes transferred by offload DSP
+ * @sleep: poll sleep
+ */
+struct snd_compr_runtime {
+ snd_pcm_state_t state;
+ struct snd_compr_ops *ops;
+ void *buffer;
+ u64 buffer_size;
+ u32 fragment_size;
+ u32 fragments;
+ u64 hw_pointer;
+ u64 app_pointer;
+ u64 total_bytes_available;
+ u64 total_bytes_transferred;
+ wait_queue_head_t sleep;
+};
+
+/**
+ * struct snd_compr_stream: compressed stream
+ * @name: device name
+ * @ops: pointer to DSP callbacks
+ * @runtime: pointer to runtime structure
+ * @device: device pointer
+ * @direction: stream direction, playback/recording
+ * @private_data: pointer to DSP private data
+ */
+struct snd_compr_stream {
+ const char *name;
+ struct snd_compr_ops *ops;
+ struct snd_compr_runtime *runtime;
+ struct snd_compr *device;
+ enum snd_compr_direction direction;
+ void *private_data;
+};
+
+/**
+ * struct snd_compr_ops: compressed path DSP operations
+ * @open: Open the compressed stream
+ * This callback is mandatory and shall keep dsp ready to receive the stream
+ * parameter
+ * @free: Close the compressed stream, mandatory
+ * @set_params: Sets the compressed stream parameters, mandatory
+ * This can be called in during stream creation only to set codec params
+ * and the stream properties
+ * @get_params: retrieve the codec parameters, mandatory
+ * @trigger: Trigger operations like start, pause, resume, drain, stop.
+ * This callback is mandatory
+ * @pointer: Retrieve current h/w pointer information. Mandatory
+ * @copy: Copy the compressed data to/from userspace, Optional
+ * Can't be implemented if DSP supports mmap
+ * @mmap: DSP mmap method to mmap DSP memory
+ * @ack: Ack for DSP when data is written to audio buffer, Optional
+ * Not valid if copy is implemented
+ * @get_caps: Retrieve DSP capabilities, mandatory
+ * @get_codec_caps: Retrieve capabilities for a specific codec, mandatory
+ */
+struct snd_compr_ops {
+ int (*open)(struct snd_compr_stream *stream);
+ int (*free)(struct snd_compr_stream *stream);
+ int (*set_params)(struct snd_compr_stream *stream,
+ struct snd_compr_params *params);
+ int (*get_params)(struct snd_compr_stream *stream,
+ struct snd_codec *params);
+ int (*trigger)(struct snd_compr_stream *stream, int cmd);
+ int (*pointer)(struct snd_compr_stream *stream,
+ struct snd_compr_tstamp *tstamp);
+ int (*copy)(struct snd_compr_stream *stream, const char __user *buf,
+ size_t count);
+ int (*mmap)(struct snd_compr_stream *stream,
+ struct vm_area_struct *vma);
+ int (*ack)(struct snd_compr_stream *stream, size_t bytes);
+ int (*get_caps) (struct snd_compr_stream *stream,
+ struct snd_compr_caps *caps);
+ int (*get_codec_caps) (struct snd_compr_stream *stream,
+ struct snd_compr_codec_caps *codec);
+};
+
+/**
+ * struct snd_compr: Compressed device
+ * @name: DSP device name
+ * @dev: Device pointer
+ * @ops: pointer to DSP callbacks
+ * @private_data: pointer to DSP pvt data
+ * @card: sound card pointer
+ * @direction: Playback or capture direction
+ * @lock: device lock
+ * @device: device id
+ */
+struct snd_compr {
+ const char *name;
+ struct device *dev;
+ struct snd_compr_ops *ops;
+ void *private_data;
+ struct snd_card *card;
+ unsigned int direction;
+ struct mutex lock;
+ int device;
+};
+
+/* compress device register APIs */
+int snd_compress_register(struct snd_compr *device);
+int snd_compress_deregister(struct snd_compr *device);
+int snd_compress_new(struct snd_card *card, int device,
+ int type, struct snd_compr *compr);
+
+/* dsp driver callback apis
+ * For playback: driver should call snd_compress_fragment_elapsed() to let the
+ * framework know that a fragment has been consumed from the ring buffer
+ *
+ * For recording: we want to know when a frame is available or when
+ * at least one frame is available so snd_compress_frame_elapsed()
+ * callback should be called when a encodeded frame is available
+ */
+static inline void snd_compr_fragment_elapsed(struct snd_compr_stream *stream)
+{
+ wake_up(&stream->runtime->sleep);
+}
+
+#endif
diff --git a/include/sound/compress_offload.h b/include/sound/compress_offload.h
new file mode 100644
index 0000000..05341a4
--- /dev/null
+++ b/include/sound/compress_offload.h
@@ -0,0 +1,161 @@
+/*
+ * compress_offload.h - compress offload header definations
+ *
+ * Copyright (C) 2011 Intel Corporation
+ * Authors: Vinod Koul <vinod.koul@linux.intel.com>
+ * Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ * 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; version 2 of the License.
+ *
+ * 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.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ */
+#ifndef __COMPRESS_OFFLOAD_H
+#define __COMPRESS_OFFLOAD_H
+
+#include <linux/types.h>
+#include <sound/asound.h>
+#include <sound/compress_params.h>
+
+
+#define SNDRV_COMPRESS_VERSION SNDRV_PROTOCOL_VERSION(0, 1, 0)
+/**
+ * struct snd_compressed_buffer: compressed buffer
+ * @fragment_size: size of buffer fragment in bytes
+ * @fragments: number of such fragments
+ */
+struct snd_compressed_buffer {
+ __u32 fragment_size;
+ __u32 fragments;
+};
+
+/**
+ * struct snd_compr_params: compressed stream params
+ * @buffer: buffer description
+ * @codec: codec parameters
+ * @no_wake_mode: dont wake on fragment elapsed
+ */
+struct snd_compr_params {
+ struct snd_compressed_buffer buffer;
+ struct snd_codec codec;
+ __u8 no_wake_mode;
+};
+
+/**
+ * struct snd_compr_tstamp: timestamp descriptor
+ * @byte_offset: Byte offset in ring buffer to DSP
+ * @copied_total: Total number of bytes copied from/to ring buffer to/by DSP
+ * @pcm_frames: Frames decoded or encoded by DSP. This field will evolve by
+ * large steps and should only be used to monitor encoding/decoding
+ * progress. It shall not be used for timing estimates.
+ * @pcm_io_frames: Frames rendered or received by DSP into a mixer or an audio
+ * output/input. This field should be used for A/V sync or time estimates.
+ * @sampling_rate: sampling rate of audio
+ */
+struct snd_compr_tstamp {
+ __u32 byte_offset;
+ __u32 copied_total;
+ snd_pcm_uframes_t pcm_frames;
+ snd_pcm_uframes_t pcm_io_frames;
+ __u32 sampling_rate;
+};
+
+/**
+ * struct snd_compr_avail: avail descriptor
+ * @avail: Number of bytes available in ring buffer for writing/reading
+ * @tstamp: timestamp infomation
+ */
+struct snd_compr_avail {
+ __u64 avail;
+ struct snd_compr_tstamp tstamp;
+};
+
+enum snd_compr_direction {
+ SND_COMPRESS_PLAYBACK = 0,
+ SND_COMPRESS_CAPTURE
+};
+
+/**
+ * struct snd_compr_caps: caps descriptor
+ * @codecs: pointer to array of codecs
+ * @direction: direction supported. Of type snd_compr_direction
+ * @min_fragment_size: minimum fragment supported by DSP
+ * @max_fragment_size: maximum fragment supported by DSP
+ * @min_fragments: min fragments supported by DSP
+ * @max_fragments: max fragments supported by DSP
+ * @num_codecs: number of codecs supported
+ * @reserved: reserved field
+ */
+struct snd_compr_caps {
+ __u32 num_codecs;
+ __u32 direction;
+ __u32 min_fragment_size;
+ __u32 max_fragment_size;
+ __u32 min_fragments;
+ __u32 max_fragments;
+ __u32 codecs[MAX_NUM_CODECS];
+ __u32 reserved[11];
+};
+
+/**
+ * struct snd_compr_codec_caps: query capability of codec
+ * @codec: codec for which capability is queried
+ * @num_descriptors: number of codec descriptors
+ * @descriptor: array of codec capability descriptor
+ */
+struct snd_compr_codec_caps {
+ __u32 codec;
+ __u32 num_descriptors;
+ struct snd_codec_desc descriptor[MAX_NUM_CODEC_DESCRIPTORS];
+};
+
+/**
+ * compress path ioctl definitions
+ * SNDRV_COMPRESS_GET_CAPS: Query capability of DSP
+ * SNDRV_COMPRESS_GET_CODEC_CAPS: Query capability of a codec
+ * SNDRV_COMPRESS_SET_PARAMS: Set codec and stream parameters
+ * Note: only codec params can be changed runtime and stream params cant be
+ * SNDRV_COMPRESS_GET_PARAMS: Query codec params
+ * SNDRV_COMPRESS_TSTAMP: get the current timestamp value
+ * SNDRV_COMPRESS_AVAIL: get the current buffer avail value.
+ * This also queries the tstamp properties
+ * SNDRV_COMPRESS_PAUSE: Pause the running stream
+ * SNDRV_COMPRESS_RESUME: resume a paused stream
+ * SNDRV_COMPRESS_START: Start a stream
+ * SNDRV_COMPRESS_STOP: stop a running stream, discarding ring buffer content
+ * and the buffers currently with DSP
+ * SNDRV_COMPRESS_DRAIN: Play till end of buffers and stop after that
+ * SNDRV_COMPRESS_IOCTL_VERSION: Query the API version
+ */
+#define SNDRV_COMPRESS_IOCTL_VERSION _IOR('C', 0x00, int)
+#define SNDRV_COMPRESS_GET_CAPS _IOWR('C', 0x10, struct snd_compr_caps)
+#define SNDRV_COMPRESS_GET_CODEC_CAPS _IOWR('C', 0x11,\
+ struct snd_compr_codec_caps)
+#define SNDRV_COMPRESS_SET_PARAMS _IOW('C', 0x12, struct snd_compr_params)
+#define SNDRV_COMPRESS_GET_PARAMS _IOR('C', 0x13, struct snd_codec)
+#define SNDRV_COMPRESS_TSTAMP _IOR('C', 0x20, struct snd_compr_tstamp)
+#define SNDRV_COMPRESS_AVAIL _IOR('C', 0x21, struct snd_compr_avail)
+#define SNDRV_COMPRESS_PAUSE _IO('C', 0x30)
+#define SNDRV_COMPRESS_RESUME _IO('C', 0x31)
+#define SNDRV_COMPRESS_START _IO('C', 0x32)
+#define SNDRV_COMPRESS_STOP _IO('C', 0x33)
+#define SNDRV_COMPRESS_DRAIN _IO('C', 0x34)
+/*
+ * TODO
+ * 1. add mmap support
+ *
+ */
+#define SND_COMPR_TRIGGER_DRAIN 7 /*FIXME move this to pcm.h */
+#endif
diff --git a/include/sound/compress_params.h b/include/sound/compress_params.h
new file mode 100644
index 0000000..d97d69f
--- /dev/null
+++ b/include/sound/compress_params.h
@@ -0,0 +1,397 @@
+/*
+ * compress_params.h - codec types and parameters for compressed data
+ * streaming interface
+ *
+ * Copyright (C) 2011 Intel Corporation
+ * Authors: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+ * Vinod Koul <vinod.koul@linux.intel.com>
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ * 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; version 2 of the License.
+ *
+ * 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.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ * The definitions in this file are derived from the OpenMAX AL version 1.1
+ * and OpenMAX IL v 1.1.2 header files which contain the copyright notice below.
+ *
+ * Copyright (c) 2007-2010 The Khronos Group Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and/or associated documentation files (the
+ * "Materials "), to deal in the Materials without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Materials, and to
+ * permit persons to whom the Materials are furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Materials.
+ *
+ * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+ *
+ */
+#ifndef __SND_COMPRESS_PARAMS_H
+#define __SND_COMPRESS_PARAMS_H
+
+/* AUDIO CODECS SUPPORTED */
+#define MAX_NUM_CODECS 32
+#define MAX_NUM_CODEC_DESCRIPTORS 32
+#define MAX_NUM_BITRATES 32
+
+/* Codecs are listed linearly to allow for extensibility */
+#define SND_AUDIOCODEC_PCM ((__u32) 0x00000001)
+#define SND_AUDIOCODEC_MP3 ((__u32) 0x00000002)
+#define SND_AUDIOCODEC_AMR ((__u32) 0x00000003)
+#define SND_AUDIOCODEC_AMRWB ((__u32) 0x00000004)
+#define SND_AUDIOCODEC_AMRWBPLUS ((__u32) 0x00000005)
+#define SND_AUDIOCODEC_AAC ((__u32) 0x00000006)
+#define SND_AUDIOCODEC_WMA ((__u32) 0x00000007)
+#define SND_AUDIOCODEC_REAL ((__u32) 0x00000008)
+#define SND_AUDIOCODEC_VORBIS ((__u32) 0x00000009)
+#define SND_AUDIOCODEC_FLAC ((__u32) 0x0000000A)
+#define SND_AUDIOCODEC_IEC61937 ((__u32) 0x0000000B)
+#define SND_AUDIOCODEC_G723_1 ((__u32) 0x0000000C)
+#define SND_AUDIOCODEC_G729 ((__u32) 0x0000000D)
+
+/*
+ * Profile and modes are listed with bit masks. This allows for a
+ * more compact representation of fields that will not evolve
+ * (in contrast to the list of codecs)
+ */
+
+#define SND_AUDIOPROFILE_PCM ((__u32) 0x00000001)
+
+/* MP3 modes are only useful for encoders */
+#define SND_AUDIOCHANMODE_MP3_MONO ((__u32) 0x00000001)
+#define SND_AUDIOCHANMODE_MP3_STEREO ((__u32) 0x00000002)
+#define SND_AUDIOCHANMODE_MP3_JOINTSTEREO ((__u32) 0x00000004)
+#define SND_AUDIOCHANMODE_MP3_DUAL ((__u32) 0x00000008)
+
+#define SND_AUDIOPROFILE_AMR ((__u32) 0x00000001)
+
+/* AMR modes are only useful for encoders */
+#define SND_AUDIOMODE_AMR_DTX_OFF ((__u32) 0x00000001)
+#define SND_AUDIOMODE_AMR_VAD1 ((__u32) 0x00000002)
+#define SND_AUDIOMODE_AMR_VAD2 ((__u32) 0x00000004)
+
+#define SND_AUDIOSTREAMFORMAT_UNDEFINED ((__u32) 0x00000000)
+#define SND_AUDIOSTREAMFORMAT_CONFORMANCE ((__u32) 0x00000001)
+#define SND_AUDIOSTREAMFORMAT_IF1 ((__u32) 0x00000002)
+#define SND_AUDIOSTREAMFORMAT_IF2 ((__u32) 0x00000004)
+#define SND_AUDIOSTREAMFORMAT_FSF ((__u32) 0x00000008)
+#define SND_AUDIOSTREAMFORMAT_RTPPAYLOAD ((__u32) 0x00000010)
+#define SND_AUDIOSTREAMFORMAT_ITU ((__u32) 0x00000020)
+
+#define SND_AUDIOPROFILE_AMRWB ((__u32) 0x00000001)
+
+/* AMRWB modes are only useful for encoders */
+#define SND_AUDIOMODE_AMRWB_DTX_OFF ((__u32) 0x00000001)
+#define SND_AUDIOMODE_AMRWB_VAD1 ((__u32) 0x00000002)
+#define SND_AUDIOMODE_AMRWB_VAD2 ((__u32) 0x00000004)
+
+#define SND_AUDIOPROFILE_AMRWBPLUS ((__u32) 0x00000001)
+
+#define SND_AUDIOPROFILE_AAC ((__u32) 0x00000001)
+
+/* AAC modes are required for encoders and decoders */
+#define SND_AUDIOMODE_AAC_MAIN ((__u32) 0x00000001)
+#define SND_AUDIOMODE_AAC_LC ((__u32) 0x00000002)
+#define SND_AUDIOMODE_AAC_SSR ((__u32) 0x00000004)
+#define SND_AUDIOMODE_AAC_LTP ((__u32) 0x00000008)
+#define SND_AUDIOMODE_AAC_HE ((__u32) 0x00000010)
+#define SND_AUDIOMODE_AAC_SCALABLE ((__u32) 0x00000020)
+#define SND_AUDIOMODE_AAC_ERLC ((__u32) 0x00000040)
+#define SND_AUDIOMODE_AAC_LD ((__u32) 0x00000080)
+#define SND_AUDIOMODE_AAC_HE_PS ((__u32) 0x00000100)
+#define SND_AUDIOMODE_AAC_HE_MPS ((__u32) 0x00000200)
+
+/* AAC formats are required for encoders and decoders */
+#define SND_AUDIOSTREAMFORMAT_MP2ADTS ((__u32) 0x00000001)
+#define SND_AUDIOSTREAMFORMAT_MP4ADTS ((__u32) 0x00000002)
+#define SND_AUDIOSTREAMFORMAT_MP4LOAS ((__u32) 0x00000004)
+#define SND_AUDIOSTREAMFORMAT_MP4LATM ((__u32) 0x00000008)
+#define SND_AUDIOSTREAMFORMAT_ADIF ((__u32) 0x00000010)
+#define SND_AUDIOSTREAMFORMAT_MP4FF ((__u32) 0x00000020)
+#define SND_AUDIOSTREAMFORMAT_RAW ((__u32) 0x00000040)
+
+#define SND_AUDIOPROFILE_WMA7 ((__u32) 0x00000001)
+#define SND_AUDIOPROFILE_WMA8 ((__u32) 0x00000002)
+#define SND_AUDIOPROFILE_WMA9 ((__u32) 0x00000004)
+#define SND_AUDIOPROFILE_WMA10 ((__u32) 0x00000008)
+
+#define SND_AUDIOMODE_WMA_LEVEL1 ((__u32) 0x00000001)
+#define SND_AUDIOMODE_WMA_LEVEL2 ((__u32) 0x00000002)
+#define SND_AUDIOMODE_WMA_LEVEL3 ((__u32) 0x00000004)
+#define SND_AUDIOMODE_WMA_LEVEL4 ((__u32) 0x00000008)
+#define SND_AUDIOMODE_WMAPRO_LEVELM0 ((__u32) 0x00000010)
+#define SND_AUDIOMODE_WMAPRO_LEVELM1 ((__u32) 0x00000020)
+#define SND_AUDIOMODE_WMAPRO_LEVELM2 ((__u32) 0x00000040)
+#define SND_AUDIOMODE_WMAPRO_LEVELM3 ((__u32) 0x00000080)
+
+#define SND_AUDIOSTREAMFORMAT_WMA_ASF ((__u32) 0x00000001)
+/*
+ * Some implementations strip the ASF header and only send ASF packets
+ * to the DSP
+ */
+#define SND_AUDIOSTREAMFORMAT_WMA_NOASF_HDR ((__u32) 0x00000002)
+
+#define SND_AUDIOPROFILE_REALAUDIO ((__u32) 0x00000001)
+
+#define SND_AUDIOMODE_REALAUDIO_G2 ((__u32) 0x00000001)
+#define SND_AUDIOMODE_REALAUDIO_8 ((__u32) 0x00000002)
+#define SND_AUDIOMODE_REALAUDIO_10 ((__u32) 0x00000004)
+#define SND_AUDIOMODE_REALAUDIO_SURROUND ((__u32) 0x00000008)
+
+#define SND_AUDIOPROFILE_VORBIS ((__u32) 0x00000001)
+
+#define SND_AUDIOMODE_VORBIS ((__u32) 0x00000001)
+
+#define SND_AUDIOPROFILE_FLAC ((__u32) 0x00000001)
+
+/*
+ * Define quality levels for FLAC encoders, from LEVEL0 (fast)
+ * to LEVEL8 (best)
+ */
+#define SND_AUDIOMODE_FLAC_LEVEL0 ((__u32) 0x00000001)
+#define SND_AUDIOMODE_FLAC_LEVEL1 ((__u32) 0x00000002)
+#define SND_AUDIOMODE_FLAC_LEVEL2 ((__u32) 0x00000004)
+#define SND_AUDIOMODE_FLAC_LEVEL3 ((__u32) 0x00000008)
+#define SND_AUDIOMODE_FLAC_LEVEL4 ((__u32) 0x00000010)
+#define SND_AUDIOMODE_FLAC_LEVEL5 ((__u32) 0x00000020)
+#define SND_AUDIOMODE_FLAC_LEVEL6 ((__u32) 0x00000040)
+#define SND_AUDIOMODE_FLAC_LEVEL7 ((__u32) 0x00000080)
+#define SND_AUDIOMODE_FLAC_LEVEL8 ((__u32) 0x00000100)
+
+#define SND_AUDIOSTREAMFORMAT_FLAC ((__u32) 0x00000001)
+#define SND_AUDIOSTREAMFORMAT_FLAC_OGG ((__u32) 0x00000002)
+
+/* IEC61937 payloads without CUVP and preambles */
+#define SND_AUDIOPROFILE_IEC61937 ((__u32) 0x00000001)
+/* IEC61937 with S/PDIF preambles+CUVP bits in 32-bit containers */
+#define SND_AUDIOPROFILE_IEC61937_SPDIF ((__u32) 0x00000002)
+
+/*
+ * IEC modes are mandatory for decoders. Format autodetection
+ * will only happen on the DSP side with mode 0. The PCM mode should
+ * not be used, the PCM codec should be used instead.
+ */
+#define SND_AUDIOMODE_IEC_REF_STREAM_HEADER ((__u32) 0x00000000)
+#define SND_AUDIOMODE_IEC_LPCM ((__u32) 0x00000001)
+#define SND_AUDIOMODE_IEC_AC3 ((__u32) 0x00000002)
+#define SND_AUDIOMODE_IEC_MPEG1 ((__u32) 0x00000004)
+#define SND_AUDIOMODE_IEC_MP3 ((__u32) 0x00000008)
+#define SND_AUDIOMODE_IEC_MPEG2 ((__u32) 0x00000010)
+#define SND_AUDIOMODE_IEC_AACLC ((__u32) 0x00000020)
+#define SND_AUDIOMODE_IEC_DTS ((__u32) 0x00000040)
+#define SND_AUDIOMODE_IEC_ATRAC ((__u32) 0x00000080)
+#define SND_AUDIOMODE_IEC_SACD ((__u32) 0x00000100)
+#define SND_AUDIOMODE_IEC_EAC3 ((__u32) 0x00000200)
+#define SND_AUDIOMODE_IEC_DTS_HD ((__u32) 0x00000400)
+#define SND_AUDIOMODE_IEC_MLP ((__u32) 0x00000800)
+#define SND_AUDIOMODE_IEC_DST ((__u32) 0x00001000)
+#define SND_AUDIOMODE_IEC_WMAPRO ((__u32) 0x00002000)
+#define SND_AUDIOMODE_IEC_REF_CXT ((__u32) 0x00004000)
+#define SND_AUDIOMODE_IEC_HE_AAC ((__u32) 0x00008000)
+#define SND_AUDIOMODE_IEC_HE_AAC2 ((__u32) 0x00010000)
+#define SND_AUDIOMODE_IEC_MPEG_SURROUND ((__u32) 0x00020000)
+
+#define SND_AUDIOPROFILE_G723_1 ((__u32) 0x00000001)
+
+#define SND_AUDIOMODE_G723_1_ANNEX_A ((__u32) 0x00000001)
+#define SND_AUDIOMODE_G723_1_ANNEX_B ((__u32) 0x00000002)
+#define SND_AUDIOMODE_G723_1_ANNEX_C ((__u32) 0x00000004)
+
+#define SND_AUDIOPROFILE_G729 ((__u32) 0x00000001)
+
+#define SND_AUDIOMODE_G729_ANNEX_A ((__u32) 0x00000001)
+#define SND_AUDIOMODE_G729_ANNEX_B ((__u32) 0x00000002)
+
+/* <FIXME: multichannel encoders aren't supported for now. Would need
+ an additional definition of channel arrangement> */
+
+/* VBR/CBR definitions */
+#define SND_RATECONTROLMODE_CONSTANTBITRATE ((__u32) 0x00000001)
+#define SND_RATECONTROLMODE_VARIABLEBITRATE ((__u32) 0x00000002)
+
+/* Encoder options */
+
+struct snd_enc_wma {
+ __u32 super_block_align; /* WMA Type-specific data */
+};
+
+
+/**
+ * struct snd_enc_vorbis
+ * @quality: Sets encoding quality to n, between -1 (low) and 10 (high).
+ * In the default mode of operation, the quality level is 3.
+ * Normal quality range is 0 - 10.
+ * @managed: Boolean. Set bitrate management mode. This turns off the
+ * normal VBR encoding, but allows hard or soft bitrate constraints to be
+ * enforced by the encoder. This mode can be slower, and may also be
+ * lower quality. It is primarily useful for streaming.
+ * @max_bit_rate: Enabled only if managed is TRUE
+ * @min_bit_rate: Enabled only if managed is TRUE
+ * @downmix: Boolean. Downmix input from stereo to mono (has no effect on
+ * non-stereo streams). Useful for lower-bitrate encoding.
+ *
+ * These options were extracted from the OpenMAX IL spec and Gstreamer vorbisenc
+ * properties
+ *
+ * For best quality users should specify VBR mode and set quality levels.
+ */
+
+struct snd_enc_vorbis {
+ __s32 quality;
+ __u32 managed;
+ __u32 max_bit_rate;
+ __u32 min_bit_rate;
+ __u32 downmix;
+};
+
+
+/**
+ * struct snd_enc_real
+ * @quant_bits: number of coupling quantization bits in the stream
+ * @start_region: coupling start region in the stream
+ * @num_regions: number of regions value
+ *
+ * These options were extracted from the OpenMAX IL spec
+ */
+
+struct snd_enc_real {
+ __u32 quant_bits;
+ __u32 start_region;
+ __u32 num_regions;
+};
+
+/**
+ * struct snd_enc_flac
+ * @num: serial number, valid only for OGG formats
+ * needs to be set by application
+ * @gain: Add replay gain tags
+ *
+ * These options were extracted from the FLAC online documentation
+ * at http://flac.sourceforge.net/documentation_tools_flac.html
+ *
+ * To make the API simpler, it is assumed that the user will select quality
+ * profiles. Additional options that affect encoding quality and speed can
+ * be added at a later stage if needed.
+ *
+ * By default the Subset format is used by encoders.
+ *
+ * TAGS such as pictures, etc, cannot be handled by an offloaded encoder and are
+ * not supported in this API.
+ */
+
+struct snd_enc_flac {
+ __u32 num;
+ __u32 gain;
+};
+
+struct snd_enc_generic {
+ __u32 bw; /* encoder bandwidth */
+ __s32 reserved[15];
+};
+
+union snd_codec_options {
+ struct snd_enc_wma wma;
+ struct snd_enc_vorbis vorbis;
+ struct snd_enc_real real;
+ struct snd_enc_flac flac;
+ struct snd_enc_generic generic;
+};
+
+/** struct snd_codec_desc - description of codec capabilities
+ * @max_ch: Maximum number of audio channels
+ * @sample_rates: Sampling rates in Hz, use SNDRV_PCM_RATE_xxx for this
+ * @bit_rate: Indexed array containing supported bit rates
+ * @num_bitrates: Number of valid values in bit_rate array
+ * @rate_control: value is specified by SND_RATECONTROLMODE defines.
+ * @profiles: Supported profiles. See SND_AUDIOPROFILE defines.
+ * @modes: Supported modes. See SND_AUDIOMODE defines
+ * @formats: Supported formats. See SND_AUDIOSTREAMFORMAT defines
+ * @min_buffer: Minimum buffer size handled by codec implementation
+ * @reserved: reserved for future use
+ *
+ * This structure provides a scalar value for profiles, modes and stream
+ * format fields.
+ * If an implementation supports multiple combinations, they will be listed as
+ * codecs with different descriptors, for example there would be 2 descriptors
+ * for AAC-RAW and AAC-ADTS.
+ * This entails some redundancy but makes it easier to avoid invalid
+ * configurations.
+ *
+ */
+
+struct snd_codec_desc {
+ __u32 max_ch;
+ __u32 sample_rates;
+ __u32 bit_rate[MAX_NUM_BITRATES];
+ __u32 num_bitrates;
+ __u32 rate_control;
+ __u32 profiles;
+ __u32 modes;
+ __u32 formats;
+ __u32 min_buffer;
+ __u32 reserved[15];
+};
+
+/** struct snd_codec
+ * @id: Identifies the supported audio encoder/decoder.
+ * See SND_AUDIOCODEC macros.
+ * @ch_in: Number of input audio channels
+ * @ch_out: Number of output channels. In case of contradiction between
+ * this field and the channelMode field, the channelMode field
+ * overrides.
+ * @sample_rate: Audio sample rate of input data
+ * @bit_rate: Bitrate of encoded data. May be ignored by decoders
+ * @rate_control: Encoding rate control. See SND_RATECONTROLMODE defines.
+ * Encoders may rely on profiles for quality levels.
+ * May be ignored by decoders.
+ * @profile: Mandatory for encoders, can be mandatory for specific
+ * decoders as well. See SND_AUDIOPROFILE defines.
+ * @level: Supported level (Only used by WMA at the moment)
+ * @ch_mode: Channel mode for encoder. See SND_AUDIOCHANMODE defines
+ * @format: Format of encoded bistream. Mandatory when defined.
+ * See SND_AUDIOSTREAMFORMAT defines.
+ * @align: Block alignment in bytes of an audio sample.
+ * Only required for PCM or IEC formats.
+ * @options: encoder-specific settings
+ * @reserved: reserved for future use
+ */
+
+struct snd_codec {
+ __u32 id;
+ __u32 ch_in;
+ __u32 ch_out;
+ __u32 sample_rate;
+ __u32 bit_rate;
+ __u32 rate_control;
+ __u32 profile;
+ __u32 level;
+ __u32 ch_mode;
+ __u32 format;
+ __u32 align;
+ union snd_codec_options options;
+ __u32 reserved[3];
+};
+
+#endif
diff --git a/include/sound/control.h b/include/sound/control.h
index 1a94a21..b2796e8 100644
--- a/include/sound/control.h
+++ b/include/sound/control.h
@@ -227,4 +227,12 @@
return _snd_ctl_add_slave(master, slave, SND_CTL_SLAVE_NEED_UPDATE);
}
+/*
+ * Helper functions for jack-detection controls
+ */
+struct snd_kcontrol *
+snd_kctl_jack_new(const char *name, int idx, void *private_data);
+void snd_kctl_jack_report(struct snd_card *card,
+ struct snd_kcontrol *kctl, bool status);
+
#endif /* __SOUND_CONTROL_H */
diff --git a/include/sound/core.h b/include/sound/core.h
index 3be5ab7..5ab255f 100644
--- a/include/sound/core.h
+++ b/include/sound/core.h
@@ -62,6 +62,7 @@
#define SNDRV_DEV_BUS ((__force snd_device_type_t) 0x1007)
#define SNDRV_DEV_CODEC ((__force snd_device_type_t) 0x1008)
#define SNDRV_DEV_JACK ((__force snd_device_type_t) 0x1009)
+#define SNDRV_DEV_COMPRESS ((__force snd_device_type_t) 0x100A)
#define SNDRV_DEV_LOWLEVEL ((__force snd_device_type_t) 0x2000)
typedef int __bitwise snd_device_state_t;
diff --git a/include/sound/minors.h b/include/sound/minors.h
index 8f76420..5978f9a 100644
--- a/include/sound/minors.h
+++ b/include/sound/minors.h
@@ -35,7 +35,7 @@
#define SNDRV_MINOR_TIMER 33 /* SNDRV_MINOR_GLOBAL + 1 * 32 */
#ifndef CONFIG_SND_DYNAMIC_MINORS
- /* 2 - 3 (reserved) */
+#define SNDRV_MINOR_COMPRESS 2 /* 2 - 3 */
#define SNDRV_MINOR_HWDEP 4 /* 4 - 7 */
#define SNDRV_MINOR_RAWMIDI 8 /* 8 - 15 */
#define SNDRV_MINOR_PCM_PLAYBACK 16 /* 16 - 23 */
@@ -49,6 +49,7 @@
#define SNDRV_DEVICE_TYPE_PCM_CAPTURE SNDRV_MINOR_PCM_CAPTURE
#define SNDRV_DEVICE_TYPE_SEQUENCER SNDRV_MINOR_SEQUENCER
#define SNDRV_DEVICE_TYPE_TIMER SNDRV_MINOR_TIMER
+#define SNDRV_DEVICE_TYPE_COMPRESS SNDRV_MINOR_COMPRESS
#else /* CONFIG_SND_DYNAMIC_MINORS */
@@ -60,6 +61,7 @@
SNDRV_DEVICE_TYPE_RAWMIDI,
SNDRV_DEVICE_TYPE_PCM_PLAYBACK,
SNDRV_DEVICE_TYPE_PCM_CAPTURE,
+ SNDRV_DEVICE_TYPE_COMPRESS,
};
#endif /* CONFIG_SND_DYNAMIC_MINORS */
diff --git a/include/sound/sh_fsi.h b/include/sound/sh_fsi.h
index 9a155f9..9b1aaca 100644
--- a/include/sound/sh_fsi.h
+++ b/include/sound/sh_fsi.h
@@ -78,4 +78,16 @@
int (*set_rate)(struct device *dev, int is_porta, int rate, int enable);
};
+/*
+ * for fsi-ak4642
+ */
+struct fsi_ak4642_info {
+ const char *name;
+ const char *card;
+ const char *cpu_dai;
+ const char *codec;
+ const char *platform;
+ int id;
+};
+
#endif /* __SOUND_FSI_H */
diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h
index 17a4c17..d26a9b7 100644
--- a/include/sound/soc-dapm.h
+++ b/include/sound/soc-dapm.h
@@ -43,6 +43,9 @@
.num_kcontrols = 0}
/* platform domain */
+#define SND_SOC_DAPM_SIGGEN(wname) \
+{ .id = snd_soc_dapm_siggen, .name = wname, .kcontrol_news = NULL, \
+ .num_kcontrols = 0, .reg = SND_SOC_NOPM }
#define SND_SOC_DAPM_INPUT(wname) \
{ .id = snd_soc_dapm_input, .name = wname, .kcontrol_news = NULL, \
.num_kcontrols = 0, .reg = SND_SOC_NOPM }
@@ -380,6 +383,7 @@
const char *pin);
int snd_soc_dapm_ignore_suspend(struct snd_soc_dapm_context *dapm,
const char *pin);
+void snd_soc_dapm_auto_nc_codec_pins(struct snd_soc_codec *codec);
/* Mostly internal - should not normally be used */
void dapm_mark_dirty(struct snd_soc_dapm_widget *w, const char *reason);
@@ -409,6 +413,7 @@
snd_soc_dapm_supply, /* power/clock supply */
snd_soc_dapm_aif_in, /* audio interface input */
snd_soc_dapm_aif_out, /* audio interface output */
+ snd_soc_dapm_siggen, /* signal generator */
};
/*
diff --git a/include/sound/soc.h b/include/sound/soc.h
index 11cfb59..0992dff 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -231,6 +231,7 @@
SND_SOC_BIAS_ON = 3,
};
+struct device_node;
struct snd_jack;
struct snd_soc_card;
struct snd_soc_pcm_stream;
@@ -266,8 +267,6 @@
enum snd_soc_compress_type {
SND_SOC_FLAT_COMPRESSION = 1,
- SND_SOC_LZO_COMPRESSION,
- SND_SOC_RBTREE_COMPRESSION
};
enum snd_soc_pcm_subclass {
@@ -318,6 +317,7 @@
unsigned int reg);
int snd_soc_platform_write(struct snd_soc_platform *platform,
unsigned int reg, unsigned int val);
+int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num);
/* Utility functions to get clock rates from various things */
int snd_soc_calc_frame_size(int sample_size, int channels, int tdm_slots);
@@ -593,8 +593,7 @@
/* driver ops */
int (*probe)(struct snd_soc_codec *);
int (*remove)(struct snd_soc_codec *);
- int (*suspend)(struct snd_soc_codec *,
- pm_message_t state);
+ int (*suspend)(struct snd_soc_codec *);
int (*resume)(struct snd_soc_codec *);
/* Default control and setup, added after probe() is run */
@@ -706,8 +705,11 @@
const char *name; /* Codec name */
const char *stream_name; /* Stream name */
const char *codec_name; /* for multi-codec */
+ const struct device_node *codec_of_node;
const char *platform_name; /* for multi-platform */
+ const struct device_node *platform_of_node;
const char *cpu_dai_name;
+ const struct device_node *cpu_dai_of_node;
const char *codec_dai_name;
unsigned int dai_fmt; /* format to set on init */
@@ -718,6 +720,9 @@
/* Symmetry requirements */
unsigned int symmetric_rates:1;
+ /* pmdown_time is ignored at stop */
+ unsigned int ignore_pmdown_time:1;
+
/* codec/machine specific init - e.g. add machine controls */
int (*init)(struct snd_soc_pcm_runtime *rtd);
@@ -813,6 +818,7 @@
int num_dapm_widgets;
const struct snd_soc_dapm_route *dapm_routes;
int num_dapm_routes;
+ bool fully_routed;
struct work_struct deferred_resume_work;
@@ -840,8 +846,8 @@
};
/* SoC machine DAI configuration, glues a codec and cpu DAI together */
-struct snd_soc_pcm_runtime {
- struct device dev;
+struct snd_soc_pcm_runtime {
+ struct device *dev;
struct snd_soc_card *card;
struct snd_soc_dai_link *dai_link;
struct mutex pcm_mutex;
@@ -927,12 +933,12 @@
static inline void snd_soc_pcm_set_drvdata(struct snd_soc_pcm_runtime *rtd,
void *data)
{
- dev_set_drvdata(&rtd->dev, data);
+ dev_set_drvdata(rtd->dev, data);
}
static inline void *snd_soc_pcm_get_drvdata(struct snd_soc_pcm_runtime *rtd)
{
- return dev_get_drvdata(&rtd->dev);
+ return dev_get_drvdata(rtd->dev);
}
static inline void snd_soc_initialize_card_lists(struct snd_soc_card *card)
@@ -960,6 +966,11 @@
int snd_soc_util_init(void);
void snd_soc_util_exit(void);
+int snd_soc_of_parse_card_name(struct snd_soc_card *card,
+ const char *propname);
+int snd_soc_of_parse_audio_routing(struct snd_soc_card *card,
+ const char *propname);
+
#include <sound/soc-dai.h>
#ifdef CONFIG_DEBUG_FS
diff --git a/include/sound/sta32x.h b/include/sound/sta32x.h
new file mode 100644
index 0000000..8d93b03
--- /dev/null
+++ b/include/sound/sta32x.h
@@ -0,0 +1,35 @@
+/*
+ * Platform data for ST STA32x ASoC codec driver.
+ *
+ * Copyright: 2011 Raumfeld GmbH
+ * Author: Johannes Stezenbach <js@sig21.net>
+ *
+ * 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.
+ */
+#ifndef __LINUX_SND__STA32X_H
+#define __LINUX_SND__STA32X_H
+
+#define STA32X_OCFG_2CH 0
+#define STA32X_OCFG_2_1CH 1
+#define STA32X_OCFG_1CH 3
+
+#define STA32X_OM_CH1 0
+#define STA32X_OM_CH2 1
+#define STA32X_OM_CH3 2
+
+#define STA32X_THERMAL_ADJUSTMENT_ENABLE 1
+#define STA32X_THERMAL_RECOVERY_ENABLE 2
+
+struct sta32x_platform_data {
+ int output_conf;
+ int ch1_output_mapping;
+ int ch2_output_mapping;
+ int ch3_output_mapping;
+ int thermal_conf;
+ int needs_esd_watchdog;
+};
+
+#endif /* __LINUX_SND__STA32X_H */
diff --git a/include/sound/wm8903.h b/include/sound/wm8903.h
index cf7ccb7..b310c5a 100644
--- a/include/sound/wm8903.h
+++ b/include/sound/wm8903.h
@@ -11,8 +11,11 @@
#ifndef __LINUX_SND_WM8903_H
#define __LINUX_SND_WM8903_H
-/* Used to enable configuration of a GPIO to all zeros */
-#define WM8903_GPIO_NO_CONFIG 0x8000
+/*
+ * Used to enable configuration of a GPIO to all zeros; a gpio_cfg value of
+ * zero in platform data means "don't touch this pin".
+ */
+#define WM8903_GPIO_CONFIG_ZERO 0x8000
/*
* R6 (0x06) - Mic Bias Control 0
diff --git a/init/Kconfig b/init/Kconfig
index a075765..018d206 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -713,7 +713,6 @@
menuconfig CGROUP_SCHED
bool "Group CPU scheduler"
- depends on EXPERIMENTAL
default n
help
This feature lets CPU scheduler recognize task groups and control CPU
diff --git a/init/calibrate.c b/init/calibrate.c
index 24df797..5f117ca 100644
--- a/init/calibrate.c
+++ b/init/calibrate.c
@@ -246,6 +246,19 @@
static DEFINE_PER_CPU(unsigned long, cpu_loops_per_jiffy) = { 0 };
+/*
+ * Check if cpu calibration delay is already known. For example,
+ * some processors with multi-core sockets may have all cores
+ * with the same calibration delay.
+ *
+ * Architectures should override this function if a faster calibration
+ * method is available.
+ */
+unsigned long __attribute__((weak)) __cpuinit calibrate_delay_is_known(void)
+{
+ return 0;
+}
+
void __cpuinit calibrate_delay(void)
{
unsigned long lpj;
@@ -265,6 +278,8 @@
lpj = lpj_fine;
pr_info("Calibrating delay loop (skipped), "
"value calculated using timer frequency.. ");
+ } else if ((lpj = calibrate_delay_is_known())) {
+ ;
} else if ((lpj = calibrate_delay_direct()) != 0) {
if (!printed)
pr_info("Calibrating delay using timer "
diff --git a/init/main.c b/init/main.c
index 2c76efb..415548e 100644
--- a/init/main.c
+++ b/init/main.c
@@ -282,10 +282,6 @@
return 0;
}
-#ifdef CONFIG_DEBUG_PAGEALLOC
-int __read_mostly debug_pagealloc_enabled = 0;
-#endif
-
static int __init init_setup(char *str)
{
unsigned int i;
@@ -596,7 +592,6 @@
}
#endif
page_cgroup_init();
- enable_debug_pagealloc();
debug_objects_mem_init();
kmemleak_init();
setup_per_cpu_pageset();
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index cecbb64..fd7b25e 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -7134,10 +7134,6 @@
#endif
-#ifdef CONFIG_RT_GROUP_SCHED
-#else /* !CONFIG_RT_GROUP_SCHED */
-#endif /* CONFIG_RT_GROUP_SCHED */
-
#ifdef CONFIG_CGROUP_SCHED
/* task_group_lock serializes the addition/removal of task groups */
static DEFINE_SPINLOCK(task_group_lock);
@@ -7246,9 +7242,6 @@
}
#endif /* CONFIG_CGROUP_SCHED */
-#ifdef CONFIG_FAIR_GROUP_SCHED
-#endif
-
#if defined(CONFIG_RT_GROUP_SCHED) || defined(CONFIG_CFS_BANDWIDTH)
static unsigned long to_ratio(u64 period, u64 runtime)
{
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index 8e42de9..84adb2d 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -3130,8 +3130,10 @@
}
#define LBF_ALL_PINNED 0x01
-#define LBF_NEED_BREAK 0x02
-#define LBF_ABORT 0x04
+#define LBF_NEED_BREAK 0x02 /* clears into HAD_BREAK */
+#define LBF_HAD_BREAK 0x04
+#define LBF_HAD_BREAKS 0x0C /* count HAD_BREAKs overflows into ABORT */
+#define LBF_ABORT 0x10
/*
* can_migrate_task - may task p from runqueue rq be migrated to this_cpu?
@@ -4508,7 +4510,9 @@
goto out_balanced;
if (lb_flags & LBF_NEED_BREAK) {
- lb_flags &= ~LBF_NEED_BREAK;
+ lb_flags += LBF_HAD_BREAK - LBF_NEED_BREAK;
+ if (lb_flags & LBF_ABORT)
+ goto out_balanced;
goto redo;
}
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index ae27196..f487f25 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -803,6 +803,15 @@
.mode = 0644,
.proc_handler = proc_dointvec,
},
+#ifdef CONFIG_DEBUG_STACKOVERFLOW
+ {
+ .procname = "panic_on_stackoverflow",
+ .data = &sysctl_panic_on_stackoverflow,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = proc_dointvec,
+ },
+#endif
{
.procname = "bootloader_type",
.data = &bootloader_type,
diff --git a/lib/Kconfig b/lib/Kconfig
index 7f6b8bc..201e1b3 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -285,4 +285,29 @@
This option provides an implementation of the CORDIC algorithm;
calculations are in fixed point. Module will be called cordic.
+config MPILIB
+ tristate "Multiprecision maths library"
+ help
+ Multiprecision maths library from GnuPG.
+ It is used to implement RSA digital signature verification,
+ which is used by IMA/EVM digital signature extension.
+
+config MPILIB_EXTRA
+ bool "Multiprecision maths library - additional sources"
+ depends on MPILIB
+ help
+ Multiprecision maths library from GnuPG.
+ It is used to implement RSA digital signature verification,
+ which is used by IMA/EVM digital signature extension.
+ This code in unnecessary for RSA digital signature verification,
+ and can be compiled if needed.
+
+config DIGSIG
+ tristate "In-kernel signature checker"
+ depends on KEYS
+ select MPILIB
+ help
+ Digital signature verification. Currently only RSA is supported.
+ Implementation is done using GnuPG MPI library
+
endmenu
diff --git a/lib/Makefile b/lib/Makefile
index 884ed37..dace162 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -118,6 +118,9 @@
obj-$(CONFIG_DQL) += dynamic_queue_limits.o
+obj-$(CONFIG_MPILIB) += mpi/
+obj-$(CONFIG_DIGSIG) += digsig.o
+
hostprogs-y := gen_crc32table
clean-files := crc32table.h
diff --git a/lib/devres.c b/lib/devres.c
index 4fbc09e..9676617 100644
--- a/lib/devres.c
+++ b/lib/devres.c
@@ -304,7 +304,7 @@
*
* Request and iomap regions specified by @mask.
*/
-int pcim_iomap_regions(struct pci_dev *pdev, u16 mask, const char *name)
+int pcim_iomap_regions(struct pci_dev *pdev, int mask, const char *name)
{
void __iomem * const *iomap;
int i, rc;
@@ -357,7 +357,7 @@
*
* Request all PCI BARs and iomap regions specified by @mask.
*/
-int pcim_iomap_regions_request_all(struct pci_dev *pdev, u16 mask,
+int pcim_iomap_regions_request_all(struct pci_dev *pdev, int mask,
const char *name)
{
int request_mask = ((1 << 6) - 1) & ~mask;
@@ -381,7 +381,7 @@
*
* Unmap and release regions specified by @mask.
*/
-void pcim_iounmap_regions(struct pci_dev *pdev, u16 mask)
+void pcim_iounmap_regions(struct pci_dev *pdev, int mask)
{
void __iomem * const *iomap;
int i;
diff --git a/lib/digsig.c b/lib/digsig.c
new file mode 100644
index 0000000..fd2402f
--- /dev/null
+++ b/lib/digsig.c
@@ -0,0 +1,284 @@
+/*
+ * Copyright (C) 2011 Nokia Corporation
+ * Copyright (C) 2011 Intel Corporation
+ *
+ * Author:
+ * Dmitry Kasatkin <dmitry.kasatkin@nokia.com>
+ * <dmitry.kasatkin@intel.com>
+ *
+ * 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, version 2 of the License.
+ *
+ * File: sign.c
+ * implements signature (RSA) verification
+ * pkcs decoding is based on LibTomCrypt code
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/err.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/key.h>
+#include <linux/crypto.h>
+#include <crypto/hash.h>
+#include <crypto/sha.h>
+#include <keys/user-type.h>
+#include <linux/mpi.h>
+#include <linux/digsig.h>
+
+static struct crypto_shash *shash;
+
+static int pkcs_1_v1_5_decode_emsa(const unsigned char *msg,
+ unsigned long msglen,
+ unsigned long modulus_bitlen,
+ unsigned char *out,
+ unsigned long *outlen,
+ int *is_valid)
+{
+ unsigned long modulus_len, ps_len, i;
+ int result;
+
+ /* default to invalid packet */
+ *is_valid = 0;
+
+ modulus_len = (modulus_bitlen >> 3) + (modulus_bitlen & 7 ? 1 : 0);
+
+ /* test message size */
+ if ((msglen > modulus_len) || (modulus_len < 11))
+ return -EINVAL;
+
+ /* separate encoded message */
+ if ((msg[0] != 0x00) || (msg[1] != (unsigned char)1)) {
+ result = -EINVAL;
+ goto bail;
+ }
+
+ for (i = 2; i < modulus_len - 1; i++)
+ if (msg[i] != 0xFF)
+ break;
+
+ /* separator check */
+ if (msg[i] != 0) {
+ /* There was no octet with hexadecimal value 0x00
+ to separate ps from m. */
+ result = -EINVAL;
+ goto bail;
+ }
+
+ ps_len = i - 2;
+
+ if (*outlen < (msglen - (2 + ps_len + 1))) {
+ *outlen = msglen - (2 + ps_len + 1);
+ result = -EOVERFLOW;
+ goto bail;
+ }
+
+ *outlen = (msglen - (2 + ps_len + 1));
+ memcpy(out, &msg[2 + ps_len + 1], *outlen);
+
+ /* valid packet */
+ *is_valid = 1;
+ result = 0;
+bail:
+ return result;
+}
+
+/*
+ * RSA Signature verification with public key
+ */
+static int digsig_verify_rsa(struct key *key,
+ const char *sig, int siglen,
+ const char *h, int hlen)
+{
+ int err = -EINVAL;
+ unsigned long len;
+ unsigned long mlen, mblen;
+ unsigned nret, l;
+ int valid, head, i;
+ unsigned char *out1 = NULL, *out2 = NULL;
+ MPI in = NULL, res = NULL, pkey[2];
+ uint8_t *p, *datap, *endp;
+ struct user_key_payload *ukp;
+ struct pubkey_hdr *pkh;
+
+ down_read(&key->sem);
+ ukp = key->payload.data;
+ pkh = (struct pubkey_hdr *)ukp->data;
+
+ if (pkh->version != 1)
+ goto err1;
+
+ if (pkh->algo != PUBKEY_ALGO_RSA)
+ goto err1;
+
+ if (pkh->nmpi != 2)
+ goto err1;
+
+ datap = pkh->mpi;
+ endp = datap + ukp->datalen;
+
+ for (i = 0; i < pkh->nmpi; i++) {
+ unsigned int remaining = endp - datap;
+ pkey[i] = mpi_read_from_buffer(datap, &remaining);
+ datap += remaining;
+ }
+
+ mblen = mpi_get_nbits(pkey[0]);
+ mlen = (mblen + 7)/8;
+
+ err = -ENOMEM;
+
+ out1 = kzalloc(mlen, GFP_KERNEL);
+ if (!out1)
+ goto err;
+
+ out2 = kzalloc(mlen, GFP_KERNEL);
+ if (!out2)
+ goto err;
+
+ nret = siglen;
+ in = mpi_read_from_buffer(sig, &nret);
+ if (!in)
+ goto err;
+
+ res = mpi_alloc(mpi_get_nlimbs(in) * 2);
+ if (!res)
+ goto err;
+
+ err = mpi_powm(res, in, pkey[1], pkey[0]);
+ if (err)
+ goto err;
+
+ if (mpi_get_nlimbs(res) * BYTES_PER_MPI_LIMB > mlen) {
+ err = -EINVAL;
+ goto err;
+ }
+
+ p = mpi_get_buffer(res, &l, NULL);
+ if (!p) {
+ err = -EINVAL;
+ goto err;
+ }
+
+ len = mlen;
+ head = len - l;
+ memset(out1, 0, head);
+ memcpy(out1 + head, p, l);
+
+ err = -EINVAL;
+ pkcs_1_v1_5_decode_emsa(out1, len, mblen, out2, &len, &valid);
+
+ if (valid && len == hlen)
+ err = memcmp(out2, h, hlen);
+
+err:
+ mpi_free(in);
+ mpi_free(res);
+ kfree(out1);
+ kfree(out2);
+ mpi_free(pkey[0]);
+ mpi_free(pkey[1]);
+err1:
+ up_read(&key->sem);
+
+ return err;
+}
+
+/**
+ * digsig_verify() - digital signature verification with public key
+ * @keyring: keyring to search key in
+ * @sig: digital signature
+ * @sigen: length of the signature
+ * @data: data
+ * @datalen: length of the data
+ * @return: 0 on success, -EINVAL otherwise
+ *
+ * Verifies data integrity against digital signature.
+ * Currently only RSA is supported.
+ * Normally hash of the content is used as a data for this function.
+ *
+ */
+int digsig_verify(struct key *keyring, const char *sig, int siglen,
+ const char *data, int datalen)
+{
+ int err = -ENOMEM;
+ struct signature_hdr *sh = (struct signature_hdr *)sig;
+ struct shash_desc *desc = NULL;
+ unsigned char hash[SHA1_DIGEST_SIZE];
+ struct key *key;
+ char name[20];
+
+ if (siglen < sizeof(*sh) + 2)
+ return -EINVAL;
+
+ if (sh->algo != PUBKEY_ALGO_RSA)
+ return -ENOTSUPP;
+
+ sprintf(name, "%llX", __be64_to_cpup((uint64_t *)sh->keyid));
+
+ if (keyring) {
+ /* search in specific keyring */
+ key_ref_t kref;
+ kref = keyring_search(make_key_ref(keyring, 1UL),
+ &key_type_user, name);
+ if (IS_ERR(kref))
+ key = ERR_PTR(PTR_ERR(kref));
+ else
+ key = key_ref_to_ptr(kref);
+ } else {
+ key = request_key(&key_type_user, name, NULL);
+ }
+ if (IS_ERR(key)) {
+ pr_err("key not found, id: %s\n", name);
+ return PTR_ERR(key);
+ }
+
+ desc = kzalloc(sizeof(*desc) + crypto_shash_descsize(shash),
+ GFP_KERNEL);
+ if (!desc)
+ goto err;
+
+ desc->tfm = shash;
+ desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP;
+
+ crypto_shash_init(desc);
+ crypto_shash_update(desc, data, datalen);
+ crypto_shash_update(desc, sig, sizeof(*sh));
+ crypto_shash_final(desc, hash);
+
+ kfree(desc);
+
+ /* pass signature mpis address */
+ err = digsig_verify_rsa(key, sig + sizeof(*sh), siglen - sizeof(*sh),
+ hash, sizeof(hash));
+
+err:
+ key_put(key);
+
+ return err ? -EINVAL : 0;
+}
+EXPORT_SYMBOL_GPL(digsig_verify);
+
+static int __init digsig_init(void)
+{
+ shash = crypto_alloc_shash("sha1", 0, 0);
+ if (IS_ERR(shash)) {
+ pr_err("shash allocation failed\n");
+ return PTR_ERR(shash);
+ }
+
+ return 0;
+
+}
+
+static void __exit digsig_cleanup(void)
+{
+ crypto_free_shash(shash);
+}
+
+module_init(digsig_init);
+module_exit(digsig_cleanup);
+
+MODULE_LICENSE("GPL");
diff --git a/lib/mpi/Makefile b/lib/mpi/Makefile
new file mode 100644
index 0000000..567d52e
--- /dev/null
+++ b/lib/mpi/Makefile
@@ -0,0 +1,32 @@
+#
+# MPI multiprecision maths library (from gpg)
+#
+
+obj-$(CONFIG_MPILIB) = mpi.o
+
+mpi-y = \
+ generic_mpih-lshift.o \
+ generic_mpih-mul1.o \
+ generic_mpih-mul2.o \
+ generic_mpih-mul3.o \
+ generic_mpih-rshift.o \
+ generic_mpih-sub1.o \
+ generic_mpih-add1.o \
+ mpicoder.o \
+ mpi-bit.o \
+ mpih-cmp.o \
+ mpih-div.o \
+ mpih-mul.o \
+ mpi-pow.o \
+ mpiutil.o
+
+mpi-$(CONFIG_MPILIB_EXTRA) += \
+ mpi-add.o \
+ mpi-div.o \
+ mpi-cmp.o \
+ mpi-gcd.o \
+ mpi-inline.o \
+ mpi-inv.o \
+ mpi-mpow.o \
+ mpi-mul.o \
+ mpi-scan.o
diff --git a/lib/mpi/generic_mpi-asm-defs.h b/lib/mpi/generic_mpi-asm-defs.h
new file mode 100644
index 0000000..047d1f5
--- /dev/null
+++ b/lib/mpi/generic_mpi-asm-defs.h
@@ -0,0 +1,4 @@
+/* This file defines some basic constants for the MPI machinery. We
+ * need to define the types on a per-CPU basis, so it is done with
+ * this file here. */
+#define BYTES_PER_MPI_LIMB (SIZEOF_UNSIGNED_LONG)
diff --git a/lib/mpi/generic_mpih-add1.c b/lib/mpi/generic_mpih-add1.c
new file mode 100644
index 0000000..c94c7dd
--- /dev/null
+++ b/lib/mpi/generic_mpih-add1.c
@@ -0,0 +1,61 @@
+/* mpihelp-add_1.c - MPI helper functions
+ * Copyright (C) 1994, 1996, 1997, 1998,
+ * 2000 Free Software Foundation, Inc.
+ *
+ * This file is part of GnuPG.
+ *
+ * GnuPG 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.
+ *
+ * GnuPG 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ * The GNU MP Library itself is published under the LGPL;
+ * however I decided to publish this code under the plain GPL.
+ */
+
+#include "mpi-internal.h"
+#include "longlong.h"
+
+mpi_limb_t
+mpihelp_add_n(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
+ mpi_ptr_t s2_ptr, mpi_size_t size)
+{
+ mpi_limb_t x, y, cy;
+ mpi_size_t j;
+
+ /* The loop counter and index J goes from -SIZE to -1. This way
+ the loop becomes faster. */
+ j = -size;
+
+ /* Offset the base pointers to compensate for the negative indices. */
+ s1_ptr -= j;
+ s2_ptr -= j;
+ res_ptr -= j;
+
+ cy = 0;
+ do {
+ y = s2_ptr[j];
+ x = s1_ptr[j];
+ y += cy; /* add previous carry to one addend */
+ cy = y < cy; /* get out carry from that addition */
+ y += x; /* add other addend */
+ cy += y < x; /* get out carry from that add, combine */
+ res_ptr[j] = y;
+ } while (++j);
+
+ return cy;
+}
diff --git a/lib/mpi/generic_mpih-lshift.c b/lib/mpi/generic_mpih-lshift.c
new file mode 100644
index 0000000..8631892
--- /dev/null
+++ b/lib/mpi/generic_mpih-lshift.c
@@ -0,0 +1,63 @@
+/* mpihelp-lshift.c - MPI helper functions
+ * Copyright (C) 1994, 1996, 1998, 2001 Free Software Foundation, Inc.
+ *
+ * This file is part of GnuPG.
+ *
+ * GnuPG 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.
+ *
+ * GnuPG 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ * The GNU MP Library itself is published under the LGPL;
+ * however I decided to publish this code under the plain GPL.
+ */
+
+#include "mpi-internal.h"
+
+/* Shift U (pointed to by UP and USIZE digits long) CNT bits to the left
+ * and store the USIZE least significant digits of the result at WP.
+ * Return the bits shifted out from the most significant digit.
+ *
+ * Argument constraints:
+ * 1. 0 < CNT < BITS_PER_MP_LIMB
+ * 2. If the result is to be written over the input, WP must be >= UP.
+ */
+
+mpi_limb_t
+mpihelp_lshift(mpi_ptr_t wp, mpi_ptr_t up, mpi_size_t usize, unsigned int cnt)
+{
+ mpi_limb_t high_limb, low_limb;
+ unsigned sh_1, sh_2;
+ mpi_size_t i;
+ mpi_limb_t retval;
+
+ sh_1 = cnt;
+ wp += 1;
+ sh_2 = BITS_PER_MPI_LIMB - sh_1;
+ i = usize - 1;
+ low_limb = up[i];
+ retval = low_limb >> sh_2;
+ high_limb = low_limb;
+ while (--i >= 0) {
+ low_limb = up[i];
+ wp[i] = (high_limb << sh_1) | (low_limb >> sh_2);
+ high_limb = low_limb;
+ }
+ wp[i] = high_limb << sh_1;
+
+ return retval;
+}
diff --git a/lib/mpi/generic_mpih-mul1.c b/lib/mpi/generic_mpih-mul1.c
new file mode 100644
index 0000000..1668dfd
--- /dev/null
+++ b/lib/mpi/generic_mpih-mul1.c
@@ -0,0 +1,57 @@
+/* mpihelp-mul_1.c - MPI helper functions
+ * Copyright (C) 1994, 1996, 1997, 1998, 2001 Free Software Foundation, Inc.
+ *
+ * This file is part of GnuPG.
+ *
+ * GnuPG 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.
+ *
+ * GnuPG 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ * The GNU MP Library itself is published under the LGPL;
+ * however I decided to publish this code under the plain GPL.
+ */
+
+#include "mpi-internal.h"
+#include "longlong.h"
+
+mpi_limb_t
+mpihelp_mul_1(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, mpi_size_t s1_size,
+ mpi_limb_t s2_limb)
+{
+ mpi_limb_t cy_limb;
+ mpi_size_t j;
+ mpi_limb_t prod_high, prod_low;
+
+ /* The loop counter and index J goes from -S1_SIZE to -1. This way
+ * the loop becomes faster. */
+ j = -s1_size;
+
+ /* Offset the base pointers to compensate for the negative indices. */
+ s1_ptr -= j;
+ res_ptr -= j;
+
+ cy_limb = 0;
+ do {
+ umul_ppmm(prod_high, prod_low, s1_ptr[j], s2_limb);
+ prod_low += cy_limb;
+ cy_limb = (prod_low < cy_limb ? 1 : 0) + prod_high;
+ res_ptr[j] = prod_low;
+ } while (++j);
+
+ return cy_limb;
+}
diff --git a/lib/mpi/generic_mpih-mul2.c b/lib/mpi/generic_mpih-mul2.c
new file mode 100644
index 0000000..8a7b29e
--- /dev/null
+++ b/lib/mpi/generic_mpih-mul2.c
@@ -0,0 +1,60 @@
+/* mpihelp-mul_2.c - MPI helper functions
+ * Copyright (C) 1994, 1996, 1997, 1998, 2001 Free Software Foundation, Inc.
+ *
+ * This file is part of GnuPG.
+ *
+ * GnuPG 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.
+ *
+ * GnuPG 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ * The GNU MP Library itself is published under the LGPL;
+ * however I decided to publish this code under the plain GPL.
+ */
+
+#include "mpi-internal.h"
+#include "longlong.h"
+
+mpi_limb_t
+mpihelp_addmul_1(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
+ mpi_size_t s1_size, mpi_limb_t s2_limb)
+{
+ mpi_limb_t cy_limb;
+ mpi_size_t j;
+ mpi_limb_t prod_high, prod_low;
+ mpi_limb_t x;
+
+ /* The loop counter and index J goes from -SIZE to -1. This way
+ * the loop becomes faster. */
+ j = -s1_size;
+ res_ptr -= j;
+ s1_ptr -= j;
+
+ cy_limb = 0;
+ do {
+ umul_ppmm(prod_high, prod_low, s1_ptr[j], s2_limb);
+
+ prod_low += cy_limb;
+ cy_limb = (prod_low < cy_limb ? 1 : 0) + prod_high;
+
+ x = res_ptr[j];
+ prod_low = x + prod_low;
+ cy_limb += prod_low < x ? 1 : 0;
+ res_ptr[j] = prod_low;
+ } while (++j);
+ return cy_limb;
+}
diff --git a/lib/mpi/generic_mpih-mul3.c b/lib/mpi/generic_mpih-mul3.c
new file mode 100644
index 0000000..f96df327
--- /dev/null
+++ b/lib/mpi/generic_mpih-mul3.c
@@ -0,0 +1,61 @@
+/* mpihelp-mul_3.c - MPI helper functions
+ * Copyright (C) 1994, 1996, 1997, 1998, 2001 Free Software Foundation, Inc.
+ *
+ * This file is part of GnuPG.
+ *
+ * GnuPG 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.
+ *
+ * GnuPG 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ * The GNU MP Library itself is published under the LGPL;
+ * however I decided to publish this code under the plain GPL.
+ */
+
+#include "mpi-internal.h"
+#include "longlong.h"
+
+mpi_limb_t
+mpihelp_submul_1(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
+ mpi_size_t s1_size, mpi_limb_t s2_limb)
+{
+ mpi_limb_t cy_limb;
+ mpi_size_t j;
+ mpi_limb_t prod_high, prod_low;
+ mpi_limb_t x;
+
+ /* The loop counter and index J goes from -SIZE to -1. This way
+ * the loop becomes faster. */
+ j = -s1_size;
+ res_ptr -= j;
+ s1_ptr -= j;
+
+ cy_limb = 0;
+ do {
+ umul_ppmm(prod_high, prod_low, s1_ptr[j], s2_limb);
+
+ prod_low += cy_limb;
+ cy_limb = (prod_low < cy_limb ? 1 : 0) + prod_high;
+
+ x = res_ptr[j];
+ prod_low = x - prod_low;
+ cy_limb += prod_low > x ? 1 : 0;
+ res_ptr[j] = prod_low;
+ } while (++j);
+
+ return cy_limb;
+}
diff --git a/lib/mpi/generic_mpih-rshift.c b/lib/mpi/generic_mpih-rshift.c
new file mode 100644
index 0000000..ffa3288
--- /dev/null
+++ b/lib/mpi/generic_mpih-rshift.c
@@ -0,0 +1,63 @@
+/* mpih-rshift.c - MPI helper functions
+ * Copyright (C) 1994, 1996, 1998, 1999,
+ * 2000, 2001 Free Software Foundation, Inc.
+ *
+ * This file is part of GNUPG
+ *
+ * GNUPG 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.
+ *
+ * GNUPG 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ * The GNU MP Library itself is published under the LGPL;
+ * however I decided to publish this code under the plain GPL.
+ */
+
+#include "mpi-internal.h"
+
+/* Shift U (pointed to by UP and USIZE limbs long) CNT bits to the right
+ * and store the USIZE least significant limbs of the result at WP.
+ * The bits shifted out to the right are returned.
+ *
+ * Argument constraints:
+ * 1. 0 < CNT < BITS_PER_MP_LIMB
+ * 2. If the result is to be written over the input, WP must be <= UP.
+ */
+
+mpi_limb_t
+mpihelp_rshift(mpi_ptr_t wp, mpi_ptr_t up, mpi_size_t usize, unsigned cnt)
+{
+ mpi_limb_t high_limb, low_limb;
+ unsigned sh_1, sh_2;
+ mpi_size_t i;
+ mpi_limb_t retval;
+
+ sh_1 = cnt;
+ wp -= 1;
+ sh_2 = BITS_PER_MPI_LIMB - sh_1;
+ high_limb = up[0];
+ retval = high_limb << sh_2;
+ low_limb = high_limb;
+ for (i = 1; i < usize; i++) {
+ high_limb = up[i];
+ wp[i] = (low_limb >> sh_1) | (high_limb << sh_2);
+ low_limb = high_limb;
+ }
+ wp[i] = low_limb >> sh_1;
+
+ return retval;
+}
diff --git a/lib/mpi/generic_mpih-sub1.c b/lib/mpi/generic_mpih-sub1.c
new file mode 100644
index 0000000..5d98ab7
--- /dev/null
+++ b/lib/mpi/generic_mpih-sub1.c
@@ -0,0 +1,60 @@
+/* mpihelp-add_2.c - MPI helper functions
+ * Copyright (C) 1994, 1996, 1997, 1998, 2001 Free Software Foundation, Inc.
+ *
+ * This file is part of GnuPG.
+ *
+ * GnuPG 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.
+ *
+ * GnuPG 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ * The GNU MP Library itself is published under the LGPL;
+ * however I decided to publish this code under the plain GPL.
+ */
+
+#include "mpi-internal.h"
+#include "longlong.h"
+
+mpi_limb_t
+mpihelp_sub_n(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
+ mpi_ptr_t s2_ptr, mpi_size_t size)
+{
+ mpi_limb_t x, y, cy;
+ mpi_size_t j;
+
+ /* The loop counter and index J goes from -SIZE to -1. This way
+ the loop becomes faster. */
+ j = -size;
+
+ /* Offset the base pointers to compensate for the negative indices. */
+ s1_ptr -= j;
+ s2_ptr -= j;
+ res_ptr -= j;
+
+ cy = 0;
+ do {
+ y = s2_ptr[j];
+ x = s1_ptr[j];
+ y += cy; /* add previous carry to subtrahend */
+ cy = y < cy; /* get out carry from that addition */
+ y = x - y; /* main subtract */
+ cy += y > x; /* get out carry from the subtract, combine */
+ res_ptr[j] = y;
+ } while (++j);
+
+ return cy;
+}
diff --git a/lib/mpi/longlong.h b/lib/mpi/longlong.h
new file mode 100644
index 0000000..b87487b
--- /dev/null
+++ b/lib/mpi/longlong.h
@@ -0,0 +1,1478 @@
+/* longlong.h -- definitions for mixed size 32/64 bit arithmetic.
+ * Note: I added some stuff for use with gnupg
+ *
+ * Copyright (C) 1991, 1992, 1993, 1994, 1996, 1998,
+ * 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Library General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This file 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 Library General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this file; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA. */
+
+/* You have to define the following before including this file:
+ *
+ * UWtype -- An unsigned type, default type for operations (typically a "word")
+ * UHWtype -- An unsigned type, at least half the size of UWtype.
+ * UDWtype -- An unsigned type, at least twice as large a UWtype
+ * W_TYPE_SIZE -- size in bits of UWtype
+ *
+ * SItype, USItype -- Signed and unsigned 32 bit types.
+ * DItype, UDItype -- Signed and unsigned 64 bit types.
+ *
+ * On a 32 bit machine UWtype should typically be USItype;
+ * on a 64 bit machine, UWtype should typically be UDItype.
+*/
+
+#define __BITS4 (W_TYPE_SIZE / 4)
+#define __ll_B ((UWtype) 1 << (W_TYPE_SIZE / 2))
+#define __ll_lowpart(t) ((UWtype) (t) & (__ll_B - 1))
+#define __ll_highpart(t) ((UWtype) (t) >> (W_TYPE_SIZE / 2))
+
+/* This is used to make sure no undesirable sharing between different libraries
+ that use this file takes place. */
+#ifndef __MPN
+#define __MPN(x) __##x
+#endif
+
+/* Define auxiliary asm macros.
+ *
+ * 1) umul_ppmm(high_prod, low_prod, multipler, multiplicand) multiplies two
+ * UWtype integers MULTIPLER and MULTIPLICAND, and generates a two UWtype
+ * word product in HIGH_PROD and LOW_PROD.
+ *
+ * 2) __umulsidi3(a,b) multiplies two UWtype integers A and B, and returns a
+ * UDWtype product. This is just a variant of umul_ppmm.
+
+ * 3) udiv_qrnnd(quotient, remainder, high_numerator, low_numerator,
+ * denominator) divides a UDWtype, composed by the UWtype integers
+ * HIGH_NUMERATOR and LOW_NUMERATOR, by DENOMINATOR and places the quotient
+ * in QUOTIENT and the remainder in REMAINDER. HIGH_NUMERATOR must be less
+ * than DENOMINATOR for correct operation. If, in addition, the most
+ * significant bit of DENOMINATOR must be 1, then the pre-processor symbol
+ * UDIV_NEEDS_NORMALIZATION is defined to 1.
+ * 4) sdiv_qrnnd(quotient, remainder, high_numerator, low_numerator,
+ * denominator). Like udiv_qrnnd but the numbers are signed. The quotient
+ * is rounded towards 0.
+ *
+ * 5) count_leading_zeros(count, x) counts the number of zero-bits from the
+ * msb to the first non-zero bit in the UWtype X. This is the number of
+ * steps X needs to be shifted left to set the msb. Undefined for X == 0,
+ * unless the symbol COUNT_LEADING_ZEROS_0 is defined to some value.
+ *
+ * 6) count_trailing_zeros(count, x) like count_leading_zeros, but counts
+ * from the least significant end.
+ *
+ * 7) add_ssaaaa(high_sum, low_sum, high_addend_1, low_addend_1,
+ * high_addend_2, low_addend_2) adds two UWtype integers, composed by
+ * HIGH_ADDEND_1 and LOW_ADDEND_1, and HIGH_ADDEND_2 and LOW_ADDEND_2
+ * respectively. The result is placed in HIGH_SUM and LOW_SUM. Overflow
+ * (i.e. carry out) is not stored anywhere, and is lost.
+ *
+ * 8) sub_ddmmss(high_difference, low_difference, high_minuend, low_minuend,
+ * high_subtrahend, low_subtrahend) subtracts two two-word UWtype integers,
+ * composed by HIGH_MINUEND_1 and LOW_MINUEND_1, and HIGH_SUBTRAHEND_2 and
+ * LOW_SUBTRAHEND_2 respectively. The result is placed in HIGH_DIFFERENCE
+ * and LOW_DIFFERENCE. Overflow (i.e. carry out) is not stored anywhere,
+ * and is lost.
+ *
+ * If any of these macros are left undefined for a particular CPU,
+ * C macros are used. */
+
+/* The CPUs come in alphabetical order below.
+ *
+ * Please add support for more CPUs here, or improve the current support
+ * for the CPUs below! */
+
+#if defined(__GNUC__) && !defined(NO_ASM)
+
+/* We sometimes need to clobber "cc" with gcc2, but that would not be
+ understood by gcc1. Use cpp to avoid major code duplication. */
+#if __GNUC__ < 2
+#define __CLOBBER_CC
+#define __AND_CLOBBER_CC
+#else /* __GNUC__ >= 2 */
+#define __CLOBBER_CC : "cc"
+#define __AND_CLOBBER_CC , "cc"
+#endif /* __GNUC__ < 2 */
+
+/***************************************
+ ************** A29K *****************
+ ***************************************/
+#if (defined(__a29k__) || defined(_AM29K)) && W_TYPE_SIZE == 32
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("add %1,%4,%5\n" \
+ "addc %0,%2,%3" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "%r" ((USItype)(ah)), \
+ "rI" ((USItype)(bh)), \
+ "%r" ((USItype)(al)), \
+ "rI" ((USItype)(bl)))
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("sub %1,%4,%5\n" \
+ "subc %0,%2,%3" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "r" ((USItype)(ah)), \
+ "rI" ((USItype)(bh)), \
+ "r" ((USItype)(al)), \
+ "rI" ((USItype)(bl)))
+#define umul_ppmm(xh, xl, m0, m1) \
+do { \
+ USItype __m0 = (m0), __m1 = (m1); \
+ __asm__ ("multiplu %0,%1,%2" \
+ : "=r" ((USItype)(xl)) \
+ : "r" (__m0), \
+ "r" (__m1)); \
+ __asm__ ("multmu %0,%1,%2" \
+ : "=r" ((USItype)(xh)) \
+ : "r" (__m0), \
+ "r" (__m1)); \
+} while (0)
+#define udiv_qrnnd(q, r, n1, n0, d) \
+ __asm__ ("dividu %0,%3,%4" \
+ : "=r" ((USItype)(q)), \
+ "=q" ((USItype)(r)) \
+ : "1" ((USItype)(n1)), \
+ "r" ((USItype)(n0)), \
+ "r" ((USItype)(d)))
+
+#define count_leading_zeros(count, x) \
+ __asm__ ("clz %0,%1" \
+ : "=r" ((USItype)(count)) \
+ : "r" ((USItype)(x)))
+#define COUNT_LEADING_ZEROS_0 32
+#endif /* __a29k__ */
+
+#if defined(__alpha) && W_TYPE_SIZE == 64
+#define umul_ppmm(ph, pl, m0, m1) \
+do { \
+ UDItype __m0 = (m0), __m1 = (m1); \
+ __asm__ ("umulh %r1,%2,%0" \
+ : "=r" ((UDItype) ph) \
+ : "%rJ" (__m0), \
+ "rI" (__m1)); \
+ (pl) = __m0 * __m1; \
+ } while (0)
+#define UMUL_TIME 46
+#ifndef LONGLONG_STANDALONE
+#define udiv_qrnnd(q, r, n1, n0, d) \
+do { UDItype __r; \
+ (q) = __udiv_qrnnd(&__r, (n1), (n0), (d)); \
+ (r) = __r; \
+} while (0)
+extern UDItype __udiv_qrnnd();
+#define UDIV_TIME 220
+#endif /* LONGLONG_STANDALONE */
+#endif /* __alpha */
+
+/***************************************
+ ************** ARM ******************
+ ***************************************/
+#if defined(__arm__) && W_TYPE_SIZE == 32
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("adds %1, %4, %5\n" \
+ "adc %0, %2, %3" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "%r" ((USItype)(ah)), \
+ "rI" ((USItype)(bh)), \
+ "%r" ((USItype)(al)), \
+ "rI" ((USItype)(bl)))
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("subs %1, %4, %5\n" \
+ "sbc %0, %2, %3" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "r" ((USItype)(ah)), \
+ "rI" ((USItype)(bh)), \
+ "r" ((USItype)(al)), \
+ "rI" ((USItype)(bl)))
+#if defined __ARM_ARCH_2__ || defined __ARM_ARCH_3__
+#define umul_ppmm(xh, xl, a, b) \
+ __asm__ ("%@ Inlined umul_ppmm\n" \
+ "mov %|r0, %2, lsr #16 @ AAAA\n" \
+ "mov %|r2, %3, lsr #16 @ BBBB\n" \
+ "bic %|r1, %2, %|r0, lsl #16 @ aaaa\n" \
+ "bic %0, %3, %|r2, lsl #16 @ bbbb\n" \
+ "mul %1, %|r1, %|r2 @ aaaa * BBBB\n" \
+ "mul %|r2, %|r0, %|r2 @ AAAA * BBBB\n" \
+ "mul %|r1, %0, %|r1 @ aaaa * bbbb\n" \
+ "mul %0, %|r0, %0 @ AAAA * bbbb\n" \
+ "adds %|r0, %1, %0 @ central sum\n" \
+ "addcs %|r2, %|r2, #65536\n" \
+ "adds %1, %|r1, %|r0, lsl #16\n" \
+ "adc %0, %|r2, %|r0, lsr #16" \
+ : "=&r" ((USItype)(xh)), \
+ "=r" ((USItype)(xl)) \
+ : "r" ((USItype)(a)), \
+ "r" ((USItype)(b)) \
+ : "r0", "r1", "r2")
+#else
+#define umul_ppmm(xh, xl, a, b) \
+ __asm__ ("%@ Inlined umul_ppmm\n" \
+ "umull %r1, %r0, %r2, %r3" \
+ : "=&r" ((USItype)(xh)), \
+ "=r" ((USItype)(xl)) \
+ : "r" ((USItype)(a)), \
+ "r" ((USItype)(b)) \
+ : "r0", "r1")
+#endif
+#define UMUL_TIME 20
+#define UDIV_TIME 100
+#endif /* __arm__ */
+
+/***************************************
+ ************** CLIPPER **************
+ ***************************************/
+#if defined(__clipper__) && W_TYPE_SIZE == 32
+#define umul_ppmm(w1, w0, u, v) \
+ ({union {UDItype __ll; \
+ struct {USItype __l, __h; } __i; \
+ } __xx; \
+ __asm__ ("mulwux %2,%0" \
+ : "=r" (__xx.__ll) \
+ : "%0" ((USItype)(u)), \
+ "r" ((USItype)(v))); \
+ (w1) = __xx.__i.__h; (w0) = __xx.__i.__l; })
+#define smul_ppmm(w1, w0, u, v) \
+ ({union {DItype __ll; \
+ struct {SItype __l, __h; } __i; \
+ } __xx; \
+ __asm__ ("mulwx %2,%0" \
+ : "=r" (__xx.__ll) \
+ : "%0" ((SItype)(u)), \
+ "r" ((SItype)(v))); \
+ (w1) = __xx.__i.__h; (w0) = __xx.__i.__l; })
+#define __umulsidi3(u, v) \
+ ({UDItype __w; \
+ __asm__ ("mulwux %2,%0" \
+ : "=r" (__w) \
+ : "%0" ((USItype)(u)), \
+ "r" ((USItype)(v))); \
+ __w; })
+#endif /* __clipper__ */
+
+/***************************************
+ ************** GMICRO ***************
+ ***************************************/
+#if defined(__gmicro__) && W_TYPE_SIZE == 32
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("add.w %5,%1\n" \
+ "addx %3,%0" \
+ : "=g" ((USItype)(sh)), \
+ "=&g" ((USItype)(sl)) \
+ : "%0" ((USItype)(ah)), \
+ "g" ((USItype)(bh)), \
+ "%1" ((USItype)(al)), \
+ "g" ((USItype)(bl)))
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("sub.w %5,%1\n" \
+ "subx %3,%0" \
+ : "=g" ((USItype)(sh)), \
+ "=&g" ((USItype)(sl)) \
+ : "0" ((USItype)(ah)), \
+ "g" ((USItype)(bh)), \
+ "1" ((USItype)(al)), \
+ "g" ((USItype)(bl)))
+#define umul_ppmm(ph, pl, m0, m1) \
+ __asm__ ("mulx %3,%0,%1" \
+ : "=g" ((USItype)(ph)), \
+ "=r" ((USItype)(pl)) \
+ : "%0" ((USItype)(m0)), \
+ "g" ((USItype)(m1)))
+#define udiv_qrnnd(q, r, nh, nl, d) \
+ __asm__ ("divx %4,%0,%1" \
+ : "=g" ((USItype)(q)), \
+ "=r" ((USItype)(r)) \
+ : "1" ((USItype)(nh)), \
+ "0" ((USItype)(nl)), \
+ "g" ((USItype)(d)))
+#define count_leading_zeros(count, x) \
+ __asm__ ("bsch/1 %1,%0" \
+ : "=g" (count) \
+ : "g" ((USItype)(x)), \
+ "0" ((USItype)0))
+#endif
+
+/***************************************
+ ************** HPPA *****************
+ ***************************************/
+#if defined(__hppa) && W_TYPE_SIZE == 32
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("add %4,%5,%1\n" \
+ "addc %2,%3,%0" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "%rM" ((USItype)(ah)), \
+ "rM" ((USItype)(bh)), \
+ "%rM" ((USItype)(al)), \
+ "rM" ((USItype)(bl)))
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("sub %4,%5,%1\n" \
+ "subb %2,%3,%0" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "rM" ((USItype)(ah)), \
+ "rM" ((USItype)(bh)), \
+ "rM" ((USItype)(al)), \
+ "rM" ((USItype)(bl)))
+#if defined(_PA_RISC1_1)
+#define umul_ppmm(wh, wl, u, v) \
+do { \
+ union {UDItype __ll; \
+ struct {USItype __h, __l; } __i; \
+ } __xx; \
+ __asm__ ("xmpyu %1,%2,%0" \
+ : "=*f" (__xx.__ll) \
+ : "*f" ((USItype)(u)), \
+ "*f" ((USItype)(v))); \
+ (wh) = __xx.__i.__h; \
+ (wl) = __xx.__i.__l; \
+} while (0)
+#define UMUL_TIME 8
+#define UDIV_TIME 60
+#else
+#define UMUL_TIME 40
+#define UDIV_TIME 80
+#endif
+#ifndef LONGLONG_STANDALONE
+#define udiv_qrnnd(q, r, n1, n0, d) \
+do { USItype __r; \
+ (q) = __udiv_qrnnd(&__r, (n1), (n0), (d)); \
+ (r) = __r; \
+} while (0)
+extern USItype __udiv_qrnnd();
+#endif /* LONGLONG_STANDALONE */
+#define count_leading_zeros(count, x) \
+do { \
+ USItype __tmp; \
+ __asm__ ( \
+ "ldi 1,%0\n" \
+ "extru,= %1,15,16,%%r0 ; Bits 31..16 zero?\n" \
+ "extru,tr %1,15,16,%1 ; No. Shift down, skip add.\n" \
+ "ldo 16(%0),%0 ; Yes. Perform add.\n" \
+ "extru,= %1,23,8,%%r0 ; Bits 15..8 zero?\n" \
+ "extru,tr %1,23,8,%1 ; No. Shift down, skip add.\n" \
+ "ldo 8(%0),%0 ; Yes. Perform add.\n" \
+ "extru,= %1,27,4,%%r0 ; Bits 7..4 zero?\n" \
+ "extru,tr %1,27,4,%1 ; No. Shift down, skip add.\n" \
+ "ldo 4(%0),%0 ; Yes. Perform add.\n" \
+ "extru,= %1,29,2,%%r0 ; Bits 3..2 zero?\n" \
+ "extru,tr %1,29,2,%1 ; No. Shift down, skip add.\n" \
+ "ldo 2(%0),%0 ; Yes. Perform add.\n" \
+ "extru %1,30,1,%1 ; Extract bit 1.\n" \
+ "sub %0,%1,%0 ; Subtract it. " \
+ : "=r" (count), "=r" (__tmp) : "1" (x)); \
+} while (0)
+#endif /* hppa */
+
+/***************************************
+ ************** I370 *****************
+ ***************************************/
+#if (defined(__i370__) || defined(__mvs__)) && W_TYPE_SIZE == 32
+#define umul_ppmm(xh, xl, m0, m1) \
+do { \
+ union {UDItype __ll; \
+ struct {USItype __h, __l; } __i; \
+ } __xx; \
+ USItype __m0 = (m0), __m1 = (m1); \
+ __asm__ ("mr %0,%3" \
+ : "=r" (__xx.__i.__h), \
+ "=r" (__xx.__i.__l) \
+ : "%1" (__m0), \
+ "r" (__m1)); \
+ (xh) = __xx.__i.__h; (xl) = __xx.__i.__l; \
+ (xh) += ((((SItype) __m0 >> 31) & __m1) \
+ + (((SItype) __m1 >> 31) & __m0)); \
+} while (0)
+#define smul_ppmm(xh, xl, m0, m1) \
+do { \
+ union {DItype __ll; \
+ struct {USItype __h, __l; } __i; \
+ } __xx; \
+ __asm__ ("mr %0,%3" \
+ : "=r" (__xx.__i.__h), \
+ "=r" (__xx.__i.__l) \
+ : "%1" (m0), \
+ "r" (m1)); \
+ (xh) = __xx.__i.__h; (xl) = __xx.__i.__l; \
+} while (0)
+#define sdiv_qrnnd(q, r, n1, n0, d) \
+do { \
+ union {DItype __ll; \
+ struct {USItype __h, __l; } __i; \
+ } __xx; \
+ __xx.__i.__h = n1; __xx.__i.__l = n0; \
+ __asm__ ("dr %0,%2" \
+ : "=r" (__xx.__ll) \
+ : "0" (__xx.__ll), "r" (d)); \
+ (q) = __xx.__i.__l; (r) = __xx.__i.__h; \
+} while (0)
+#endif
+
+/***************************************
+ ************** I386 *****************
+ ***************************************/
+#undef __i386__
+#if (defined(__i386__) || defined(__i486__)) && W_TYPE_SIZE == 32
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("addl %5,%1\n" \
+ "adcl %3,%0" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "%0" ((USItype)(ah)), \
+ "g" ((USItype)(bh)), \
+ "%1" ((USItype)(al)), \
+ "g" ((USItype)(bl)))
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("subl %5,%1\n" \
+ "sbbl %3,%0" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "0" ((USItype)(ah)), \
+ "g" ((USItype)(bh)), \
+ "1" ((USItype)(al)), \
+ "g" ((USItype)(bl)))
+#define umul_ppmm(w1, w0, u, v) \
+ __asm__ ("mull %3" \
+ : "=a" ((USItype)(w0)), \
+ "=d" ((USItype)(w1)) \
+ : "%0" ((USItype)(u)), \
+ "rm" ((USItype)(v)))
+#define udiv_qrnnd(q, r, n1, n0, d) \
+ __asm__ ("divl %4" \
+ : "=a" ((USItype)(q)), \
+ "=d" ((USItype)(r)) \
+ : "0" ((USItype)(n0)), \
+ "1" ((USItype)(n1)), \
+ "rm" ((USItype)(d)))
+#define count_leading_zeros(count, x) \
+do { \
+ USItype __cbtmp; \
+ __asm__ ("bsrl %1,%0" \
+ : "=r" (__cbtmp) : "rm" ((USItype)(x))); \
+ (count) = __cbtmp ^ 31; \
+} while (0)
+#define count_trailing_zeros(count, x) \
+ __asm__ ("bsfl %1,%0" : "=r" (count) : "rm" ((USItype)(x)))
+#ifndef UMUL_TIME
+#define UMUL_TIME 40
+#endif
+#ifndef UDIV_TIME
+#define UDIV_TIME 40
+#endif
+#endif /* 80x86 */
+
+/***************************************
+ ************** I860 *****************
+ ***************************************/
+#if defined(__i860__) && W_TYPE_SIZE == 32
+#define rshift_rhlc(r, h, l, c) \
+ __asm__ ("shr %3,r0,r0\n" \
+ "shrd %1,%2,%0" \
+ "=r" (r) : "r" (h), "r" (l), "rn" (c))
+#endif /* i860 */
+
+/***************************************
+ ************** I960 *****************
+ ***************************************/
+#if defined(__i960__) && W_TYPE_SIZE == 32
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("cmpo 1,0\n" \
+ "addc %5,%4,%1\n" \
+ "addc %3,%2,%0" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "%dI" ((USItype)(ah)), \
+ "dI" ((USItype)(bh)), \
+ "%dI" ((USItype)(al)), \
+ "dI" ((USItype)(bl)))
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("cmpo 0,0\n" \
+ "subc %5,%4,%1\n" \
+ "subc %3,%2,%0" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "dI" ((USItype)(ah)), \
+ "dI" ((USItype)(bh)), \
+ "dI" ((USItype)(al)), \
+ "dI" ((USItype)(bl)))
+#define umul_ppmm(w1, w0, u, v) \
+ ({union {UDItype __ll; \
+ struct {USItype __l, __h; } __i; \
+ } __xx; \
+ __asm__ ("emul %2,%1,%0" \
+ : "=d" (__xx.__ll) \
+ : "%dI" ((USItype)(u)), \
+ "dI" ((USItype)(v))); \
+ (w1) = __xx.__i.__h; (w0) = __xx.__i.__l; })
+#define __umulsidi3(u, v) \
+ ({UDItype __w; \
+ __asm__ ("emul %2,%1,%0" \
+ : "=d" (__w) \
+ : "%dI" ((USItype)(u)), \
+ "dI" ((USItype)(v))); \
+ __w; })
+#define udiv_qrnnd(q, r, nh, nl, d) \
+do { \
+ union {UDItype __ll; \
+ struct {USItype __l, __h; } __i; \
+ } __nn; \
+ __nn.__i.__h = (nh); __nn.__i.__l = (nl); \
+ __asm__ ("ediv %d,%n,%0" \
+ : "=d" (__rq.__ll) \
+ : "dI" (__nn.__ll), \
+ "dI" ((USItype)(d))); \
+ (r) = __rq.__i.__l; (q) = __rq.__i.__h; \
+} while (0)
+#define count_leading_zeros(count, x) \
+do { \
+ USItype __cbtmp; \
+ __asm__ ("scanbit %1,%0" \
+ : "=r" (__cbtmp) \
+ : "r" ((USItype)(x))); \
+ (count) = __cbtmp ^ 31; \
+} while (0)
+#define COUNT_LEADING_ZEROS_0 (-32) /* sic */
+#if defined(__i960mx) /* what is the proper symbol to test??? */
+#define rshift_rhlc(r, h, l, c) \
+do { \
+ union {UDItype __ll; \
+ struct {USItype __l, __h; } __i; \
+ } __nn; \
+ __nn.__i.__h = (h); __nn.__i.__l = (l); \
+ __asm__ ("shre %2,%1,%0" \
+ : "=d" (r) : "dI" (__nn.__ll), "dI" (c)); \
+}
+#endif /* i960mx */
+#endif /* i960 */
+
+/***************************************
+ ************** 68000 ****************
+ ***************************************/
+#if (defined(__mc68000__) || defined(__mc68020__) || defined(__NeXT__) || defined(mc68020)) && W_TYPE_SIZE == 32
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("add%.l %5,%1\n" \
+ "addx%.l %3,%0" \
+ : "=d" ((USItype)(sh)), \
+ "=&d" ((USItype)(sl)) \
+ : "%0" ((USItype)(ah)), \
+ "d" ((USItype)(bh)), \
+ "%1" ((USItype)(al)), \
+ "g" ((USItype)(bl)))
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("sub%.l %5,%1\n" \
+ "subx%.l %3,%0" \
+ : "=d" ((USItype)(sh)), \
+ "=&d" ((USItype)(sl)) \
+ : "0" ((USItype)(ah)), \
+ "d" ((USItype)(bh)), \
+ "1" ((USItype)(al)), \
+ "g" ((USItype)(bl)))
+#if (defined(__mc68020__) || defined(__NeXT__) || defined(mc68020))
+#define umul_ppmm(w1, w0, u, v) \
+ __asm__ ("mulu%.l %3,%1:%0" \
+ : "=d" ((USItype)(w0)), \
+ "=d" ((USItype)(w1)) \
+ : "%0" ((USItype)(u)), \
+ "dmi" ((USItype)(v)))
+#define UMUL_TIME 45
+#define udiv_qrnnd(q, r, n1, n0, d) \
+ __asm__ ("divu%.l %4,%1:%0" \
+ : "=d" ((USItype)(q)), \
+ "=d" ((USItype)(r)) \
+ : "0" ((USItype)(n0)), \
+ "1" ((USItype)(n1)), \
+ "dmi" ((USItype)(d)))
+#define UDIV_TIME 90
+#define sdiv_qrnnd(q, r, n1, n0, d) \
+ __asm__ ("divs%.l %4,%1:%0" \
+ : "=d" ((USItype)(q)), \
+ "=d" ((USItype)(r)) \
+ : "0" ((USItype)(n0)), \
+ "1" ((USItype)(n1)), \
+ "dmi" ((USItype)(d)))
+#define count_leading_zeros(count, x) \
+ __asm__ ("bfffo %1{%b2:%b2},%0" \
+ : "=d" ((USItype)(count)) \
+ : "od" ((USItype)(x)), "n" (0))
+#define COUNT_LEADING_ZEROS_0 32
+#else /* not mc68020 */
+#define umul_ppmm(xh, xl, a, b) \
+do { USItype __umul_tmp1, __umul_tmp2; \
+ __asm__ ("| Inlined umul_ppmm\n" \
+ "move%.l %5,%3\n" \
+ "move%.l %2,%0\n" \
+ "move%.w %3,%1\n" \
+ "swap %3\n" \
+ "swap %0\n" \
+ "mulu %2,%1\n" \
+ "mulu %3,%0\n" \
+ "mulu %2,%3\n" \
+ "swap %2\n" \
+ "mulu %5,%2\n" \
+ "add%.l %3,%2\n" \
+ "jcc 1f\n" \
+ "add%.l %#0x10000,%0\n" \
+ "1: move%.l %2,%3\n" \
+ "clr%.w %2\n" \
+ "swap %2\n" \
+ "swap %3\n" \
+ "clr%.w %3\n" \
+ "add%.l %3,%1\n" \
+ "addx%.l %2,%0\n" \
+ "| End inlined umul_ppmm" \
+ : "=&d" ((USItype)(xh)), "=&d" ((USItype)(xl)), \
+ "=d" (__umul_tmp1), "=&d" (__umul_tmp2) \
+ : "%2" ((USItype)(a)), "d" ((USItype)(b))); \
+} while (0)
+#define UMUL_TIME 100
+#define UDIV_TIME 400
+#endif /* not mc68020 */
+#endif /* mc68000 */
+
+/***************************************
+ ************** 88000 ****************
+ ***************************************/
+#if defined(__m88000__) && W_TYPE_SIZE == 32
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("addu.co %1,%r4,%r5\n" \
+ "addu.ci %0,%r2,%r3" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "%rJ" ((USItype)(ah)), \
+ "rJ" ((USItype)(bh)), \
+ "%rJ" ((USItype)(al)), \
+ "rJ" ((USItype)(bl)))
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("subu.co %1,%r4,%r5\n" \
+ "subu.ci %0,%r2,%r3" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "rJ" ((USItype)(ah)), \
+ "rJ" ((USItype)(bh)), \
+ "rJ" ((USItype)(al)), \
+ "rJ" ((USItype)(bl)))
+#define count_leading_zeros(count, x) \
+do { \
+ USItype __cbtmp; \
+ __asm__ ("ff1 %0,%1" \
+ : "=r" (__cbtmp) \
+ : "r" ((USItype)(x))); \
+ (count) = __cbtmp ^ 31; \
+} while (0)
+#define COUNT_LEADING_ZEROS_0 63 /* sic */
+#if defined(__m88110__)
+#define umul_ppmm(wh, wl, u, v) \
+do { \
+ union {UDItype __ll; \
+ struct {USItype __h, __l; } __i; \
+ } __x; \
+ __asm__ ("mulu.d %0,%1,%2" : "=r" (__x.__ll) : "r" (u), "r" (v)); \
+ (wh) = __x.__i.__h; \
+ (wl) = __x.__i.__l; \
+} while (0)
+#define udiv_qrnnd(q, r, n1, n0, d) \
+ ({union {UDItype __ll; \
+ struct {USItype __h, __l; } __i; \
+ } __x, __q; \
+ __x.__i.__h = (n1); __x.__i.__l = (n0); \
+ __asm__ ("divu.d %0,%1,%2" \
+ : "=r" (__q.__ll) : "r" (__x.__ll), "r" (d)); \
+ (r) = (n0) - __q.__l * (d); (q) = __q.__l; })
+#define UMUL_TIME 5
+#define UDIV_TIME 25
+#else
+#define UMUL_TIME 17
+#define UDIV_TIME 150
+#endif /* __m88110__ */
+#endif /* __m88000__ */
+
+/***************************************
+ ************** MIPS *****************
+ ***************************************/
+#if defined(__mips__) && W_TYPE_SIZE == 32
+#if __GNUC__ > 2 || __GNUC_MINOR__ >= 7
+#define umul_ppmm(w1, w0, u, v) \
+ __asm__ ("multu %2,%3" \
+ : "=l" ((USItype)(w0)), \
+ "=h" ((USItype)(w1)) \
+ : "d" ((USItype)(u)), \
+ "d" ((USItype)(v)))
+#else
+#define umul_ppmm(w1, w0, u, v) \
+ __asm__ ("multu %2,%3\n" \
+ "mflo %0\n" \
+ "mfhi %1" \
+ : "=d" ((USItype)(w0)), \
+ "=d" ((USItype)(w1)) \
+ : "d" ((USItype)(u)), \
+ "d" ((USItype)(v)))
+#endif
+#define UMUL_TIME 10
+#define UDIV_TIME 100
+#endif /* __mips__ */
+
+/***************************************
+ ************** MIPS/64 **************
+ ***************************************/
+#if (defined(__mips) && __mips >= 3) && W_TYPE_SIZE == 64
+#if __GNUC__ > 2 || __GNUC_MINOR__ >= 7
+#define umul_ppmm(w1, w0, u, v) \
+ __asm__ ("dmultu %2,%3" \
+ : "=l" ((UDItype)(w0)), \
+ "=h" ((UDItype)(w1)) \
+ : "d" ((UDItype)(u)), \
+ "d" ((UDItype)(v)))
+#else
+#define umul_ppmm(w1, w0, u, v) \
+ __asm__ ("dmultu %2,%3\n" \
+ "mflo %0\n" \
+ "mfhi %1" \
+ : "=d" ((UDItype)(w0)), \
+ "=d" ((UDItype)(w1)) \
+ : "d" ((UDItype)(u)), \
+ "d" ((UDItype)(v)))
+#endif
+#define UMUL_TIME 20
+#define UDIV_TIME 140
+#endif /* __mips__ */
+
+/***************************************
+ ************** 32000 ****************
+ ***************************************/
+#if defined(__ns32000__) && W_TYPE_SIZE == 32
+#define umul_ppmm(w1, w0, u, v) \
+ ({union {UDItype __ll; \
+ struct {USItype __l, __h; } __i; \
+ } __xx; \
+ __asm__ ("meid %2,%0" \
+ : "=g" (__xx.__ll) \
+ : "%0" ((USItype)(u)), \
+ "g" ((USItype)(v))); \
+ (w1) = __xx.__i.__h; (w0) = __xx.__i.__l; })
+#define __umulsidi3(u, v) \
+ ({UDItype __w; \
+ __asm__ ("meid %2,%0" \
+ : "=g" (__w) \
+ : "%0" ((USItype)(u)), \
+ "g" ((USItype)(v))); \
+ __w; })
+#define udiv_qrnnd(q, r, n1, n0, d) \
+ ({union {UDItype __ll; \
+ struct {USItype __l, __h; } __i; \
+ } __xx; \
+ __xx.__i.__h = (n1); __xx.__i.__l = (n0); \
+ __asm__ ("deid %2,%0" \
+ : "=g" (__xx.__ll) \
+ : "0" (__xx.__ll), \
+ "g" ((USItype)(d))); \
+ (r) = __xx.__i.__l; (q) = __xx.__i.__h; })
+#define count_trailing_zeros(count, x) \
+do { \
+ __asm__("ffsd %2,%0" \
+ : "=r"((USItype) (count)) \
+ : "0"((USItype) 0), "r"((USItype) (x))); \
+ } while (0)
+#endif /* __ns32000__ */
+
+/***************************************
+ ************** PPC ******************
+ ***************************************/
+#if (defined(_ARCH_PPC) || defined(_IBMR2)) && W_TYPE_SIZE == 32
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+do { \
+ if (__builtin_constant_p(bh) && (bh) == 0) \
+ __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{aze|addze} %0,%2" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "%r" ((USItype)(ah)), \
+ "%r" ((USItype)(al)), \
+ "rI" ((USItype)(bl))); \
+ else if (__builtin_constant_p(bh) && (bh) == ~(USItype) 0) \
+ __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{ame|addme} %0,%2" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "%r" ((USItype)(ah)), \
+ "%r" ((USItype)(al)), \
+ "rI" ((USItype)(bl))); \
+ else \
+ __asm__ ("{a%I5|add%I5c} %1,%4,%5\n\t{ae|adde} %0,%2,%3" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "%r" ((USItype)(ah)), \
+ "r" ((USItype)(bh)), \
+ "%r" ((USItype)(al)), \
+ "rI" ((USItype)(bl))); \
+} while (0)
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+do { \
+ if (__builtin_constant_p(ah) && (ah) == 0) \
+ __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfze|subfze} %0,%2" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "r" ((USItype)(bh)), \
+ "rI" ((USItype)(al)), \
+ "r" ((USItype)(bl))); \
+ else if (__builtin_constant_p(ah) && (ah) == ~(USItype) 0) \
+ __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfme|subfme} %0,%2" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "r" ((USItype)(bh)), \
+ "rI" ((USItype)(al)), \
+ "r" ((USItype)(bl))); \
+ else if (__builtin_constant_p(bh) && (bh) == 0) \
+ __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{ame|addme} %0,%2" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "r" ((USItype)(ah)), \
+ "rI" ((USItype)(al)), \
+ "r" ((USItype)(bl))); \
+ else if (__builtin_constant_p(bh) && (bh) == ~(USItype) 0) \
+ __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{aze|addze} %0,%2" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "r" ((USItype)(ah)), \
+ "rI" ((USItype)(al)), \
+ "r" ((USItype)(bl))); \
+ else \
+ __asm__ ("{sf%I4|subf%I4c} %1,%5,%4\n\t{sfe|subfe} %0,%3,%2" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "r" ((USItype)(ah)), \
+ "r" ((USItype)(bh)), \
+ "rI" ((USItype)(al)), \
+ "r" ((USItype)(bl))); \
+} while (0)
+#define count_leading_zeros(count, x) \
+ __asm__ ("{cntlz|cntlzw} %0,%1" \
+ : "=r" ((USItype)(count)) \
+ : "r" ((USItype)(x)))
+#define COUNT_LEADING_ZEROS_0 32
+#if defined(_ARCH_PPC)
+#define umul_ppmm(ph, pl, m0, m1) \
+do { \
+ USItype __m0 = (m0), __m1 = (m1); \
+ __asm__ ("mulhwu %0,%1,%2" \
+ : "=r" ((USItype) ph) \
+ : "%r" (__m0), \
+ "r" (__m1)); \
+ (pl) = __m0 * __m1; \
+} while (0)
+#define UMUL_TIME 15
+#define smul_ppmm(ph, pl, m0, m1) \
+do { \
+ SItype __m0 = (m0), __m1 = (m1); \
+ __asm__ ("mulhw %0,%1,%2" \
+ : "=r" ((SItype) ph) \
+ : "%r" (__m0), \
+ "r" (__m1)); \
+ (pl) = __m0 * __m1; \
+} while (0)
+#define SMUL_TIME 14
+#define UDIV_TIME 120
+#else
+#define umul_ppmm(xh, xl, m0, m1) \
+do { \
+ USItype __m0 = (m0), __m1 = (m1); \
+ __asm__ ("mul %0,%2,%3" \
+ : "=r" ((USItype)(xh)), \
+ "=q" ((USItype)(xl)) \
+ : "r" (__m0), \
+ "r" (__m1)); \
+ (xh) += ((((SItype) __m0 >> 31) & __m1) \
+ + (((SItype) __m1 >> 31) & __m0)); \
+} while (0)
+#define UMUL_TIME 8
+#define smul_ppmm(xh, xl, m0, m1) \
+ __asm__ ("mul %0,%2,%3" \
+ : "=r" ((SItype)(xh)), \
+ "=q" ((SItype)(xl)) \
+ : "r" (m0), \
+ "r" (m1))
+#define SMUL_TIME 4
+#define sdiv_qrnnd(q, r, nh, nl, d) \
+ __asm__ ("div %0,%2,%4" \
+ : "=r" ((SItype)(q)), "=q" ((SItype)(r)) \
+ : "r" ((SItype)(nh)), "1" ((SItype)(nl)), "r" ((SItype)(d)))
+#define UDIV_TIME 100
+#endif
+#endif /* Power architecture variants. */
+
+/***************************************
+ ************** PYR ******************
+ ***************************************/
+#if defined(__pyr__) && W_TYPE_SIZE == 32
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("addw %5,%1\n" \
+ "addwc %3,%0" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "%0" ((USItype)(ah)), \
+ "g" ((USItype)(bh)), \
+ "%1" ((USItype)(al)), \
+ "g" ((USItype)(bl)))
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("subw %5,%1\n" \
+ "subwb %3,%0" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "0" ((USItype)(ah)), \
+ "g" ((USItype)(bh)), \
+ "1" ((USItype)(al)), \
+ "g" ((USItype)(bl)))
+ /* This insn works on Pyramids with AP, XP, or MI CPUs, but not with SP. */
+#define umul_ppmm(w1, w0, u, v) \
+ ({union {UDItype __ll; \
+ struct {USItype __h, __l; } __i; \
+ } __xx; \
+ __asm__ ("movw %1,%R0\n" \
+ "uemul %2,%0" \
+ : "=&r" (__xx.__ll) \
+ : "g" ((USItype) (u)), \
+ "g" ((USItype)(v))); \
+ (w1) = __xx.__i.__h; (w0) = __xx.__i.__l; })
+#endif /* __pyr__ */
+
+/***************************************
+ ************** RT/ROMP **************
+ ***************************************/
+#if defined(__ibm032__) /* RT/ROMP */ && W_TYPE_SIZE == 32
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("a %1,%5\n" \
+ "ae %0,%3" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "%0" ((USItype)(ah)), \
+ "r" ((USItype)(bh)), \
+ "%1" ((USItype)(al)), \
+ "r" ((USItype)(bl)))
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("s %1,%5\n" \
+ "se %0,%3" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "0" ((USItype)(ah)), \
+ "r" ((USItype)(bh)), \
+ "1" ((USItype)(al)), \
+ "r" ((USItype)(bl)))
+#define umul_ppmm(ph, pl, m0, m1) \
+do { \
+ USItype __m0 = (m0), __m1 = (m1); \
+ __asm__ ( \
+ "s r2,r2\n" \
+ "mts r10,%2\n" \
+ "m r2,%3\n" \
+ "m r2,%3\n" \
+ "m r2,%3\n" \
+ "m r2,%3\n" \
+ "m r2,%3\n" \
+ "m r2,%3\n" \
+ "m r2,%3\n" \
+ "m r2,%3\n" \
+ "m r2,%3\n" \
+ "m r2,%3\n" \
+ "m r2,%3\n" \
+ "m r2,%3\n" \
+ "m r2,%3\n" \
+ "m r2,%3\n" \
+ "m r2,%3\n" \
+ "m r2,%3\n" \
+ "cas %0,r2,r0\n" \
+ "mfs r10,%1" \
+ : "=r" ((USItype)(ph)), \
+ "=r" ((USItype)(pl)) \
+ : "%r" (__m0), \
+ "r" (__m1) \
+ : "r2"); \
+ (ph) += ((((SItype) __m0 >> 31) & __m1) \
+ + (((SItype) __m1 >> 31) & __m0)); \
+} while (0)
+#define UMUL_TIME 20
+#define UDIV_TIME 200
+#define count_leading_zeros(count, x) \
+do { \
+ if ((x) >= 0x10000) \
+ __asm__ ("clz %0,%1" \
+ : "=r" ((USItype)(count)) \
+ : "r" ((USItype)(x) >> 16)); \
+ else { \
+ __asm__ ("clz %0,%1" \
+ : "=r" ((USItype)(count)) \
+ : "r" ((USItype)(x))); \
+ (count) += 16; \
+ } \
+} while (0)
+#endif /* RT/ROMP */
+
+/***************************************
+ ************** SH2 ******************
+ ***************************************/
+#if (defined(__sh2__) || defined(__sh3__) || defined(__SH4__)) \
+ && W_TYPE_SIZE == 32
+#define umul_ppmm(w1, w0, u, v) \
+ __asm__ ( \
+ "dmulu.l %2,%3\n" \
+ "sts macl,%1\n" \
+ "sts mach,%0" \
+ : "=r" ((USItype)(w1)), \
+ "=r" ((USItype)(w0)) \
+ : "r" ((USItype)(u)), \
+ "r" ((USItype)(v)) \
+ : "macl", "mach")
+#define UMUL_TIME 5
+#endif
+
+/***************************************
+ ************** SPARC ****************
+ ***************************************/
+#if defined(__sparc__) && W_TYPE_SIZE == 32
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("addcc %r4,%5,%1\n" \
+ "addx %r2,%3,%0" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "%rJ" ((USItype)(ah)), \
+ "rI" ((USItype)(bh)), \
+ "%rJ" ((USItype)(al)), \
+ "rI" ((USItype)(bl)) \
+ __CLOBBER_CC)
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("subcc %r4,%5,%1\n" \
+ "subx %r2,%3,%0" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "rJ" ((USItype)(ah)), \
+ "rI" ((USItype)(bh)), \
+ "rJ" ((USItype)(al)), \
+ "rI" ((USItype)(bl)) \
+ __CLOBBER_CC)
+#if defined(__sparc_v8__)
+/* Don't match immediate range because, 1) it is not often useful,
+ 2) the 'I' flag thinks of the range as a 13 bit signed interval,
+ while we want to match a 13 bit interval, sign extended to 32 bits,
+ but INTERPRETED AS UNSIGNED. */
+#define umul_ppmm(w1, w0, u, v) \
+ __asm__ ("umul %2,%3,%1;rd %%y,%0" \
+ : "=r" ((USItype)(w1)), \
+ "=r" ((USItype)(w0)) \
+ : "r" ((USItype)(u)), \
+ "r" ((USItype)(v)))
+#define UMUL_TIME 5
+#ifndef SUPERSPARC /* SuperSPARC's udiv only handles 53 bit dividends */
+#define udiv_qrnnd(q, r, n1, n0, d) \
+do { \
+ USItype __q; \
+ __asm__ ("mov %1,%%y;nop;nop;nop;udiv %2,%3,%0" \
+ : "=r" ((USItype)(__q)) \
+ : "r" ((USItype)(n1)), \
+ "r" ((USItype)(n0)), \
+ "r" ((USItype)(d))); \
+ (r) = (n0) - __q * (d); \
+ (q) = __q; \
+} while (0)
+#define UDIV_TIME 25
+#endif /* SUPERSPARC */
+#else /* ! __sparc_v8__ */
+#if defined(__sparclite__)
+/* This has hardware multiply but not divide. It also has two additional
+ instructions scan (ffs from high bit) and divscc. */
+#define umul_ppmm(w1, w0, u, v) \
+ __asm__ ("umul %2,%3,%1;rd %%y,%0" \
+ : "=r" ((USItype)(w1)), \
+ "=r" ((USItype)(w0)) \
+ : "r" ((USItype)(u)), \
+ "r" ((USItype)(v)))
+#define UMUL_TIME 5
+#define udiv_qrnnd(q, r, n1, n0, d) \
+ __asm__ ("! Inlined udiv_qrnnd\n" \
+ "wr %%g0,%2,%%y ! Not a delayed write for sparclite\n" \
+ "tst %%g0\n" \
+ "divscc %3,%4,%%g1\n" \
+ "divscc %%g1,%4,%%g1\n" \
+ "divscc %%g1,%4,%%g1\n" \
+ "divscc %%g1,%4,%%g1\n" \
+ "divscc %%g1,%4,%%g1\n" \
+ "divscc %%g1,%4,%%g1\n" \
+ "divscc %%g1,%4,%%g1\n" \
+ "divscc %%g1,%4,%%g1\n" \
+ "divscc %%g1,%4,%%g1\n" \
+ "divscc %%g1,%4,%%g1\n" \
+ "divscc %%g1,%4,%%g1\n" \
+ "divscc %%g1,%4,%%g1\n" \
+ "divscc %%g1,%4,%%g1\n" \
+ "divscc %%g1,%4,%%g1\n" \
+ "divscc %%g1,%4,%%g1\n" \
+ "divscc %%g1,%4,%%g1\n" \
+ "divscc %%g1,%4,%%g1\n" \
+ "divscc %%g1,%4,%%g1\n" \
+ "divscc %%g1,%4,%%g1\n" \
+ "divscc %%g1,%4,%%g1\n" \
+ "divscc %%g1,%4,%%g1\n" \
+ "divscc %%g1,%4,%%g1\n" \
+ "divscc %%g1,%4,%%g1\n" \
+ "divscc %%g1,%4,%%g1\n" \
+ "divscc %%g1,%4,%%g1\n" \
+ "divscc %%g1,%4,%%g1\n" \
+ "divscc %%g1,%4,%%g1\n" \
+ "divscc %%g1,%4,%%g1\n" \
+ "divscc %%g1,%4,%%g1\n" \
+ "divscc %%g1,%4,%%g1\n" \
+ "divscc %%g1,%4,%%g1\n" \
+ "divscc %%g1,%4,%0\n" \
+ "rd %%y,%1\n" \
+ "bl,a 1f\n" \
+ "add %1,%4,%1\n" \
+ "1: ! End of inline udiv_qrnnd" \
+ : "=r" ((USItype)(q)), \
+ "=r" ((USItype)(r)) \
+ : "r" ((USItype)(n1)), \
+ "r" ((USItype)(n0)), \
+ "rI" ((USItype)(d)) \
+ : "%g1" __AND_CLOBBER_CC)
+#define UDIV_TIME 37
+#define count_leading_zeros(count, x) \
+ __asm__ ("scan %1,0,%0" \
+ : "=r" ((USItype)(x)) \
+ : "r" ((USItype)(count)))
+/* Early sparclites return 63 for an argument of 0, but they warn that future
+ implementations might change this. Therefore, leave COUNT_LEADING_ZEROS_0
+ undefined. */
+#endif /* __sparclite__ */
+#endif /* __sparc_v8__ */
+ /* Default to sparc v7 versions of umul_ppmm and udiv_qrnnd. */
+#ifndef umul_ppmm
+#define umul_ppmm(w1, w0, u, v) \
+ __asm__ ("! Inlined umul_ppmm\n" \
+ "wr %%g0,%2,%%y ! SPARC has 0-3 delay insn after a wr\n" \
+ "sra %3,31,%%g2 ! Don't move this insn\n" \
+ "and %2,%%g2,%%g2 ! Don't move this insn\n" \
+ "andcc %%g0,0,%%g1 ! Don't move this insn\n" \
+ "mulscc %%g1,%3,%%g1\n" \
+ "mulscc %%g1,%3,%%g1\n" \
+ "mulscc %%g1,%3,%%g1\n" \
+ "mulscc %%g1,%3,%%g1\n" \
+ "mulscc %%g1,%3,%%g1\n" \
+ "mulscc %%g1,%3,%%g1\n" \
+ "mulscc %%g1,%3,%%g1\n" \
+ "mulscc %%g1,%3,%%g1\n" \
+ "mulscc %%g1,%3,%%g1\n" \
+ "mulscc %%g1,%3,%%g1\n" \
+ "mulscc %%g1,%3,%%g1\n" \
+ "mulscc %%g1,%3,%%g1\n" \
+ "mulscc %%g1,%3,%%g1\n" \
+ "mulscc %%g1,%3,%%g1\n" \
+ "mulscc %%g1,%3,%%g1\n" \
+ "mulscc %%g1,%3,%%g1\n" \
+ "mulscc %%g1,%3,%%g1\n" \
+ "mulscc %%g1,%3,%%g1\n" \
+ "mulscc %%g1,%3,%%g1\n" \
+ "mulscc %%g1,%3,%%g1\n" \
+ "mulscc %%g1,%3,%%g1\n" \
+ "mulscc %%g1,%3,%%g1\n" \
+ "mulscc %%g1,%3,%%g1\n" \
+ "mulscc %%g1,%3,%%g1\n" \
+ "mulscc %%g1,%3,%%g1\n" \
+ "mulscc %%g1,%3,%%g1\n" \
+ "mulscc %%g1,%3,%%g1\n" \
+ "mulscc %%g1,%3,%%g1\n" \
+ "mulscc %%g1,%3,%%g1\n" \
+ "mulscc %%g1,%3,%%g1\n" \
+ "mulscc %%g1,%3,%%g1\n" \
+ "mulscc %%g1,%3,%%g1\n" \
+ "mulscc %%g1,0,%%g1\n" \
+ "add %%g1,%%g2,%0\n" \
+ "rd %%y,%1" \
+ : "=r" ((USItype)(w1)), \
+ "=r" ((USItype)(w0)) \
+ : "%rI" ((USItype)(u)), \
+ "r" ((USItype)(v)) \
+ : "%g1", "%g2" __AND_CLOBBER_CC)
+#define UMUL_TIME 39 /* 39 instructions */
+#endif
+#ifndef udiv_qrnnd
+#ifndef LONGLONG_STANDALONE
+#define udiv_qrnnd(q, r, n1, n0, d) \
+do { USItype __r; \
+ (q) = __udiv_qrnnd(&__r, (n1), (n0), (d)); \
+ (r) = __r; \
+} while (0)
+ extern USItype __udiv_qrnnd();
+#define UDIV_TIME 140
+#endif /* LONGLONG_STANDALONE */
+#endif /* udiv_qrnnd */
+#endif /* __sparc__ */
+
+/***************************************
+ ************** VAX ******************
+ ***************************************/
+#if defined(__vax__) && W_TYPE_SIZE == 32
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("addl2 %5,%1\n" \
+ "adwc %3,%0" \
+ : "=g" ((USItype)(sh)), \
+ "=&g" ((USItype)(sl)) \
+ : "%0" ((USItype)(ah)), \
+ "g" ((USItype)(bh)), \
+ "%1" ((USItype)(al)), \
+ "g" ((USItype)(bl)))
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("subl2 %5,%1\n" \
+ "sbwc %3,%0" \
+ : "=g" ((USItype)(sh)), \
+ "=&g" ((USItype)(sl)) \
+ : "0" ((USItype)(ah)), \
+ "g" ((USItype)(bh)), \
+ "1" ((USItype)(al)), \
+ "g" ((USItype)(bl)))
+#define umul_ppmm(xh, xl, m0, m1) \
+do { \
+ union {UDItype __ll; \
+ struct {USItype __l, __h; } __i; \
+ } __xx; \
+ USItype __m0 = (m0), __m1 = (m1); \
+ __asm__ ("emul %1,%2,$0,%0" \
+ : "=g" (__xx.__ll) \
+ : "g" (__m0), \
+ "g" (__m1)); \
+ (xh) = __xx.__i.__h; (xl) = __xx.__i.__l; \
+ (xh) += ((((SItype) __m0 >> 31) & __m1) \
+ + (((SItype) __m1 >> 31) & __m0)); \
+} while (0)
+#define sdiv_qrnnd(q, r, n1, n0, d) \
+do { \
+ union {DItype __ll; \
+ struct {SItype __l, __h; } __i; \
+ } __xx; \
+ __xx.__i.__h = n1; __xx.__i.__l = n0; \
+ __asm__ ("ediv %3,%2,%0,%1" \
+ : "=g" (q), "=g" (r) \
+ : "g" (__xx.__ll), "g" (d)); \
+} while (0)
+#endif /* __vax__ */
+
+/***************************************
+ ************** Z8000 ****************
+ ***************************************/
+#if defined(__z8000__) && W_TYPE_SIZE == 16
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("add %H1,%H5\n\tadc %H0,%H3" \
+ : "=r" ((unsigned int)(sh)), \
+ "=&r" ((unsigned int)(sl)) \
+ : "%0" ((unsigned int)(ah)), \
+ "r" ((unsigned int)(bh)), \
+ "%1" ((unsigned int)(al)), \
+ "rQR" ((unsigned int)(bl)))
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("sub %H1,%H5\n\tsbc %H0,%H3" \
+ : "=r" ((unsigned int)(sh)), \
+ "=&r" ((unsigned int)(sl)) \
+ : "0" ((unsigned int)(ah)), \
+ "r" ((unsigned int)(bh)), \
+ "1" ((unsigned int)(al)), \
+ "rQR" ((unsigned int)(bl)))
+#define umul_ppmm(xh, xl, m0, m1) \
+do { \
+ union {long int __ll; \
+ struct {unsigned int __h, __l; } __i; \
+ } __xx; \
+ unsigned int __m0 = (m0), __m1 = (m1); \
+ __asm__ ("mult %S0,%H3" \
+ : "=r" (__xx.__i.__h), \
+ "=r" (__xx.__i.__l) \
+ : "%1" (__m0), \
+ "rQR" (__m1)); \
+ (xh) = __xx.__i.__h; (xl) = __xx.__i.__l; \
+ (xh) += ((((signed int) __m0 >> 15) & __m1) \
+ + (((signed int) __m1 >> 15) & __m0)); \
+} while (0)
+#endif /* __z8000__ */
+
+#endif /* __GNUC__ */
+
+/***************************************
+ *********** Generic Versions ********
+ ***************************************/
+#if !defined(umul_ppmm) && defined(__umulsidi3)
+#define umul_ppmm(ph, pl, m0, m1) \
+{ \
+ UDWtype __ll = __umulsidi3(m0, m1); \
+ ph = (UWtype) (__ll >> W_TYPE_SIZE); \
+ pl = (UWtype) __ll; \
+}
+#endif
+
+#if !defined(__umulsidi3)
+#define __umulsidi3(u, v) \
+ ({UWtype __hi, __lo; \
+ umul_ppmm(__hi, __lo, u, v); \
+ ((UDWtype) __hi << W_TYPE_SIZE) | __lo; })
+#endif
+
+ /* If this machine has no inline assembler, use C macros. */
+
+#if !defined(add_ssaaaa)
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+do { \
+ UWtype __x; \
+ __x = (al) + (bl); \
+ (sh) = (ah) + (bh) + (__x < (al)); \
+ (sl) = __x; \
+} while (0)
+#endif
+
+#if !defined(sub_ddmmss)
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+do { \
+ UWtype __x; \
+ __x = (al) - (bl); \
+ (sh) = (ah) - (bh) - (__x > (al)); \
+ (sl) = __x; \
+} while (0)
+#endif
+
+#if !defined(umul_ppmm)
+#define umul_ppmm(w1, w0, u, v) \
+do { \
+ UWtype __x0, __x1, __x2, __x3; \
+ UHWtype __ul, __vl, __uh, __vh; \
+ UWtype __u = (u), __v = (v); \
+ \
+ __ul = __ll_lowpart(__u); \
+ __uh = __ll_highpart(__u); \
+ __vl = __ll_lowpart(__v); \
+ __vh = __ll_highpart(__v); \
+ \
+ __x0 = (UWtype) __ul * __vl; \
+ __x1 = (UWtype) __ul * __vh; \
+ __x2 = (UWtype) __uh * __vl; \
+ __x3 = (UWtype) __uh * __vh; \
+ \
+ __x1 += __ll_highpart(__x0);/* this can't give carry */ \
+ __x1 += __x2; /* but this indeed can */ \
+ if (__x1 < __x2) /* did we get it? */ \
+ __x3 += __ll_B; /* yes, add it in the proper pos. */ \
+ \
+ (w1) = __x3 + __ll_highpart(__x1); \
+ (w0) = (__ll_lowpart(__x1) << W_TYPE_SIZE/2) + __ll_lowpart(__x0); \
+} while (0)
+#endif
+
+#if !defined(umul_ppmm)
+#define smul_ppmm(w1, w0, u, v) \
+do { \
+ UWtype __w1; \
+ UWtype __m0 = (u), __m1 = (v); \
+ umul_ppmm(__w1, w0, __m0, __m1); \
+ (w1) = __w1 - (-(__m0 >> (W_TYPE_SIZE - 1)) & __m1) \
+ - (-(__m1 >> (W_TYPE_SIZE - 1)) & __m0); \
+} while (0)
+#endif
+
+ /* Define this unconditionally, so it can be used for debugging. */
+#define __udiv_qrnnd_c(q, r, n1, n0, d) \
+do { \
+ UWtype __d1, __d0, __q1, __q0, __r1, __r0, __m; \
+ __d1 = __ll_highpart(d); \
+ __d0 = __ll_lowpart(d); \
+ \
+ __r1 = (n1) % __d1; \
+ __q1 = (n1) / __d1; \
+ __m = (UWtype) __q1 * __d0; \
+ __r1 = __r1 * __ll_B | __ll_highpart(n0); \
+ if (__r1 < __m) { \
+ __q1--, __r1 += (d); \
+ if (__r1 >= (d)) /* i.e. we didn't get carry when adding to __r1 */ \
+ if (__r1 < __m) \
+ __q1--, __r1 += (d); \
+ } \
+ __r1 -= __m; \
+ \
+ __r0 = __r1 % __d1; \
+ __q0 = __r1 / __d1; \
+ __m = (UWtype) __q0 * __d0; \
+ __r0 = __r0 * __ll_B | __ll_lowpart(n0); \
+ if (__r0 < __m) { \
+ __q0--, __r0 += (d); \
+ if (__r0 >= (d)) \
+ if (__r0 < __m) \
+ __q0--, __r0 += (d); \
+ } \
+ __r0 -= __m; \
+ \
+ (q) = (UWtype) __q1 * __ll_B | __q0; \
+ (r) = __r0; \
+} while (0)
+
+/* If the processor has no udiv_qrnnd but sdiv_qrnnd, go through
+ __udiv_w_sdiv (defined in libgcc or elsewhere). */
+#if !defined(udiv_qrnnd) && defined(sdiv_qrnnd)
+#define udiv_qrnnd(q, r, nh, nl, d) \
+do { \
+ UWtype __r; \
+ (q) = __MPN(udiv_w_sdiv) (&__r, nh, nl, d); \
+ (r) = __r; \
+} while (0)
+#endif
+
+ /* If udiv_qrnnd was not defined for this processor, use __udiv_qrnnd_c. */
+#if !defined(udiv_qrnnd)
+#define UDIV_NEEDS_NORMALIZATION 1
+#define udiv_qrnnd __udiv_qrnnd_c
+#endif
+
+#undef count_leading_zeros
+#if !defined(count_leading_zeros)
+ extern
+#ifdef __STDC__
+ const
+#endif
+ unsigned char __clz_tab[];
+#define count_leading_zeros(count, x) \
+do { \
+ UWtype __xr = (x); \
+ UWtype __a; \
+ \
+ if (W_TYPE_SIZE <= 32) { \
+ __a = __xr < ((UWtype) 1 << 2*__BITS4) \
+ ? (__xr < ((UWtype) 1 << __BITS4) ? 0 : __BITS4) \
+ : (__xr < ((UWtype) 1 << 3*__BITS4) ? 2*__BITS4 : 3*__BITS4); \
+ } \
+ else { \
+ for (__a = W_TYPE_SIZE - 8; __a > 0; __a -= 8) \
+ if (((__xr >> __a) & 0xff) != 0) \
+ break; \
+ } \
+ \
+ (count) = W_TYPE_SIZE - (__clz_tab[__xr >> __a] + __a); \
+} while (0)
+ /* This version gives a well-defined value for zero. */
+#define COUNT_LEADING_ZEROS_0 W_TYPE_SIZE
+#endif
+
+#if !defined(count_trailing_zeros)
+/* Define count_trailing_zeros using count_leading_zeros. The latter might be
+ defined in asm, but if it is not, the C version above is good enough. */
+#define count_trailing_zeros(count, x) \
+do { \
+ UWtype __ctz_x = (x); \
+ UWtype __ctz_c; \
+ count_leading_zeros(__ctz_c, __ctz_x & -__ctz_x); \
+ (count) = W_TYPE_SIZE - 1 - __ctz_c; \
+} while (0)
+#endif
+
+#ifndef UDIV_NEEDS_NORMALIZATION
+#define UDIV_NEEDS_NORMALIZATION 0
+#endif
diff --git a/lib/mpi/mpi-add.c b/lib/mpi/mpi-add.c
new file mode 100644
index 0000000..f56b9ba
--- /dev/null
+++ b/lib/mpi/mpi-add.c
@@ -0,0 +1,234 @@
+/* mpi-add.c - MPI functions
+ * Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+ * Copyright (C) 1994, 1996 Free Software Foundation, Inc.
+ *
+ * This file is part of GnuPG.
+ *
+ * GnuPG 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.
+ *
+ * GnuPG 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ * The GNU MP Library itself is published under the LGPL;
+ * however I decided to publish this code under the plain GPL.
+ */
+
+#include "mpi-internal.h"
+
+/****************
+ * Add the unsigned integer V to the mpi-integer U and store the
+ * result in W. U and V may be the same.
+ */
+int mpi_add_ui(MPI w, const MPI u, unsigned long v)
+{
+ mpi_ptr_t wp, up;
+ mpi_size_t usize, wsize;
+ int usign, wsign;
+
+ usize = u->nlimbs;
+ usign = u->sign;
+ wsign = 0;
+
+ /* If not space for W (and possible carry), increase space. */
+ wsize = usize + 1;
+ if (w->alloced < wsize)
+ if (mpi_resize(w, wsize) < 0)
+ return -ENOMEM;
+
+ /* These must be after realloc (U may be the same as W). */
+ up = u->d;
+ wp = w->d;
+
+ if (!usize) { /* simple */
+ wp[0] = v;
+ wsize = v ? 1 : 0;
+ } else if (!usign) { /* mpi is not negative */
+ mpi_limb_t cy;
+ cy = mpihelp_add_1(wp, up, usize, v);
+ wp[usize] = cy;
+ wsize = usize + cy;
+ } else { /* The signs are different. Need exact comparison to determine
+ * which operand to subtract from which. */
+ if (usize == 1 && up[0] < v) {
+ wp[0] = v - up[0];
+ wsize = 1;
+ } else {
+ mpihelp_sub_1(wp, up, usize, v);
+ /* Size can decrease with at most one limb. */
+ wsize = usize - (wp[usize - 1] == 0);
+ wsign = 1;
+ }
+ }
+
+ w->nlimbs = wsize;
+ w->sign = wsign;
+ return 0;
+}
+
+int mpi_add(MPI w, MPI u, MPI v)
+{
+ mpi_ptr_t wp, up, vp;
+ mpi_size_t usize, vsize, wsize;
+ int usign, vsign, wsign;
+
+ if (u->nlimbs < v->nlimbs) { /* Swap U and V. */
+ usize = v->nlimbs;
+ usign = v->sign;
+ vsize = u->nlimbs;
+ vsign = u->sign;
+ wsize = usize + 1;
+ if (RESIZE_IF_NEEDED(w, wsize) < 0)
+ return -ENOMEM;
+ /* These must be after realloc (u or v may be the same as w). */
+ up = v->d;
+ vp = u->d;
+ } else {
+ usize = u->nlimbs;
+ usign = u->sign;
+ vsize = v->nlimbs;
+ vsign = v->sign;
+ wsize = usize + 1;
+ if (RESIZE_IF_NEEDED(w, wsize) < 0)
+ return -ENOMEM;
+ /* These must be after realloc (u or v may be the same as w). */
+ up = u->d;
+ vp = v->d;
+ }
+ wp = w->d;
+ wsign = 0;
+
+ if (!vsize) { /* simple */
+ MPN_COPY(wp, up, usize);
+ wsize = usize;
+ wsign = usign;
+ } else if (usign != vsign) { /* different sign */
+ /* This test is right since USIZE >= VSIZE */
+ if (usize != vsize) {
+ mpihelp_sub(wp, up, usize, vp, vsize);
+ wsize = usize;
+ MPN_NORMALIZE(wp, wsize);
+ wsign = usign;
+ } else if (mpihelp_cmp(up, vp, usize) < 0) {
+ mpihelp_sub_n(wp, vp, up, usize);
+ wsize = usize;
+ MPN_NORMALIZE(wp, wsize);
+ if (!usign)
+ wsign = 1;
+ } else {
+ mpihelp_sub_n(wp, up, vp, usize);
+ wsize = usize;
+ MPN_NORMALIZE(wp, wsize);
+ if (usign)
+ wsign = 1;
+ }
+ } else { /* U and V have same sign. Add them. */
+ mpi_limb_t cy = mpihelp_add(wp, up, usize, vp, vsize);
+ wp[usize] = cy;
+ wsize = usize + cy;
+ if (usign)
+ wsign = 1;
+ }
+
+ w->nlimbs = wsize;
+ w->sign = wsign;
+ return 0;
+}
+
+/****************
+ * Subtract the unsigned integer V from the mpi-integer U and store the
+ * result in W.
+ */
+int mpi_sub_ui(MPI w, MPI u, unsigned long v)
+{
+ mpi_ptr_t wp, up;
+ mpi_size_t usize, wsize;
+ int usign, wsign;
+
+ usize = u->nlimbs;
+ usign = u->sign;
+ wsign = 0;
+
+ /* If not space for W (and possible carry), increase space. */
+ wsize = usize + 1;
+ if (w->alloced < wsize)
+ if (mpi_resize(w, wsize) < 0)
+ return -ENOMEM;
+
+ /* These must be after realloc (U may be the same as W). */
+ up = u->d;
+ wp = w->d;
+
+ if (!usize) { /* simple */
+ wp[0] = v;
+ wsize = v ? 1 : 0;
+ wsign = 1;
+ } else if (usign) { /* mpi and v are negative */
+ mpi_limb_t cy;
+ cy = mpihelp_add_1(wp, up, usize, v);
+ wp[usize] = cy;
+ wsize = usize + cy;
+ } else { /* The signs are different. Need exact comparison to determine
+ * which operand to subtract from which. */
+ if (usize == 1 && up[0] < v) {
+ wp[0] = v - up[0];
+ wsize = 1;
+ wsign = 1;
+ } else {
+ mpihelp_sub_1(wp, up, usize, v);
+ /* Size can decrease with at most one limb. */
+ wsize = usize - (wp[usize - 1] == 0);
+ }
+ }
+
+ w->nlimbs = wsize;
+ w->sign = wsign;
+ return 0;
+}
+
+int mpi_sub(MPI w, MPI u, MPI v)
+{
+ int rc;
+
+ if (w == v) {
+ MPI vv;
+ if (mpi_copy(&vv, v) < 0)
+ return -ENOMEM;
+ vv->sign = !vv->sign;
+ rc = mpi_add(w, u, vv);
+ mpi_free(vv);
+ } else {
+ /* fixme: this is not thread-save (we temp. modify v) */
+ v->sign = !v->sign;
+ rc = mpi_add(w, u, v);
+ v->sign = !v->sign;
+ }
+ return rc;
+}
+
+int mpi_addm(MPI w, MPI u, MPI v, MPI m)
+{
+ if (mpi_add(w, u, v) < 0 || mpi_fdiv_r(w, w, m) < 0)
+ return -ENOMEM;
+ return 0;
+}
+
+int mpi_subm(MPI w, MPI u, MPI v, MPI m)
+{
+ if (mpi_sub(w, u, v) < 0 || mpi_fdiv_r(w, w, m) < 0)
+ return -ENOMEM;
+ return 0;
+}
diff --git a/lib/mpi/mpi-bit.c b/lib/mpi/mpi-bit.c
new file mode 100644
index 0000000..854c9c6
--- /dev/null
+++ b/lib/mpi/mpi-bit.c
@@ -0,0 +1,236 @@
+/* mpi-bit.c - MPI bit level fucntions
+ * Copyright (C) 1998, 1999 Free Software Foundation, Inc.
+ *
+ * This file is part of GnuPG.
+ *
+ * GnuPG 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.
+ *
+ * GnuPG 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "mpi-internal.h"
+#include "longlong.h"
+
+const unsigned char __clz_tab[] = {
+ 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8,
+};
+
+#define A_LIMB_1 ((mpi_limb_t) 1)
+
+/****************
+ * Sometimes we have MSL (most significant limbs) which are 0;
+ * this is for some reasons not good, so this function removes them.
+ */
+void mpi_normalize(MPI a)
+{
+ for (; a->nlimbs && !a->d[a->nlimbs - 1]; a->nlimbs--)
+ ;
+}
+
+/****************
+ * Return the number of bits in A.
+ */
+unsigned mpi_get_nbits(MPI a)
+{
+ unsigned n;
+
+ mpi_normalize(a);
+
+ if (a->nlimbs) {
+ mpi_limb_t alimb = a->d[a->nlimbs - 1];
+ if (alimb)
+ count_leading_zeros(n, alimb);
+ else
+ n = BITS_PER_MPI_LIMB;
+ n = BITS_PER_MPI_LIMB - n + (a->nlimbs - 1) * BITS_PER_MPI_LIMB;
+ } else
+ n = 0;
+ return n;
+}
+EXPORT_SYMBOL_GPL(mpi_get_nbits);
+
+/****************
+ * Test whether bit N is set.
+ */
+int mpi_test_bit(MPI a, unsigned n)
+{
+ unsigned limbno, bitno;
+ mpi_limb_t limb;
+
+ limbno = n / BITS_PER_MPI_LIMB;
+ bitno = n % BITS_PER_MPI_LIMB;
+
+ if (limbno >= a->nlimbs)
+ return 0; /* too far left: this is a 0 */
+ limb = a->d[limbno];
+ return (limb & (A_LIMB_1 << bitno)) ? 1 : 0;
+}
+
+/****************
+ * Set bit N of A.
+ */
+int mpi_set_bit(MPI a, unsigned n)
+{
+ unsigned limbno, bitno;
+
+ limbno = n / BITS_PER_MPI_LIMB;
+ bitno = n % BITS_PER_MPI_LIMB;
+
+ if (limbno >= a->nlimbs) { /* resize */
+ if (a->alloced >= limbno)
+ if (mpi_resize(a, limbno + 1) < 0)
+ return -ENOMEM;
+ a->nlimbs = limbno + 1;
+ }
+ a->d[limbno] |= (A_LIMB_1 << bitno);
+ return 0;
+}
+
+/****************
+ * Set bit N of A. and clear all bits above
+ */
+int mpi_set_highbit(MPI a, unsigned n)
+{
+ unsigned limbno, bitno;
+
+ limbno = n / BITS_PER_MPI_LIMB;
+ bitno = n % BITS_PER_MPI_LIMB;
+
+ if (limbno >= a->nlimbs) { /* resize */
+ if (a->alloced >= limbno)
+ if (mpi_resize(a, limbno + 1) < 0)
+ return -ENOMEM;
+ a->nlimbs = limbno + 1;
+ }
+ a->d[limbno] |= (A_LIMB_1 << bitno);
+ for (bitno++; bitno < BITS_PER_MPI_LIMB; bitno++)
+ a->d[limbno] &= ~(A_LIMB_1 << bitno);
+ a->nlimbs = limbno + 1;
+ return 0;
+}
+
+/****************
+ * clear bit N of A and all bits above
+ */
+void mpi_clear_highbit(MPI a, unsigned n)
+{
+ unsigned limbno, bitno;
+
+ limbno = n / BITS_PER_MPI_LIMB;
+ bitno = n % BITS_PER_MPI_LIMB;
+
+ if (limbno >= a->nlimbs)
+ return; /* not allocated, so need to clear bits :-) */
+
+ for (; bitno < BITS_PER_MPI_LIMB; bitno++)
+ a->d[limbno] &= ~(A_LIMB_1 << bitno);
+ a->nlimbs = limbno + 1;
+}
+
+/****************
+ * Clear bit N of A.
+ */
+void mpi_clear_bit(MPI a, unsigned n)
+{
+ unsigned limbno, bitno;
+
+ limbno = n / BITS_PER_MPI_LIMB;
+ bitno = n % BITS_PER_MPI_LIMB;
+
+ if (limbno >= a->nlimbs)
+ return; /* don't need to clear this bit, it's to far to left */
+ a->d[limbno] &= ~(A_LIMB_1 << bitno);
+}
+
+/****************
+ * Shift A by N bits to the right
+ * FIXME: should use alloc_limb if X and A are same.
+ */
+int mpi_rshift(MPI x, MPI a, unsigned n)
+{
+ mpi_ptr_t xp;
+ mpi_size_t xsize;
+
+ xsize = a->nlimbs;
+ x->sign = a->sign;
+ if (RESIZE_IF_NEEDED(x, (size_t) xsize) < 0)
+ return -ENOMEM;
+ xp = x->d;
+
+ if (xsize) {
+ mpihelp_rshift(xp, a->d, xsize, n);
+ MPN_NORMALIZE(xp, xsize);
+ }
+ x->nlimbs = xsize;
+ return 0;
+}
+
+/****************
+ * Shift A by COUNT limbs to the left
+ * This is used only within the MPI library
+ */
+int mpi_lshift_limbs(MPI a, unsigned int count)
+{
+ mpi_ptr_t ap = a->d;
+ int n = a->nlimbs;
+ int i;
+
+ if (!count || !n)
+ return 0;
+
+ if (RESIZE_IF_NEEDED(a, n + count) < 0)
+ return -ENOMEM;
+
+ for (i = n - 1; i >= 0; i--)
+ ap[i + count] = ap[i];
+ for (i = 0; i < count; i++)
+ ap[i] = 0;
+ a->nlimbs += count;
+ return 0;
+}
+
+/****************
+ * Shift A by COUNT limbs to the right
+ * This is used only within the MPI library
+ */
+void mpi_rshift_limbs(MPI a, unsigned int count)
+{
+ mpi_ptr_t ap = a->d;
+ mpi_size_t n = a->nlimbs;
+ unsigned int i;
+
+ if (count >= n) {
+ a->nlimbs = 0;
+ return;
+ }
+
+ for (i = 0; i < n - count; i++)
+ ap[i] = ap[i + count];
+ ap[i] = 0;
+ a->nlimbs -= count;
+}
diff --git a/lib/mpi/mpi-cmp.c b/lib/mpi/mpi-cmp.c
new file mode 100644
index 0000000..914bc42
--- /dev/null
+++ b/lib/mpi/mpi-cmp.c
@@ -0,0 +1,68 @@
+/* mpi-cmp.c - MPI functions
+ * Copyright (C) 1998, 1999 Free Software Foundation, Inc.
+ *
+ * This file is part of GnuPG.
+ *
+ * GnuPG 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.
+ *
+ * GnuPG 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "mpi-internal.h"
+
+int mpi_cmp_ui(MPI u, unsigned long v)
+{
+ mpi_limb_t limb = v;
+
+ mpi_normalize(u);
+ if (!u->nlimbs && !limb)
+ return 0;
+ if (u->sign)
+ return -1;
+ if (u->nlimbs > 1)
+ return 1;
+
+ if (u->d[0] == limb)
+ return 0;
+ else if (u->d[0] > limb)
+ return 1;
+ else
+ return -1;
+}
+
+int mpi_cmp(MPI u, MPI v)
+{
+ mpi_size_t usize, vsize;
+ int cmp;
+
+ mpi_normalize(u);
+ mpi_normalize(v);
+ usize = u->nlimbs;
+ vsize = v->nlimbs;
+ if (!u->sign && v->sign)
+ return 1;
+ if (u->sign && !v->sign)
+ return -1;
+ if (usize != vsize && !u->sign && !v->sign)
+ return usize - vsize;
+ if (usize != vsize && u->sign && v->sign)
+ return vsize + usize;
+ if (!usize)
+ return 0;
+ cmp = mpihelp_cmp(u->d, v->d, usize);
+ if (!cmp)
+ return 0;
+ if ((cmp < 0 ? 1 : 0) == (u->sign ? 1 : 0))
+ return 1;
+ return -1;
+}
diff --git a/lib/mpi/mpi-div.c b/lib/mpi/mpi-div.c
new file mode 100644
index 0000000..c3087d1
--- /dev/null
+++ b/lib/mpi/mpi-div.c
@@ -0,0 +1,333 @@
+/* mpi-div.c - MPI functions
+ * Copyright (C) 1994, 1996 Free Software Foundation, Inc.
+ * Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+ *
+ * This file is part of GnuPG.
+ *
+ * GnuPG 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.
+ *
+ * GnuPG 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ * The GNU MP Library itself is published under the LGPL;
+ * however I decided to publish this code under the plain GPL.
+ */
+
+#include <linux/string.h>
+#include "mpi-internal.h"
+#include "longlong.h"
+
+int mpi_fdiv_r(MPI rem, MPI dividend, MPI divisor)
+{
+ int rc = -ENOMEM;
+ int divisor_sign = divisor->sign;
+ MPI temp_divisor = NULL;
+
+ /* We need the original value of the divisor after the remainder has been
+ * preliminary calculated. We have to copy it to temporary space if it's
+ * the same variable as REM. */
+ if (rem == divisor) {
+ if (mpi_copy(&temp_divisor, divisor) < 0)
+ goto nomem;
+ divisor = temp_divisor;
+ }
+
+ if (mpi_tdiv_qr(NULL, rem, dividend, divisor) < 0)
+ goto nomem;
+ if (((divisor_sign ? 1 : 0) ^ (dividend->sign ? 1 : 0)) && rem->nlimbs)
+ if (mpi_add(rem, rem, divisor) < 0)
+ goto nomem;
+
+ rc = 0;
+
+nomem:
+ if (temp_divisor)
+ mpi_free(temp_divisor);
+ return rc;
+}
+
+/****************
+ * Division rounding the quotient towards -infinity.
+ * The remainder gets the same sign as the denominator.
+ * rem is optional
+ */
+
+ulong mpi_fdiv_r_ui(MPI rem, MPI dividend, ulong divisor)
+{
+ mpi_limb_t rlimb;
+
+ rlimb = mpihelp_mod_1(dividend->d, dividend->nlimbs, divisor);
+ if (rlimb && dividend->sign)
+ rlimb = divisor - rlimb;
+
+ if (rem) {
+ rem->d[0] = rlimb;
+ rem->nlimbs = rlimb ? 1 : 0;
+ }
+ return rlimb;
+}
+
+int mpi_fdiv_q(MPI quot, MPI dividend, MPI divisor)
+{
+ MPI tmp = mpi_alloc(mpi_get_nlimbs(quot));
+ if (!tmp)
+ return -ENOMEM;
+ mpi_fdiv_qr(quot, tmp, dividend, divisor);
+ mpi_free(tmp);
+ return 0;
+}
+
+int mpi_fdiv_qr(MPI quot, MPI rem, MPI dividend, MPI divisor)
+{
+ int divisor_sign = divisor->sign;
+ MPI temp_divisor = NULL;
+
+ if (quot == divisor || rem == divisor) {
+ if (mpi_copy(&temp_divisor, divisor) < 0)
+ return -ENOMEM;
+ divisor = temp_divisor;
+ }
+
+ if (mpi_tdiv_qr(quot, rem, dividend, divisor) < 0)
+ goto nomem;
+
+ if ((divisor_sign ^ dividend->sign) && rem->nlimbs) {
+ if (mpi_sub_ui(quot, quot, 1) < 0)
+ goto nomem;
+ if (mpi_add(rem, rem, divisor) < 0)
+ goto nomem;
+ }
+
+ if (temp_divisor)
+ mpi_free(temp_divisor);
+
+ return 0;
+
+nomem:
+ mpi_free(temp_divisor);
+ return -ENOMEM;
+}
+
+/* If den == quot, den needs temporary storage.
+ * If den == rem, den needs temporary storage.
+ * If num == quot, num needs temporary storage.
+ * If den has temporary storage, it can be normalized while being copied,
+ * i.e no extra storage should be allocated.
+ */
+
+int mpi_tdiv_r(MPI rem, MPI num, MPI den)
+{
+ return mpi_tdiv_qr(NULL, rem, num, den);
+}
+
+int mpi_tdiv_qr(MPI quot, MPI rem, MPI num, MPI den)
+{
+ int rc = -ENOMEM;
+ mpi_ptr_t np, dp;
+ mpi_ptr_t qp, rp;
+ mpi_size_t nsize = num->nlimbs;
+ mpi_size_t dsize = den->nlimbs;
+ mpi_size_t qsize, rsize;
+ mpi_size_t sign_remainder = num->sign;
+ mpi_size_t sign_quotient = num->sign ^ den->sign;
+ unsigned normalization_steps;
+ mpi_limb_t q_limb;
+ mpi_ptr_t marker[5];
+ int markidx = 0;
+
+ memset(marker, 0, sizeof(marker));
+
+ /* Ensure space is enough for quotient and remainder.
+ * We need space for an extra limb in the remainder, because it's
+ * up-shifted (normalized) below. */
+ rsize = nsize + 1;
+ if (mpi_resize(rem, rsize) < 0)
+ goto nomem;
+
+ qsize = rsize - dsize; /* qsize cannot be bigger than this. */
+ if (qsize <= 0) {
+ if (num != rem) {
+ rem->nlimbs = num->nlimbs;
+ rem->sign = num->sign;
+ MPN_COPY(rem->d, num->d, nsize);
+ }
+ if (quot) {
+ /* This needs to follow the assignment to rem, in case the
+ * numerator and quotient are the same. */
+ quot->nlimbs = 0;
+ quot->sign = 0;
+ }
+ return 0;
+ }
+
+ if (quot)
+ if (mpi_resize(quot, qsize) < 0)
+ goto nomem;
+
+ /* Read pointers here, when reallocation is finished. */
+ np = num->d;
+ dp = den->d;
+ rp = rem->d;
+
+ /* Optimize division by a single-limb divisor. */
+ if (dsize == 1) {
+ mpi_limb_t rlimb;
+ if (quot) {
+ qp = quot->d;
+ rlimb = mpihelp_divmod_1(qp, np, nsize, dp[0]);
+ qsize -= qp[qsize - 1] == 0;
+ quot->nlimbs = qsize;
+ quot->sign = sign_quotient;
+ } else
+ rlimb = mpihelp_mod_1(np, nsize, dp[0]);
+ rp[0] = rlimb;
+ rsize = rlimb != 0 ? 1 : 0;
+ rem->nlimbs = rsize;
+ rem->sign = sign_remainder;
+ return 0;
+ }
+
+ if (quot) {
+ qp = quot->d;
+ /* Make sure QP and NP point to different objects. Otherwise the
+ * numerator would be gradually overwritten by the quotient limbs. */
+ if (qp == np) { /* Copy NP object to temporary space. */
+ np = marker[markidx++] = mpi_alloc_limb_space(nsize);
+ MPN_COPY(np, qp, nsize);
+ }
+ } else /* Put quotient at top of remainder. */
+ qp = rp + dsize;
+
+ count_leading_zeros(normalization_steps, dp[dsize - 1]);
+
+ /* Normalize the denominator, i.e. make its most significant bit set by
+ * shifting it NORMALIZATION_STEPS bits to the left. Also shift the
+ * numerator the same number of steps (to keep the quotient the same!).
+ */
+ if (normalization_steps) {
+ mpi_ptr_t tp;
+ mpi_limb_t nlimb;
+
+ /* Shift up the denominator setting the most significant bit of
+ * the most significant word. Use temporary storage not to clobber
+ * the original contents of the denominator. */
+ tp = marker[markidx++] = mpi_alloc_limb_space(dsize);
+ if (!tp)
+ goto nomem;
+ mpihelp_lshift(tp, dp, dsize, normalization_steps);
+ dp = tp;
+
+ /* Shift up the numerator, possibly introducing a new most
+ * significant word. Move the shifted numerator in the remainder
+ * meanwhile. */
+ nlimb = mpihelp_lshift(rp, np, nsize, normalization_steps);
+ if (nlimb) {
+ rp[nsize] = nlimb;
+ rsize = nsize + 1;
+ } else
+ rsize = nsize;
+ } else {
+ /* The denominator is already normalized, as required. Copy it to
+ * temporary space if it overlaps with the quotient or remainder. */
+ if (dp == rp || (quot && (dp == qp))) {
+ mpi_ptr_t tp;
+
+ tp = marker[markidx++] = mpi_alloc_limb_space(dsize);
+ if (!tp)
+ goto nomem;
+ MPN_COPY(tp, dp, dsize);
+ dp = tp;
+ }
+
+ /* Move the numerator to the remainder. */
+ if (rp != np)
+ MPN_COPY(rp, np, nsize);
+
+ rsize = nsize;
+ }
+
+ q_limb = mpihelp_divrem(qp, 0, rp, rsize, dp, dsize);
+
+ if (quot) {
+ qsize = rsize - dsize;
+ if (q_limb) {
+ qp[qsize] = q_limb;
+ qsize += 1;
+ }
+
+ quot->nlimbs = qsize;
+ quot->sign = sign_quotient;
+ }
+
+ rsize = dsize;
+ MPN_NORMALIZE(rp, rsize);
+
+ if (normalization_steps && rsize) {
+ mpihelp_rshift(rp, rp, rsize, normalization_steps);
+ rsize -= rp[rsize - 1] == 0 ? 1 : 0;
+ }
+
+ rem->nlimbs = rsize;
+ rem->sign = sign_remainder;
+
+ rc = 0;
+nomem:
+ while (markidx)
+ mpi_free_limb_space(marker[--markidx]);
+ return rc;
+}
+
+int mpi_tdiv_q_2exp(MPI w, MPI u, unsigned count)
+{
+ mpi_size_t usize, wsize;
+ mpi_size_t limb_cnt;
+
+ usize = u->nlimbs;
+ limb_cnt = count / BITS_PER_MPI_LIMB;
+ wsize = usize - limb_cnt;
+ if (limb_cnt >= usize)
+ w->nlimbs = 0;
+ else {
+ mpi_ptr_t wp;
+ mpi_ptr_t up;
+
+ if (RESIZE_IF_NEEDED(w, wsize) < 0)
+ return -ENOMEM;
+ wp = w->d;
+ up = u->d;
+
+ count %= BITS_PER_MPI_LIMB;
+ if (count) {
+ mpihelp_rshift(wp, up + limb_cnt, wsize, count);
+ wsize -= !wp[wsize - 1];
+ } else {
+ MPN_COPY_INCR(wp, up + limb_cnt, wsize);
+ }
+
+ w->nlimbs = wsize;
+ }
+ return 0;
+}
+
+/****************
+ * Check whether dividend is divisible by divisor
+ * (note: divisor must fit into a limb)
+ */
+int mpi_divisible_ui(MPI dividend, ulong divisor)
+{
+ return !mpihelp_mod_1(dividend->d, dividend->nlimbs, divisor);
+}
diff --git a/lib/mpi/mpi-gcd.c b/lib/mpi/mpi-gcd.c
new file mode 100644
index 0000000..13c48ae
--- /dev/null
+++ b/lib/mpi/mpi-gcd.c
@@ -0,0 +1,59 @@
+/* mpi-gcd.c - MPI functions
+ * Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+ *
+ * This file is part of GnuPG.
+ *
+ * GnuPG 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.
+ *
+ * GnuPG 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "mpi-internal.h"
+
+/****************
+ * Find the greatest common divisor G of A and B.
+ * Return: true if this 1, false in all other cases
+ */
+int mpi_gcd(MPI g, const MPI xa, const MPI xb)
+{
+ MPI a = NULL, b = NULL;
+
+ if (mpi_copy(&a, xa) < 0)
+ goto nomem;
+
+ if (mpi_copy(&b, xb) < 0)
+ goto nomem;
+
+ /* TAOCP Vol II, 4.5.2, Algorithm A */
+ a->sign = 0;
+ b->sign = 0;
+ while (mpi_cmp_ui(b, 0)) {
+ if (mpi_fdiv_r(g, a, b) < 0) /* g used as temorary variable */
+ goto nomem;
+ if (mpi_set(a, b) < 0)
+ goto nomem;
+ if (mpi_set(b, g) < 0)
+ goto nomem;
+ }
+ if (mpi_set(g, a) < 0)
+ goto nomem;
+
+ mpi_free(a);
+ mpi_free(b);
+ return !mpi_cmp_ui(g, 1);
+
+nomem:
+ mpi_free(a);
+ mpi_free(b);
+ return -ENOMEM;
+}
diff --git a/lib/mpi/mpi-inline.c b/lib/mpi/mpi-inline.c
new file mode 100644
index 0000000..654f68a
--- /dev/null
+++ b/lib/mpi/mpi-inline.c
@@ -0,0 +1,31 @@
+/* mpi-inline.c
+ * Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
+ *
+ * This file is part of GnuPG.
+ *
+ * GnuPG 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.
+ *
+ * GnuPG 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+/* put the inline functions as real functions into the lib */
+#define G10_MPI_INLINE_DECL
+
+#include "mpi-internal.h"
+
+/* always include the header becuase it is only
+ * included by mpi-internal if __GCC__ is defined but we
+ * need it here in all cases and the above definition of
+ * of the macro allows us to do so
+ */
+#include "mpi-inline.h"
diff --git a/lib/mpi/mpi-inline.h b/lib/mpi/mpi-inline.h
new file mode 100644
index 0000000..e2b3985
--- /dev/null
+++ b/lib/mpi/mpi-inline.h
@@ -0,0 +1,122 @@
+/* mpi-inline.h - Internal to the Multi Precision Integers
+ * Copyright (C) 1994, 1996, 1998, 1999 Free Software Foundation, Inc.
+ *
+ * This file is part of GnuPG.
+ *
+ * GnuPG 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.
+ *
+ * GnuPG 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ * The GNU MP Library itself is published under the LGPL;
+ * however I decided to publish this code under the plain GPL.
+ */
+
+#ifndef G10_MPI_INLINE_H
+#define G10_MPI_INLINE_H
+
+#ifndef G10_MPI_INLINE_DECL
+#define G10_MPI_INLINE_DECL extern inline
+#endif
+
+G10_MPI_INLINE_DECL mpi_limb_t
+mpihelp_add_1(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
+ mpi_size_t s1_size, mpi_limb_t s2_limb)
+{
+ mpi_limb_t x;
+
+ x = *s1_ptr++;
+ s2_limb += x;
+ *res_ptr++ = s2_limb;
+ if (s2_limb < x) { /* sum is less than the left operand: handle carry */
+ while (--s1_size) {
+ x = *s1_ptr++ + 1; /* add carry */
+ *res_ptr++ = x; /* and store */
+ if (x) /* not 0 (no overflow): we can stop */
+ goto leave;
+ }
+ return 1; /* return carry (size of s1 to small) */
+ }
+
+leave:
+ if (res_ptr != s1_ptr) { /* not the same variable */
+ mpi_size_t i; /* copy the rest */
+ for (i = 0; i < s1_size - 1; i++)
+ res_ptr[i] = s1_ptr[i];
+ }
+ return 0; /* no carry */
+}
+
+G10_MPI_INLINE_DECL mpi_limb_t
+mpihelp_add(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, mpi_size_t s1_size,
+ mpi_ptr_t s2_ptr, mpi_size_t s2_size)
+{
+ mpi_limb_t cy = 0;
+
+ if (s2_size)
+ cy = mpihelp_add_n(res_ptr, s1_ptr, s2_ptr, s2_size);
+
+ if (s1_size - s2_size)
+ cy = mpihelp_add_1(res_ptr + s2_size, s1_ptr + s2_size,
+ s1_size - s2_size, cy);
+ return cy;
+}
+
+G10_MPI_INLINE_DECL mpi_limb_t
+mpihelp_sub_1(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
+ mpi_size_t s1_size, mpi_limb_t s2_limb)
+{
+ mpi_limb_t x;
+
+ x = *s1_ptr++;
+ s2_limb = x - s2_limb;
+ *res_ptr++ = s2_limb;
+ if (s2_limb > x) {
+ while (--s1_size) {
+ x = *s1_ptr++;
+ *res_ptr++ = x - 1;
+ if (x)
+ goto leave;
+ }
+ return 1;
+ }
+
+leave:
+ if (res_ptr != s1_ptr) {
+ mpi_size_t i;
+ for (i = 0; i < s1_size - 1; i++)
+ res_ptr[i] = s1_ptr[i];
+ }
+ return 0;
+}
+
+G10_MPI_INLINE_DECL mpi_limb_t
+mpihelp_sub(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, mpi_size_t s1_size,
+ mpi_ptr_t s2_ptr, mpi_size_t s2_size)
+{
+ mpi_limb_t cy = 0;
+
+ if (s2_size)
+ cy = mpihelp_sub_n(res_ptr, s1_ptr, s2_ptr, s2_size);
+
+ if (s1_size - s2_size)
+ cy = mpihelp_sub_1(res_ptr + s2_size, s1_ptr + s2_size,
+ s1_size - s2_size, cy);
+ return cy;
+}
+
+#endif /*G10_MPI_INLINE_H */
diff --git a/lib/mpi/mpi-internal.h b/lib/mpi/mpi-internal.h
new file mode 100644
index 0000000..77adcf6
--- /dev/null
+++ b/lib/mpi/mpi-internal.h
@@ -0,0 +1,261 @@
+/* mpi-internal.h - Internal to the Multi Precision Integers
+ * Copyright (C) 1994, 1996 Free Software Foundation, Inc.
+ * Copyright (C) 1998, 2000 Free Software Foundation, Inc.
+ *
+ * This file is part of GnuPG.
+ *
+ * GnuPG 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.
+ *
+ * GnuPG 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ * The GNU MP Library itself is published under the LGPL;
+ * however I decided to publish this code under the plain GPL.
+ */
+
+#ifndef G10_MPI_INTERNAL_H
+#define G10_MPI_INTERNAL_H
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/mpi.h>
+#include <linux/errno.h>
+
+#define log_debug printk
+#define log_bug printk
+
+#define assert(x) \
+ do { \
+ if (!x) \
+ log_bug("failed assertion\n"); \
+ } while (0);
+
+/* If KARATSUBA_THRESHOLD is not already defined, define it to a
+ * value which is good on most machines. */
+
+/* tested 4, 16, 32 and 64, where 16 gave the best performance when
+ * checking a 768 and a 1024 bit ElGamal signature.
+ * (wk 22.12.97) */
+#ifndef KARATSUBA_THRESHOLD
+#define KARATSUBA_THRESHOLD 16
+#endif
+
+/* The code can't handle KARATSUBA_THRESHOLD smaller than 2. */
+#if KARATSUBA_THRESHOLD < 2
+#undef KARATSUBA_THRESHOLD
+#define KARATSUBA_THRESHOLD 2
+#endif
+
+typedef mpi_limb_t *mpi_ptr_t; /* pointer to a limb */
+typedef int mpi_size_t; /* (must be a signed type) */
+
+#define ABS(x) (x >= 0 ? x : -x)
+#define MIN(l, o) ((l) < (o) ? (l) : (o))
+#define MAX(h, i) ((h) > (i) ? (h) : (i))
+
+static inline int RESIZE_IF_NEEDED(MPI a, unsigned b)
+{
+ if (a->alloced < b)
+ return mpi_resize(a, b);
+ return 0;
+}
+
+/* Copy N limbs from S to D. */
+#define MPN_COPY(d, s, n) \
+ do { \
+ mpi_size_t _i; \
+ for (_i = 0; _i < (n); _i++) \
+ (d)[_i] = (s)[_i]; \
+ } while (0)
+
+#define MPN_COPY_INCR(d, s, n) \
+ do { \
+ mpi_size_t _i; \
+ for (_i = 0; _i < (n); _i++) \
+ (d)[_i] = (d)[_i]; \
+ } while (0)
+
+#define MPN_COPY_DECR(d, s, n) \
+ do { \
+ mpi_size_t _i; \
+ for (_i = (n)-1; _i >= 0; _i--) \
+ (d)[_i] = (s)[_i]; \
+ } while (0)
+
+/* Zero N limbs at D */
+#define MPN_ZERO(d, n) \
+ do { \
+ int _i; \
+ for (_i = 0; _i < (n); _i++) \
+ (d)[_i] = 0; \
+ } while (0)
+
+#define MPN_NORMALIZE(d, n) \
+ do { \
+ while ((n) > 0) { \
+ if ((d)[(n)-1]) \
+ break; \
+ (n)--; \
+ } \
+ } while (0)
+
+#define MPN_NORMALIZE_NOT_ZERO(d, n) \
+ do { \
+ for (;;) { \
+ if ((d)[(n)-1]) \
+ break; \
+ (n)--; \
+ } \
+ } while (0)
+
+#define MPN_MUL_N_RECURSE(prodp, up, vp, size, tspace) \
+ do { \
+ if ((size) < KARATSUBA_THRESHOLD) \
+ mul_n_basecase(prodp, up, vp, size); \
+ else \
+ mul_n(prodp, up, vp, size, tspace); \
+ } while (0);
+
+/* Divide the two-limb number in (NH,,NL) by D, with DI being the largest
+ * limb not larger than (2**(2*BITS_PER_MP_LIMB))/D - (2**BITS_PER_MP_LIMB).
+ * If this would yield overflow, DI should be the largest possible number
+ * (i.e., only ones). For correct operation, the most significant bit of D
+ * has to be set. Put the quotient in Q and the remainder in R.
+ */
+#define UDIV_QRNND_PREINV(q, r, nh, nl, d, di) \
+ do { \
+ mpi_limb_t _q, _ql, _r; \
+ mpi_limb_t _xh, _xl; \
+ umul_ppmm(_q, _ql, (nh), (di)); \
+ _q += (nh); /* DI is 2**BITS_PER_MPI_LIMB too small */ \
+ umul_ppmm(_xh, _xl, _q, (d)); \
+ sub_ddmmss(_xh, _r, (nh), (nl), _xh, _xl); \
+ if (_xh) { \
+ sub_ddmmss(_xh, _r, _xh, _r, 0, (d)); \
+ _q++; \
+ if (_xh) { \
+ sub_ddmmss(_xh, _r, _xh, _r, 0, (d)); \
+ _q++; \
+ } \
+ } \
+ if (_r >= (d)) { \
+ _r -= (d); \
+ _q++; \
+ } \
+ (r) = _r; \
+ (q) = _q; \
+ } while (0)
+
+/*-- mpiutil.c --*/
+mpi_ptr_t mpi_alloc_limb_space(unsigned nlimbs);
+void mpi_free_limb_space(mpi_ptr_t a);
+void mpi_assign_limb_space(MPI a, mpi_ptr_t ap, unsigned nlimbs);
+
+/*-- mpi-bit.c --*/
+void mpi_rshift_limbs(MPI a, unsigned int count);
+int mpi_lshift_limbs(MPI a, unsigned int count);
+
+/*-- mpihelp-add.c --*/
+mpi_limb_t mpihelp_add_1(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
+ mpi_size_t s1_size, mpi_limb_t s2_limb);
+mpi_limb_t mpihelp_add_n(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
+ mpi_ptr_t s2_ptr, mpi_size_t size);
+mpi_limb_t mpihelp_add(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, mpi_size_t s1_size,
+ mpi_ptr_t s2_ptr, mpi_size_t s2_size);
+
+/*-- mpihelp-sub.c --*/
+mpi_limb_t mpihelp_sub_1(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
+ mpi_size_t s1_size, mpi_limb_t s2_limb);
+mpi_limb_t mpihelp_sub_n(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
+ mpi_ptr_t s2_ptr, mpi_size_t size);
+mpi_limb_t mpihelp_sub(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, mpi_size_t s1_size,
+ mpi_ptr_t s2_ptr, mpi_size_t s2_size);
+
+/*-- mpihelp-cmp.c --*/
+int mpihelp_cmp(mpi_ptr_t op1_ptr, mpi_ptr_t op2_ptr, mpi_size_t size);
+
+/*-- mpihelp-mul.c --*/
+
+struct karatsuba_ctx {
+ struct karatsuba_ctx *next;
+ mpi_ptr_t tspace;
+ mpi_size_t tspace_size;
+ mpi_ptr_t tp;
+ mpi_size_t tp_size;
+};
+
+void mpihelp_release_karatsuba_ctx(struct karatsuba_ctx *ctx);
+
+mpi_limb_t mpihelp_addmul_1(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
+ mpi_size_t s1_size, mpi_limb_t s2_limb);
+mpi_limb_t mpihelp_submul_1(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
+ mpi_size_t s1_size, mpi_limb_t s2_limb);
+int mpihelp_mul_n(mpi_ptr_t prodp, mpi_ptr_t up, mpi_ptr_t vp, mpi_size_t size);
+int mpihelp_mul(mpi_ptr_t prodp, mpi_ptr_t up, mpi_size_t usize,
+ mpi_ptr_t vp, mpi_size_t vsize, mpi_limb_t *_result);
+void mpih_sqr_n_basecase(mpi_ptr_t prodp, mpi_ptr_t up, mpi_size_t size);
+void mpih_sqr_n(mpi_ptr_t prodp, mpi_ptr_t up, mpi_size_t size,
+ mpi_ptr_t tspace);
+
+int mpihelp_mul_karatsuba_case(mpi_ptr_t prodp,
+ mpi_ptr_t up, mpi_size_t usize,
+ mpi_ptr_t vp, mpi_size_t vsize,
+ struct karatsuba_ctx *ctx);
+
+/*-- mpihelp-mul_1.c (or xxx/cpu/ *.S) --*/
+mpi_limb_t mpihelp_mul_1(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
+ mpi_size_t s1_size, mpi_limb_t s2_limb);
+
+/*-- mpihelp-div.c --*/
+mpi_limb_t mpihelp_mod_1(mpi_ptr_t dividend_ptr, mpi_size_t dividend_size,
+ mpi_limb_t divisor_limb);
+mpi_limb_t mpihelp_divrem(mpi_ptr_t qp, mpi_size_t qextra_limbs,
+ mpi_ptr_t np, mpi_size_t nsize,
+ mpi_ptr_t dp, mpi_size_t dsize);
+mpi_limb_t mpihelp_divmod_1(mpi_ptr_t quot_ptr,
+ mpi_ptr_t dividend_ptr, mpi_size_t dividend_size,
+ mpi_limb_t divisor_limb);
+
+/*-- mpihelp-shift.c --*/
+mpi_limb_t mpihelp_lshift(mpi_ptr_t wp, mpi_ptr_t up, mpi_size_t usize,
+ unsigned cnt);
+mpi_limb_t mpihelp_rshift(mpi_ptr_t wp, mpi_ptr_t up, mpi_size_t usize,
+ unsigned cnt);
+
+/* Define stuff for longlong.h. */
+#define W_TYPE_SIZE BITS_PER_MPI_LIMB
+typedef mpi_limb_t UWtype;
+typedef unsigned int UHWtype;
+#if defined(__GNUC__)
+typedef unsigned int UQItype __attribute__ ((mode(QI)));
+typedef int SItype __attribute__ ((mode(SI)));
+typedef unsigned int USItype __attribute__ ((mode(SI)));
+typedef int DItype __attribute__ ((mode(DI)));
+typedef unsigned int UDItype __attribute__ ((mode(DI)));
+#else
+typedef unsigned char UQItype;
+typedef long SItype;
+typedef unsigned long USItype;
+#endif
+
+#ifdef __GNUC__
+#include "mpi-inline.h"
+#endif
+
+#endif /*G10_MPI_INTERNAL_H */
diff --git a/lib/mpi/mpi-inv.c b/lib/mpi/mpi-inv.c
new file mode 100644
index 0000000..0951f98
--- /dev/null
+++ b/lib/mpi/mpi-inv.c
@@ -0,0 +1,187 @@
+/* mpi-inv.c - MPI functions
+ * Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+ *
+ * This file is part of GnuPG.
+ *
+ * GnuPG 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.
+ *
+ * GnuPG 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "mpi-internal.h"
+
+/****************
+ * Calculate the multiplicative inverse X of A mod N
+ * That is: Find the solution x for
+ * 1 = (a*x) mod n
+ */
+int mpi_invm(MPI x, const MPI a, const MPI n)
+{
+ /* Extended Euclid's algorithm (See TAOPC Vol II, 4.5.2, Alg X)
+ * modified according to Michael Penk's solution for Exercice 35
+ * with further enhancement */
+ MPI u = NULL, v = NULL;
+ MPI u1 = NULL, u2 = NULL, u3 = NULL;
+ MPI v1 = NULL, v2 = NULL, v3 = NULL;
+ MPI t1 = NULL, t2 = NULL, t3 = NULL;
+ unsigned k;
+ int sign;
+ int odd = 0;
+ int rc = -ENOMEM;
+
+ if (mpi_copy(&u, a) < 0)
+ goto cleanup;
+ if (mpi_copy(&v, n) < 0)
+ goto cleanup;
+
+ for (k = 0; !mpi_test_bit(u, 0) && !mpi_test_bit(v, 0); k++) {
+ if (mpi_rshift(u, u, 1) < 0)
+ goto cleanup;
+ if (mpi_rshift(v, v, 1) < 0)
+ goto cleanup;
+ }
+ odd = mpi_test_bit(v, 0);
+
+ u1 = mpi_alloc_set_ui(1);
+ if (!u1)
+ goto cleanup;
+ if (!odd) {
+ u2 = mpi_alloc_set_ui(0);
+ if (!u2)
+ goto cleanup;
+ }
+ if (mpi_copy(&u3, u) < 0)
+ goto cleanup;
+ if (mpi_copy(&v1, v) < 0)
+ goto cleanup;
+ if (!odd) {
+ v2 = mpi_alloc(mpi_get_nlimbs(u));
+ if (!v2)
+ goto cleanup;
+ if (mpi_sub(v2, u1, u) < 0)
+ goto cleanup; /* U is used as const 1 */
+ }
+ if (mpi_copy(&v3, v) < 0)
+ goto cleanup;
+ if (mpi_test_bit(u, 0)) { /* u is odd */
+ t1 = mpi_alloc_set_ui(0);
+ if (!t1)
+ goto cleanup;
+ if (!odd) {
+ t2 = mpi_alloc_set_ui(1);
+ if (!t2)
+ goto cleanup;
+ t2->sign = 1;
+ }
+ if (mpi_copy(&t3, v) < 0)
+ goto cleanup;
+ t3->sign = !t3->sign;
+ goto Y4;
+ } else {
+ t1 = mpi_alloc_set_ui(1);
+ if (!t1)
+ goto cleanup;
+ if (!odd) {
+ t2 = mpi_alloc_set_ui(0);
+ if (!t2)
+ goto cleanup;
+ }
+ if (mpi_copy(&t3, u) < 0)
+ goto cleanup;
+ }
+ do {
+ do {
+ if (!odd) {
+ if (mpi_test_bit(t1, 0) || mpi_test_bit(t2, 0)) { /* one is odd */
+ if (mpi_add(t1, t1, v) < 0)
+ goto cleanup;
+ if (mpi_sub(t2, t2, u) < 0)
+ goto cleanup;
+ }
+ if (mpi_rshift(t1, t1, 1) < 0)
+ goto cleanup;
+ if (mpi_rshift(t2, t2, 1) < 0)
+ goto cleanup;
+ if (mpi_rshift(t3, t3, 1) < 0)
+ goto cleanup;
+ } else {
+ if (mpi_test_bit(t1, 0))
+ if (mpi_add(t1, t1, v) < 0)
+ goto cleanup;
+ if (mpi_rshift(t1, t1, 1) < 0)
+ goto cleanup;
+ if (mpi_rshift(t3, t3, 1) < 0)
+ goto cleanup;
+ }
+Y4:
+ ;
+ } while (!mpi_test_bit(t3, 0)); /* while t3 is even */
+
+ if (!t3->sign) {
+ if (mpi_set(u1, t1) < 0)
+ goto cleanup;
+ if (!odd)
+ if (mpi_set(u2, t2) < 0)
+ goto cleanup;
+ if (mpi_set(u3, t3) < 0)
+ goto cleanup;
+ } else {
+ if (mpi_sub(v1, v, t1) < 0)
+ goto cleanup;
+ sign = u->sign;
+ u->sign = !u->sign;
+ if (!odd)
+ if (mpi_sub(v2, u, t2) < 0)
+ goto cleanup;
+ u->sign = sign;
+ sign = t3->sign;
+ t3->sign = !t3->sign;
+ if (mpi_set(v3, t3) < 0)
+ goto cleanup;
+ t3->sign = sign;
+ }
+ if (mpi_sub(t1, u1, v1) < 0)
+ goto cleanup;
+ if (!odd)
+ if (mpi_sub(t2, u2, v2) < 0)
+ goto cleanup;
+ if (mpi_sub(t3, u3, v3) < 0)
+ goto cleanup;
+ if (t1->sign) {
+ if (mpi_add(t1, t1, v) < 0)
+ goto cleanup;
+ if (!odd)
+ if (mpi_sub(t2, t2, u) < 0)
+ goto cleanup;
+ }
+ } while (mpi_cmp_ui(t3, 0)); /* while t3 != 0 */
+ /* mpi_lshift( u3, k ); */
+ rc = mpi_set(x, u1);
+
+cleanup:
+ mpi_free(u1);
+ mpi_free(v1);
+ mpi_free(t1);
+ if (!odd) {
+ mpi_free(u2);
+ mpi_free(v2);
+ mpi_free(t2);
+ }
+ mpi_free(u3);
+ mpi_free(v3);
+ mpi_free(t3);
+
+ mpi_free(u);
+ mpi_free(v);
+ return rc;
+}
diff --git a/lib/mpi/mpi-mpow.c b/lib/mpi/mpi-mpow.c
new file mode 100644
index 0000000..7328d0d
--- /dev/null
+++ b/lib/mpi/mpi-mpow.c
@@ -0,0 +1,134 @@
+/* mpi-mpow.c - MPI functions
+ * Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
+ *
+ * This file is part of GnuPG.
+ *
+ * GnuPG 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.
+ *
+ * GnuPG 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "mpi-internal.h"
+#include "longlong.h"
+
+static int build_index(const MPI *exparray, int k, int i, int t)
+{
+ int j, bitno;
+ int index = 0;
+
+ bitno = t - i;
+ for (j = k - 1; j >= 0; j--) {
+ index <<= 1;
+ if (mpi_test_bit(exparray[j], bitno))
+ index |= 1;
+ }
+ return index;
+}
+
+/****************
+ * RES = (BASE[0] ^ EXP[0]) * (BASE[1] ^ EXP[1]) * ... * mod M
+ */
+int mpi_mulpowm(MPI res, MPI *basearray, MPI *exparray, MPI m)
+{
+ int rc = -ENOMEM;
+ int k; /* number of elements */
+ int t; /* bit size of largest exponent */
+ int i, j, idx;
+ MPI *G = NULL; /* table with precomputed values of size 2^k */
+ MPI tmp = NULL;
+
+ for (k = 0; basearray[k]; k++)
+ ;
+ if (!k) {
+ pr_emerg("mpi_mulpowm: assert(k) failed\n");
+ BUG();
+ }
+ for (t = 0, i = 0; (tmp = exparray[i]); i++) {
+ j = mpi_get_nbits(tmp);
+ if (j > t)
+ t = j;
+ }
+ if (i != k) {
+ pr_emerg("mpi_mulpowm: assert(i==k) failed\n");
+ BUG();
+ }
+ if (!t) {
+ pr_emerg("mpi_mulpowm: assert(t) failed\n");
+ BUG();
+ }
+ if (k >= 10) {
+ pr_emerg("mpi_mulpowm: assert(k<10) failed\n");
+ BUG();
+ }
+
+ G = kzalloc((1 << k) * sizeof *G, GFP_KERNEL);
+ if (!G)
+ goto err_out;
+
+ /* and calculate */
+ tmp = mpi_alloc(mpi_get_nlimbs(m) + 1);
+ if (!tmp)
+ goto nomem;
+ if (mpi_set_ui(res, 1) < 0)
+ goto nomem;
+ for (i = 1; i <= t; i++) {
+ if (mpi_mulm(tmp, res, res, m) < 0)
+ goto nomem;
+ idx = build_index(exparray, k, i, t);
+ if (!(idx >= 0 && idx < (1 << k))) {
+ pr_emerg("mpi_mulpowm: assert(idx >= 0 && idx < (1<<k)) failed\n");
+ BUG();
+ }
+ if (!G[idx]) {
+ if (!idx) {
+ G[0] = mpi_alloc_set_ui(1);
+ if (!G[0])
+ goto nomem;
+ } else {
+ for (j = 0; j < k; j++) {
+ if ((idx & (1 << j))) {
+ if (!G[idx]) {
+ if (mpi_copy
+ (&G[idx],
+ basearray[j]) < 0)
+ goto nomem;
+ } else {
+ if (mpi_mulm
+ (G[idx], G[idx],
+ basearray[j],
+ m) < 0)
+ goto nomem;
+ }
+ }
+ }
+ if (!G[idx]) {
+ G[idx] = mpi_alloc(0);
+ if (!G[idx])
+ goto nomem;
+ }
+ }
+ }
+ if (mpi_mulm(res, tmp, G[idx], m) < 0)
+ goto nomem;
+ }
+
+ rc = 0;
+nomem:
+ /* cleanup */
+ mpi_free(tmp);
+ for (i = 0; i < (1 << k); i++)
+ mpi_free(G[i]);
+ kfree(G);
+err_out:
+ return rc;
+}
diff --git a/lib/mpi/mpi-mul.c b/lib/mpi/mpi-mul.c
new file mode 100644
index 0000000..1f3219e
--- /dev/null
+++ b/lib/mpi/mpi-mul.c
@@ -0,0 +1,194 @@
+/* mpi-mul.c - MPI functions
+ * Copyright (C) 1994, 1996 Free Software Foundation, Inc.
+ * Copyright (C) 1998, 2001 Free Software Foundation, Inc.
+ *
+ * This file is part of GnuPG.
+ *
+ * GnuPG 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.
+ *
+ * GnuPG 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ * The GNU MP Library itself is published under the LGPL;
+ * however I decided to publish this code under the plain GPL.
+ */
+
+#include "mpi-internal.h"
+
+int mpi_mul_ui(MPI prod, MPI mult, unsigned long small_mult)
+{
+ mpi_size_t size, prod_size;
+ mpi_ptr_t prod_ptr;
+ mpi_limb_t cy;
+ int sign;
+
+ size = mult->nlimbs;
+ sign = mult->sign;
+
+ if (!size || !small_mult) {
+ prod->nlimbs = 0;
+ prod->sign = 0;
+ return 0;
+ }
+
+ prod_size = size + 1;
+ if (prod->alloced < prod_size)
+ if (mpi_resize(prod, prod_size) < 0)
+ return -ENOMEM;
+ prod_ptr = prod->d;
+
+ cy = mpihelp_mul_1(prod_ptr, mult->d, size, (mpi_limb_t) small_mult);
+ if (cy)
+ prod_ptr[size++] = cy;
+ prod->nlimbs = size;
+ prod->sign = sign;
+ return 0;
+}
+
+int mpi_mul_2exp(MPI w, MPI u, unsigned long cnt)
+{
+ mpi_size_t usize, wsize, limb_cnt;
+ mpi_ptr_t wp;
+ mpi_limb_t wlimb;
+ int usign, wsign;
+
+ usize = u->nlimbs;
+ usign = u->sign;
+
+ if (!usize) {
+ w->nlimbs = 0;
+ w->sign = 0;
+ return 0;
+ }
+
+ limb_cnt = cnt / BITS_PER_MPI_LIMB;
+ wsize = usize + limb_cnt + 1;
+ if (w->alloced < wsize)
+ if (mpi_resize(w, wsize) < 0)
+ return -ENOMEM;
+ wp = w->d;
+ wsize = usize + limb_cnt;
+ wsign = usign;
+
+ cnt %= BITS_PER_MPI_LIMB;
+ if (cnt) {
+ wlimb = mpihelp_lshift(wp + limb_cnt, u->d, usize, cnt);
+ if (wlimb) {
+ wp[wsize] = wlimb;
+ wsize++;
+ }
+ } else {
+ MPN_COPY_DECR(wp + limb_cnt, u->d, usize);
+ }
+
+ /* Zero all whole limbs at low end. Do it here and not before calling
+ * mpn_lshift, not to lose for U == W. */
+ MPN_ZERO(wp, limb_cnt);
+
+ w->nlimbs = wsize;
+ w->sign = wsign;
+ return 0;
+}
+
+int mpi_mul(MPI w, MPI u, MPI v)
+{
+ int rc = -ENOMEM;
+ mpi_size_t usize, vsize, wsize;
+ mpi_ptr_t up, vp, wp;
+ mpi_limb_t cy;
+ int usign, vsign, sign_product;
+ int assign_wp = 0;
+ mpi_ptr_t tmp_limb = NULL;
+
+ if (u->nlimbs < v->nlimbs) { /* Swap U and V. */
+ usize = v->nlimbs;
+ usign = v->sign;
+ up = v->d;
+ vsize = u->nlimbs;
+ vsign = u->sign;
+ vp = u->d;
+ } else {
+ usize = u->nlimbs;
+ usign = u->sign;
+ up = u->d;
+ vsize = v->nlimbs;
+ vsign = v->sign;
+ vp = v->d;
+ }
+ sign_product = usign ^ vsign;
+ wp = w->d;
+
+ /* Ensure W has space enough to store the result. */
+ wsize = usize + vsize;
+ if (w->alloced < (size_t) wsize) {
+ if (wp == up || wp == vp) {
+ wp = mpi_alloc_limb_space(wsize);
+ if (!wp)
+ goto nomem;
+ assign_wp = 1;
+ } else {
+ if (mpi_resize(w, wsize) < 0)
+ goto nomem;
+ wp = w->d;
+ }
+ } else { /* Make U and V not overlap with W. */
+ if (wp == up) {
+ /* W and U are identical. Allocate temporary space for U. */
+ up = tmp_limb = mpi_alloc_limb_space(usize);
+ if (!up)
+ goto nomem;
+ /* Is V identical too? Keep it identical with U. */
+ if (wp == vp)
+ vp = up;
+ /* Copy to the temporary space. */
+ MPN_COPY(up, wp, usize);
+ } else if (wp == vp) {
+ /* W and V are identical. Allocate temporary space for V. */
+ vp = tmp_limb = mpi_alloc_limb_space(vsize);
+ if (!vp)
+ goto nomem;
+ /* Copy to the temporary space. */
+ MPN_COPY(vp, wp, vsize);
+ }
+ }
+
+ if (!vsize)
+ wsize = 0;
+ else {
+ if (mpihelp_mul(wp, up, usize, vp, vsize, &cy) < 0)
+ goto nomem;
+ wsize -= cy ? 0 : 1;
+ }
+
+ if (assign_wp)
+ mpi_assign_limb_space(w, wp, wsize);
+
+ w->nlimbs = wsize;
+ w->sign = sign_product;
+ rc = 0;
+nomem:
+ if (tmp_limb)
+ mpi_free_limb_space(tmp_limb);
+ return rc;
+}
+
+int mpi_mulm(MPI w, MPI u, MPI v, MPI m)
+{
+ if (mpi_mul(w, u, v) < 0)
+ return -ENOMEM;
+ return mpi_fdiv_r(w, w, m);
+}
diff --git a/lib/mpi/mpi-pow.c b/lib/mpi/mpi-pow.c
new file mode 100644
index 0000000..b04a3cf
--- /dev/null
+++ b/lib/mpi/mpi-pow.c
@@ -0,0 +1,323 @@
+/* mpi-pow.c - MPI functions
+ * Copyright (C) 1994, 1996, 1998, 2000 Free Software Foundation, Inc.
+ *
+ * This file is part of GnuPG.
+ *
+ * GnuPG 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.
+ *
+ * GnuPG 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ * The GNU MP Library itself is published under the LGPL;
+ * however I decided to publish this code under the plain GPL.
+ */
+
+#include <linux/string.h>
+#include "mpi-internal.h"
+#include "longlong.h"
+
+/****************
+ * RES = BASE ^ EXP mod MOD
+ */
+int mpi_powm(MPI res, MPI base, MPI exp, MPI mod)
+{
+ mpi_ptr_t mp_marker = NULL, bp_marker = NULL, ep_marker = NULL;
+ mpi_ptr_t xp_marker = NULL;
+ mpi_ptr_t tspace = NULL;
+ mpi_ptr_t rp, ep, mp, bp;
+ mpi_size_t esize, msize, bsize, rsize;
+ int esign, msign, bsign, rsign;
+ mpi_size_t size;
+ int mod_shift_cnt;
+ int negative_result;
+ int assign_rp = 0;
+ mpi_size_t tsize = 0; /* to avoid compiler warning */
+ /* fixme: we should check that the warning is void */
+ int rc = -ENOMEM;
+
+ esize = exp->nlimbs;
+ msize = mod->nlimbs;
+ size = 2 * msize;
+ esign = exp->sign;
+ msign = mod->sign;
+
+ rp = res->d;
+ ep = exp->d;
+
+ if (!msize)
+ msize = 1 / msize; /* provoke a signal */
+
+ if (!esize) {
+ /* Exponent is zero, result is 1 mod MOD, i.e., 1 or 0
+ * depending on if MOD equals 1. */
+ rp[0] = 1;
+ res->nlimbs = (msize == 1 && mod->d[0] == 1) ? 0 : 1;
+ res->sign = 0;
+ goto leave;
+ }
+
+ /* Normalize MOD (i.e. make its most significant bit set) as required by
+ * mpn_divrem. This will make the intermediate values in the calculation
+ * slightly larger, but the correct result is obtained after a final
+ * reduction using the original MOD value. */
+ mp = mp_marker = mpi_alloc_limb_space(msize);
+ if (!mp)
+ goto enomem;
+ count_leading_zeros(mod_shift_cnt, mod->d[msize - 1]);
+ if (mod_shift_cnt)
+ mpihelp_lshift(mp, mod->d, msize, mod_shift_cnt);
+ else
+ MPN_COPY(mp, mod->d, msize);
+
+ bsize = base->nlimbs;
+ bsign = base->sign;
+ if (bsize > msize) { /* The base is larger than the module. Reduce it. */
+ /* Allocate (BSIZE + 1) with space for remainder and quotient.
+ * (The quotient is (bsize - msize + 1) limbs.) */
+ bp = bp_marker = mpi_alloc_limb_space(bsize + 1);
+ if (!bp)
+ goto enomem;
+ MPN_COPY(bp, base->d, bsize);
+ /* We don't care about the quotient, store it above the remainder,
+ * at BP + MSIZE. */
+ mpihelp_divrem(bp + msize, 0, bp, bsize, mp, msize);
+ bsize = msize;
+ /* Canonicalize the base, since we are going to multiply with it
+ * quite a few times. */
+ MPN_NORMALIZE(bp, bsize);
+ } else
+ bp = base->d;
+
+ if (!bsize) {
+ res->nlimbs = 0;
+ res->sign = 0;
+ goto leave;
+ }
+
+ if (res->alloced < size) {
+ /* We have to allocate more space for RES. If any of the input
+ * parameters are identical to RES, defer deallocation of the old
+ * space. */
+ if (rp == ep || rp == mp || rp == bp) {
+ rp = mpi_alloc_limb_space(size);
+ if (!rp)
+ goto enomem;
+ assign_rp = 1;
+ } else {
+ if (mpi_resize(res, size) < 0)
+ goto enomem;
+ rp = res->d;
+ }
+ } else { /* Make BASE, EXP and MOD not overlap with RES. */
+ if (rp == bp) {
+ /* RES and BASE are identical. Allocate temp. space for BASE. */
+ BUG_ON(bp_marker);
+ bp = bp_marker = mpi_alloc_limb_space(bsize);
+ if (!bp)
+ goto enomem;
+ MPN_COPY(bp, rp, bsize);
+ }
+ if (rp == ep) {
+ /* RES and EXP are identical. Allocate temp. space for EXP. */
+ ep = ep_marker = mpi_alloc_limb_space(esize);
+ if (!ep)
+ goto enomem;
+ MPN_COPY(ep, rp, esize);
+ }
+ if (rp == mp) {
+ /* RES and MOD are identical. Allocate temporary space for MOD. */
+ BUG_ON(mp_marker);
+ mp = mp_marker = mpi_alloc_limb_space(msize);
+ if (!mp)
+ goto enomem;
+ MPN_COPY(mp, rp, msize);
+ }
+ }
+
+ MPN_COPY(rp, bp, bsize);
+ rsize = bsize;
+ rsign = bsign;
+
+ {
+ mpi_size_t i;
+ mpi_ptr_t xp;
+ int c;
+ mpi_limb_t e;
+ mpi_limb_t carry_limb;
+ struct karatsuba_ctx karactx;
+
+ xp = xp_marker = mpi_alloc_limb_space(2 * (msize + 1));
+ if (!xp)
+ goto enomem;
+
+ memset(&karactx, 0, sizeof karactx);
+ negative_result = (ep[0] & 1) && base->sign;
+
+ i = esize - 1;
+ e = ep[i];
+ count_leading_zeros(c, e);
+ e = (e << c) << 1; /* shift the exp bits to the left, lose msb */
+ c = BITS_PER_MPI_LIMB - 1 - c;
+
+ /* Main loop.
+ *
+ * Make the result be pointed to alternately by XP and RP. This
+ * helps us avoid block copying, which would otherwise be necessary
+ * with the overlap restrictions of mpihelp_divmod. With 50% probability
+ * the result after this loop will be in the area originally pointed
+ * by RP (==RES->d), and with 50% probability in the area originally
+ * pointed to by XP.
+ */
+
+ for (;;) {
+ while (c) {
+ mpi_ptr_t tp;
+ mpi_size_t xsize;
+
+ /*if (mpihelp_mul_n(xp, rp, rp, rsize) < 0) goto enomem */
+ if (rsize < KARATSUBA_THRESHOLD)
+ mpih_sqr_n_basecase(xp, rp, rsize);
+ else {
+ if (!tspace) {
+ tsize = 2 * rsize;
+ tspace =
+ mpi_alloc_limb_space(tsize);
+ if (!tspace)
+ goto enomem;
+ } else if (tsize < (2 * rsize)) {
+ mpi_free_limb_space(tspace);
+ tsize = 2 * rsize;
+ tspace =
+ mpi_alloc_limb_space(tsize);
+ if (!tspace)
+ goto enomem;
+ }
+ mpih_sqr_n(xp, rp, rsize, tspace);
+ }
+
+ xsize = 2 * rsize;
+ if (xsize > msize) {
+ mpihelp_divrem(xp + msize, 0, xp, xsize,
+ mp, msize);
+ xsize = msize;
+ }
+
+ tp = rp;
+ rp = xp;
+ xp = tp;
+ rsize = xsize;
+
+ if ((mpi_limb_signed_t) e < 0) {
+ /*mpihelp_mul( xp, rp, rsize, bp, bsize ); */
+ if (bsize < KARATSUBA_THRESHOLD) {
+ mpi_limb_t tmp;
+ if (mpihelp_mul
+ (xp, rp, rsize, bp, bsize,
+ &tmp) < 0)
+ goto enomem;
+ } else {
+ if (mpihelp_mul_karatsuba_case
+ (xp, rp, rsize, bp, bsize,
+ &karactx) < 0)
+ goto enomem;
+ }
+
+ xsize = rsize + bsize;
+ if (xsize > msize) {
+ mpihelp_divrem(xp + msize, 0,
+ xp, xsize, mp,
+ msize);
+ xsize = msize;
+ }
+
+ tp = rp;
+ rp = xp;
+ xp = tp;
+ rsize = xsize;
+ }
+ e <<= 1;
+ c--;
+ }
+
+ i--;
+ if (i < 0)
+ break;
+ e = ep[i];
+ c = BITS_PER_MPI_LIMB;
+ }
+
+ /* We shifted MOD, the modulo reduction argument, left MOD_SHIFT_CNT
+ * steps. Adjust the result by reducing it with the original MOD.
+ *
+ * Also make sure the result is put in RES->d (where it already
+ * might be, see above).
+ */
+ if (mod_shift_cnt) {
+ carry_limb =
+ mpihelp_lshift(res->d, rp, rsize, mod_shift_cnt);
+ rp = res->d;
+ if (carry_limb) {
+ rp[rsize] = carry_limb;
+ rsize++;
+ }
+ } else {
+ MPN_COPY(res->d, rp, rsize);
+ rp = res->d;
+ }
+
+ if (rsize >= msize) {
+ mpihelp_divrem(rp + msize, 0, rp, rsize, mp, msize);
+ rsize = msize;
+ }
+
+ /* Remove any leading zero words from the result. */
+ if (mod_shift_cnt)
+ mpihelp_rshift(rp, rp, rsize, mod_shift_cnt);
+ MPN_NORMALIZE(rp, rsize);
+
+ mpihelp_release_karatsuba_ctx(&karactx);
+ }
+
+ if (negative_result && rsize) {
+ if (mod_shift_cnt)
+ mpihelp_rshift(mp, mp, msize, mod_shift_cnt);
+ mpihelp_sub(rp, mp, msize, rp, rsize);
+ rsize = msize;
+ rsign = msign;
+ MPN_NORMALIZE(rp, rsize);
+ }
+ res->nlimbs = rsize;
+ res->sign = rsign;
+
+leave:
+ rc = 0;
+enomem:
+ if (assign_rp)
+ mpi_assign_limb_space(res, rp, size);
+ if (mp_marker)
+ mpi_free_limb_space(mp_marker);
+ if (bp_marker)
+ mpi_free_limb_space(bp_marker);
+ if (ep_marker)
+ mpi_free_limb_space(ep_marker);
+ if (xp_marker)
+ mpi_free_limb_space(xp_marker);
+ if (tspace)
+ mpi_free_limb_space(tspace);
+ return rc;
+}
+EXPORT_SYMBOL_GPL(mpi_powm);
diff --git a/lib/mpi/mpi-scan.c b/lib/mpi/mpi-scan.c
new file mode 100644
index 0000000..b2da5ad
--- /dev/null
+++ b/lib/mpi/mpi-scan.c
@@ -0,0 +1,136 @@
+/* mpi-scan.c - MPI functions
+ * Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+ *
+ * This file is part of GnuPG.
+ *
+ * GnuPG 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.
+ *
+ * GnuPG 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "mpi-internal.h"
+#include "longlong.h"
+
+/****************
+ * Scan through an mpi and return byte for byte. a -1 is returned to indicate
+ * the end of the mpi. Scanning is done from the lsb to the msb, returned
+ * values are in the range of 0 .. 255.
+ *
+ * FIXME: This code is VERY ugly!
+ */
+int mpi_getbyte(const MPI a, unsigned idx)
+{
+ int i, j;
+ unsigned n;
+ mpi_ptr_t ap;
+ mpi_limb_t limb;
+
+ ap = a->d;
+ for (n = 0, i = 0; i < a->nlimbs; i++) {
+ limb = ap[i];
+ for (j = 0; j < BYTES_PER_MPI_LIMB; j++, n++)
+ if (n == idx)
+ return (limb >> j * 8) & 0xff;
+ }
+ return -1;
+}
+
+/****************
+ * Put a value at position IDX into A. idx counts from lsb to msb
+ */
+void mpi_putbyte(MPI a, unsigned idx, int xc)
+{
+ int i, j;
+ unsigned n;
+ mpi_ptr_t ap;
+ mpi_limb_t limb, c;
+
+ c = xc & 0xff;
+ ap = a->d;
+ for (n = 0, i = 0; i < a->alloced; i++) {
+ limb = ap[i];
+ for (j = 0; j < BYTES_PER_MPI_LIMB; j++, n++)
+ if (n == idx) {
+#if BYTES_PER_MPI_LIMB == 4
+ if (j == 0)
+ limb = (limb & 0xffffff00) | c;
+ else if (j == 1)
+ limb = (limb & 0xffff00ff) | (c << 8);
+ else if (j == 2)
+ limb = (limb & 0xff00ffff) | (c << 16);
+ else
+ limb = (limb & 0x00ffffff) | (c << 24);
+#elif BYTES_PER_MPI_LIMB == 8
+ if (j == 0)
+ limb = (limb & 0xffffffffffffff00) | c;
+ else if (j == 1)
+ limb =
+ (limb & 0xffffffffffff00ff) | (c <<
+ 8);
+ else if (j == 2)
+ limb =
+ (limb & 0xffffffffff00ffff) | (c <<
+ 16);
+ else if (j == 3)
+ limb =
+ (limb & 0xffffffff00ffffff) | (c <<
+ 24);
+ else if (j == 4)
+ limb =
+ (limb & 0xffffff00ffffffff) | (c <<
+ 32);
+ else if (j == 5)
+ limb =
+ (limb & 0xffff00ffffffffff) | (c <<
+ 40);
+ else if (j == 6)
+ limb =
+ (limb & 0xff00ffffffffffff) | (c <<
+ 48);
+ else
+ limb =
+ (limb & 0x00ffffffffffffff) | (c <<
+ 56);
+#else
+#error please enhance this function, its ugly - i know.
+#endif
+ if (a->nlimbs <= i)
+ a->nlimbs = i + 1;
+ ap[i] = limb;
+ return;
+ }
+ }
+ log_bug("index out of range\n");
+}
+
+/****************
+ * Count the number of zerobits at the low end of A
+ */
+unsigned mpi_trailing_zeros(const MPI a)
+{
+ unsigned n, count = 0;
+
+ for (n = 0; n < a->nlimbs; n++) {
+ if (a->d[n]) {
+ unsigned nn;
+ mpi_limb_t alimb = a->d[n];
+
+ count_trailing_zeros(nn, alimb);
+ count += nn;
+ break;
+ }
+ count += BITS_PER_MPI_LIMB;
+ }
+ return count;
+
+}
diff --git a/lib/mpi/mpicoder.c b/lib/mpi/mpicoder.c
new file mode 100644
index 0000000..fe84bb9
--- /dev/null
+++ b/lib/mpi/mpicoder.c
@@ -0,0 +1,365 @@
+/* mpicoder.c - Coder for the external representation of MPIs
+ * Copyright (C) 1998, 1999 Free Software Foundation, Inc.
+ *
+ * This file is part of GnuPG.
+ *
+ * GnuPG 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.
+ *
+ * GnuPG 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "mpi-internal.h"
+
+#define DIM(v) (sizeof(v)/sizeof((v)[0]))
+#define MAX_EXTERN_MPI_BITS 16384
+
+static uint8_t asn[15] = /* Object ID is 1.3.14.3.2.26 */
+{ 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03,
+ 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14
+};
+
+MPI do_encode_md(const void *sha_buffer, unsigned nbits)
+{
+ int nframe = (nbits + 7) / 8;
+ uint8_t *frame, *fr_pt;
+ int i = 0, n;
+ size_t asnlen = DIM(asn);
+ MPI a = MPI_NULL;
+
+ if (SHA1_DIGEST_LENGTH + asnlen + 4 > nframe)
+ pr_info("MPI: can't encode a %d bit MD into a %d bits frame\n",
+ (int)(SHA1_DIGEST_LENGTH * 8), (int)nbits);
+
+ /* We encode the MD in this way:
+ *
+ * 0 A PAD(n bytes) 0 ASN(asnlen bytes) MD(len bytes)
+ *
+ * PAD consists of FF bytes.
+ */
+ frame = kmalloc(nframe, GFP_KERNEL);
+ if (!frame)
+ return MPI_NULL;
+ n = 0;
+ frame[n++] = 0;
+ frame[n++] = 1; /* block type */
+ i = nframe - SHA1_DIGEST_LENGTH - asnlen - 3;
+
+ if (i <= 1) {
+ pr_info("MPI: message digest encoding failed\n");
+ kfree(frame);
+ return a;
+ }
+
+ memset(frame + n, 0xff, i);
+ n += i;
+ frame[n++] = 0;
+ memcpy(frame + n, &asn, asnlen);
+ n += asnlen;
+ memcpy(frame + n, sha_buffer, SHA1_DIGEST_LENGTH);
+ n += SHA1_DIGEST_LENGTH;
+
+ i = nframe;
+ fr_pt = frame;
+
+ if (n != nframe) {
+ printk
+ ("MPI: message digest encoding failed, frame length is wrong\n");
+ kfree(frame);
+ return a;
+ }
+
+ a = mpi_alloc((nframe + BYTES_PER_MPI_LIMB - 1) / BYTES_PER_MPI_LIMB);
+ mpi_set_buffer(a, frame, nframe, 0);
+ kfree(frame);
+
+ return a;
+}
+
+MPI mpi_read_from_buffer(const void *xbuffer, unsigned *ret_nread)
+{
+ const uint8_t *buffer = xbuffer;
+ int i, j;
+ unsigned nbits, nbytes, nlimbs, nread = 0;
+ mpi_limb_t a;
+ MPI val = MPI_NULL;
+
+ if (*ret_nread < 2)
+ goto leave;
+ nbits = buffer[0] << 8 | buffer[1];
+
+ if (nbits > MAX_EXTERN_MPI_BITS) {
+ pr_info("MPI: mpi too large (%u bits)\n", nbits);
+ goto leave;
+ }
+ buffer += 2;
+ nread = 2;
+
+ nbytes = (nbits + 7) / 8;
+ nlimbs = (nbytes + BYTES_PER_MPI_LIMB - 1) / BYTES_PER_MPI_LIMB;
+ val = mpi_alloc(nlimbs);
+ if (!val)
+ return MPI_NULL;
+ i = BYTES_PER_MPI_LIMB - nbytes % BYTES_PER_MPI_LIMB;
+ i %= BYTES_PER_MPI_LIMB;
+ val->nbits = nbits;
+ j = val->nlimbs = nlimbs;
+ val->sign = 0;
+ for (; j > 0; j--) {
+ a = 0;
+ for (; i < BYTES_PER_MPI_LIMB; i++) {
+ if (++nread > *ret_nread) {
+ printk
+ ("MPI: mpi larger than buffer nread=%d ret_nread=%d\n",
+ nread, *ret_nread);
+ goto leave;
+ }
+ a <<= 8;
+ a |= *buffer++;
+ }
+ i = 0;
+ val->d[j - 1] = a;
+ }
+
+leave:
+ *ret_nread = nread;
+ return val;
+}
+EXPORT_SYMBOL_GPL(mpi_read_from_buffer);
+
+/****************
+ * Make an mpi from a character string.
+ */
+int mpi_fromstr(MPI val, const char *str)
+{
+ int hexmode = 0, sign = 0, prepend_zero = 0, i, j, c, c1, c2;
+ unsigned nbits, nbytes, nlimbs;
+ mpi_limb_t a;
+
+ if (*str == '-') {
+ sign = 1;
+ str++;
+ }
+ if (*str == '0' && str[1] == 'x')
+ hexmode = 1;
+ else
+ return -EINVAL; /* other bases are not yet supported */
+ str += 2;
+
+ nbits = strlen(str) * 4;
+ if (nbits % 8)
+ prepend_zero = 1;
+ nbytes = (nbits + 7) / 8;
+ nlimbs = (nbytes + BYTES_PER_MPI_LIMB - 1) / BYTES_PER_MPI_LIMB;
+ if (val->alloced < nlimbs)
+ if (!mpi_resize(val, nlimbs))
+ return -ENOMEM;
+ i = BYTES_PER_MPI_LIMB - nbytes % BYTES_PER_MPI_LIMB;
+ i %= BYTES_PER_MPI_LIMB;
+ j = val->nlimbs = nlimbs;
+ val->sign = sign;
+ for (; j > 0; j--) {
+ a = 0;
+ for (; i < BYTES_PER_MPI_LIMB; i++) {
+ if (prepend_zero) {
+ c1 = '0';
+ prepend_zero = 0;
+ } else
+ c1 = *str++;
+ assert(c1);
+ c2 = *str++;
+ assert(c2);
+ if (c1 >= '0' && c1 <= '9')
+ c = c1 - '0';
+ else if (c1 >= 'a' && c1 <= 'f')
+ c = c1 - 'a' + 10;
+ else if (c1 >= 'A' && c1 <= 'F')
+ c = c1 - 'A' + 10;
+ else {
+ mpi_clear(val);
+ return 1;
+ }
+ c <<= 4;
+ if (c2 >= '0' && c2 <= '9')
+ c |= c2 - '0';
+ else if (c2 >= 'a' && c2 <= 'f')
+ c |= c2 - 'a' + 10;
+ else if (c2 >= 'A' && c2 <= 'F')
+ c |= c2 - 'A' + 10;
+ else {
+ mpi_clear(val);
+ return 1;
+ }
+ a <<= 8;
+ a |= c;
+ }
+ i = 0;
+
+ val->d[j - 1] = a;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(mpi_fromstr);
+
+/****************
+ * Special function to get the low 8 bytes from an mpi.
+ * This can be used as a keyid; KEYID is an 2 element array.
+ * Return the low 4 bytes.
+ */
+u32 mpi_get_keyid(const MPI a, u32 *keyid)
+{
+#if BYTES_PER_MPI_LIMB == 4
+ if (keyid) {
+ keyid[0] = a->nlimbs >= 2 ? a->d[1] : 0;
+ keyid[1] = a->nlimbs >= 1 ? a->d[0] : 0;
+ }
+ return a->nlimbs >= 1 ? a->d[0] : 0;
+#elif BYTES_PER_MPI_LIMB == 8
+ if (keyid) {
+ keyid[0] = a->nlimbs ? (u32) (a->d[0] >> 32) : 0;
+ keyid[1] = a->nlimbs ? (u32) (a->d[0] & 0xffffffff) : 0;
+ }
+ return a->nlimbs ? (u32) (a->d[0] & 0xffffffff) : 0;
+#else
+#error Make this function work with other LIMB sizes
+#endif
+}
+
+/****************
+ * Return an allocated buffer with the MPI (msb first).
+ * NBYTES receives the length of this buffer. Caller must free the
+ * return string (This function does return a 0 byte buffer with NBYTES
+ * set to zero if the value of A is zero. If sign is not NULL, it will
+ * be set to the sign of the A.
+ */
+void *mpi_get_buffer(MPI a, unsigned *nbytes, int *sign)
+{
+ uint8_t *p, *buffer;
+ mpi_limb_t alimb;
+ int i;
+ unsigned int n;
+
+ if (sign)
+ *sign = a->sign;
+ *nbytes = n = a->nlimbs * BYTES_PER_MPI_LIMB;
+ if (!n)
+ n++; /* avoid zero length allocation */
+ p = buffer = kmalloc(n, GFP_KERNEL);
+
+ for (i = a->nlimbs - 1; i >= 0; i--) {
+ alimb = a->d[i];
+#if BYTES_PER_MPI_LIMB == 4
+ *p++ = alimb >> 24;
+ *p++ = alimb >> 16;
+ *p++ = alimb >> 8;
+ *p++ = alimb;
+#elif BYTES_PER_MPI_LIMB == 8
+ *p++ = alimb >> 56;
+ *p++ = alimb >> 48;
+ *p++ = alimb >> 40;
+ *p++ = alimb >> 32;
+ *p++ = alimb >> 24;
+ *p++ = alimb >> 16;
+ *p++ = alimb >> 8;
+ *p++ = alimb;
+#else
+#error please implement for this limb size.
+#endif
+ }
+
+ /* this is sub-optimal but we need to do the shift operation
+ * because the caller has to free the returned buffer */
+ for (p = buffer; !*p && *nbytes; p++, --*nbytes)
+ ;
+ if (p != buffer)
+ memmove(buffer, p, *nbytes);
+
+ return buffer;
+}
+EXPORT_SYMBOL_GPL(mpi_get_buffer);
+
+/****************
+ * Use BUFFER to update MPI.
+ */
+int mpi_set_buffer(MPI a, const void *xbuffer, unsigned nbytes, int sign)
+{
+ const uint8_t *buffer = xbuffer, *p;
+ mpi_limb_t alimb;
+ int nlimbs;
+ int i;
+
+ nlimbs = (nbytes + BYTES_PER_MPI_LIMB - 1) / BYTES_PER_MPI_LIMB;
+ if (RESIZE_IF_NEEDED(a, nlimbs) < 0)
+ return -ENOMEM;
+ a->sign = sign;
+
+ for (i = 0, p = buffer + nbytes - 1; p >= buffer + BYTES_PER_MPI_LIMB;) {
+#if BYTES_PER_MPI_LIMB == 4
+ alimb = (mpi_limb_t) *p--;
+ alimb |= (mpi_limb_t) *p-- << 8;
+ alimb |= (mpi_limb_t) *p-- << 16;
+ alimb |= (mpi_limb_t) *p-- << 24;
+#elif BYTES_PER_MPI_LIMB == 8
+ alimb = (mpi_limb_t) *p--;
+ alimb |= (mpi_limb_t) *p-- << 8;
+ alimb |= (mpi_limb_t) *p-- << 16;
+ alimb |= (mpi_limb_t) *p-- << 24;
+ alimb |= (mpi_limb_t) *p-- << 32;
+ alimb |= (mpi_limb_t) *p-- << 40;
+ alimb |= (mpi_limb_t) *p-- << 48;
+ alimb |= (mpi_limb_t) *p-- << 56;
+#else
+#error please implement for this limb size.
+#endif
+ a->d[i++] = alimb;
+ }
+ if (p >= buffer) {
+#if BYTES_PER_MPI_LIMB == 4
+ alimb = *p--;
+ if (p >= buffer)
+ alimb |= (mpi_limb_t) *p-- << 8;
+ if (p >= buffer)
+ alimb |= (mpi_limb_t) *p-- << 16;
+ if (p >= buffer)
+ alimb |= (mpi_limb_t) *p-- << 24;
+#elif BYTES_PER_MPI_LIMB == 8
+ alimb = (mpi_limb_t) *p--;
+ if (p >= buffer)
+ alimb |= (mpi_limb_t) *p-- << 8;
+ if (p >= buffer)
+ alimb |= (mpi_limb_t) *p-- << 16;
+ if (p >= buffer)
+ alimb |= (mpi_limb_t) *p-- << 24;
+ if (p >= buffer)
+ alimb |= (mpi_limb_t) *p-- << 32;
+ if (p >= buffer)
+ alimb |= (mpi_limb_t) *p-- << 40;
+ if (p >= buffer)
+ alimb |= (mpi_limb_t) *p-- << 48;
+ if (p >= buffer)
+ alimb |= (mpi_limb_t) *p-- << 56;
+#else
+#error please implement for this limb size.
+#endif
+ a->d[i++] = alimb;
+ }
+ a->nlimbs = i;
+
+ if (i != nlimbs) {
+ pr_emerg("MPI: mpi_set_buffer: Assertion failed (%d != %d)", i,
+ nlimbs);
+ BUG();
+ }
+ return 0;
+}
+EXPORT_SYMBOL_GPL(mpi_set_buffer);
diff --git a/lib/mpi/mpih-cmp.c b/lib/mpi/mpih-cmp.c
new file mode 100644
index 0000000..b2fd396
--- /dev/null
+++ b/lib/mpi/mpih-cmp.c
@@ -0,0 +1,56 @@
+/* mpihelp-sub.c - MPI helper functions
+ * Copyright (C) 1994, 1996 Free Software Foundation, Inc.
+ * Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+ *
+ * This file is part of GnuPG.
+ *
+ * GnuPG 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.
+ *
+ * GnuPG 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ * The GNU MP Library itself is published under the LGPL;
+ * however I decided to publish this code under the plain GPL.
+ */
+
+#include "mpi-internal.h"
+
+/****************
+ * Compare OP1_PTR/OP1_SIZE with OP2_PTR/OP2_SIZE.
+ * There are no restrictions on the relative sizes of
+ * the two arguments.
+ * Return 1 if OP1 > OP2, 0 if they are equal, and -1 if OP1 < OP2.
+ */
+int mpihelp_cmp(mpi_ptr_t op1_ptr, mpi_ptr_t op2_ptr, mpi_size_t size)
+{
+ mpi_size_t i;
+ mpi_limb_t op1_word, op2_word;
+
+ for (i = size - 1; i >= 0; i--) {
+ op1_word = op1_ptr[i];
+ op2_word = op2_ptr[i];
+ if (op1_word != op2_word)
+ goto diff;
+ }
+ return 0;
+
+diff:
+ /* This can *not* be simplified to
+ * op2_word - op2_word
+ * since that expression might give signed overflow. */
+ return (op1_word > op2_word) ? 1 : -1;
+}
diff --git a/lib/mpi/mpih-div.c b/lib/mpi/mpih-div.c
new file mode 100644
index 0000000..87ede16
--- /dev/null
+++ b/lib/mpi/mpih-div.c
@@ -0,0 +1,541 @@
+/* mpihelp-div.c - MPI helper functions
+ * Copyright (C) 1994, 1996 Free Software Foundation, Inc.
+ * Copyright (C) 1998, 1999 Free Software Foundation, Inc.
+ *
+ * This file is part of GnuPG.
+ *
+ * GnuPG 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.
+ *
+ * GnuPG 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ * The GNU MP Library itself is published under the LGPL;
+ * however I decided to publish this code under the plain GPL.
+ */
+
+#include "mpi-internal.h"
+#include "longlong.h"
+
+#ifndef UMUL_TIME
+#define UMUL_TIME 1
+#endif
+#ifndef UDIV_TIME
+#define UDIV_TIME UMUL_TIME
+#endif
+
+/* FIXME: We should be using invert_limb (or invert_normalized_limb)
+ * here (not udiv_qrnnd).
+ */
+
+mpi_limb_t
+mpihelp_mod_1(mpi_ptr_t dividend_ptr, mpi_size_t dividend_size,
+ mpi_limb_t divisor_limb)
+{
+ mpi_size_t i;
+ mpi_limb_t n1, n0, r;
+ int dummy;
+
+ /* Botch: Should this be handled at all? Rely on callers? */
+ if (!dividend_size)
+ return 0;
+
+ /* If multiplication is much faster than division, and the
+ * dividend is large, pre-invert the divisor, and use
+ * only multiplications in the inner loop.
+ *
+ * This test should be read:
+ * Does it ever help to use udiv_qrnnd_preinv?
+ * && Does what we save compensate for the inversion overhead?
+ */
+ if (UDIV_TIME > (2 * UMUL_TIME + 6)
+ && (UDIV_TIME - (2 * UMUL_TIME + 6)) * dividend_size > UDIV_TIME) {
+ int normalization_steps;
+
+ count_leading_zeros(normalization_steps, divisor_limb);
+ if (normalization_steps) {
+ mpi_limb_t divisor_limb_inverted;
+
+ divisor_limb <<= normalization_steps;
+
+ /* Compute (2**2N - 2**N * DIVISOR_LIMB) / DIVISOR_LIMB. The
+ * result is a (N+1)-bit approximation to 1/DIVISOR_LIMB, with the
+ * most significant bit (with weight 2**N) implicit.
+ *
+ * Special case for DIVISOR_LIMB == 100...000.
+ */
+ if (!(divisor_limb << 1))
+ divisor_limb_inverted = ~(mpi_limb_t) 0;
+ else
+ udiv_qrnnd(divisor_limb_inverted, dummy,
+ -divisor_limb, 0, divisor_limb);
+
+ n1 = dividend_ptr[dividend_size - 1];
+ r = n1 >> (BITS_PER_MPI_LIMB - normalization_steps);
+
+ /* Possible optimization:
+ * if (r == 0
+ * && divisor_limb > ((n1 << normalization_steps)
+ * | (dividend_ptr[dividend_size - 2] >> ...)))
+ * ...one division less...
+ */
+ for (i = dividend_size - 2; i >= 0; i--) {
+ n0 = dividend_ptr[i];
+ UDIV_QRNND_PREINV(dummy, r, r,
+ ((n1 << normalization_steps)
+ | (n0 >>
+ (BITS_PER_MPI_LIMB -
+ normalization_steps))),
+ divisor_limb,
+ divisor_limb_inverted);
+ n1 = n0;
+ }
+ UDIV_QRNND_PREINV(dummy, r, r,
+ n1 << normalization_steps,
+ divisor_limb, divisor_limb_inverted);
+ return r >> normalization_steps;
+ } else {
+ mpi_limb_t divisor_limb_inverted;
+
+ /* Compute (2**2N - 2**N * DIVISOR_LIMB) / DIVISOR_LIMB. The
+ * result is a (N+1)-bit approximation to 1/DIVISOR_LIMB, with the
+ * most significant bit (with weight 2**N) implicit.
+ *
+ * Special case for DIVISOR_LIMB == 100...000.
+ */
+ if (!(divisor_limb << 1))
+ divisor_limb_inverted = ~(mpi_limb_t) 0;
+ else
+ udiv_qrnnd(divisor_limb_inverted, dummy,
+ -divisor_limb, 0, divisor_limb);
+
+ i = dividend_size - 1;
+ r = dividend_ptr[i];
+
+ if (r >= divisor_limb)
+ r = 0;
+ else
+ i--;
+
+ for (; i >= 0; i--) {
+ n0 = dividend_ptr[i];
+ UDIV_QRNND_PREINV(dummy, r, r,
+ n0, divisor_limb,
+ divisor_limb_inverted);
+ }
+ return r;
+ }
+ } else {
+ if (UDIV_NEEDS_NORMALIZATION) {
+ int normalization_steps;
+
+ count_leading_zeros(normalization_steps, divisor_limb);
+ if (normalization_steps) {
+ divisor_limb <<= normalization_steps;
+
+ n1 = dividend_ptr[dividend_size - 1];
+ r = n1 >> (BITS_PER_MPI_LIMB -
+ normalization_steps);
+
+ /* Possible optimization:
+ * if (r == 0
+ * && divisor_limb > ((n1 << normalization_steps)
+ * | (dividend_ptr[dividend_size - 2] >> ...)))
+ * ...one division less...
+ */
+ for (i = dividend_size - 2; i >= 0; i--) {
+ n0 = dividend_ptr[i];
+ udiv_qrnnd(dummy, r, r,
+ ((n1 << normalization_steps)
+ | (n0 >>
+ (BITS_PER_MPI_LIMB -
+ normalization_steps))),
+ divisor_limb);
+ n1 = n0;
+ }
+ udiv_qrnnd(dummy, r, r,
+ n1 << normalization_steps,
+ divisor_limb);
+ return r >> normalization_steps;
+ }
+ }
+ /* No normalization needed, either because udiv_qrnnd doesn't require
+ * it, or because DIVISOR_LIMB is already normalized. */
+ i = dividend_size - 1;
+ r = dividend_ptr[i];
+
+ if (r >= divisor_limb)
+ r = 0;
+ else
+ i--;
+
+ for (; i >= 0; i--) {
+ n0 = dividend_ptr[i];
+ udiv_qrnnd(dummy, r, r, n0, divisor_limb);
+ }
+ return r;
+ }
+}
+
+/* Divide num (NP/NSIZE) by den (DP/DSIZE) and write
+ * the NSIZE-DSIZE least significant quotient limbs at QP
+ * and the DSIZE long remainder at NP. If QEXTRA_LIMBS is
+ * non-zero, generate that many fraction bits and append them after the
+ * other quotient limbs.
+ * Return the most significant limb of the quotient, this is always 0 or 1.
+ *
+ * Preconditions:
+ * 0. NSIZE >= DSIZE.
+ * 1. The most significant bit of the divisor must be set.
+ * 2. QP must either not overlap with the input operands at all, or
+ * QP + DSIZE >= NP must hold true. (This means that it's
+ * possible to put the quotient in the high part of NUM, right after the
+ * remainder in NUM.
+ * 3. NSIZE >= DSIZE, even if QEXTRA_LIMBS is non-zero.
+ */
+
+mpi_limb_t
+mpihelp_divrem(mpi_ptr_t qp, mpi_size_t qextra_limbs,
+ mpi_ptr_t np, mpi_size_t nsize, mpi_ptr_t dp, mpi_size_t dsize)
+{
+ mpi_limb_t most_significant_q_limb = 0;
+
+ switch (dsize) {
+ case 0:
+ /* We are asked to divide by zero, so go ahead and do it! (To make
+ the compiler not remove this statement, return the value.) */
+ return 1 / dsize;
+
+ case 1:
+ {
+ mpi_size_t i;
+ mpi_limb_t n1;
+ mpi_limb_t d;
+
+ d = dp[0];
+ n1 = np[nsize - 1];
+
+ if (n1 >= d) {
+ n1 -= d;
+ most_significant_q_limb = 1;
+ }
+
+ qp += qextra_limbs;
+ for (i = nsize - 2; i >= 0; i--)
+ udiv_qrnnd(qp[i], n1, n1, np[i], d);
+ qp -= qextra_limbs;
+
+ for (i = qextra_limbs - 1; i >= 0; i--)
+ udiv_qrnnd(qp[i], n1, n1, 0, d);
+
+ np[0] = n1;
+ }
+ break;
+
+ case 2:
+ {
+ mpi_size_t i;
+ mpi_limb_t n1, n0, n2;
+ mpi_limb_t d1, d0;
+
+ np += nsize - 2;
+ d1 = dp[1];
+ d0 = dp[0];
+ n1 = np[1];
+ n0 = np[0];
+
+ if (n1 >= d1 && (n1 > d1 || n0 >= d0)) {
+ sub_ddmmss(n1, n0, n1, n0, d1, d0);
+ most_significant_q_limb = 1;
+ }
+
+ for (i = qextra_limbs + nsize - 2 - 1; i >= 0; i--) {
+ mpi_limb_t q;
+ mpi_limb_t r;
+
+ if (i >= qextra_limbs)
+ np--;
+ else
+ np[0] = 0;
+
+ if (n1 == d1) {
+ /* Q should be either 111..111 or 111..110. Need special
+ * treatment of this rare case as normal division would
+ * give overflow. */
+ q = ~(mpi_limb_t) 0;
+
+ r = n0 + d1;
+ if (r < d1) { /* Carry in the addition? */
+ add_ssaaaa(n1, n0, r - d0,
+ np[0], 0, d0);
+ qp[i] = q;
+ continue;
+ }
+ n1 = d0 - (d0 != 0 ? 1 : 0);
+ n0 = -d0;
+ } else {
+ udiv_qrnnd(q, r, n1, n0, d1);
+ umul_ppmm(n1, n0, d0, q);
+ }
+
+ n2 = np[0];
+q_test:
+ if (n1 > r || (n1 == r && n0 > n2)) {
+ /* The estimated Q was too large. */
+ q--;
+ sub_ddmmss(n1, n0, n1, n0, 0, d0);
+ r += d1;
+ if (r >= d1) /* If not carry, test Q again. */
+ goto q_test;
+ }
+
+ qp[i] = q;
+ sub_ddmmss(n1, n0, r, n2, n1, n0);
+ }
+ np[1] = n1;
+ np[0] = n0;
+ }
+ break;
+
+ default:
+ {
+ mpi_size_t i;
+ mpi_limb_t dX, d1, n0;
+
+ np += nsize - dsize;
+ dX = dp[dsize - 1];
+ d1 = dp[dsize - 2];
+ n0 = np[dsize - 1];
+
+ if (n0 >= dX) {
+ if (n0 > dX
+ || mpihelp_cmp(np, dp, dsize - 1) >= 0) {
+ mpihelp_sub_n(np, np, dp, dsize);
+ n0 = np[dsize - 1];
+ most_significant_q_limb = 1;
+ }
+ }
+
+ for (i = qextra_limbs + nsize - dsize - 1; i >= 0; i--) {
+ mpi_limb_t q;
+ mpi_limb_t n1, n2;
+ mpi_limb_t cy_limb;
+
+ if (i >= qextra_limbs) {
+ np--;
+ n2 = np[dsize];
+ } else {
+ n2 = np[dsize - 1];
+ MPN_COPY_DECR(np + 1, np, dsize - 1);
+ np[0] = 0;
+ }
+
+ if (n0 == dX) {
+ /* This might over-estimate q, but it's probably not worth
+ * the extra code here to find out. */
+ q = ~(mpi_limb_t) 0;
+ } else {
+ mpi_limb_t r;
+
+ udiv_qrnnd(q, r, n0, np[dsize - 1], dX);
+ umul_ppmm(n1, n0, d1, q);
+
+ while (n1 > r
+ || (n1 == r
+ && n0 > np[dsize - 2])) {
+ q--;
+ r += dX;
+ if (r < dX) /* I.e. "carry in previous addition?" */
+ break;
+ n1 -= n0 < d1;
+ n0 -= d1;
+ }
+ }
+
+ /* Possible optimization: We already have (q * n0) and (1 * n1)
+ * after the calculation of q. Taking advantage of that, we
+ * could make this loop make two iterations less. */
+ cy_limb = mpihelp_submul_1(np, dp, dsize, q);
+
+ if (n2 != cy_limb) {
+ mpihelp_add_n(np, np, dp, dsize);
+ q--;
+ }
+
+ qp[i] = q;
+ n0 = np[dsize - 1];
+ }
+ }
+ }
+
+ return most_significant_q_limb;
+}
+
+/****************
+ * Divide (DIVIDEND_PTR,,DIVIDEND_SIZE) by DIVISOR_LIMB.
+ * Write DIVIDEND_SIZE limbs of quotient at QUOT_PTR.
+ * Return the single-limb remainder.
+ * There are no constraints on the value of the divisor.
+ *
+ * QUOT_PTR and DIVIDEND_PTR might point to the same limb.
+ */
+
+mpi_limb_t
+mpihelp_divmod_1(mpi_ptr_t quot_ptr,
+ mpi_ptr_t dividend_ptr, mpi_size_t dividend_size,
+ mpi_limb_t divisor_limb)
+{
+ mpi_size_t i;
+ mpi_limb_t n1, n0, r;
+ int dummy;
+
+ if (!dividend_size)
+ return 0;
+
+ /* If multiplication is much faster than division, and the
+ * dividend is large, pre-invert the divisor, and use
+ * only multiplications in the inner loop.
+ *
+ * This test should be read:
+ * Does it ever help to use udiv_qrnnd_preinv?
+ * && Does what we save compensate for the inversion overhead?
+ */
+ if (UDIV_TIME > (2 * UMUL_TIME + 6)
+ && (UDIV_TIME - (2 * UMUL_TIME + 6)) * dividend_size > UDIV_TIME) {
+ int normalization_steps;
+
+ count_leading_zeros(normalization_steps, divisor_limb);
+ if (normalization_steps) {
+ mpi_limb_t divisor_limb_inverted;
+
+ divisor_limb <<= normalization_steps;
+
+ /* Compute (2**2N - 2**N * DIVISOR_LIMB) / DIVISOR_LIMB. The
+ * result is a (N+1)-bit approximation to 1/DIVISOR_LIMB, with the
+ * most significant bit (with weight 2**N) implicit.
+ */
+ /* Special case for DIVISOR_LIMB == 100...000. */
+ if (!(divisor_limb << 1))
+ divisor_limb_inverted = ~(mpi_limb_t) 0;
+ else
+ udiv_qrnnd(divisor_limb_inverted, dummy,
+ -divisor_limb, 0, divisor_limb);
+
+ n1 = dividend_ptr[dividend_size - 1];
+ r = n1 >> (BITS_PER_MPI_LIMB - normalization_steps);
+
+ /* Possible optimization:
+ * if (r == 0
+ * && divisor_limb > ((n1 << normalization_steps)
+ * | (dividend_ptr[dividend_size - 2] >> ...)))
+ * ...one division less...
+ */
+ for (i = dividend_size - 2; i >= 0; i--) {
+ n0 = dividend_ptr[i];
+ UDIV_QRNND_PREINV(quot_ptr[i + 1], r, r,
+ ((n1 << normalization_steps)
+ | (n0 >>
+ (BITS_PER_MPI_LIMB -
+ normalization_steps))),
+ divisor_limb,
+ divisor_limb_inverted);
+ n1 = n0;
+ }
+ UDIV_QRNND_PREINV(quot_ptr[0], r, r,
+ n1 << normalization_steps,
+ divisor_limb, divisor_limb_inverted);
+ return r >> normalization_steps;
+ } else {
+ mpi_limb_t divisor_limb_inverted;
+
+ /* Compute (2**2N - 2**N * DIVISOR_LIMB) / DIVISOR_LIMB. The
+ * result is a (N+1)-bit approximation to 1/DIVISOR_LIMB, with the
+ * most significant bit (with weight 2**N) implicit.
+ */
+ /* Special case for DIVISOR_LIMB == 100...000. */
+ if (!(divisor_limb << 1))
+ divisor_limb_inverted = ~(mpi_limb_t) 0;
+ else
+ udiv_qrnnd(divisor_limb_inverted, dummy,
+ -divisor_limb, 0, divisor_limb);
+
+ i = dividend_size - 1;
+ r = dividend_ptr[i];
+
+ if (r >= divisor_limb)
+ r = 0;
+ else
+ quot_ptr[i--] = 0;
+
+ for (; i >= 0; i--) {
+ n0 = dividend_ptr[i];
+ UDIV_QRNND_PREINV(quot_ptr[i], r, r,
+ n0, divisor_limb,
+ divisor_limb_inverted);
+ }
+ return r;
+ }
+ } else {
+ if (UDIV_NEEDS_NORMALIZATION) {
+ int normalization_steps;
+
+ count_leading_zeros(normalization_steps, divisor_limb);
+ if (normalization_steps) {
+ divisor_limb <<= normalization_steps;
+
+ n1 = dividend_ptr[dividend_size - 1];
+ r = n1 >> (BITS_PER_MPI_LIMB -
+ normalization_steps);
+
+ /* Possible optimization:
+ * if (r == 0
+ * && divisor_limb > ((n1 << normalization_steps)
+ * | (dividend_ptr[dividend_size - 2] >> ...)))
+ * ...one division less...
+ */
+ for (i = dividend_size - 2; i >= 0; i--) {
+ n0 = dividend_ptr[i];
+ udiv_qrnnd(quot_ptr[i + 1], r, r,
+ ((n1 << normalization_steps)
+ | (n0 >>
+ (BITS_PER_MPI_LIMB -
+ normalization_steps))),
+ divisor_limb);
+ n1 = n0;
+ }
+ udiv_qrnnd(quot_ptr[0], r, r,
+ n1 << normalization_steps,
+ divisor_limb);
+ return r >> normalization_steps;
+ }
+ }
+ /* No normalization needed, either because udiv_qrnnd doesn't require
+ * it, or because DIVISOR_LIMB is already normalized. */
+ i = dividend_size - 1;
+ r = dividend_ptr[i];
+
+ if (r >= divisor_limb)
+ r = 0;
+ else
+ quot_ptr[i--] = 0;
+
+ for (; i >= 0; i--) {
+ n0 = dividend_ptr[i];
+ udiv_qrnnd(quot_ptr[i], r, r, n0, divisor_limb);
+ }
+ return r;
+ }
+}
diff --git a/lib/mpi/mpih-mul.c b/lib/mpi/mpih-mul.c
new file mode 100644
index 0000000..c69c5ee
--- /dev/null
+++ b/lib/mpi/mpih-mul.c
@@ -0,0 +1,527 @@
+/* mpihelp-mul.c - MPI helper functions
+ * Copyright (C) 1994, 1996, 1998, 1999,
+ * 2000 Free Software Foundation, Inc.
+ *
+ * This file is part of GnuPG.
+ *
+ * GnuPG 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.
+ *
+ * GnuPG 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ * The GNU MP Library itself is published under the LGPL;
+ * however I decided to publish this code under the plain GPL.
+ */
+
+#include <linux/string.h>
+#include "mpi-internal.h"
+#include "longlong.h"
+
+#define MPN_MUL_N_RECURSE(prodp, up, vp, size, tspace) \
+ do { \
+ if ((size) < KARATSUBA_THRESHOLD) \
+ mul_n_basecase(prodp, up, vp, size); \
+ else \
+ mul_n(prodp, up, vp, size, tspace); \
+ } while (0);
+
+#define MPN_SQR_N_RECURSE(prodp, up, size, tspace) \
+ do { \
+ if ((size) < KARATSUBA_THRESHOLD) \
+ mpih_sqr_n_basecase(prodp, up, size); \
+ else \
+ mpih_sqr_n(prodp, up, size, tspace); \
+ } while (0);
+
+/* Multiply the natural numbers u (pointed to by UP) and v (pointed to by VP),
+ * both with SIZE limbs, and store the result at PRODP. 2 * SIZE limbs are
+ * always stored. Return the most significant limb.
+ *
+ * Argument constraints:
+ * 1. PRODP != UP and PRODP != VP, i.e. the destination
+ * must be distinct from the multiplier and the multiplicand.
+ *
+ *
+ * Handle simple cases with traditional multiplication.
+ *
+ * This is the most critical code of multiplication. All multiplies rely
+ * on this, both small and huge. Small ones arrive here immediately. Huge
+ * ones arrive here as this is the base case for Karatsuba's recursive
+ * algorithm below.
+ */
+
+static mpi_limb_t
+mul_n_basecase(mpi_ptr_t prodp, mpi_ptr_t up, mpi_ptr_t vp, mpi_size_t size)
+{
+ mpi_size_t i;
+ mpi_limb_t cy;
+ mpi_limb_t v_limb;
+
+ /* Multiply by the first limb in V separately, as the result can be
+ * stored (not added) to PROD. We also avoid a loop for zeroing. */
+ v_limb = vp[0];
+ if (v_limb <= 1) {
+ if (v_limb == 1)
+ MPN_COPY(prodp, up, size);
+ else
+ MPN_ZERO(prodp, size);
+ cy = 0;
+ } else
+ cy = mpihelp_mul_1(prodp, up, size, v_limb);
+
+ prodp[size] = cy;
+ prodp++;
+
+ /* For each iteration in the outer loop, multiply one limb from
+ * U with one limb from V, and add it to PROD. */
+ for (i = 1; i < size; i++) {
+ v_limb = vp[i];
+ if (v_limb <= 1) {
+ cy = 0;
+ if (v_limb == 1)
+ cy = mpihelp_add_n(prodp, prodp, up, size);
+ } else
+ cy = mpihelp_addmul_1(prodp, up, size, v_limb);
+
+ prodp[size] = cy;
+ prodp++;
+ }
+
+ return cy;
+}
+
+static void
+mul_n(mpi_ptr_t prodp, mpi_ptr_t up, mpi_ptr_t vp,
+ mpi_size_t size, mpi_ptr_t tspace)
+{
+ if (size & 1) {
+ /* The size is odd, and the code below doesn't handle that.
+ * Multiply the least significant (size - 1) limbs with a recursive
+ * call, and handle the most significant limb of S1 and S2
+ * separately.
+ * A slightly faster way to do this would be to make the Karatsuba
+ * code below behave as if the size were even, and let it check for
+ * odd size in the end. I.e., in essence move this code to the end.
+ * Doing so would save us a recursive call, and potentially make the
+ * stack grow a lot less.
+ */
+ mpi_size_t esize = size - 1; /* even size */
+ mpi_limb_t cy_limb;
+
+ MPN_MUL_N_RECURSE(prodp, up, vp, esize, tspace);
+ cy_limb = mpihelp_addmul_1(prodp + esize, up, esize, vp[esize]);
+ prodp[esize + esize] = cy_limb;
+ cy_limb = mpihelp_addmul_1(prodp + esize, vp, size, up[esize]);
+ prodp[esize + size] = cy_limb;
+ } else {
+ /* Anatolij Alekseevich Karatsuba's divide-and-conquer algorithm.
+ *
+ * Split U in two pieces, U1 and U0, such that
+ * U = U0 + U1*(B**n),
+ * and V in V1 and V0, such that
+ * V = V0 + V1*(B**n).
+ *
+ * UV is then computed recursively using the identity
+ *
+ * 2n n n n
+ * UV = (B + B )U V + B (U -U )(V -V ) + (B + 1)U V
+ * 1 1 1 0 0 1 0 0
+ *
+ * Where B = 2**BITS_PER_MP_LIMB.
+ */
+ mpi_size_t hsize = size >> 1;
+ mpi_limb_t cy;
+ int negflg;
+
+ /* Product H. ________________ ________________
+ * |_____U1 x V1____||____U0 x V0_____|
+ * Put result in upper part of PROD and pass low part of TSPACE
+ * as new TSPACE.
+ */
+ MPN_MUL_N_RECURSE(prodp + size, up + hsize, vp + hsize, hsize,
+ tspace);
+
+ /* Product M. ________________
+ * |_(U1-U0)(V0-V1)_|
+ */
+ if (mpihelp_cmp(up + hsize, up, hsize) >= 0) {
+ mpihelp_sub_n(prodp, up + hsize, up, hsize);
+ negflg = 0;
+ } else {
+ mpihelp_sub_n(prodp, up, up + hsize, hsize);
+ negflg = 1;
+ }
+ if (mpihelp_cmp(vp + hsize, vp, hsize) >= 0) {
+ mpihelp_sub_n(prodp + hsize, vp + hsize, vp, hsize);
+ negflg ^= 1;
+ } else {
+ mpihelp_sub_n(prodp + hsize, vp, vp + hsize, hsize);
+ /* No change of NEGFLG. */
+ }
+ /* Read temporary operands from low part of PROD.
+ * Put result in low part of TSPACE using upper part of TSPACE
+ * as new TSPACE.
+ */
+ MPN_MUL_N_RECURSE(tspace, prodp, prodp + hsize, hsize,
+ tspace + size);
+
+ /* Add/copy product H. */
+ MPN_COPY(prodp + hsize, prodp + size, hsize);
+ cy = mpihelp_add_n(prodp + size, prodp + size,
+ prodp + size + hsize, hsize);
+
+ /* Add product M (if NEGFLG M is a negative number) */
+ if (negflg)
+ cy -=
+ mpihelp_sub_n(prodp + hsize, prodp + hsize, tspace,
+ size);
+ else
+ cy +=
+ mpihelp_add_n(prodp + hsize, prodp + hsize, tspace,
+ size);
+
+ /* Product L. ________________ ________________
+ * |________________||____U0 x V0_____|
+ * Read temporary operands from low part of PROD.
+ * Put result in low part of TSPACE using upper part of TSPACE
+ * as new TSPACE.
+ */
+ MPN_MUL_N_RECURSE(tspace, up, vp, hsize, tspace + size);
+
+ /* Add/copy Product L (twice) */
+
+ cy += mpihelp_add_n(prodp + hsize, prodp + hsize, tspace, size);
+ if (cy)
+ mpihelp_add_1(prodp + hsize + size,
+ prodp + hsize + size, hsize, cy);
+
+ MPN_COPY(prodp, tspace, hsize);
+ cy = mpihelp_add_n(prodp + hsize, prodp + hsize, tspace + hsize,
+ hsize);
+ if (cy)
+ mpihelp_add_1(prodp + size, prodp + size, size, 1);
+ }
+}
+
+void mpih_sqr_n_basecase(mpi_ptr_t prodp, mpi_ptr_t up, mpi_size_t size)
+{
+ mpi_size_t i;
+ mpi_limb_t cy_limb;
+ mpi_limb_t v_limb;
+
+ /* Multiply by the first limb in V separately, as the result can be
+ * stored (not added) to PROD. We also avoid a loop for zeroing. */
+ v_limb = up[0];
+ if (v_limb <= 1) {
+ if (v_limb == 1)
+ MPN_COPY(prodp, up, size);
+ else
+ MPN_ZERO(prodp, size);
+ cy_limb = 0;
+ } else
+ cy_limb = mpihelp_mul_1(prodp, up, size, v_limb);
+
+ prodp[size] = cy_limb;
+ prodp++;
+
+ /* For each iteration in the outer loop, multiply one limb from
+ * U with one limb from V, and add it to PROD. */
+ for (i = 1; i < size; i++) {
+ v_limb = up[i];
+ if (v_limb <= 1) {
+ cy_limb = 0;
+ if (v_limb == 1)
+ cy_limb = mpihelp_add_n(prodp, prodp, up, size);
+ } else
+ cy_limb = mpihelp_addmul_1(prodp, up, size, v_limb);
+
+ prodp[size] = cy_limb;
+ prodp++;
+ }
+}
+
+void
+mpih_sqr_n(mpi_ptr_t prodp, mpi_ptr_t up, mpi_size_t size, mpi_ptr_t tspace)
+{
+ if (size & 1) {
+ /* The size is odd, and the code below doesn't handle that.
+ * Multiply the least significant (size - 1) limbs with a recursive
+ * call, and handle the most significant limb of S1 and S2
+ * separately.
+ * A slightly faster way to do this would be to make the Karatsuba
+ * code below behave as if the size were even, and let it check for
+ * odd size in the end. I.e., in essence move this code to the end.
+ * Doing so would save us a recursive call, and potentially make the
+ * stack grow a lot less.
+ */
+ mpi_size_t esize = size - 1; /* even size */
+ mpi_limb_t cy_limb;
+
+ MPN_SQR_N_RECURSE(prodp, up, esize, tspace);
+ cy_limb = mpihelp_addmul_1(prodp + esize, up, esize, up[esize]);
+ prodp[esize + esize] = cy_limb;
+ cy_limb = mpihelp_addmul_1(prodp + esize, up, size, up[esize]);
+
+ prodp[esize + size] = cy_limb;
+ } else {
+ mpi_size_t hsize = size >> 1;
+ mpi_limb_t cy;
+
+ /* Product H. ________________ ________________
+ * |_____U1 x U1____||____U0 x U0_____|
+ * Put result in upper part of PROD and pass low part of TSPACE
+ * as new TSPACE.
+ */
+ MPN_SQR_N_RECURSE(prodp + size, up + hsize, hsize, tspace);
+
+ /* Product M. ________________
+ * |_(U1-U0)(U0-U1)_|
+ */
+ if (mpihelp_cmp(up + hsize, up, hsize) >= 0)
+ mpihelp_sub_n(prodp, up + hsize, up, hsize);
+ else
+ mpihelp_sub_n(prodp, up, up + hsize, hsize);
+
+ /* Read temporary operands from low part of PROD.
+ * Put result in low part of TSPACE using upper part of TSPACE
+ * as new TSPACE. */
+ MPN_SQR_N_RECURSE(tspace, prodp, hsize, tspace + size);
+
+ /* Add/copy product H */
+ MPN_COPY(prodp + hsize, prodp + size, hsize);
+ cy = mpihelp_add_n(prodp + size, prodp + size,
+ prodp + size + hsize, hsize);
+
+ /* Add product M (if NEGFLG M is a negative number). */
+ cy -= mpihelp_sub_n(prodp + hsize, prodp + hsize, tspace, size);
+
+ /* Product L. ________________ ________________
+ * |________________||____U0 x U0_____|
+ * Read temporary operands from low part of PROD.
+ * Put result in low part of TSPACE using upper part of TSPACE
+ * as new TSPACE. */
+ MPN_SQR_N_RECURSE(tspace, up, hsize, tspace + size);
+
+ /* Add/copy Product L (twice). */
+ cy += mpihelp_add_n(prodp + hsize, prodp + hsize, tspace, size);
+ if (cy)
+ mpihelp_add_1(prodp + hsize + size,
+ prodp + hsize + size, hsize, cy);
+
+ MPN_COPY(prodp, tspace, hsize);
+ cy = mpihelp_add_n(prodp + hsize, prodp + hsize, tspace + hsize,
+ hsize);
+ if (cy)
+ mpihelp_add_1(prodp + size, prodp + size, size, 1);
+ }
+}
+
+/* This should be made into an inline function in gmp.h. */
+int mpihelp_mul_n(mpi_ptr_t prodp, mpi_ptr_t up, mpi_ptr_t vp, mpi_size_t size)
+{
+ if (up == vp) {
+ if (size < KARATSUBA_THRESHOLD)
+ mpih_sqr_n_basecase(prodp, up, size);
+ else {
+ mpi_ptr_t tspace;
+ tspace = mpi_alloc_limb_space(2 * size);
+ if (!tspace)
+ return -ENOMEM;
+ mpih_sqr_n(prodp, up, size, tspace);
+ mpi_free_limb_space(tspace);
+ }
+ } else {
+ if (size < KARATSUBA_THRESHOLD)
+ mul_n_basecase(prodp, up, vp, size);
+ else {
+ mpi_ptr_t tspace;
+ tspace = mpi_alloc_limb_space(2 * size);
+ if (!tspace)
+ return -ENOMEM;
+ mul_n(prodp, up, vp, size, tspace);
+ mpi_free_limb_space(tspace);
+ }
+ }
+
+ return 0;
+}
+
+int
+mpihelp_mul_karatsuba_case(mpi_ptr_t prodp,
+ mpi_ptr_t up, mpi_size_t usize,
+ mpi_ptr_t vp, mpi_size_t vsize,
+ struct karatsuba_ctx *ctx)
+{
+ mpi_limb_t cy;
+
+ if (!ctx->tspace || ctx->tspace_size < vsize) {
+ if (ctx->tspace)
+ mpi_free_limb_space(ctx->tspace);
+ ctx->tspace = mpi_alloc_limb_space(2 * vsize);
+ if (!ctx->tspace)
+ return -ENOMEM;
+ ctx->tspace_size = vsize;
+ }
+
+ MPN_MUL_N_RECURSE(prodp, up, vp, vsize, ctx->tspace);
+
+ prodp += vsize;
+ up += vsize;
+ usize -= vsize;
+ if (usize >= vsize) {
+ if (!ctx->tp || ctx->tp_size < vsize) {
+ if (ctx->tp)
+ mpi_free_limb_space(ctx->tp);
+ ctx->tp = mpi_alloc_limb_space(2 * vsize);
+ if (!ctx->tp) {
+ if (ctx->tspace)
+ mpi_free_limb_space(ctx->tspace);
+ ctx->tspace = NULL;
+ return -ENOMEM;
+ }
+ ctx->tp_size = vsize;
+ }
+
+ do {
+ MPN_MUL_N_RECURSE(ctx->tp, up, vp, vsize, ctx->tspace);
+ cy = mpihelp_add_n(prodp, prodp, ctx->tp, vsize);
+ mpihelp_add_1(prodp + vsize, ctx->tp + vsize, vsize,
+ cy);
+ prodp += vsize;
+ up += vsize;
+ usize -= vsize;
+ } while (usize >= vsize);
+ }
+
+ if (usize) {
+ if (usize < KARATSUBA_THRESHOLD) {
+ mpi_limb_t tmp;
+ if (mpihelp_mul(ctx->tspace, vp, vsize, up, usize, &tmp)
+ < 0)
+ return -ENOMEM;
+ } else {
+ if (!ctx->next) {
+ ctx->next = kzalloc(sizeof *ctx, GFP_KERNEL);
+ if (!ctx->next)
+ return -ENOMEM;
+ }
+ if (mpihelp_mul_karatsuba_case(ctx->tspace,
+ vp, vsize,
+ up, usize,
+ ctx->next) < 0)
+ return -ENOMEM;
+ }
+
+ cy = mpihelp_add_n(prodp, prodp, ctx->tspace, vsize);
+ mpihelp_add_1(prodp + vsize, ctx->tspace + vsize, usize, cy);
+ }
+
+ return 0;
+}
+
+void mpihelp_release_karatsuba_ctx(struct karatsuba_ctx *ctx)
+{
+ struct karatsuba_ctx *ctx2;
+
+ if (ctx->tp)
+ mpi_free_limb_space(ctx->tp);
+ if (ctx->tspace)
+ mpi_free_limb_space(ctx->tspace);
+ for (ctx = ctx->next; ctx; ctx = ctx2) {
+ ctx2 = ctx->next;
+ if (ctx->tp)
+ mpi_free_limb_space(ctx->tp);
+ if (ctx->tspace)
+ mpi_free_limb_space(ctx->tspace);
+ kfree(ctx);
+ }
+}
+
+/* Multiply the natural numbers u (pointed to by UP, with USIZE limbs)
+ * and v (pointed to by VP, with VSIZE limbs), and store the result at
+ * PRODP. USIZE + VSIZE limbs are always stored, but if the input
+ * operands are normalized. Return the most significant limb of the
+ * result.
+ *
+ * NOTE: The space pointed to by PRODP is overwritten before finished
+ * with U and V, so overlap is an error.
+ *
+ * Argument constraints:
+ * 1. USIZE >= VSIZE.
+ * 2. PRODP != UP and PRODP != VP, i.e. the destination
+ * must be distinct from the multiplier and the multiplicand.
+ */
+
+int
+mpihelp_mul(mpi_ptr_t prodp, mpi_ptr_t up, mpi_size_t usize,
+ mpi_ptr_t vp, mpi_size_t vsize, mpi_limb_t *_result)
+{
+ mpi_ptr_t prod_endp = prodp + usize + vsize - 1;
+ mpi_limb_t cy;
+ struct karatsuba_ctx ctx;
+
+ if (vsize < KARATSUBA_THRESHOLD) {
+ mpi_size_t i;
+ mpi_limb_t v_limb;
+
+ if (!vsize) {
+ *_result = 0;
+ return 0;
+ }
+
+ /* Multiply by the first limb in V separately, as the result can be
+ * stored (not added) to PROD. We also avoid a loop for zeroing. */
+ v_limb = vp[0];
+ if (v_limb <= 1) {
+ if (v_limb == 1)
+ MPN_COPY(prodp, up, usize);
+ else
+ MPN_ZERO(prodp, usize);
+ cy = 0;
+ } else
+ cy = mpihelp_mul_1(prodp, up, usize, v_limb);
+
+ prodp[usize] = cy;
+ prodp++;
+
+ /* For each iteration in the outer loop, multiply one limb from
+ * U with one limb from V, and add it to PROD. */
+ for (i = 1; i < vsize; i++) {
+ v_limb = vp[i];
+ if (v_limb <= 1) {
+ cy = 0;
+ if (v_limb == 1)
+ cy = mpihelp_add_n(prodp, prodp, up,
+ usize);
+ } else
+ cy = mpihelp_addmul_1(prodp, up, usize, v_limb);
+
+ prodp[usize] = cy;
+ prodp++;
+ }
+
+ *_result = cy;
+ return 0;
+ }
+
+ memset(&ctx, 0, sizeof ctx);
+ if (mpihelp_mul_karatsuba_case(prodp, up, usize, vp, vsize, &ctx) < 0)
+ return -ENOMEM;
+ mpihelp_release_karatsuba_ctx(&ctx);
+ *_result = *prod_endp;
+ return 0;
+}
diff --git a/lib/mpi/mpiutil.c b/lib/mpi/mpiutil.c
new file mode 100644
index 0000000..eefc55d
--- /dev/null
+++ b/lib/mpi/mpiutil.c
@@ -0,0 +1,208 @@
+/* mpiutil.ac - Utility functions for MPI
+ * Copyright (C) 1998, 1999 Free Software Foundation, Inc.
+ *
+ * This file is part of GnuPG.
+ *
+ * GnuPG 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.
+ *
+ * GnuPG 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "mpi-internal.h"
+
+/****************
+ * Note: It was a bad idea to use the number of limbs to allocate
+ * because on a alpha the limbs are large but we normally need
+ * integers of n bits - So we should chnage this to bits (or bytes).
+ *
+ * But mpi_alloc is used in a lot of places :-)
+ */
+MPI mpi_alloc(unsigned nlimbs)
+{
+ MPI a;
+
+ a = kmalloc(sizeof *a, GFP_KERNEL);
+ if (!a)
+ return a;
+
+ if (nlimbs) {
+ a->d = mpi_alloc_limb_space(nlimbs);
+ if (!a->d) {
+ kfree(a);
+ return NULL;
+ }
+ } else {
+ a->d = NULL;
+ }
+
+ a->alloced = nlimbs;
+ a->nlimbs = 0;
+ a->sign = 0;
+ a->flags = 0;
+ a->nbits = 0;
+ return a;
+}
+EXPORT_SYMBOL_GPL(mpi_alloc);
+
+mpi_ptr_t mpi_alloc_limb_space(unsigned nlimbs)
+{
+ size_t len = nlimbs * sizeof(mpi_limb_t);
+
+ return kmalloc(len, GFP_KERNEL);
+}
+
+void mpi_free_limb_space(mpi_ptr_t a)
+{
+ if (!a)
+ return;
+
+ kfree(a);
+}
+
+void mpi_assign_limb_space(MPI a, mpi_ptr_t ap, unsigned nlimbs)
+{
+ mpi_free_limb_space(a->d);
+ a->d = ap;
+ a->alloced = nlimbs;
+}
+
+/****************
+ * Resize the array of A to NLIMBS. the additional space is cleared
+ * (set to 0) [done by m_realloc()]
+ */
+int mpi_resize(MPI a, unsigned nlimbs)
+{
+ void *p;
+
+ if (nlimbs <= a->alloced)
+ return 0; /* no need to do it */
+
+ if (a->d) {
+ p = kmalloc(nlimbs * sizeof(mpi_limb_t), GFP_KERNEL);
+ if (!p)
+ return -ENOMEM;
+ memcpy(p, a->d, a->alloced * sizeof(mpi_limb_t));
+ kfree(a->d);
+ a->d = p;
+ } else {
+ a->d = kzalloc(nlimbs * sizeof(mpi_limb_t), GFP_KERNEL);
+ if (!a->d)
+ return -ENOMEM;
+ }
+ a->alloced = nlimbs;
+ return 0;
+}
+
+void mpi_clear(MPI a)
+{
+ a->nlimbs = 0;
+ a->nbits = 0;
+ a->flags = 0;
+}
+
+void mpi_free(MPI a)
+{
+ if (!a)
+ return;
+
+ if (a->flags & 4)
+ kfree(a->d);
+ else
+ mpi_free_limb_space(a->d);
+
+ if (a->flags & ~7)
+ pr_info("invalid flag value in mpi\n");
+ kfree(a);
+}
+EXPORT_SYMBOL_GPL(mpi_free);
+
+/****************
+ * Note: This copy function should not interpret the MPI
+ * but copy it transparently.
+ */
+int mpi_copy(MPI *copied, const MPI a)
+{
+ size_t i;
+ MPI b;
+
+ *copied = MPI_NULL;
+
+ if (a) {
+ b = mpi_alloc(a->nlimbs);
+ if (!b)
+ return -ENOMEM;
+
+ b->nlimbs = a->nlimbs;
+ b->sign = a->sign;
+ b->flags = a->flags;
+ b->nbits = a->nbits;
+
+ for (i = 0; i < b->nlimbs; i++)
+ b->d[i] = a->d[i];
+
+ *copied = b;
+ }
+
+ return 0;
+}
+
+int mpi_set(MPI w, const MPI u)
+{
+ mpi_ptr_t wp, up;
+ mpi_size_t usize = u->nlimbs;
+ int usign = u->sign;
+
+ if (RESIZE_IF_NEEDED(w, (size_t) usize) < 0)
+ return -ENOMEM;
+
+ wp = w->d;
+ up = u->d;
+ MPN_COPY(wp, up, usize);
+ w->nlimbs = usize;
+ w->nbits = u->nbits;
+ w->flags = u->flags;
+ w->sign = usign;
+ return 0;
+}
+
+int mpi_set_ui(MPI w, unsigned long u)
+{
+ if (RESIZE_IF_NEEDED(w, 1) < 0)
+ return -ENOMEM;
+ w->d[0] = u;
+ w->nlimbs = u ? 1 : 0;
+ w->sign = 0;
+ w->nbits = 0;
+ w->flags = 0;
+ return 0;
+}
+
+MPI mpi_alloc_set_ui(unsigned long u)
+{
+ MPI w = mpi_alloc(1);
+ if (!w)
+ return w;
+ w->d[0] = u;
+ w->nlimbs = u ? 1 : 0;
+ w->sign = 0;
+ return w;
+}
+
+void mpi_swap(MPI a, MPI b)
+{
+ struct gcry_mpi tmp;
+
+ tmp = *a;
+ *a = *b;
+ *b = tmp;
+}
diff --git a/mm/debug-pagealloc.c b/mm/debug-pagealloc.c
index 7cea557..789ff70 100644
--- a/mm/debug-pagealloc.c
+++ b/mm/debug-pagealloc.c
@@ -95,9 +95,6 @@
void kernel_map_pages(struct page *page, int numpages, int enable)
{
- if (!debug_pagealloc_enabled)
- return;
-
if (enable)
unpoison_pages(page, numpages);
else
diff --git a/mm/slab.c b/mm/slab.c
index 2acfa0d..f0bd785 100644
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -481,11 +481,13 @@
#endif
/*
- * Do not go above this order unless 0 objects fit into the slab.
+ * Do not go above this order unless 0 objects fit into the slab or
+ * overridden on the command line.
*/
-#define BREAK_GFP_ORDER_HI 1
-#define BREAK_GFP_ORDER_LO 0
-static int slab_break_gfp_order = BREAK_GFP_ORDER_LO;
+#define SLAB_MAX_ORDER_HI 1
+#define SLAB_MAX_ORDER_LO 0
+static int slab_max_order = SLAB_MAX_ORDER_LO;
+static bool slab_max_order_set __initdata;
/*
* Functions for storing/retrieving the cachep and or slab from the page
@@ -854,6 +856,17 @@
}
__setup("noaliencache", noaliencache_setup);
+static int __init slab_max_order_setup(char *str)
+{
+ get_option(&str, &slab_max_order);
+ slab_max_order = slab_max_order < 0 ? 0 :
+ min(slab_max_order, MAX_ORDER - 1);
+ slab_max_order_set = true;
+
+ return 1;
+}
+__setup("slab_max_order=", slab_max_order_setup);
+
#ifdef CONFIG_NUMA
/*
* Special reaping functions for NUMA systems called from cache_reap().
@@ -1502,10 +1515,11 @@
/*
* Fragmentation resistance on low memory - only use bigger
- * page orders on machines with more than 32MB of memory.
+ * page orders on machines with more than 32MB of memory if
+ * not overridden on the command line.
*/
- if (totalram_pages > (32 << 20) >> PAGE_SHIFT)
- slab_break_gfp_order = BREAK_GFP_ORDER_HI;
+ if (!slab_max_order_set && totalram_pages > (32 << 20) >> PAGE_SHIFT)
+ slab_max_order = SLAB_MAX_ORDER_HI;
/* Bootstrap is tricky, because several objects are allocated
* from caches that do not exist yet:
@@ -1932,8 +1946,8 @@
/* Print header */
if (lines == 0) {
printk(KERN_ERR
- "Slab corruption: %s start=%p, len=%d\n",
- cachep->name, realobj, size);
+ "Slab corruption (%s): %s start=%p, len=%d\n",
+ print_tainted(), cachep->name, realobj, size);
print_objinfo(cachep, objp, 0);
}
/* Hexdump the affected line */
@@ -2117,7 +2131,7 @@
* Large number of objects is good, but very large slabs are
* currently bad for the gfp()s.
*/
- if (gfporder >= slab_break_gfp_order)
+ if (gfporder >= slab_max_order)
break;
/*
@@ -3042,8 +3056,9 @@
if (entries != cachep->num - slabp->inuse) {
bad:
printk(KERN_ERR "slab: Internal list corruption detected in "
- "cache '%s'(%d), slabp %p(%d). Hexdump:\n",
- cachep->name, cachep->num, slabp, slabp->inuse);
+ "cache '%s'(%d), slabp %p(%d). Tainted(%s). Hexdump:\n",
+ cachep->name, cachep->num, slabp, slabp->inuse,
+ print_tainted());
print_hex_dump(KERN_ERR, "", DUMP_PREFIX_OFFSET, 16, 1, slabp,
sizeof(*slabp) + cachep->num * sizeof(kmem_bufctl_t),
1);
diff --git a/mm/slub.c b/mm/slub.c
index d99acbf..5d37b5e4 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -570,7 +570,7 @@
va_end(args);
printk(KERN_ERR "========================================"
"=====================================\n");
- printk(KERN_ERR "BUG %s: %s\n", s->name, buf);
+ printk(KERN_ERR "BUG %s (%s): %s\n", s->name, print_tainted(), buf);
printk(KERN_ERR "----------------------------------------"
"-------------------------------------\n\n");
}
@@ -1901,11 +1901,14 @@
}
if (l != m) {
- if (l == M_PARTIAL)
+ if (l == M_PARTIAL) {
remove_partial(n, page);
- else
+ stat(s, FREE_REMOVE_PARTIAL);
+ } else {
add_partial(n, page,
DEACTIVATE_TO_TAIL);
+ stat(s, FREE_ADD_PARTIAL);
+ }
l = m;
}
@@ -2124,6 +2127,37 @@
}
/*
+ * Check the page->freelist of a page and either transfer the freelist to the per cpu freelist
+ * or deactivate the page.
+ *
+ * The page is still frozen if the return value is not NULL.
+ *
+ * If this function returns NULL then the page has been unfrozen.
+ */
+static inline void *get_freelist(struct kmem_cache *s, struct page *page)
+{
+ struct page new;
+ unsigned long counters;
+ void *freelist;
+
+ do {
+ freelist = page->freelist;
+ counters = page->counters;
+ new.counters = counters;
+ VM_BUG_ON(!new.frozen);
+
+ new.inuse = page->objects;
+ new.frozen = freelist != NULL;
+
+ } while (!cmpxchg_double_slab(s, page,
+ freelist, counters,
+ NULL, new.counters,
+ "get_freelist"));
+
+ return freelist;
+}
+
+/*
* Slow path. The lockless freelist is empty or we need to perform
* debugging duties.
*
@@ -2144,8 +2178,6 @@
{
void **object;
unsigned long flags;
- struct page new;
- unsigned long counters;
local_irq_save(flags);
#ifdef CONFIG_PREEMPT
@@ -2166,31 +2198,14 @@
goto new_slab;
}
+ /* must check again c->freelist in case of cpu migration or IRQ */
+ object = c->freelist;
+ if (object)
+ goto load_freelist;
+
stat(s, ALLOC_SLOWPATH);
- do {
- object = c->page->freelist;
- counters = c->page->counters;
- new.counters = counters;
- VM_BUG_ON(!new.frozen);
-
- /*
- * If there is no object left then we use this loop to
- * deactivate the slab which is simple since no objects
- * are left in the slab and therefore we do not need to
- * put the page back onto the partial list.
- *
- * If there are objects left then we retrieve them
- * and use them to refill the per cpu queue.
- */
-
- new.inuse = c->page->objects;
- new.frozen = object != NULL;
-
- } while (!__cmpxchg_double_slab(s, c->page,
- object, counters,
- NULL, new.counters,
- "__slab_alloc"));
+ object = get_freelist(s, c->page);
if (!object) {
c->page = NULL;
@@ -3028,7 +3043,9 @@
* per node list when we run out of per cpu objects. We only fetch 50%
* to keep some capacity around for frees.
*/
- if (s->size >= PAGE_SIZE)
+ if (kmem_cache_debug(s))
+ s->cpu_partial = 0;
+ else if (s->size >= PAGE_SIZE)
s->cpu_partial = 2;
else if (s->size >= 1024)
s->cpu_partial = 6;
@@ -4637,6 +4654,8 @@
err = strict_strtoul(buf, 10, &objects);
if (err)
return err;
+ if (objects && kmem_cache_debug(s))
+ return -EINVAL;
s->cpu_partial = objects;
flush_all(s);
diff --git a/security/apparmor/audit.c b/security/apparmor/audit.c
index 96502b2..f3fafed 100644
--- a/security/apparmor/audit.c
+++ b/security/apparmor/audit.c
@@ -133,7 +133,7 @@
struct aa_profile *profile = sa->aad.profile;
pid_t pid;
rcu_read_lock();
- pid = tsk->real_parent->pid;
+ pid = rcu_dereference(tsk->real_parent)->pid;
rcu_read_unlock();
audit_log_format(ab, " parent=%d", pid);
if (profile->ns != root_ns) {
diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
index 2c0a0ff..d7f06f8 100644
--- a/security/apparmor/lsm.c
+++ b/security/apparmor/lsm.c
@@ -670,7 +670,7 @@
static int param_set_aabool(const char *val, const struct kernel_param *kp);
static int param_get_aabool(char *buffer, const struct kernel_param *kp);
-#define param_check_aabool(name, p) __param_check(name, p, int)
+#define param_check_aabool param_check_bool
static struct kernel_param_ops param_ops_aabool = {
.set = param_set_aabool,
.get = param_get_aabool
@@ -678,7 +678,7 @@
static int param_set_aauint(const char *val, const struct kernel_param *kp);
static int param_get_aauint(char *buffer, const struct kernel_param *kp);
-#define param_check_aauint(name, p) __param_check(name, p, int)
+#define param_check_aauint param_check_uint
static struct kernel_param_ops param_ops_aauint = {
.set = param_set_aauint,
.get = param_get_aauint
@@ -686,7 +686,7 @@
static int param_set_aalockpolicy(const char *val, const struct kernel_param *kp);
static int param_get_aalockpolicy(char *buffer, const struct kernel_param *kp);
-#define param_check_aalockpolicy(name, p) __param_check(name, p, int)
+#define param_check_aalockpolicy param_check_bool
static struct kernel_param_ops param_ops_aalockpolicy = {
.set = param_set_aalockpolicy,
.get = param_get_aalockpolicy
diff --git a/security/inode.c b/security/inode.c
index 90a70a6..43ce6e1 100644
--- a/security/inode.c
+++ b/security/inode.c
@@ -25,100 +25,6 @@
static struct vfsmount *mount;
static int mount_count;
-/*
- * TODO:
- * I think I can get rid of these default_file_ops, but not quite sure...
- */
-static ssize_t default_read_file(struct file *file, char __user *buf,
- size_t count, loff_t *ppos)
-{
- return 0;
-}
-
-static ssize_t default_write_file(struct file *file, const char __user *buf,
- size_t count, loff_t *ppos)
-{
- return count;
-}
-
-static int default_open(struct inode *inode, struct file *file)
-{
- if (inode->i_private)
- file->private_data = inode->i_private;
-
- return 0;
-}
-
-static const struct file_operations default_file_ops = {
- .read = default_read_file,
- .write = default_write_file,
- .open = default_open,
- .llseek = noop_llseek,
-};
-
-static struct inode *get_inode(struct super_block *sb, umode_t mode, dev_t dev)
-{
- struct inode *inode = new_inode(sb);
-
- if (inode) {
- inode->i_ino = get_next_ino();
- inode->i_mode = mode;
- inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
- switch (mode & S_IFMT) {
- default:
- init_special_inode(inode, mode, dev);
- break;
- case S_IFREG:
- inode->i_fop = &default_file_ops;
- break;
- case S_IFDIR:
- inode->i_op = &simple_dir_inode_operations;
- inode->i_fop = &simple_dir_operations;
-
- /* directory inodes start off with i_nlink == 2 (for "." entry) */
- inc_nlink(inode);
- break;
- }
- }
- return inode;
-}
-
-/* SMP-safe */
-static int mknod(struct inode *dir, struct dentry *dentry,
- umode_t mode, dev_t dev)
-{
- struct inode *inode;
- int error = -ENOMEM;
-
- if (dentry->d_inode)
- return -EEXIST;
-
- inode = get_inode(dir->i_sb, mode, dev);
- if (inode) {
- d_instantiate(dentry, inode);
- dget(dentry);
- error = 0;
- }
- return error;
-}
-
-static int mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
-{
- int res;
-
- mode = (mode & (S_IRWXUGO | S_ISVTX)) | S_IFDIR;
- res = mknod(dir, dentry, mode, 0);
- if (!res)
- inc_nlink(dir);
- return res;
-}
-
-static int create(struct inode *dir, struct dentry *dentry, umode_t mode)
-{
- mode = (mode & S_IALLUGO) | S_IFREG;
- return mknod(dir, dentry, mode, 0);
-}
-
static inline int positive(struct dentry *dentry)
{
return dentry->d_inode && !d_unhashed(dentry);
@@ -145,38 +51,6 @@
.kill_sb = kill_litter_super,
};
-static int create_by_name(const char *name, umode_t mode,
- struct dentry *parent,
- struct dentry **dentry)
-{
- int error = 0;
-
- *dentry = NULL;
-
- /* If the parent is not specified, we create it in the root.
- * We need the root dentry to do this, which is in the super
- * block. A pointer to that is in the struct vfsmount that we
- * have around.
- */
- if (!parent)
- parent = mount->mnt_root;
-
- mutex_lock(&parent->d_inode->i_mutex);
- *dentry = lookup_one_len(name, parent, strlen(name));
- if (!IS_ERR(*dentry)) {
- if (S_ISDIR(mode))
- error = mkdir(parent->d_inode, *dentry, mode);
- else
- error = create(parent->d_inode, *dentry, mode);
- if (error)
- dput(*dentry);
- } else
- error = PTR_ERR(*dentry);
- mutex_unlock(&parent->d_inode->i_mutex);
-
- return error;
-}
-
/**
* securityfs_create_file - create a file in the securityfs filesystem
*
@@ -209,31 +83,66 @@
struct dentry *parent, void *data,
const struct file_operations *fops)
{
- struct dentry *dentry = NULL;
+ struct dentry *dentry;
+ int is_dir = S_ISDIR(mode);
+ struct inode *dir, *inode;
int error;
+ if (!is_dir) {
+ BUG_ON(!fops);
+ mode = (mode & S_IALLUGO) | S_IFREG;
+ }
+
pr_debug("securityfs: creating file '%s'\n",name);
error = simple_pin_fs(&fs_type, &mount, &mount_count);
- if (error) {
- dentry = ERR_PTR(error);
- goto exit;
- }
+ if (error)
+ return ERR_PTR(error);
- error = create_by_name(name, mode, parent, &dentry);
- if (error) {
- dentry = ERR_PTR(error);
- simple_release_fs(&mount, &mount_count);
- goto exit;
- }
+ if (!parent)
+ parent = mount->mnt_root;
+
+ dir = parent->d_inode;
+
+ mutex_lock(&dir->i_mutex);
+ dentry = lookup_one_len(name, parent, strlen(name));
+ if (IS_ERR(dentry))
+ goto out;
if (dentry->d_inode) {
- if (fops)
- dentry->d_inode->i_fop = fops;
- if (data)
- dentry->d_inode->i_private = data;
+ error = -EEXIST;
+ goto out1;
}
-exit:
+
+ inode = new_inode(dir->i_sb);
+ if (!inode) {
+ error = -ENOMEM;
+ goto out1;
+ }
+
+ inode->i_ino = get_next_ino();
+ inode->i_mode = mode;
+ inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
+ inode->i_private = data;
+ if (is_dir) {
+ inode->i_op = &simple_dir_inode_operations;
+ inode->i_fop = &simple_dir_operations;
+ inc_nlink(inode);
+ inc_nlink(dir);
+ } else {
+ inode->i_fop = fops;
+ }
+ d_instantiate(dentry, inode);
+ dget(dentry);
+ mutex_unlock(&dir->i_mutex);
+ return dentry;
+
+out1:
+ dput(dentry);
+ dentry = ERR_PTR(error);
+out:
+ mutex_unlock(&dir->i_mutex);
+ simple_release_fs(&mount, &mount_count);
return dentry;
}
EXPORT_SYMBOL_GPL(securityfs_create_file);
diff --git a/security/integrity/Kconfig b/security/integrity/Kconfig
index 4bf00ac..d384ea9 100644
--- a/security/integrity/Kconfig
+++ b/security/integrity/Kconfig
@@ -3,5 +3,19 @@
def_bool y
depends on IMA || EVM
+config INTEGRITY_DIGSIG
+ boolean "Digital signature verification using multiple keyrings"
+ depends on INTEGRITY && KEYS
+ default n
+ select DIGSIG
+ help
+ This option enables digital signature verification support
+ using multiple keyrings. It defines separate keyrings for each
+ of the different use cases - evm, ima, and modules.
+ Different keyrings improves search performance, but also allow
+ to "lock" certain keyring to prevent adding new keys.
+ This is useful for evm and module keyrings, when keys are
+ usually only added from initramfs.
+
source security/integrity/ima/Kconfig
source security/integrity/evm/Kconfig
diff --git a/security/integrity/Makefile b/security/integrity/Makefile
index 0ae44ae..bece056 100644
--- a/security/integrity/Makefile
+++ b/security/integrity/Makefile
@@ -3,6 +3,7 @@
#
obj-$(CONFIG_INTEGRITY) += integrity.o
+obj-$(CONFIG_INTEGRITY_DIGSIG) += digsig.o
integrity-y := iint.o
diff --git a/security/integrity/digsig.c b/security/integrity/digsig.c
new file mode 100644
index 0000000..2dc167d
--- /dev/null
+++ b/security/integrity/digsig.c
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2011 Intel Corporation
+ *
+ * Author:
+ * Dmitry Kasatkin <dmitry.kasatkin@intel.com>
+ *
+ * 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, version 2 of the License.
+ *
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/err.h>
+#include <linux/rbtree.h>
+#include <linux/key-type.h>
+#include <linux/digsig.h>
+
+#include "integrity.h"
+
+static struct key *keyring[INTEGRITY_KEYRING_MAX];
+
+static const char *keyring_name[INTEGRITY_KEYRING_MAX] = {
+ "_evm",
+ "_module",
+ "_ima",
+};
+
+int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen,
+ const char *digest, int digestlen)
+{
+ if (id >= INTEGRITY_KEYRING_MAX)
+ return -EINVAL;
+
+ if (!keyring[id]) {
+ keyring[id] =
+ request_key(&key_type_keyring, keyring_name[id], NULL);
+ if (IS_ERR(keyring[id])) {
+ int err = PTR_ERR(keyring[id]);
+ pr_err("no %s keyring: %d\n", keyring_name[id], err);
+ keyring[id] = NULL;
+ return err;
+ }
+ }
+
+ return digsig_verify(keyring[id], sig, siglen, digest, digestlen);
+}
diff --git a/security/integrity/evm/evm.h b/security/integrity/evm/evm.h
index d320f51..c885247 100644
--- a/security/integrity/evm/evm.h
+++ b/security/integrity/evm/evm.h
@@ -12,14 +12,21 @@
* File: evm.h
*
*/
+
+#ifndef __INTEGRITY_EVM_H
+#define __INTEGRITY_EVM_H
+
#include <linux/xattr.h>
#include <linux/security.h>
+
#include "../integrity.h"
extern int evm_initialized;
extern char *evm_hmac;
+extern char *evm_hash;
extern struct crypto_shash *hmac_tfm;
+extern struct crypto_shash *hash_tfm;
/* List of EVM protected security xattrs */
extern char *evm_config_xattrnames[];
@@ -32,7 +39,12 @@
extern int evm_calc_hmac(struct dentry *dentry, const char *req_xattr_name,
const char *req_xattr_value,
size_t req_xattr_value_len, char *digest);
+extern int evm_calc_hash(struct dentry *dentry, const char *req_xattr_name,
+ const char *req_xattr_value,
+ size_t req_xattr_value_len, char *digest);
extern int evm_init_hmac(struct inode *inode, const struct xattr *xattr,
char *hmac_val);
extern int evm_init_secfs(void);
extern void evm_cleanup_secfs(void);
+
+#endif
diff --git a/security/integrity/evm/evm_crypto.c b/security/integrity/evm/evm_crypto.c
index 8738def..49a464f 100644
--- a/security/integrity/evm/evm_crypto.c
+++ b/security/integrity/evm/evm_crypto.c
@@ -26,44 +26,56 @@
static int evmkey_len = MAX_KEY_SIZE;
struct crypto_shash *hmac_tfm;
+struct crypto_shash *hash_tfm;
static DEFINE_MUTEX(mutex);
-static struct shash_desc *init_desc(void)
+static struct shash_desc *init_desc(char type)
{
- int rc;
+ long rc;
+ char *algo;
+ struct crypto_shash **tfm;
struct shash_desc *desc;
- if (hmac_tfm == NULL) {
+ if (type == EVM_XATTR_HMAC) {
+ tfm = &hmac_tfm;
+ algo = evm_hmac;
+ } else {
+ tfm = &hash_tfm;
+ algo = evm_hash;
+ }
+
+ if (*tfm == NULL) {
mutex_lock(&mutex);
- if (hmac_tfm)
+ if (*tfm)
goto out;
- hmac_tfm = crypto_alloc_shash(evm_hmac, 0, CRYPTO_ALG_ASYNC);
- if (IS_ERR(hmac_tfm)) {
- pr_err("Can not allocate %s (reason: %ld)\n",
- evm_hmac, PTR_ERR(hmac_tfm));
- rc = PTR_ERR(hmac_tfm);
- hmac_tfm = NULL;
+ *tfm = crypto_alloc_shash(algo, 0, CRYPTO_ALG_ASYNC);
+ if (IS_ERR(*tfm)) {
+ rc = PTR_ERR(*tfm);
+ pr_err("Can not allocate %s (reason: %ld)\n", algo, rc);
+ *tfm = NULL;
mutex_unlock(&mutex);
return ERR_PTR(rc);
}
- rc = crypto_shash_setkey(hmac_tfm, evmkey, evmkey_len);
- if (rc) {
- crypto_free_shash(hmac_tfm);
- hmac_tfm = NULL;
- mutex_unlock(&mutex);
- return ERR_PTR(rc);
+ if (type == EVM_XATTR_HMAC) {
+ rc = crypto_shash_setkey(*tfm, evmkey, evmkey_len);
+ if (rc) {
+ crypto_free_shash(*tfm);
+ *tfm = NULL;
+ mutex_unlock(&mutex);
+ return ERR_PTR(rc);
+ }
}
out:
mutex_unlock(&mutex);
}
- desc = kmalloc(sizeof(*desc) + crypto_shash_descsize(hmac_tfm),
+ desc = kmalloc(sizeof(*desc) + crypto_shash_descsize(*tfm),
GFP_KERNEL);
if (!desc)
return ERR_PTR(-ENOMEM);
- desc->tfm = hmac_tfm;
+ desc->tfm = *tfm;
desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP;
rc = crypto_shash_init(desc);
@@ -108,9 +120,11 @@
* the hmac using the requested xattr value. Don't alloc/free memory for
* each xattr, but attempt to re-use the previously allocated memory.
*/
-int evm_calc_hmac(struct dentry *dentry, const char *req_xattr_name,
- const char *req_xattr_value, size_t req_xattr_value_len,
- char *digest)
+static int evm_calc_hmac_or_hash(struct dentry *dentry,
+ const char *req_xattr_name,
+ const char *req_xattr_value,
+ size_t req_xattr_value_len,
+ char type, char *digest)
{
struct inode *inode = dentry->d_inode;
struct shash_desc *desc;
@@ -122,7 +136,7 @@
if (!inode->i_op || !inode->i_op->getxattr)
return -EOPNOTSUPP;
- desc = init_desc();
+ desc = init_desc(type);
if (IS_ERR(desc))
return PTR_ERR(desc);
@@ -156,6 +170,22 @@
return error;
}
+int evm_calc_hmac(struct dentry *dentry, const char *req_xattr_name,
+ const char *req_xattr_value, size_t req_xattr_value_len,
+ char *digest)
+{
+ return evm_calc_hmac_or_hash(dentry, req_xattr_name, req_xattr_value,
+ req_xattr_value_len, EVM_XATTR_HMAC, digest);
+}
+
+int evm_calc_hash(struct dentry *dentry, const char *req_xattr_name,
+ const char *req_xattr_value, size_t req_xattr_value_len,
+ char *digest)
+{
+ return evm_calc_hmac_or_hash(dentry, req_xattr_name, req_xattr_value,
+ req_xattr_value_len, IMA_XATTR_DIGEST, digest);
+}
+
/*
* Calculate the hmac and update security.evm xattr
*
@@ -186,7 +216,7 @@
{
struct shash_desc *desc;
- desc = init_desc();
+ desc = init_desc(EVM_XATTR_HMAC);
if (IS_ERR(desc)) {
printk(KERN_INFO "init_desc failed\n");
return PTR_ERR(desc);
diff --git a/security/integrity/evm/evm_main.c b/security/integrity/evm/evm_main.c
index 92d3d99..8901501 100644
--- a/security/integrity/evm/evm_main.c
+++ b/security/integrity/evm/evm_main.c
@@ -25,6 +25,7 @@
int evm_initialized;
char *evm_hmac = "hmac(sha1)";
+char *evm_hash = "sha1";
char *evm_config_xattrnames[] = {
#ifdef CONFIG_SECURITY_SELINUX
@@ -46,6 +47,29 @@
}
__setup("evm=", evm_set_fixmode);
+static int evm_find_protected_xattrs(struct dentry *dentry)
+{
+ struct inode *inode = dentry->d_inode;
+ char **xattr;
+ int error;
+ int count = 0;
+
+ if (!inode->i_op || !inode->i_op->getxattr)
+ return -EOPNOTSUPP;
+
+ for (xattr = evm_config_xattrnames; *xattr != NULL; xattr++) {
+ error = inode->i_op->getxattr(dentry, *xattr, NULL, 0);
+ if (error < 0) {
+ if (error == -ENODATA)
+ continue;
+ return error;
+ }
+ count++;
+ }
+
+ return count;
+}
+
/*
* evm_verify_hmac - calculate and compare the HMAC with the EVM xattr
*
@@ -65,32 +89,72 @@
size_t xattr_value_len,
struct integrity_iint_cache *iint)
{
- struct evm_ima_xattr_data xattr_data;
+ struct evm_ima_xattr_data *xattr_data = NULL;
+ struct evm_ima_xattr_data calc;
enum integrity_status evm_status = INTEGRITY_PASS;
- int rc;
+ int rc, xattr_len;
if (iint && iint->evm_status == INTEGRITY_PASS)
return iint->evm_status;
/* if status is not PASS, try to check again - against -ENOMEM */
- rc = evm_calc_hmac(dentry, xattr_name, xattr_value,
- xattr_value_len, xattr_data.digest);
- if (rc < 0) {
- evm_status = (rc == -ENODATA)
- ? INTEGRITY_NOXATTRS : INTEGRITY_FAIL;
+ /* first need to know the sig type */
+ rc = vfs_getxattr_alloc(dentry, XATTR_NAME_EVM, (char **)&xattr_data, 0,
+ GFP_NOFS);
+ if (rc <= 0) {
+ if (rc == 0)
+ evm_status = INTEGRITY_FAIL; /* empty */
+ else if (rc == -ENODATA) {
+ rc = evm_find_protected_xattrs(dentry);
+ if (rc > 0)
+ evm_status = INTEGRITY_NOLABEL;
+ else if (rc == 0)
+ evm_status = INTEGRITY_NOXATTRS; /* new file */
+ }
goto out;
}
- xattr_data.type = EVM_XATTR_HMAC;
- rc = vfs_xattr_cmp(dentry, XATTR_NAME_EVM, (u8 *)&xattr_data,
- sizeof xattr_data, GFP_NOFS);
- if (rc < 0)
- evm_status = (rc == -ENODATA)
- ? INTEGRITY_NOLABEL : INTEGRITY_FAIL;
+ xattr_len = rc - 1;
+
+ /* check value type */
+ switch (xattr_data->type) {
+ case EVM_XATTR_HMAC:
+ rc = evm_calc_hmac(dentry, xattr_name, xattr_value,
+ xattr_value_len, calc.digest);
+ if (rc)
+ break;
+ rc = memcmp(xattr_data->digest, calc.digest,
+ sizeof(calc.digest));
+ if (rc)
+ rc = -EINVAL;
+ break;
+ case EVM_IMA_XATTR_DIGSIG:
+ rc = evm_calc_hash(dentry, xattr_name, xattr_value,
+ xattr_value_len, calc.digest);
+ if (rc)
+ break;
+ rc = integrity_digsig_verify(INTEGRITY_KEYRING_EVM,
+ xattr_data->digest, xattr_len,
+ calc.digest, sizeof(calc.digest));
+ if (!rc) {
+ /* we probably want to replace rsa with hmac here */
+ evm_update_evmxattr(dentry, xattr_name, xattr_value,
+ xattr_value_len);
+ }
+ break;
+ default:
+ rc = -EINVAL;
+ break;
+ }
+
+ if (rc)
+ evm_status = (rc == -ENODATA) ?
+ INTEGRITY_NOXATTRS : INTEGRITY_FAIL;
out:
if (iint)
iint->evm_status = evm_status;
+ kfree(xattr_data);
return evm_status;
}
@@ -354,6 +418,8 @@
printk(KERN_INFO "EVM: Error registering secfs\n");
goto err;
}
+
+ return 0;
err:
return error;
}
@@ -363,6 +429,8 @@
evm_cleanup_secfs();
if (hmac_tfm)
crypto_free_shash(hmac_tfm);
+ if (hash_tfm)
+ crypto_free_shash(hash_tfm);
}
/*
diff --git a/security/integrity/ima/ima_api.c b/security/integrity/ima/ima_api.c
index 0d50df0..88a2788 100644
--- a/security/integrity/ima/ima_api.c
+++ b/security/integrity/ima/ima_api.c
@@ -178,8 +178,8 @@
strncpy(entry->template.file_name, filename, IMA_EVENT_NAME_LEN_MAX);
result = ima_store_template(entry, violation, inode);
- if (!result)
+ if (!result || result == -EEXIST)
iint->flags |= IMA_MEASURED;
- else
+ if (result < 0)
kfree(entry);
}
diff --git a/security/integrity/ima/ima_queue.c b/security/integrity/ima/ima_queue.c
index 8e28f04..55a6271 100644
--- a/security/integrity/ima/ima_queue.c
+++ b/security/integrity/ima/ima_queue.c
@@ -23,6 +23,8 @@
#include <linux/slab.h>
#include "ima.h"
+#define AUDIT_CAUSE_LEN_MAX 32
+
LIST_HEAD(ima_measurements); /* list of all measurements */
/* key: inode (before secure-hashing a file) */
@@ -94,7 +96,8 @@
result = tpm_pcr_extend(TPM_ANY_NUM, CONFIG_IMA_MEASURE_PCR_IDX, hash);
if (result != 0)
- pr_err("IMA: Error Communicating to TPM chip\n");
+ pr_err("IMA: Error Communicating to TPM chip, result: %d\n",
+ result);
return result;
}
@@ -106,14 +109,16 @@
{
u8 digest[IMA_DIGEST_SIZE];
const char *audit_cause = "hash_added";
+ char tpm_audit_cause[AUDIT_CAUSE_LEN_MAX];
int audit_info = 1;
- int result = 0;
+ int result = 0, tpmresult = 0;
mutex_lock(&ima_extend_list_mutex);
if (!violation) {
memcpy(digest, entry->digest, sizeof digest);
if (ima_lookup_digest_entry(digest)) {
audit_cause = "hash_exists";
+ result = -EEXIST;
goto out;
}
}
@@ -128,9 +133,11 @@
if (violation) /* invalidate pcr */
memset(digest, 0xff, sizeof digest);
- result = ima_pcr_extend(digest);
- if (result != 0) {
- audit_cause = "TPM error";
+ tpmresult = ima_pcr_extend(digest);
+ if (tpmresult != 0) {
+ snprintf(tpm_audit_cause, AUDIT_CAUSE_LEN_MAX, "TPM_error(%d)",
+ tpmresult);
+ audit_cause = tpm_audit_cause;
audit_info = 0;
}
out:
diff --git a/security/integrity/integrity.h b/security/integrity/integrity.h
index 3143a3c..4da6ba8 100644
--- a/security/integrity/integrity.h
+++ b/security/integrity/integrity.h
@@ -46,5 +46,26 @@
struct integrity_iint_cache *integrity_iint_insert(struct inode *inode);
struct integrity_iint_cache *integrity_iint_find(struct inode *inode);
+#define INTEGRITY_KEYRING_EVM 0
+#define INTEGRITY_KEYRING_MODULE 1
+#define INTEGRITY_KEYRING_IMA 2
+#define INTEGRITY_KEYRING_MAX 3
+
+#ifdef CONFIG_INTEGRITY_DIGSIG
+
+int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen,
+ const char *digest, int digestlen);
+
+#else
+
+static inline int integrity_digsig_verify(const unsigned int id,
+ const char *sig, int siglen,
+ const char *digest, int digestlen)
+{
+ return -EOPNOTSUPP;
+}
+
+#endif /* CONFIG_INTEGRITY_DIGSIG */
+
/* set during initialization */
extern int iint_initialized;
diff --git a/security/keys/key.c b/security/keys/key.c
index 4414abd..4f64c72 100644
--- a/security/keys/key.c
+++ b/security/keys/key.c
@@ -291,6 +291,7 @@
atomic_set(&key->usage, 1);
init_rwsem(&key->sem);
+ lockdep_set_class(&key->sem, &type->lock_class);
key->type = type;
key->user = user;
key->quotalen = quotalen;
@@ -946,6 +947,8 @@
struct key_type *p;
int ret;
+ memset(&ktype->lock_class, 0, sizeof(ktype->lock_class));
+
ret = -EEXIST;
down_write(&key_types_sem);
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
index f466587..48a7d00 100644
--- a/security/selinux/selinuxfs.c
+++ b/security/selinux/selinuxfs.c
@@ -749,14 +749,6 @@
return length;
}
-static inline int hexcode_to_int(int code) {
- if (code == '\0' || !isxdigit(code))
- return -1;
- if (isdigit(code))
- return code - '0';
- return tolower(code) - 'a' + 10;
-}
-
static ssize_t sel_write_create(struct file *file, char *buf, size_t size)
{
char *scon = NULL, *tcon = NULL;
@@ -808,9 +800,11 @@
if (c1 == '+')
c1 = ' ';
else if (c1 == '%') {
- if ((c1 = hexcode_to_int(*r++)) < 0)
+ c1 = hex_to_bin(*r++);
+ if (c1 < 0)
goto out;
- if ((c2 = hexcode_to_int(*r++)) < 0)
+ c2 = hex_to_bin(*r++);
+ if (c2 < 0)
goto out;
c1 = (c1 << 4) | c2;
}
diff --git a/security/selinux/ss/conditional.c b/security/selinux/ss/conditional.c
index 2ec9041..377d148 100644
--- a/security/selinux/ss/conditional.c
+++ b/security/selinux/ss/conditional.c
@@ -175,7 +175,7 @@
int cond_init_bool_indexes(struct policydb *p)
{
kfree(p->bool_val_to_struct);
- p->bool_val_to_struct = (struct cond_bool_datum **)
+ p->bool_val_to_struct =
kmalloc(p->p_bools.nprim * sizeof(struct cond_bool_datum *), GFP_KERNEL);
if (!p->bool_val_to_struct)
return -ENOMEM;
diff --git a/security/tomoyo/.gitignore b/security/tomoyo/.gitignore
new file mode 100644
index 0000000..5caf1a6
--- /dev/null
+++ b/security/tomoyo/.gitignore
@@ -0,0 +1,2 @@
+builtin-policy.h
+policy/
diff --git a/security/tomoyo/common.h b/security/tomoyo/common.h
index deeab7b..9512222 100644
--- a/security/tomoyo/common.h
+++ b/security/tomoyo/common.h
@@ -1122,7 +1122,7 @@
{
pid_t pid;
rcu_read_lock();
- pid = task_tgid_vnr(current->real_parent);
+ pid = task_tgid_vnr(rcu_dereference(current->real_parent));
rcu_read_unlock();
return pid;
}
diff --git a/sound/arm/pxa2xx-ac97.c b/sound/arm/pxa2xx-ac97.c
index 5d94118..3a39626 100644
--- a/sound/arm/pxa2xx-ac97.c
+++ b/sound/arm/pxa2xx-ac97.c
@@ -251,18 +251,7 @@
},
};
-static int __init pxa2xx_ac97_init(void)
-{
- return platform_driver_register(&pxa2xx_ac97_driver);
-}
-
-static void __exit pxa2xx_ac97_exit(void)
-{
- platform_driver_unregister(&pxa2xx_ac97_driver);
-}
-
-module_init(pxa2xx_ac97_init);
-module_exit(pxa2xx_ac97_exit);
+module_platform_driver(pxa2xx_ac97_driver);
MODULE_AUTHOR("Nicolas Pitre");
MODULE_DESCRIPTION("AC97 driver for the Intel PXA2xx chip");
diff --git a/sound/core/Kconfig b/sound/core/Kconfig
index c15682a..ad40938 100644
--- a/sound/core/Kconfig
+++ b/sound/core/Kconfig
@@ -154,6 +154,16 @@
If you are unsure about this, say N here.
+config SND_COMPRESS_OFFLOAD
+ tristate "ALSA Compressed audio offload support"
+ default n
+ help
+ If you want support for offloading compressed audio and have such
+ a hardware, then you should say Y here and also to the DSP driver
+ of your platform.
+
+ If you are unsure about this, say N here.
+
config SND_SUPPORT_OLD_API
bool "Support old ALSA API"
default y
@@ -206,6 +216,9 @@
config SND_VMASTER
bool
+config SND_KCTL_JACK
+ bool
+
config SND_DMA_SGBUF
def_bool y
depends on X86
diff --git a/sound/core/Makefile b/sound/core/Makefile
index 350a08d..43d4117 100644
--- a/sound/core/Makefile
+++ b/sound/core/Makefile
@@ -7,6 +7,7 @@
snd-$(CONFIG_ISA_DMA_API) += isadma.o
snd-$(CONFIG_SND_OSSEMUL) += sound_oss.o info_oss.o
snd-$(CONFIG_SND_VMASTER) += vmaster.o
+snd-$(CONFIG_SND_KCTL_JACK) += ctljack.o
snd-$(CONFIG_SND_JACK) += jack.o
snd-pcm-objs := pcm.o pcm_native.o pcm_lib.o pcm_timer.o pcm_misc.o \
@@ -21,6 +22,8 @@
snd-rtctimer-objs := rtctimer.o
snd-hwdep-objs := hwdep.o
+snd-compress-objs := compress_offload.o
+
obj-$(CONFIG_SND) += snd.o
obj-$(CONFIG_SND_HWDEP) += snd-hwdep.o
obj-$(CONFIG_SND_TIMER) += snd-timer.o
@@ -31,3 +34,5 @@
obj-$(CONFIG_SND_OSSEMUL) += oss/
obj-$(CONFIG_SND_SEQUENCER) += seq/
+
+obj-$(CONFIG_SND_COMPRESS_OFFLOAD) += snd-compress.o
diff --git a/sound/core/compress_offload.c b/sound/core/compress_offload.c
new file mode 100644
index 0000000..dac3633
--- /dev/null
+++ b/sound/core/compress_offload.c
@@ -0,0 +1,765 @@
+/*
+ * compress_core.c - compress offload core
+ *
+ * Copyright (C) 2011 Intel Corporation
+ * Authors: Vinod Koul <vinod.koul@linux.intel.com>
+ * Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ * 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; version 2 of the License.
+ *
+ * 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.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ */
+#define FORMAT(fmt) "%s: %d: " fmt, __func__, __LINE__
+#define pr_fmt(fmt) KBUILD_MODNAME ": " FORMAT(fmt)
+
+#include <linux/file.h>
+#include <linux/fs.h>
+#include <linux/list.h>
+#include <linux/mm.h>
+#include <linux/mutex.h>
+#include <linux/poll.h>
+#include <linux/slab.h>
+#include <linux/sched.h>
+#include <linux/uio.h>
+#include <linux/uaccess.h>
+#include <linux/module.h>
+#include <sound/core.h>
+#include <sound/initval.h>
+#include <sound/compress_params.h>
+#include <sound/compress_offload.h>
+#include <sound/compress_driver.h>
+
+/* TODO:
+ * - add substream support for multiple devices in case of
+ * SND_DYNAMIC_MINORS is not used
+ * - Multiple node representation
+ * driver should be able to register multiple nodes
+ */
+
+static DEFINE_MUTEX(device_mutex);
+
+struct snd_compr_file {
+ unsigned long caps;
+ struct snd_compr_stream stream;
+};
+
+/*
+ * a note on stream states used:
+ * we use follwing states in the compressed core
+ * SNDRV_PCM_STATE_OPEN: When stream has been opened.
+ * SNDRV_PCM_STATE_SETUP: When stream has been initialized. This is done by
+ * calling SNDRV_COMPRESS_SET_PARAMS. running streams will come to this
+ * state at stop by calling SNDRV_COMPRESS_STOP, or at end of drain.
+ * SNDRV_PCM_STATE_RUNNING: When stream has been started and is
+ * decoding/encoding and rendering/capturing data.
+ * SNDRV_PCM_STATE_DRAINING: When stream is draining current data. This is done
+ * by calling SNDRV_COMPRESS_DRAIN.
+ * SNDRV_PCM_STATE_PAUSED: When stream is paused. This is done by calling
+ * SNDRV_COMPRESS_PAUSE. It can be stopped or resumed by calling
+ * SNDRV_COMPRESS_STOP or SNDRV_COMPRESS_RESUME respectively.
+ */
+static int snd_compr_open(struct inode *inode, struct file *f)
+{
+ struct snd_compr *compr;
+ struct snd_compr_file *data;
+ struct snd_compr_runtime *runtime;
+ enum snd_compr_direction dirn;
+ int maj = imajor(inode);
+ int ret;
+
+ if (f->f_flags & O_WRONLY)
+ dirn = SND_COMPRESS_PLAYBACK;
+ else if (f->f_flags & O_RDONLY)
+ dirn = SND_COMPRESS_CAPTURE;
+ else {
+ pr_err("invalid direction\n");
+ return -EINVAL;
+ }
+
+ if (maj == snd_major)
+ compr = snd_lookup_minor_data(iminor(inode),
+ SNDRV_DEVICE_TYPE_COMPRESS);
+ else
+ return -EBADFD;
+
+ if (compr == NULL) {
+ pr_err("no device data!!!\n");
+ return -ENODEV;
+ }
+
+ if (dirn != compr->direction) {
+ pr_err("this device doesn't support this direction\n");
+ return -EINVAL;
+ }
+
+ data = kzalloc(sizeof(*data), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+ data->stream.ops = compr->ops;
+ data->stream.direction = dirn;
+ data->stream.private_data = compr->private_data;
+ data->stream.device = compr;
+ runtime = kzalloc(sizeof(*runtime), GFP_KERNEL);
+ if (!runtime) {
+ kfree(data);
+ return -ENOMEM;
+ }
+ runtime->state = SNDRV_PCM_STATE_OPEN;
+ init_waitqueue_head(&runtime->sleep);
+ data->stream.runtime = runtime;
+ f->private_data = (void *)data;
+ mutex_lock(&compr->lock);
+ ret = compr->ops->open(&data->stream);
+ mutex_unlock(&compr->lock);
+ if (ret) {
+ kfree(runtime);
+ kfree(data);
+ }
+ return ret;
+}
+
+static int snd_compr_free(struct inode *inode, struct file *f)
+{
+ struct snd_compr_file *data = f->private_data;
+ data->stream.ops->free(&data->stream);
+ kfree(data->stream.runtime->buffer);
+ kfree(data->stream.runtime);
+ kfree(data);
+ return 0;
+}
+
+static void snd_compr_update_tstamp(struct snd_compr_stream *stream,
+ struct snd_compr_tstamp *tstamp)
+{
+ if (!stream->ops->pointer)
+ return;
+ stream->ops->pointer(stream, tstamp);
+ pr_debug("dsp consumed till %d total %d bytes\n",
+ tstamp->byte_offset, tstamp->copied_total);
+ stream->runtime->hw_pointer = tstamp->byte_offset;
+ stream->runtime->total_bytes_transferred = tstamp->copied_total;
+}
+
+static size_t snd_compr_calc_avail(struct snd_compr_stream *stream,
+ struct snd_compr_avail *avail)
+{
+ long avail_calc; /*this needs to be signed variable */
+
+ snd_compr_update_tstamp(stream, &avail->tstamp);
+
+ /* FIXME: This needs to be different for capture stream,
+ available is # of compressed data, for playback it's
+ remainder of buffer */
+
+ if (stream->runtime->total_bytes_available == 0 &&
+ stream->runtime->state == SNDRV_PCM_STATE_SETUP) {
+ pr_debug("detected init and someone forgot to do a write\n");
+ return stream->runtime->buffer_size;
+ }
+ pr_debug("app wrote %lld, DSP consumed %lld\n",
+ stream->runtime->total_bytes_available,
+ stream->runtime->total_bytes_transferred);
+ if (stream->runtime->total_bytes_available ==
+ stream->runtime->total_bytes_transferred) {
+ pr_debug("both pointers are same, returning full avail\n");
+ return stream->runtime->buffer_size;
+ }
+
+ /* FIXME: this routine isn't consistent, in one test we use
+ * cumulative values and in the other byte offsets. Do we
+ * really need the byte offsets if the cumulative values have
+ * been updated? In the PCM interface app_ptr and hw_ptr are
+ * already cumulative */
+
+ avail_calc = stream->runtime->buffer_size -
+ (stream->runtime->app_pointer - stream->runtime->hw_pointer);
+ pr_debug("calc avail as %ld, app_ptr %lld, hw+ptr %lld\n", avail_calc,
+ stream->runtime->app_pointer,
+ stream->runtime->hw_pointer);
+ if (avail_calc >= stream->runtime->buffer_size)
+ avail_calc -= stream->runtime->buffer_size;
+ pr_debug("ret avail as %ld\n", avail_calc);
+ avail->avail = avail_calc;
+ return avail_calc;
+}
+
+static inline size_t snd_compr_get_avail(struct snd_compr_stream *stream)
+{
+ struct snd_compr_avail avail;
+
+ return snd_compr_calc_avail(stream, &avail);
+}
+
+static int
+snd_compr_ioctl_avail(struct snd_compr_stream *stream, unsigned long arg)
+{
+ struct snd_compr_avail ioctl_avail;
+ size_t avail;
+
+ avail = snd_compr_calc_avail(stream, &ioctl_avail);
+ ioctl_avail.avail = avail;
+
+ if (copy_to_user((__u64 __user *)arg,
+ &ioctl_avail, sizeof(ioctl_avail)))
+ return -EFAULT;
+ return 0;
+}
+
+static int snd_compr_write_data(struct snd_compr_stream *stream,
+ const char __user *buf, size_t count)
+{
+ void *dstn;
+ size_t copy;
+ struct snd_compr_runtime *runtime = stream->runtime;
+
+ dstn = runtime->buffer + runtime->app_pointer;
+ pr_debug("copying %ld at %lld\n",
+ (unsigned long)count, runtime->app_pointer);
+ if (count < runtime->buffer_size - runtime->app_pointer) {
+ if (copy_from_user(dstn, buf, count))
+ return -EFAULT;
+ runtime->app_pointer += count;
+ } else {
+ copy = runtime->buffer_size - runtime->app_pointer;
+ if (copy_from_user(dstn, buf, copy))
+ return -EFAULT;
+ if (copy_from_user(runtime->buffer, buf + copy, count - copy))
+ return -EFAULT;
+ runtime->app_pointer = count - copy;
+ }
+ /* if DSP cares, let it know data has been written */
+ if (stream->ops->ack)
+ stream->ops->ack(stream, count);
+ return count;
+}
+
+static ssize_t snd_compr_write(struct file *f, const char __user *buf,
+ size_t count, loff_t *offset)
+{
+ struct snd_compr_file *data = f->private_data;
+ struct snd_compr_stream *stream;
+ size_t avail;
+ int retval;
+
+ if (snd_BUG_ON(!data))
+ return -EFAULT;
+
+ stream = &data->stream;
+ mutex_lock(&stream->device->lock);
+ /* write is allowed when stream is running or has been steup */
+ if (stream->runtime->state != SNDRV_PCM_STATE_SETUP &&
+ stream->runtime->state != SNDRV_PCM_STATE_RUNNING) {
+ mutex_unlock(&stream->device->lock);
+ return -EBADFD;
+ }
+
+ avail = snd_compr_get_avail(stream);
+ pr_debug("avail returned %ld\n", (unsigned long)avail);
+ /* calculate how much we can write to buffer */
+ if (avail > count)
+ avail = count;
+
+ if (stream->ops->copy)
+ retval = stream->ops->copy(stream, buf, avail);
+ else
+ retval = snd_compr_write_data(stream, buf, avail);
+ if (retval > 0)
+ stream->runtime->total_bytes_available += retval;
+
+ /* while initiating the stream, write should be called before START
+ * call, so in setup move state */
+ if (stream->runtime->state == SNDRV_PCM_STATE_SETUP) {
+ stream->runtime->state = SNDRV_PCM_STATE_PREPARED;
+ pr_debug("stream prepared, Houston we are good to go\n");
+ }
+
+ mutex_unlock(&stream->device->lock);
+ return retval;
+}
+
+
+static ssize_t snd_compr_read(struct file *f, char __user *buf,
+ size_t count, loff_t *offset)
+{
+ return -ENXIO;
+}
+
+static int snd_compr_mmap(struct file *f, struct vm_area_struct *vma)
+{
+ return -ENXIO;
+}
+
+static inline int snd_compr_get_poll(struct snd_compr_stream *stream)
+{
+ if (stream->direction == SND_COMPRESS_PLAYBACK)
+ return POLLOUT | POLLWRNORM;
+ else
+ return POLLIN | POLLRDNORM;
+}
+
+static unsigned int snd_compr_poll(struct file *f, poll_table *wait)
+{
+ struct snd_compr_file *data = f->private_data;
+ struct snd_compr_stream *stream;
+ size_t avail;
+ int retval = 0;
+
+ if (snd_BUG_ON(!data))
+ return -EFAULT;
+ stream = &data->stream;
+ if (snd_BUG_ON(!stream))
+ return -EFAULT;
+
+ mutex_lock(&stream->device->lock);
+ if (stream->runtime->state == SNDRV_PCM_STATE_PAUSED ||
+ stream->runtime->state == SNDRV_PCM_STATE_OPEN) {
+ retval = -EBADFD;
+ goto out;
+ }
+ poll_wait(f, &stream->runtime->sleep, wait);
+
+ avail = snd_compr_get_avail(stream);
+ pr_debug("avail is %ld\n", (unsigned long)avail);
+ /* check if we have at least one fragment to fill */
+ switch (stream->runtime->state) {
+ case SNDRV_PCM_STATE_DRAINING:
+ /* stream has been woken up after drain is complete
+ * draining done so set stream state to stopped
+ */
+ retval = snd_compr_get_poll(stream);
+ stream->runtime->state = SNDRV_PCM_STATE_SETUP;
+ break;
+ case SNDRV_PCM_STATE_RUNNING:
+ case SNDRV_PCM_STATE_PREPARED:
+ case SNDRV_PCM_STATE_PAUSED:
+ if (avail >= stream->runtime->fragment_size)
+ retval = snd_compr_get_poll(stream);
+ break;
+ default:
+ if (stream->direction == SND_COMPRESS_PLAYBACK)
+ retval = POLLOUT | POLLWRNORM | POLLERR;
+ else
+ retval = POLLIN | POLLRDNORM | POLLERR;
+ break;
+ }
+out:
+ mutex_unlock(&stream->device->lock);
+ return retval;
+}
+
+static int
+snd_compr_get_caps(struct snd_compr_stream *stream, unsigned long arg)
+{
+ int retval;
+ struct snd_compr_caps caps;
+
+ if (!stream->ops->get_caps)
+ return -ENXIO;
+
+ retval = stream->ops->get_caps(stream, &caps);
+ if (retval)
+ goto out;
+ if (copy_to_user((void __user *)arg, &caps, sizeof(caps)))
+ retval = -EFAULT;
+out:
+ return retval;
+}
+
+static int
+snd_compr_get_codec_caps(struct snd_compr_stream *stream, unsigned long arg)
+{
+ int retval;
+ struct snd_compr_codec_caps *caps;
+
+ if (!stream->ops->get_codec_caps)
+ return -ENXIO;
+
+ caps = kmalloc(sizeof(*caps), GFP_KERNEL);
+ if (!caps)
+ return -ENOMEM;
+
+ retval = stream->ops->get_codec_caps(stream, caps);
+ if (retval)
+ goto out;
+ if (copy_to_user((void __user *)arg, caps, sizeof(*caps)))
+ retval = -EFAULT;
+
+out:
+ kfree(caps);
+ return retval;
+}
+
+/* revisit this with snd_pcm_preallocate_xxx */
+static int snd_compr_allocate_buffer(struct snd_compr_stream *stream,
+ struct snd_compr_params *params)
+{
+ unsigned int buffer_size;
+ void *buffer;
+
+ buffer_size = params->buffer.fragment_size * params->buffer.fragments;
+ if (stream->ops->copy) {
+ buffer = NULL;
+ /* if copy is defined the driver will be required to copy
+ * the data from core
+ */
+ } else {
+ buffer = kmalloc(buffer_size, GFP_KERNEL);
+ if (!buffer)
+ return -ENOMEM;
+ }
+ stream->runtime->fragment_size = params->buffer.fragment_size;
+ stream->runtime->fragments = params->buffer.fragments;
+ stream->runtime->buffer = buffer;
+ stream->runtime->buffer_size = buffer_size;
+ return 0;
+}
+
+static int
+snd_compr_set_params(struct snd_compr_stream *stream, unsigned long arg)
+{
+ struct snd_compr_params *params;
+ int retval;
+
+ if (stream->runtime->state == SNDRV_PCM_STATE_OPEN) {
+ /*
+ * we should allow parameter change only when stream has been
+ * opened not in other cases
+ */
+ params = kmalloc(sizeof(*params), GFP_KERNEL);
+ if (!params)
+ return -ENOMEM;
+ if (copy_from_user(params, (void __user *)arg, sizeof(*params)))
+ return -EFAULT;
+ retval = snd_compr_allocate_buffer(stream, params);
+ if (retval) {
+ kfree(params);
+ return -ENOMEM;
+ }
+ retval = stream->ops->set_params(stream, params);
+ if (retval)
+ goto out;
+ stream->runtime->state = SNDRV_PCM_STATE_SETUP;
+ } else
+ return -EPERM;
+out:
+ kfree(params);
+ return retval;
+}
+
+static int
+snd_compr_get_params(struct snd_compr_stream *stream, unsigned long arg)
+{
+ struct snd_codec *params;
+ int retval;
+
+ if (!stream->ops->get_params)
+ return -EBADFD;
+
+ params = kmalloc(sizeof(*params), GFP_KERNEL);
+ if (!params)
+ return -ENOMEM;
+ retval = stream->ops->get_params(stream, params);
+ if (retval)
+ goto out;
+ if (copy_to_user((char __user *)arg, params, sizeof(*params)))
+ retval = -EFAULT;
+
+out:
+ kfree(params);
+ return retval;
+}
+
+static inline int
+snd_compr_tstamp(struct snd_compr_stream *stream, unsigned long arg)
+{
+ struct snd_compr_tstamp tstamp;
+
+ snd_compr_update_tstamp(stream, &tstamp);
+ return copy_to_user((struct snd_compr_tstamp __user *)arg,
+ &tstamp, sizeof(tstamp)) ? -EFAULT : 0;
+}
+
+static int snd_compr_pause(struct snd_compr_stream *stream)
+{
+ int retval;
+
+ if (stream->runtime->state != SNDRV_PCM_STATE_RUNNING)
+ return -EPERM;
+ retval = stream->ops->trigger(stream, SNDRV_PCM_TRIGGER_PAUSE_PUSH);
+ if (!retval) {
+ stream->runtime->state = SNDRV_PCM_STATE_PAUSED;
+ wake_up(&stream->runtime->sleep);
+ }
+ return retval;
+}
+
+static int snd_compr_resume(struct snd_compr_stream *stream)
+{
+ int retval;
+
+ if (stream->runtime->state != SNDRV_PCM_STATE_PAUSED)
+ return -EPERM;
+ retval = stream->ops->trigger(stream, SNDRV_PCM_TRIGGER_PAUSE_RELEASE);
+ if (!retval)
+ stream->runtime->state = SNDRV_PCM_STATE_RUNNING;
+ return retval;
+}
+
+static int snd_compr_start(struct snd_compr_stream *stream)
+{
+ int retval;
+
+ if (stream->runtime->state != SNDRV_PCM_STATE_PREPARED)
+ return -EPERM;
+ retval = stream->ops->trigger(stream, SNDRV_PCM_TRIGGER_START);
+ if (!retval)
+ stream->runtime->state = SNDRV_PCM_STATE_RUNNING;
+ return retval;
+}
+
+static int snd_compr_stop(struct snd_compr_stream *stream)
+{
+ int retval;
+
+ if (stream->runtime->state == SNDRV_PCM_STATE_PREPARED ||
+ stream->runtime->state == SNDRV_PCM_STATE_SETUP)
+ return -EPERM;
+ retval = stream->ops->trigger(stream, SNDRV_PCM_TRIGGER_STOP);
+ if (!retval) {
+ stream->runtime->state = SNDRV_PCM_STATE_SETUP;
+ wake_up(&stream->runtime->sleep);
+ }
+ return retval;
+}
+
+static int snd_compr_drain(struct snd_compr_stream *stream)
+{
+ int retval;
+
+ if (stream->runtime->state == SNDRV_PCM_STATE_PREPARED ||
+ stream->runtime->state == SNDRV_PCM_STATE_SETUP)
+ return -EPERM;
+ retval = stream->ops->trigger(stream, SND_COMPR_TRIGGER_DRAIN);
+ if (!retval) {
+ stream->runtime->state = SNDRV_PCM_STATE_DRAINING;
+ wake_up(&stream->runtime->sleep);
+ }
+ return retval;
+}
+
+static long snd_compr_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
+{
+ struct snd_compr_file *data = f->private_data;
+ struct snd_compr_stream *stream;
+ int retval = -ENOTTY;
+
+ if (snd_BUG_ON(!data))
+ return -EFAULT;
+ stream = &data->stream;
+ if (snd_BUG_ON(!stream))
+ return -EFAULT;
+ mutex_lock(&stream->device->lock);
+ switch (_IOC_NR(cmd)) {
+ case _IOC_NR(SNDRV_COMPRESS_IOCTL_VERSION):
+ put_user(SNDRV_COMPRESS_VERSION,
+ (int __user *)arg) ? -EFAULT : 0;
+ break;
+ case _IOC_NR(SNDRV_COMPRESS_GET_CAPS):
+ retval = snd_compr_get_caps(stream, arg);
+ break;
+ case _IOC_NR(SNDRV_COMPRESS_GET_CODEC_CAPS):
+ retval = snd_compr_get_codec_caps(stream, arg);
+ break;
+ case _IOC_NR(SNDRV_COMPRESS_SET_PARAMS):
+ retval = snd_compr_set_params(stream, arg);
+ break;
+ case _IOC_NR(SNDRV_COMPRESS_GET_PARAMS):
+ retval = snd_compr_get_params(stream, arg);
+ break;
+ case _IOC_NR(SNDRV_COMPRESS_TSTAMP):
+ retval = snd_compr_tstamp(stream, arg);
+ break;
+ case _IOC_NR(SNDRV_COMPRESS_AVAIL):
+ retval = snd_compr_ioctl_avail(stream, arg);
+ break;
+ case _IOC_NR(SNDRV_COMPRESS_PAUSE):
+ retval = snd_compr_pause(stream);
+ break;
+ case _IOC_NR(SNDRV_COMPRESS_RESUME):
+ retval = snd_compr_resume(stream);
+ break;
+ case _IOC_NR(SNDRV_COMPRESS_START):
+ retval = snd_compr_start(stream);
+ break;
+ case _IOC_NR(SNDRV_COMPRESS_STOP):
+ retval = snd_compr_stop(stream);
+ break;
+ case _IOC_NR(SNDRV_COMPRESS_DRAIN):
+ retval = snd_compr_drain(stream);
+ break;
+ }
+ mutex_unlock(&stream->device->lock);
+ return retval;
+}
+
+static const struct file_operations snd_compr_file_ops = {
+ .owner = THIS_MODULE,
+ .open = snd_compr_open,
+ .release = snd_compr_free,
+ .write = snd_compr_write,
+ .read = snd_compr_read,
+ .unlocked_ioctl = snd_compr_ioctl,
+ .mmap = snd_compr_mmap,
+ .poll = snd_compr_poll,
+};
+
+static int snd_compress_dev_register(struct snd_device *device)
+{
+ int ret = -EINVAL;
+ char str[16];
+ struct snd_compr *compr;
+
+ if (snd_BUG_ON(!device || !device->device_data))
+ return -EBADFD;
+ compr = device->device_data;
+
+ sprintf(str, "comprC%iD%i", compr->card->number, compr->device);
+ pr_debug("reg %s for device %s, direction %d\n", str, compr->name,
+ compr->direction);
+ /* register compressed device */
+ ret = snd_register_device(SNDRV_DEVICE_TYPE_COMPRESS, compr->card,
+ compr->device, &snd_compr_file_ops, compr, str);
+ if (ret < 0) {
+ pr_err("snd_register_device failed\n %d", ret);
+ return ret;
+ }
+ return ret;
+
+}
+
+static int snd_compress_dev_disconnect(struct snd_device *device)
+{
+ struct snd_compr *compr;
+
+ compr = device->device_data;
+ snd_unregister_device(compr->direction, compr->card, compr->device);
+ return 0;
+}
+
+/*
+ * snd_compress_new: create new compress device
+ * @card: sound card pointer
+ * @device: device number
+ * @dirn: device direction, should be of type enum snd_compr_direction
+ * @compr: compress device pointer
+ */
+int snd_compress_new(struct snd_card *card, int device,
+ int dirn, struct snd_compr *compr)
+{
+ static struct snd_device_ops ops = {
+ .dev_free = NULL,
+ .dev_register = snd_compress_dev_register,
+ .dev_disconnect = snd_compress_dev_disconnect,
+ };
+
+ compr->card = card;
+ compr->device = device;
+ compr->direction = dirn;
+ return snd_device_new(card, SNDRV_DEV_COMPRESS, compr, &ops);
+}
+EXPORT_SYMBOL_GPL(snd_compress_new);
+
+static int snd_compress_add_device(struct snd_compr *device)
+{
+ int ret;
+
+ if (!device->card)
+ return -EINVAL;
+
+ /* register the card */
+ ret = snd_card_register(device->card);
+ if (ret)
+ goto out;
+ return 0;
+
+out:
+ pr_err("failed with %d\n", ret);
+ return ret;
+
+}
+
+static int snd_compress_remove_device(struct snd_compr *device)
+{
+ return snd_card_free(device->card);
+}
+
+/**
+ * snd_compress_register - register compressed device
+ *
+ * @device: compressed device to register
+ */
+int snd_compress_register(struct snd_compr *device)
+{
+ int retval;
+
+ if (device->name == NULL || device->dev == NULL || device->ops == NULL)
+ return -EINVAL;
+
+ pr_debug("Registering compressed device %s\n", device->name);
+ if (snd_BUG_ON(!device->ops->open))
+ return -EINVAL;
+ if (snd_BUG_ON(!device->ops->free))
+ return -EINVAL;
+ if (snd_BUG_ON(!device->ops->set_params))
+ return -EINVAL;
+ if (snd_BUG_ON(!device->ops->trigger))
+ return -EINVAL;
+
+ mutex_init(&device->lock);
+
+ /* register a compressed card */
+ mutex_lock(&device_mutex);
+ retval = snd_compress_add_device(device);
+ mutex_unlock(&device_mutex);
+ return retval;
+}
+EXPORT_SYMBOL_GPL(snd_compress_register);
+
+int snd_compress_deregister(struct snd_compr *device)
+{
+ pr_debug("Removing compressed device %s\n", device->name);
+ mutex_lock(&device_mutex);
+ snd_compress_remove_device(device);
+ mutex_unlock(&device_mutex);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(snd_compress_deregister);
+
+static int __init snd_compress_init(void)
+{
+ return 0;
+}
+
+static void __exit snd_compress_exit(void)
+{
+}
+
+module_init(snd_compress_init);
+module_exit(snd_compress_exit);
+
+MODULE_DESCRIPTION("ALSA Compressed offload framework");
+MODULE_AUTHOR("Vinod Koul <vinod.koul@linux.intel.com>");
+MODULE_LICENSE("GPL v2");
diff --git a/sound/core/ctljack.c b/sound/core/ctljack.c
new file mode 100644
index 0000000..e4b38fb
--- /dev/null
+++ b/sound/core/ctljack.c
@@ -0,0 +1,56 @@
+/*
+ * Helper functions for jack-detection kcontrols
+ *
+ * Copyright (c) 2011 Takashi Iwai <tiwai@suse.de>
+ *
+ * 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/export.h>
+#include <sound/core.h>
+#include <sound/control.h>
+
+#define jack_detect_kctl_info snd_ctl_boolean_mono_info
+
+static int jack_detect_kctl_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ ucontrol->value.integer.value[0] = kcontrol->private_value;
+ return 0;
+}
+
+static struct snd_kcontrol_new jack_detect_kctl = {
+ /* name is filled later */
+ .iface = SNDRV_CTL_ELEM_IFACE_CARD,
+ .access = SNDRV_CTL_ELEM_ACCESS_READ,
+ .info = jack_detect_kctl_info,
+ .get = jack_detect_kctl_get,
+};
+
+struct snd_kcontrol *
+snd_kctl_jack_new(const char *name, int idx, void *private_data)
+{
+ struct snd_kcontrol *kctl;
+ kctl = snd_ctl_new1(&jack_detect_kctl, private_data);
+ if (!kctl)
+ return NULL;
+ snprintf(kctl->id.name, sizeof(kctl->id.name), "%s Jack", name);
+ kctl->id.index = idx;
+ kctl->private_value = 0;
+ return kctl;
+}
+EXPORT_SYMBOL_GPL(snd_kctl_jack_new);
+
+void snd_kctl_jack_report(struct snd_card *card,
+ struct snd_kcontrol *kctl, bool status)
+{
+ if (kctl->private_value == status)
+ return;
+ kctl->private_value = status;
+ snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE, &kctl->id);
+}
+EXPORT_SYMBOL_GPL(snd_kctl_jack_report);
diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c
index 3cc4b86..08fde00 100644
--- a/sound/core/oss/pcm_oss.c
+++ b/sound/core/oss/pcm_oss.c
@@ -47,7 +47,7 @@
static int dsp_map[SNDRV_CARDS];
static int adsp_map[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = 1};
-static int nonblock_open = 1;
+static bool nonblock_open = 1;
MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>, Abramo Bagnara <abramo@alsa-project.org>");
MODULE_DESCRIPTION("PCM OSS emulation for ALSA.");
diff --git a/sound/core/seq/seq_dummy.c b/sound/core/seq/seq_dummy.c
index b9b2235..bbe32d2 100644
--- a/sound/core/seq/seq_dummy.c
+++ b/sound/core/seq/seq_dummy.c
@@ -65,7 +65,7 @@
MODULE_ALIAS("snd-seq-client-" __stringify(SNDRV_SEQ_CLIENT_DUMMY));
static int ports = 1;
-static int duplex;
+static bool duplex;
module_param(ports, int, 0444);
MODULE_PARM_DESC(ports, "number of ports to be created");
diff --git a/sound/core/sound.c b/sound/core/sound.c
index 828af35..28f3559 100644
--- a/sound/core/sound.c
+++ b/sound/core/sound.c
@@ -229,6 +229,7 @@
case SNDRV_DEVICE_TYPE_RAWMIDI:
case SNDRV_DEVICE_TYPE_PCM_PLAYBACK:
case SNDRV_DEVICE_TYPE_PCM_CAPTURE:
+ case SNDRV_DEVICE_TYPE_COMPRESS:
if (snd_BUG_ON(!card))
return -EINVAL;
minor = SNDRV_MINOR(card->number, type + dev);
diff --git a/sound/drivers/aloop.c b/sound/drivers/aloop.c
index d83bafc..ad079b6 100644
--- a/sound/drivers/aloop.c
+++ b/sound/drivers/aloop.c
@@ -51,7 +51,7 @@
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static int enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 0};
+static bool enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 0};
static int pcm_substreams[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 8};
static int pcm_notify[SNDRV_CARDS];
diff --git a/sound/drivers/dummy.c b/sound/drivers/dummy.c
index 97f1f93..ad9434f 100644
--- a/sound/drivers/dummy.c
+++ b/sound/drivers/dummy.c
@@ -60,15 +60,15 @@
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static int enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 0};
+static bool enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 0};
static char *model[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = NULL};
static int pcm_devs[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1};
static int pcm_substreams[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 8};
//static int midi_devs[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 2};
#ifdef CONFIG_HIGH_RES_TIMERS
-static int hrtimer = 1;
+static bool hrtimer = 1;
#endif
-static int fake_buffer = 1;
+static bool fake_buffer = 1;
module_param_array(index, int, NULL, 0444);
MODULE_PARM_DESC(index, "Index value for dummy soundcard.");
diff --git a/sound/drivers/ml403-ac97cr.c b/sound/drivers/ml403-ac97cr.c
index 2ee82c5..6c83b1a 100644
--- a/sound/drivers/ml403-ac97cr.c
+++ b/sound/drivers/ml403-ac97cr.c
@@ -73,7 +73,7 @@
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE;
+static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE;
module_param_array(index, int, NULL, 0444);
MODULE_PARM_DESC(index, "Index value for ML403 AC97 Controller Reference.");
@@ -1341,15 +1341,4 @@
},
};
-static int __init alsa_card_ml403_ac97cr_init(void)
-{
- return platform_driver_register(&snd_ml403_ac97cr_driver);
-}
-
-static void __exit alsa_card_ml403_ac97cr_exit(void)
-{
- platform_driver_unregister(&snd_ml403_ac97cr_driver);
-}
-
-module_init(alsa_card_ml403_ac97cr_init)
-module_exit(alsa_card_ml403_ac97cr_exit)
+module_platform_driver(snd_ml403_ac97cr_driver);
diff --git a/sound/drivers/mpu401/mpu401.c b/sound/drivers/mpu401/mpu401.c
index 2575690..86f5fbc 100644
--- a/sound/drivers/mpu401/mpu401.c
+++ b/sound/drivers/mpu401/mpu401.c
@@ -35,13 +35,13 @@
static int index[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = -2}; /* exclude the first card */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */
+static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */
#ifdef CONFIG_PNP
-static int pnp[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1};
+static bool pnp[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1};
#endif
static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* MPU-401 port number */
static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* MPU-401 IRQ */
-static int uart_enter[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1};
+static bool uart_enter[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1};
module_param_array(index, int, NULL, 0444);
MODULE_PARM_DESC(index, "Index value for MPU-401 device.");
diff --git a/sound/drivers/mts64.c b/sound/drivers/mts64.c
index f24bf9a..621e60e 100644
--- a/sound/drivers/mts64.c
+++ b/sound/drivers/mts64.c
@@ -36,7 +36,7 @@
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 bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
static struct platform_device *platform_devices[SNDRV_CARDS];
static int device_count;
diff --git a/sound/drivers/opl3/opl3_midi.c b/sound/drivers/opl3/opl3_midi.c
index 7d722a0..2bfe4bc 100644
--- a/sound/drivers/opl3/opl3_midi.c
+++ b/sound/drivers/opl3/opl3_midi.c
@@ -27,7 +27,7 @@
extern char snd_opl3_regmap[MAX_OPL2_VOICES][4];
-extern int use_internal_drums;
+extern bool use_internal_drums;
static void snd_opl3_note_off_unsafe(void *p, int note, int vel,
struct snd_midi_channel *chan);
diff --git a/sound/drivers/opl3/opl3_seq.c b/sound/drivers/opl3/opl3_seq.c
index 723562e..6839953 100644
--- a/sound/drivers/opl3/opl3_seq.c
+++ b/sound/drivers/opl3/opl3_seq.c
@@ -32,7 +32,7 @@
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("ALSA driver for OPL3 FM synth");
-int use_internal_drums = 0;
+bool use_internal_drums = 0;
module_param(use_internal_drums, bool, 0444);
MODULE_PARM_DESC(use_internal_drums, "Enable internal OPL2/3 drums.");
diff --git a/sound/drivers/pcsp/pcsp.c b/sound/drivers/pcsp/pcsp.c
index 946a0cb..99704e6 100644
--- a/sound/drivers/pcsp/pcsp.c
+++ b/sound/drivers/pcsp/pcsp.c
@@ -25,8 +25,8 @@
static int index = SNDRV_DEFAULT_IDX1; /* Index 0-MAX */
static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */
-static int enable = SNDRV_DEFAULT_ENABLE1; /* Enable this card */
-static int nopcm; /* Disable PCM capability of the driver */
+static bool enable = SNDRV_DEFAULT_ENABLE1; /* Enable this card */
+static bool nopcm; /* Disable PCM capability of the driver */
module_param(index, int, 0444);
MODULE_PARM_DESC(index, "Index value for pcsp soundcard.");
diff --git a/sound/drivers/pcsp/pcsp_lib.c b/sound/drivers/pcsp/pcsp_lib.c
index ce9e7d1..434981d 100644
--- a/sound/drivers/pcsp/pcsp_lib.c
+++ b/sound/drivers/pcsp/pcsp_lib.c
@@ -14,7 +14,7 @@
#include <asm/io.h>
#include "pcsp.h"
-static int nforce_wa;
+static bool nforce_wa;
module_param(nforce_wa, bool, 0444);
MODULE_PARM_DESC(nforce_wa, "Apply NForce chipset workaround "
"(expect bad sound)");
diff --git a/sound/drivers/portman2x4.c b/sound/drivers/portman2x4.c
index f664823..3e32bd3 100644
--- a/sound/drivers/portman2x4.c
+++ b/sound/drivers/portman2x4.c
@@ -55,7 +55,7 @@
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 bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
static struct platform_device *platform_devices[SNDRV_CARDS];
static int device_count;
diff --git a/sound/drivers/serial-u16550.c b/sound/drivers/serial-u16550.c
index 85aad43..b2d0e8e 100644
--- a/sound/drivers/serial-u16550.c
+++ b/sound/drivers/serial-u16550.c
@@ -69,7 +69,7 @@
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */
+static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */
static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* 0x3f8,0x2f8,0x3e8,0x2e8 */
static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* 3,4,5,7,9,10,11,14,15 */
static int speed[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 38400}; /* 9600,19200,38400,57600,115200 */
@@ -77,7 +77,7 @@
static int outs[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1}; /* 1 to 16 */
static int ins[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1}; /* 1 to 16 */
static int adaptor[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = SNDRV_SERIAL_SOUNDCANVAS};
-static int droponfull[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS -1)] = SNDRV_SERIAL_NORMALBUFF };
+static bool droponfull[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS -1)] = SNDRV_SERIAL_NORMALBUFF };
module_param_array(index, int, NULL, 0444);
MODULE_PARM_DESC(index, "Index value for Serial MIDI.");
diff --git a/sound/drivers/virmidi.c b/sound/drivers/virmidi.c
index d79d6ed..9d97478 100644
--- a/sound/drivers/virmidi.c
+++ b/sound/drivers/virmidi.c
@@ -63,7 +63,7 @@
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static int enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 0};
+static bool enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 0};
static int midi_devs[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 4};
module_param_array(index, int, NULL, 0444);
diff --git a/sound/isa/ad1816a/ad1816a.c b/sound/isa/ad1816a/ad1816a.c
index cd44c74..94b83b6 100644
--- a/sound/isa/ad1816a/ad1816a.c
+++ b/sound/isa/ad1816a/ad1816a.c
@@ -44,7 +44,7 @@
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 1-MAX */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP; /* Enable this card */
+static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP; /* Enable this card */
static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */
static long mpu_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */
static long fm_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */
diff --git a/sound/isa/ad1848/ad1848.c b/sound/isa/ad1848/ad1848.c
index 34ab69b..2af77fa 100644
--- a/sound/isa/ad1848/ad1848.c
+++ b/sound/isa/ad1848/ad1848.c
@@ -43,11 +43,11 @@
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */
+static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */
static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */
static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* 5,7,9,11,12,15 */
static int dma1[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 0,1,3,5,6,7 */
-static int thinkpad[SNDRV_CARDS]; /* Thinkpad special case */
+static bool thinkpad[SNDRV_CARDS]; /* Thinkpad special case */
module_param_array(index, int, NULL, 0444);
MODULE_PARM_DESC(index, "Index value for " CRD_NAME " soundcard.");
diff --git a/sound/isa/adlib.c b/sound/isa/adlib.c
index 7465ae0..4d50c69 100644
--- a/sound/isa/adlib.c
+++ b/sound/isa/adlib.c
@@ -18,7 +18,7 @@
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE;
+static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE;
static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
module_param_array(index, int, NULL, 0444);
diff --git a/sound/isa/als100.c b/sound/isa/als100.c
index fc5b38f..d1f4351 100644
--- a/sound/isa/als100.c
+++ b/sound/isa/als100.c
@@ -54,7 +54,7 @@
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */
+static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */
static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */
static long mpu_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */
static long fm_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */
diff --git a/sound/isa/azt2320.c b/sound/isa/azt2320.c
index e55f3eb..6a2c78e 100644
--- a/sound/isa/azt2320.c
+++ b/sound/isa/azt2320.c
@@ -55,7 +55,7 @@
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP; /* Enable this card */
+static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP; /* Enable this card */
static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */
static long wss_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */
static long mpu_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */
diff --git a/sound/isa/cmi8330.c b/sound/isa/cmi8330.c
index c94578d..7bd5e33 100644
--- a/sound/isa/cmi8330.c
+++ b/sound/isa/cmi8330.c
@@ -69,9 +69,9 @@
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP;
+static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP;
#ifdef CONFIG_PNP
-static int isapnp[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1};
+static bool isapnp[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1};
#endif
static long sbport[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
static int sbirq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ;
diff --git a/sound/isa/cs423x/cs4231.c b/sound/isa/cs423x/cs4231.c
index 6d81fa7..99dda45 100644
--- a/sound/isa/cs423x/cs4231.c
+++ b/sound/isa/cs423x/cs4231.c
@@ -41,7 +41,7 @@
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */
+static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */
static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */
static long mpu_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */
static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* 5,7,9,11,12,15 */
diff --git a/sound/isa/cs423x/cs4236.c b/sound/isa/cs423x/cs4236.c
index f5a94b6..740c51a 100644
--- a/sound/isa/cs423x/cs4236.c
+++ b/sound/isa/cs423x/cs4236.c
@@ -74,9 +74,9 @@
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP; /* Enable this card */
+static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP; /* Enable this card */
#ifdef CONFIG_PNP
-static int isapnp[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1};
+static bool isapnp[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1};
#endif
static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */
static long cport[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */
diff --git a/sound/isa/es1688/es1688.c b/sound/isa/es1688/es1688.c
index 9a1a6f2..b036e60 100644
--- a/sound/isa/es1688/es1688.c
+++ b/sound/isa/es1688/es1688.c
@@ -51,9 +51,9 @@
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
#ifdef CONFIG_PNP
-static int isapnp[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP;
+static bool isapnp[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP;
#endif
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */
+static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */
static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* 0x220,0x240,0x260 */
static long fm_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* Usually 0x388 */
static long mpu_port[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = -1};
diff --git a/sound/isa/es18xx.c b/sound/isa/es18xx.c
index 98e3ac1..c20baaf 100644
--- a/sound/isa/es18xx.c
+++ b/sound/isa/es18xx.c
@@ -1964,9 +1964,9 @@
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP; /* Enable this card */
+static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP; /* Enable this card */
#ifdef CONFIG_PNP
-static int isapnp[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP;
+static bool isapnp[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP;
#endif
static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* 0x220,0x240,0x260,0x280 */
#ifndef CONFIG_PNP
diff --git a/sound/isa/galaxy/galaxy.c b/sound/isa/galaxy/galaxy.c
index e51d324..55e2078 100644
--- a/sound/isa/galaxy/galaxy.c
+++ b/sound/isa/galaxy/galaxy.c
@@ -35,7 +35,7 @@
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE;
+static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE;
module_param_array(index, int, NULL, 0444);
MODULE_PARM_DESC(index, "Index value for " CRD_NAME " soundcard.");
diff --git a/sound/isa/gus/gusclassic.c b/sound/isa/gus/gusclassic.c
index d729650..bf63336 100644
--- a/sound/isa/gus/gusclassic.c
+++ b/sound/isa/gus/gusclassic.c
@@ -42,7 +42,7 @@
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */
+static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */
static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* 0x220,0x230,0x240,0x250,0x260 */
static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* 3,5,9,11,12,15 */
static int dma1[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 1,3,5,6,7 */
diff --git a/sound/isa/gus/gusextreme.c b/sound/isa/gus/gusextreme.c
index 597accd..bc10cc2 100644
--- a/sound/isa/gus/gusextreme.c
+++ b/sound/isa/gus/gusextreme.c
@@ -46,7 +46,7 @@
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */
+static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */
static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* 0x220,0x240,0x260 */
static long gf1_port[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS) - 1] = -1}; /* 0x210,0x220,0x230,0x240,0x250,0x260,0x270 */
static long mpu_port[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS) - 1] = -1}; /* 0x300,0x310,0x320 */
diff --git a/sound/isa/gus/gusmax.c b/sound/isa/gus/gusmax.c
index 933cb0f..41c3f44 100644
--- a/sound/isa/gus/gusmax.c
+++ b/sound/isa/gus/gusmax.c
@@ -40,7 +40,7 @@
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */
+static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */
static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* 0x220,0x230,0x240,0x250,0x260 */
static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* 2,3,5,9,11,12,15 */
static int dma1[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 1,3,5,6,7 */
diff --git a/sound/isa/gus/interwave.c b/sound/isa/gus/interwave.c
index 8e7e194..a76bc8d 100644
--- a/sound/isa/gus/interwave.c
+++ b/sound/isa/gus/interwave.c
@@ -55,9 +55,9 @@
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP; /* Enable this card */
+static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP; /* Enable this card */
#ifdef CONFIG_PNP
-static int isapnp[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1};
+static bool isapnp[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1};
#endif
static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* 0x210,0x220,0x230,0x240,0x250,0x260 */
#ifdef SNDRV_STB
diff --git a/sound/isa/msnd/msnd_pinnacle.c b/sound/isa/msnd/msnd_pinnacle.c
index 0961e2c..29cc8e1 100644
--- a/sound/isa/msnd/msnd_pinnacle.c
+++ b/sound/isa/msnd/msnd_pinnacle.c
@@ -785,7 +785,7 @@
static int calibrate_signal;
#ifdef CONFIG_PNP
-static int isapnp[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
+static bool isapnp[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
module_param_array(isapnp, bool, NULL, 0444);
MODULE_PARM_DESC(isapnp, "ISA PnP detection for specified soundcard.");
#define has_isapnp(x) isapnp[x]
diff --git a/sound/isa/opl3sa2.c b/sound/isa/opl3sa2.c
index 64a9a21..f6cc0b9 100644
--- a/sound/isa/opl3sa2.c
+++ b/sound/isa/opl3sa2.c
@@ -46,9 +46,9 @@
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP; /* Enable this card */
+static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP; /* Enable this card */
#ifdef CONFIG_PNP
-static int isapnp[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1};
+static bool isapnp[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1};
#endif
static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* 0xf86,0x370,0x100 */
static long sb_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* 0x220,0x240,0x260 */
diff --git a/sound/isa/opti9xx/miro.c b/sound/isa/opti9xx/miro.c
index 3785b7a..c24594c 100644
--- a/sound/isa/opti9xx/miro.c
+++ b/sound/isa/opti9xx/miro.c
@@ -61,7 +61,7 @@
static int wss;
static int ide;
#ifdef CONFIG_PNP
-static int isapnp = 1; /* Enable ISA PnP detection */
+static bool isapnp = 1; /* Enable ISA PnP detection */
#endif
module_param(index, int, 0444);
diff --git a/sound/isa/opti9xx/opti92x-ad1848.c b/sound/isa/opti9xx/opti92x-ad1848.c
index 97871be..babaedd 100644
--- a/sound/isa/opti9xx/opti92x-ad1848.c
+++ b/sound/isa/opti9xx/opti92x-ad1848.c
@@ -63,7 +63,7 @@
static int index = SNDRV_DEFAULT_IDX1; /* Index 0-MAX */
static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */
-//static int enable = SNDRV_DEFAULT_ENABLE1; /* Enable this card */
+//static bool enable = SNDRV_DEFAULT_ENABLE1; /* Enable this card */
#ifdef CONFIG_PNP
static int isapnp = 1; /* Enable ISA PnP detection */
#endif
diff --git a/sound/isa/sb/jazz16.c b/sound/isa/sb/jazz16.c
index 54e3c2c..410758c 100644
--- a/sound/isa/sb/jazz16.c
+++ b/sound/isa/sb/jazz16.c
@@ -36,7 +36,7 @@
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */
+static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */
static unsigned long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
static unsigned long mpu_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ;
diff --git a/sound/isa/sb/sb16.c b/sound/isa/sb/sb16.c
index 115c774..39b8eca 100644
--- a/sound/isa/sb/sb16.c
+++ b/sound/isa/sb/sb16.c
@@ -68,9 +68,9 @@
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP; /* Enable this card */
+static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP; /* Enable this card */
#ifdef CONFIG_PNP
-static int isapnp[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1};
+static bool isapnp[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1};
#endif
static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* 0x220,0x240,0x260,0x280 */
static long mpu_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* 0x330,0x300 */
diff --git a/sound/isa/sb/sb8.c b/sound/isa/sb/sb8.c
index 453ef28..ab5cebe 100644
--- a/sound/isa/sb/sb8.c
+++ b/sound/isa/sb/sb8.c
@@ -36,7 +36,7 @@
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */
+static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */
static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* 0x220,0x240,0x260 */
static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* 5,7,9,10 */
static int dma8[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 1,3 */
diff --git a/sound/isa/sc6000.c b/sound/isa/sc6000.c
index 207c161..d97d0f3 100644
--- a/sound/isa/sc6000.c
+++ b/sound/isa/sc6000.c
@@ -48,7 +48,7 @@
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */
+static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */
static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* 0x220, 0x240 */
static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* 5, 7, 9, 10, 11 */
static long mss_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* 0x530, 0xe80 */
diff --git a/sound/isa/wavefront/wavefront.c b/sound/isa/wavefront/wavefront.c
index 150b96b..e0a7327 100644
--- a/sound/isa/wavefront/wavefront.c
+++ b/sound/isa/wavefront/wavefront.c
@@ -38,9 +38,9 @@
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */
+static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */
#ifdef CONFIG_PNP
-static int isapnp[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1};
+static bool isapnp[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1};
#endif
static long cs4232_pcm_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */
static int cs4232_pcm_irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* 5,7,9,11,12,15 */
@@ -51,7 +51,7 @@
static long fm_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */
static int dma1[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 0,1,3,5,6,7 */
static int dma2[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 0,1,3,5,6,7 */
-static int use_cs4232_midi[SNDRV_CARDS];
+static bool use_cs4232_midi[SNDRV_CARDS];
module_param_array(index, int, NULL, 0444);
MODULE_PARM_DESC(index, "Index value for WaveFront soundcard.");
diff --git a/sound/mips/hal2.c b/sound/mips/hal2.c
index 2e6c858..5f88d1f 100644
--- a/sound/mips/hal2.c
+++ b/sound/mips/hal2.c
@@ -935,15 +935,4 @@
}
};
-static int __init alsa_card_hal2_init(void)
-{
- return platform_driver_register(&hal2_driver);
-}
-
-static void __exit alsa_card_hal2_exit(void)
-{
- platform_driver_unregister(&hal2_driver);
-}
-
-module_init(alsa_card_hal2_init);
-module_exit(alsa_card_hal2_exit);
+module_platform_driver(hal2_driver);
diff --git a/sound/mips/sgio2audio.c b/sound/mips/sgio2audio.c
index 69425d4..ceaa593 100644
--- a/sound/mips/sgio2audio.c
+++ b/sound/mips/sgio2audio.c
@@ -976,15 +976,4 @@
}
};
-static int __init alsa_card_sgio2audio_init(void)
-{
- return platform_driver_register(&sgio2audio_driver);
-}
-
-static void __exit alsa_card_sgio2audio_exit(void)
-{
- platform_driver_unregister(&sgio2audio_driver);
-}
-
-module_init(alsa_card_sgio2audio_init)
-module_exit(alsa_card_sgio2audio_exit)
+module_platform_driver(sgio2audio_driver);
diff --git a/sound/oss/ad1848.c b/sound/oss/ad1848.c
index 8a197fd..98d23bd 100644
--- a/sound/oss/ad1848.c
+++ b/sound/oss/ad1848.c
@@ -119,9 +119,9 @@
static struct address_info cfg;
static int nr_ad1848_devs;
-static int deskpro_xl;
-static int deskpro_m;
-static int soundpro;
+static bool deskpro_xl;
+static bool deskpro_m;
+static bool soundpro;
static volatile signed char irq2dev[17] = {
-1, -1, -1, -1, -1, -1, -1, -1,
@@ -177,7 +177,7 @@
#ifdef CONFIG_PNP
static int isapnp = 1;
static int isapnpjump;
-static int reverse;
+static bool reverse;
static int audio_activated;
#else
diff --git a/sound/oss/msnd_pinnacle.c b/sound/oss/msnd_pinnacle.c
index 7b5c77b3..eba7345 100644
--- a/sound/oss/msnd_pinnacle.c
+++ b/sound/oss/msnd_pinnacle.c
@@ -1701,7 +1701,7 @@
#ifndef CONFIG_MSNDPIN_DIGITAL
# define CONFIG_MSNDPIN_DIGITAL 0
#endif
-static int digital __initdata = CONFIG_MSNDPIN_DIGITAL;
+static bool digital __initdata = CONFIG_MSNDPIN_DIGITAL;
#endif /* MSND_CLASSIC */
diff --git a/sound/oss/pas2_card.c b/sound/oss/pas2_card.c
index 7f377ec..dabf8a8 100644
--- a/sound/oss/pas2_card.c
+++ b/sound/oss/pas2_card.c
@@ -41,19 +41,19 @@
static int pas_sb_base;
DEFINE_SPINLOCK(pas_lock);
#ifndef CONFIG_PAS_JOYSTICK
-static int joystick;
+static bool joystick;
#else
-static int joystick = 1;
+static bool joystick = 1;
#endif
#ifdef SYMPHONY_PAS
-static int symphony = 1;
+static bool symphony = 1;
#else
-static int symphony;
+static bool symphony;
#endif
#ifdef BROKEN_BUS_CLOCK
-static int broken_bus_clock = 1;
+static bool broken_bus_clock = 1;
#else
-static int broken_bus_clock;
+static bool broken_bus_clock;
#endif
static struct address_info cfg;
diff --git a/sound/oss/pss.c b/sound/oss/pss.c
index 2fc0624..0f32a56 100644
--- a/sound/oss/pss.c
+++ b/sound/oss/pss.c
@@ -117,9 +117,9 @@
/* If compiled into kernel, it enable or disable pss mixer */
#ifdef CONFIG_PSS_MIXER
-static int pss_mixer = 1;
+static bool pss_mixer = 1;
#else
-static int pss_mixer;
+static bool pss_mixer;
#endif
@@ -147,7 +147,7 @@
static int pss_initialized;
static int nonstandard_microcode;
static int pss_cdrom_port = -1; /* Parameter for the PSS cdrom port */
-static int pss_enable_joystick; /* Parameter for enabling the joystick */
+static bool pss_enable_joystick; /* Parameter for enabling the joystick */
static coproc_operations pss_coproc_operations;
static void pss_write(pss_confdata *devc, int data)
@@ -1133,8 +1133,8 @@
static int mss_dma __initdata = -1;
static int mpu_io __initdata = -1;
static int mpu_irq __initdata = -1;
-static int pss_no_sound = 0; /* Just configure non-sound components */
-static int pss_keep_settings = 1; /* Keep hardware settings at module exit */
+static bool pss_no_sound = 0; /* Just configure non-sound components */
+static bool pss_keep_settings = 1; /* Keep hardware settings at module exit */
static char *pss_firmware = "/etc/sound/pss_synth";
module_param(pss_io, int, 0);
diff --git a/sound/oss/trix.c b/sound/oss/trix.c
index e04169e..944e0c0 100644
--- a/sound/oss/trix.c
+++ b/sound/oss/trix.c
@@ -31,7 +31,7 @@
static int mpu;
-static int joystick;
+static bool joystick;
static unsigned char trix_read(int addr)
{
diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c
index fac51ee..9473fca 100644
--- a/sound/pci/ac97/ac97_codec.c
+++ b/sound/pci/ac97/ac97_codec.c
@@ -42,7 +42,7 @@
MODULE_DESCRIPTION("Universal interface for Audio Codec '97");
MODULE_LICENSE("GPL");
-static int enable_loopback;
+static bool enable_loopback;
module_param(enable_loopback, bool, 0444);
MODULE_PARM_DESC(enable_loopback, "Enable AC97 ADC/DAC Loopback Control");
diff --git a/sound/pci/ad1889.c b/sound/pci/ad1889.c
index 6e31118..9d91d61 100644
--- a/sound/pci/ad1889.c
+++ b/sound/pci/ad1889.c
@@ -66,7 +66,7 @@
module_param_array(id, charp, NULL, 0444);
MODULE_PARM_DESC(id, "ID string for the AD1889 soundcard.");
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
+static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
module_param_array(enable, bool, NULL, 0444);
MODULE_PARM_DESC(enable, "Enable AD1889 soundcard.");
diff --git a/sound/pci/ali5451/ali5451.c b/sound/pci/ali5451/ali5451.c
index ef85ac5..bdd6164 100644
--- a/sound/pci/ali5451/ali5451.c
+++ b/sound/pci/ali5451/ali5451.c
@@ -48,7 +48,7 @@
static int index = SNDRV_DEFAULT_IDX1; /* Index */
static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */
static int pcm_channels = 32;
-static int spdif;
+static bool spdif;
module_param(index, int, 0444);
MODULE_PARM_DESC(index, "Index value for ALI M5451 PCI Audio.");
@@ -60,7 +60,7 @@
MODULE_PARM_DESC(spdif, "Support SPDIF I/O");
/* just for backward compatibility */
-static int enable;
+static bool enable;
module_param(enable, bool, 0444);
diff --git a/sound/pci/als300.c b/sound/pci/als300.c
index 8dc77a0..8196e22 100644
--- a/sound/pci/als300.c
+++ b/sound/pci/als300.c
@@ -115,7 +115,14 @@
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 bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
+
+module_param_array(index, int, NULL, 0444);
+MODULE_PARM_DESC(index, "Index value for ALS300 sound card.");
+module_param_array(id, charp, NULL, 0444);
+MODULE_PARM_DESC(id, "ID string for ALS300 sound card.");
+module_param_array(enable, bool, NULL, 0444);
+MODULE_PARM_DESC(enable, "Enable ALS300 sound card.");
struct snd_als300 {
unsigned long port;
diff --git a/sound/pci/als4000.c b/sound/pci/als4000.c
index 28ef40e..3269b80 100644
--- a/sound/pci/als4000.c
+++ b/sound/pci/als4000.c
@@ -90,7 +90,7 @@
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
+static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
#ifdef SUPPORT_JOYSTICK
static int joystick_port[SNDRV_CARDS];
#endif
diff --git a/sound/pci/asihpi/asihpi.c b/sound/pci/asihpi/asihpi.c
index f4b9e2b..e8de831 100644
--- a/sound/pci/asihpi/asihpi.c
+++ b/sound/pci/asihpi/asihpi.c
@@ -23,8 +23,11 @@
*/
#include "hpi_internal.h"
+#include "hpi_version.h"
#include "hpimsginit.h"
#include "hpioctl.h"
+#include "hpicmn.h"
+
#include <linux/pci.h>
#include <linux/init.h>
@@ -44,7 +47,8 @@
MODULE_LICENSE("GPL");
MODULE_AUTHOR("AudioScience inc. <support@audioscience.com>");
-MODULE_DESCRIPTION("AudioScience ALSA ASI5000 ASI6000 ASI87xx ASI89xx");
+MODULE_DESCRIPTION("AudioScience ALSA ASI5000 ASI6000 ASI87xx ASI89xx "
+ HPI_VER_STRING);
#if defined CONFIG_SND_DEBUG_VERBOSE
/**
@@ -63,8 +67,8 @@
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* index 0-MAX */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
-static int enable_hpi_hwdep = 1;
+static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
+static bool enable_hpi_hwdep = 1;
module_param_array(index, int, NULL, S_IRUGO);
MODULE_PARM_DESC(index, "ALSA index value for AudioScience soundcard.");
@@ -119,12 +123,7 @@
struct snd_card_asihpi {
struct snd_card *card;
struct pci_dev *pci;
- u16 adapter_index;
- u32 serial_number;
- u16 type;
- u16 version;
- u16 num_outstreams;
- u16 num_instreams;
+ struct hpi_adapter *hpi;
u32 h_mixer;
struct clk_cache cc;
@@ -135,6 +134,8 @@
u16 update_interval_frames;
u16 in_max_chans;
u16 out_max_chans;
+ u16 in_min_chans;
+ u16 out_min_chans;
};
/* Per stream data */
@@ -495,6 +496,7 @@
snd_printdd("stream_host_buffer_attach status 0x%x\n",
dpcm->hpi_buffer_attached);
+
}
bytes_per_sec = params_rate(params) * params_channels(params);
width = snd_pcm_format_width(params_format(params));
@@ -757,8 +759,7 @@
if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) {
pcm_buf_dma_ofs = ds->pcm_buf_host_rw_ofs - bytes_avail;
if (state == HPI_STATE_STOPPED) {
- if ((bytes_avail == 0) &&
- (on_card_bytes < ds->pcm_buf_host_rw_ofs)) {
+ if (bytes_avail == 0) {
hpi_handle_error(hpi_stream_start(ds->h_stream));
snd_printdd("P%d start\n", s->number);
ds->drained_count = 0;
@@ -767,7 +768,7 @@
snd_printd(KERN_WARNING "P%d drained\n",
s->number);
ds->drained_count++;
- if (ds->drained_count > 2) {
+ if (ds->drained_count > 20) {
snd_pcm_stop(s, SNDRV_PCM_STATE_XRUN);
continue;
}
@@ -888,8 +889,8 @@
pd, xfer2));
}
}
- ds->pcm_buf_host_rw_ofs = ds->pcm_buf_host_rw_ofs + xfercount;
- ds->pcm_buf_elapsed_dma_ofs = pcm_buf_dma_ofs;
+ ds->pcm_buf_host_rw_ofs += xfercount;
+ ds->pcm_buf_elapsed_dma_ofs += xfercount;
snd_pcm_period_elapsed(s);
}
}
@@ -902,7 +903,9 @@
static int snd_card_asihpi_playback_ioctl(struct snd_pcm_substream *substream,
unsigned int cmd, void *arg)
{
- snd_printddd(KERN_INFO "P%d ioctl %d\n", substream->number, cmd);
+ char name[16];
+ snd_pcm_debug_name(substream, name, sizeof(name));
+ snd_printddd(KERN_INFO "%s ioctl %d\n", name, cmd);
return snd_pcm_lib_ioctl(substream, cmd, arg);
}
@@ -927,21 +930,23 @@
struct snd_pcm_runtime *runtime = substream->runtime;
struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
snd_pcm_uframes_t ptr;
+ char name[16];
+ snd_pcm_debug_name(substream, name, sizeof(name));
ptr = bytes_to_frames(runtime, dpcm->pcm_buf_dma_ofs % dpcm->buffer_bytes);
- snd_printddd("P%d pointer = 0x%04lx\n", substream->number, (unsigned long)ptr);
+ snd_printddd("%s pointer = 0x%04lx\n", name, (unsigned long)ptr);
return ptr;
}
-static void snd_card_asihpi_playback_format(struct snd_card_asihpi *asihpi,
- u32 h_stream,
- struct snd_pcm_hardware *pcmhw)
+static u64 snd_card_asihpi_playback_formats(struct snd_card_asihpi *asihpi,
+ u32 h_stream)
{
struct hpi_format hpi_format;
u16 format;
u16 err;
u32 h_control;
u32 sample_rate = 48000;
+ u64 formats = 0;
/* on cards without SRC, must query at valid rate,
* maybe set by external sync
@@ -956,41 +961,29 @@
for (format = HPI_FORMAT_PCM8_UNSIGNED;
format <= HPI_FORMAT_PCM24_SIGNED; format++) {
- err = hpi_format_create(&hpi_format,
- 2, format, sample_rate, 128000, 0);
+ err = hpi_format_create(&hpi_format, asihpi->out_max_chans,
+ format, sample_rate, 128000, 0);
if (!err)
- err = hpi_outstream_query_format(h_stream,
- &hpi_format);
+ err = hpi_outstream_query_format(h_stream, &hpi_format);
if (!err && (hpi_to_alsa_formats[format] != -1))
- pcmhw->formats |=
- (1ULL << hpi_to_alsa_formats[format]);
+ formats |= (1ULL << hpi_to_alsa_formats[format]);
}
+ return formats;
}
-static struct snd_pcm_hardware snd_card_asihpi_playback = {
- .channels_min = 1,
- .channels_max = 2,
- .buffer_bytes_max = BUFFER_BYTES_MAX,
- .period_bytes_min = PERIOD_BYTES_MIN,
- .period_bytes_max = BUFFER_BYTES_MAX / PERIODS_MIN,
- .periods_min = PERIODS_MIN,
- .periods_max = BUFFER_BYTES_MAX / PERIOD_BYTES_MIN,
- .fifo_size = 0,
-};
-
static int snd_card_asihpi_playback_open(struct snd_pcm_substream *substream)
{
struct snd_pcm_runtime *runtime = substream->runtime;
struct snd_card_asihpi_pcm *dpcm;
struct snd_card_asihpi *card = snd_pcm_substream_chip(substream);
+ struct snd_pcm_hardware snd_card_asihpi_playback;
int err;
dpcm = kzalloc(sizeof(*dpcm), GFP_KERNEL);
if (dpcm == NULL)
return -ENOMEM;
- err =
- hpi_outstream_open(card->adapter_index,
+ err = hpi_outstream_open(card->hpi->adapter->index,
substream->number, &dpcm->h_stream);
hpi_handle_error(err);
if (err)
@@ -1012,12 +1005,19 @@
runtime->private_data = dpcm;
runtime->private_free = snd_card_asihpi_runtime_free;
- snd_card_asihpi_playback.channels_max = card->out_max_chans;
+ memset(&snd_card_asihpi_playback, 0, sizeof(snd_card_asihpi_playback));
+ snd_card_asihpi_playback.buffer_bytes_max = BUFFER_BYTES_MAX;
+ snd_card_asihpi_playback.period_bytes_min = PERIOD_BYTES_MIN;
/*?snd_card_asihpi_playback.period_bytes_min =
card->out_max_chans * 4096; */
-
- snd_card_asihpi_playback_format(card, dpcm->h_stream,
- &snd_card_asihpi_playback);
+ snd_card_asihpi_playback.period_bytes_max = BUFFER_BYTES_MAX / PERIODS_MIN;
+ snd_card_asihpi_playback.periods_min = PERIODS_MIN;
+ snd_card_asihpi_playback.periods_max = BUFFER_BYTES_MAX / PERIOD_BYTES_MIN;
+ /* snd_card_asihpi_playback.fifo_size = 0; */
+ snd_card_asihpi_playback.channels_max = card->out_max_chans;
+ snd_card_asihpi_playback.channels_min = card->out_min_chans;
+ snd_card_asihpi_playback.formats =
+ snd_card_asihpi_playback_formats(card, dpcm->h_stream);
snd_card_asihpi_pcm_samplerates(card, &snd_card_asihpi_playback);
@@ -1029,8 +1029,10 @@
SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_MMAP_VALID;
- if (card->support_grouping)
+ if (card->support_grouping) {
snd_card_asihpi_playback.info |= SNDRV_PCM_INFO_SYNC_START;
+ snd_pcm_set_sync(substream);
+ }
/* struct is copied, so can create initializer dynamically */
runtime->hw = snd_card_asihpi_playback;
@@ -1047,8 +1049,6 @@
snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
card->update_interval_frames * 2, UINT_MAX);
- snd_pcm_set_sync(substream);
-
snd_printdd("playback open\n");
return 0;
@@ -1114,15 +1114,15 @@
-static void snd_card_asihpi_capture_format(struct snd_card_asihpi *asihpi,
- u32 h_stream,
- struct snd_pcm_hardware *pcmhw)
+static u64 snd_card_asihpi_capture_formats(struct snd_card_asihpi *asihpi,
+ u32 h_stream)
{
struct hpi_format hpi_format;
u16 format;
u16 err;
u32 h_control;
u32 sample_rate = 48000;
+ u64 formats = 0;
/* on cards without SRC, must query at valid rate,
maybe set by external sync */
@@ -1137,34 +1137,22 @@
for (format = HPI_FORMAT_PCM8_UNSIGNED;
format <= HPI_FORMAT_PCM24_SIGNED; format++) {
- err = hpi_format_create(&hpi_format, 2, format,
- sample_rate, 128000, 0);
+ err = hpi_format_create(&hpi_format, asihpi->in_max_chans,
+ format, sample_rate, 128000, 0);
if (!err)
- err = hpi_instream_query_format(h_stream,
- &hpi_format);
+ err = hpi_instream_query_format(h_stream, &hpi_format);
if (!err)
- pcmhw->formats |=
- (1ULL << hpi_to_alsa_formats[format]);
+ formats |= (1ULL << hpi_to_alsa_formats[format]);
}
+ return formats;
}
-
-static struct snd_pcm_hardware snd_card_asihpi_capture = {
- .channels_min = 1,
- .channels_max = 2,
- .buffer_bytes_max = BUFFER_BYTES_MAX,
- .period_bytes_min = PERIOD_BYTES_MIN,
- .period_bytes_max = BUFFER_BYTES_MAX / PERIODS_MIN,
- .periods_min = PERIODS_MIN,
- .periods_max = BUFFER_BYTES_MAX / PERIOD_BYTES_MIN,
- .fifo_size = 0,
-};
-
static int snd_card_asihpi_capture_open(struct snd_pcm_substream *substream)
{
struct snd_pcm_runtime *runtime = substream->runtime;
struct snd_card_asihpi *card = snd_pcm_substream_chip(substream);
struct snd_card_asihpi_pcm *dpcm;
+ struct snd_pcm_hardware snd_card_asihpi_capture;
int err;
dpcm = kzalloc(sizeof(*dpcm), GFP_KERNEL);
@@ -1172,10 +1160,10 @@
return -ENOMEM;
snd_printdd("capture open adapter %d stream %d\n",
- card->adapter_index, substream->number);
+ card->hpi->adapter->index, substream->number);
err = hpi_handle_error(
- hpi_instream_open(card->adapter_index,
+ hpi_instream_open(card->hpi->adapter->index,
substream->number, &dpcm->h_stream));
if (err)
kfree(dpcm);
@@ -1184,7 +1172,6 @@
if (err)
return -EIO;
-
init_timer(&dpcm->timer);
dpcm->timer.data = (unsigned long) dpcm;
dpcm->timer.function = snd_card_asihpi_timer_function;
@@ -1192,9 +1179,17 @@
runtime->private_data = dpcm;
runtime->private_free = snd_card_asihpi_runtime_free;
+ memset(&snd_card_asihpi_capture, 0, sizeof(snd_card_asihpi_capture));
+ snd_card_asihpi_capture.buffer_bytes_max = BUFFER_BYTES_MAX;
+ snd_card_asihpi_capture.period_bytes_min = PERIOD_BYTES_MIN;
+ snd_card_asihpi_capture.period_bytes_max = BUFFER_BYTES_MAX / PERIODS_MIN;
+ snd_card_asihpi_capture.periods_min = PERIODS_MIN;
+ snd_card_asihpi_capture.periods_max = BUFFER_BYTES_MAX / PERIOD_BYTES_MIN;
+ /* snd_card_asihpi_capture.fifo_size = 0; */
snd_card_asihpi_capture.channels_max = card->in_max_chans;
- snd_card_asihpi_capture_format(card, dpcm->h_stream,
- &snd_card_asihpi_capture);
+ snd_card_asihpi_capture.channels_min = card->in_min_chans;
+ snd_card_asihpi_capture.formats =
+ snd_card_asihpi_capture_formats(card, dpcm->h_stream);
snd_card_asihpi_pcm_samplerates(card, &snd_card_asihpi_capture);
snd_card_asihpi_capture.info = SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_MMAP |
@@ -1240,15 +1235,20 @@
.pointer = snd_card_asihpi_capture_pointer,
};
-static int __devinit snd_card_asihpi_pcm_new(struct snd_card_asihpi *asihpi,
- int device, int substreams)
+static int __devinit snd_card_asihpi_pcm_new(
+ struct snd_card_asihpi *asihpi, int device)
{
struct snd_pcm *pcm;
int err;
+ u16 num_instreams, num_outstreams, x16;
+ u32 x32;
+
+ err = hpi_adapter_get_info(asihpi->hpi->adapter->index,
+ &num_outstreams, &num_instreams,
+ &x16, &x32, &x16);
err = snd_pcm_new(asihpi->card, "Asihpi PCM", device,
- asihpi->num_outstreams, asihpi->num_instreams,
- &pcm);
+ num_outstreams, num_instreams, &pcm);
if (err < 0)
return err;
/* pointer to ops struct is stored, dont change ops afterwards! */
@@ -1314,7 +1314,7 @@
"Analog",
"Adapter",
"RTP",
- "GPI",
+ "Internal"
};
compile_time_assert(
@@ -1332,7 +1332,6 @@
"Net",
"Analog",
"RTP",
- "GPO",
};
compile_time_assert(
@@ -1410,6 +1409,7 @@
struct snd_ctl_elem_info *uinfo)
{
u32 h_control = kcontrol->private_value;
+ u32 count;
u16 err;
/* native gains are in millibels */
short min_gain_mB;
@@ -1424,8 +1424,12 @@
step_gain_mB = VOL_STEP_mB;
}
+ err = hpi_meter_query_channels(h_control, &count);
+ if (err)
+ count = HPI_MAX_CHANNELS;
+
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 2;
+ uinfo->count = count;
uinfo->value.integer.min = min_gain_mB / VOL_STEP_mB;
uinfo->value.integer.max = max_gain_mB / VOL_STEP_mB;
uinfo->value.integer.step = step_gain_mB / VOL_STEP_mB;
@@ -2033,8 +2037,15 @@
static int snd_asihpi_meter_info(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_info *uinfo)
{
+ u32 h_control = kcontrol->private_value;
+ u32 count;
+ u16 err;
+ err = hpi_meter_query_channels(h_control, &count);
+ if (err)
+ count = HPI_MAX_CHANNELS;
+
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = HPI_MAX_CHANNELS;
+ uinfo->count = count;
uinfo->value.integer.min = 0;
uinfo->value.integer.max = 0x7FFFFFFF;
return 0;
@@ -2248,6 +2259,9 @@
valid_modes++;
}
+ if (!valid_modes)
+ return -EINVAL;
+
uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
uinfo->count = 1;
uinfo->value.enumerated.items = valid_modes;
@@ -2547,7 +2561,7 @@
strcpy(card->mixername, "Asihpi Mixer");
err =
- hpi_mixer_open(asihpi->adapter_index,
+ hpi_mixer_open(asihpi->hpi->adapter->index,
&asihpi->h_mixer);
hpi_handle_error(err);
if (err)
@@ -2665,24 +2679,33 @@
struct snd_info_buffer *buffer)
{
struct snd_card_asihpi *asihpi = entry->private_data;
- u16 version;
u32 h_control;
u32 rate = 0;
u16 source = 0;
+
+ u16 num_outstreams;
+ u16 num_instreams;
+ u16 version;
+ u32 serial_number;
+ u16 type;
+
int err;
snd_iprintf(buffer, "ASIHPI driver proc file\n");
- snd_iprintf(buffer,
- "adapter ID=%4X\n_index=%d\n"
- "num_outstreams=%d\n_num_instreams=%d\n",
- asihpi->type, asihpi->adapter_index,
- asihpi->num_outstreams, asihpi->num_instreams);
- version = asihpi->version;
+ hpi_handle_error(hpi_adapter_get_info(asihpi->hpi->adapter->index,
+ &num_outstreams, &num_instreams,
+ &version, &serial_number, &type));
+
snd_iprintf(buffer,
- "serial#=%d\n_hw version %c%d\nDSP code version %03d\n",
- asihpi->serial_number, ((version >> 3) & 0xf) + 'A',
- version & 0x7,
+ "Adapter type ASI%4X\nHardware Index %d\n"
+ "%d outstreams\n%d instreams\n",
+ type, asihpi->hpi->adapter->index,
+ num_outstreams, num_instreams);
+
+ snd_iprintf(buffer,
+ "Serial#%d\nHardware version %c%d\nDSP code version %03d\n",
+ serial_number, ((version >> 3) & 0xf) + 'A', version & 0x7,
((version >> 13) * 100) + ((version >> 7) & 0x3f));
err = hpi_mixer_get_control(asihpi->h_mixer,
@@ -2690,18 +2713,15 @@
HPI_CONTROL_SAMPLECLOCK, &h_control);
if (!err) {
- err = hpi_sample_clock_get_sample_rate(
- h_control, &rate);
+ err = hpi_sample_clock_get_sample_rate(h_control, &rate);
err += hpi_sample_clock_get_source(h_control, &source);
if (!err)
- snd_iprintf(buffer, "sample_clock=%d_hz, source %s\n",
+ snd_iprintf(buffer, "Sample Clock %dHz, source %s\n",
rate, sampleclock_sources[source]);
}
-
}
-
static void __devinit snd_asihpi_proc_init(struct snd_card_asihpi *asihpi)
{
struct snd_info_entry *entry;
@@ -2773,35 +2793,34 @@
const struct pci_device_id *pci_id)
{
int err;
-
- u16 version;
- int pcm_substreams;
-
- struct hpi_adapter *hpi_card;
+ struct hpi_adapter *hpi;
struct snd_card *card;
struct snd_card_asihpi *asihpi;
u32 h_control;
u32 h_stream;
+ u32 adapter_index;
static int dev;
if (dev >= SNDRV_CARDS)
return -ENODEV;
- /* Should this be enable[hpi_card->index] ? */
+ /* Should this be enable[hpi->index] ? */
if (!enable[dev]) {
dev++;
return -ENOENT;
}
+ /* Initialise low-level HPI driver */
err = asihpi_adapter_probe(pci_dev, pci_id);
if (err < 0)
return err;
- hpi_card = pci_get_drvdata(pci_dev);
+ hpi = pci_get_drvdata(pci_dev);
+ adapter_index = hpi->adapter->index;
/* first try to give the card the same index as its hardware index */
- err = snd_card_create(hpi_card->index,
- id[hpi_card->index], THIS_MODULE,
+ err = snd_card_create(adapter_index,
+ id[adapter_index], THIS_MODULE,
sizeof(struct snd_card_asihpi),
&card);
if (err < 0) {
@@ -2815,50 +2834,32 @@
return err;
snd_printk(KERN_WARNING
"**** WARNING **** Adapter index %d->ALSA index %d\n",
- hpi_card->index, card->number);
+ adapter_index, card->number);
}
snd_card_set_dev(card, &pci_dev->dev);
- asihpi = (struct snd_card_asihpi *) card->private_data;
+ asihpi = card->private_data;
asihpi->card = card;
asihpi->pci = pci_dev;
- asihpi->adapter_index = hpi_card->index;
- hpi_handle_error(hpi_adapter_get_info(
- asihpi->adapter_index,
- &asihpi->num_outstreams,
- &asihpi->num_instreams,
- &asihpi->version,
- &asihpi->serial_number, &asihpi->type));
+ asihpi->hpi = hpi;
- version = asihpi->version;
- snd_printk(KERN_INFO "adapter ID=%4X index=%d num_outstreams=%d "
- "num_instreams=%d S/N=%d\n"
- "Hw Version %c%d DSP code version %03d\n",
- asihpi->type, asihpi->adapter_index,
- asihpi->num_outstreams,
- asihpi->num_instreams, asihpi->serial_number,
- ((version >> 3) & 0xf) + 'A',
- version & 0x7,
- ((version >> 13) * 100) + ((version >> 7) & 0x3f));
+ snd_printk(KERN_INFO "adapter ID=%4X index=%d\n",
+ asihpi->hpi->adapter->type, adapter_index);
- pcm_substreams = asihpi->num_outstreams;
- if (pcm_substreams < asihpi->num_instreams)
- pcm_substreams = asihpi->num_instreams;
-
- err = hpi_adapter_get_property(asihpi->adapter_index,
+ err = hpi_adapter_get_property(adapter_index,
HPI_ADAPTER_PROPERTY_CAPS1,
NULL, &asihpi->support_grouping);
if (err)
asihpi->support_grouping = 0;
- err = hpi_adapter_get_property(asihpi->adapter_index,
+ err = hpi_adapter_get_property(adapter_index,
HPI_ADAPTER_PROPERTY_CAPS2,
&asihpi->support_mrx, NULL);
if (err)
asihpi->support_mrx = 0;
- err = hpi_adapter_get_property(asihpi->adapter_index,
+ err = hpi_adapter_get_property(adapter_index,
HPI_ADAPTER_PROPERTY_INTERVAL,
NULL, &asihpi->update_interval_frames);
if (err)
@@ -2867,7 +2868,7 @@
if (!asihpi->can_dma)
asihpi->update_interval_frames *= 2;
- hpi_handle_error(hpi_instream_open(asihpi->adapter_index,
+ hpi_handle_error(hpi_instream_open(adapter_index,
0, &h_stream));
err = hpi_instream_host_buffer_free(h_stream);
@@ -2875,7 +2876,7 @@
hpi_handle_error(hpi_instream_close(h_stream));
- err = hpi_adapter_get_property(asihpi->adapter_index,
+ err = hpi_adapter_get_property(adapter_index,
HPI_ADAPTER_PROPERTY_CURCHANNELS,
&asihpi->in_max_chans, &asihpi->out_max_chans);
if (err) {
@@ -2883,13 +2884,22 @@
asihpi->out_max_chans = 2;
}
- snd_printk(KERN_INFO "has dma:%d, grouping:%d, mrx:%d\n",
+ if (asihpi->out_max_chans > 2) { /* assume LL mode */
+ asihpi->out_min_chans = asihpi->out_max_chans;
+ asihpi->in_min_chans = asihpi->in_max_chans;
+ asihpi->support_grouping = 0;
+ } else {
+ asihpi->out_min_chans = 1;
+ asihpi->in_min_chans = 1;
+ }
+
+ snd_printk(KERN_INFO "Has dma:%d, grouping:%d, mrx:%d\n",
asihpi->can_dma,
asihpi->support_grouping,
asihpi->support_mrx
);
- err = snd_card_asihpi_pcm_new(asihpi, 0, pcm_substreams);
+ err = snd_card_asihpi_pcm_new(asihpi, 0);
if (err < 0) {
snd_printk(KERN_ERR "pcm_new failed\n");
goto __nodev;
@@ -2916,13 +2926,14 @@
strcpy(card->driver, "ASIHPI");
- sprintf(card->shortname, "AudioScience ASI%4X", asihpi->type);
+ sprintf(card->shortname, "AudioScience ASI%4X",
+ asihpi->hpi->adapter->type);
sprintf(card->longname, "%s %i",
- card->shortname, asihpi->adapter_index);
+ card->shortname, adapter_index);
err = snd_card_register(card);
if (!err) {
- hpi_card->snd_card_asihpi = card;
+ hpi->snd_card = card;
dev++;
return 0;
}
@@ -2935,10 +2946,9 @@
static void __devexit snd_asihpi_remove(struct pci_dev *pci_dev)
{
- struct hpi_adapter *hpi_card = pci_get_drvdata(pci_dev);
-
- snd_card_free(hpi_card->snd_card_asihpi);
- hpi_card->snd_card_asihpi = NULL;
+ struct hpi_adapter *hpi = pci_get_drvdata(pci_dev);
+ snd_card_free(hpi->snd_card);
+ hpi->snd_card = NULL;
asihpi_adapter_remove(pci_dev);
}
diff --git a/sound/pci/asihpi/hpi.h b/sound/pci/asihpi/hpi.h
index f207272..2088724 100644
--- a/sound/pci/asihpi/hpi.h
+++ b/sound/pci/asihpi/hpi.h
@@ -30,26 +30,8 @@
#ifndef _HPI_H_
#define _HPI_H_
-/* HPI Version
-If HPI_VER_MINOR is odd then its a development release not intended for the
-public. If HPI_VER_MINOR is even then is a release version
-i.e 3.05.02 is a development version
-*/
-#define HPI_VERSION_CONSTRUCTOR(maj, min, rel) \
- ((maj << 16) + (min << 8) + rel)
-
-#define HPI_VER_MAJOR(v) ((int)(v >> 16))
-#define HPI_VER_MINOR(v) ((int)((v >> 8) & 0xFF))
-#define HPI_VER_RELEASE(v) ((int)(v & 0xFF))
-
-#define HPI_VER HPI_VERSION_CONSTRUCTOR(4L, 8, 0)
-#define HPI_VER_STRING "4.08.00"
-
-/* Library version as documented in hpi-api-versions.txt */
-#define HPI_LIB_VER HPI_VERSION_CONSTRUCTOR(10, 0, 0)
#include <linux/types.h>
-#define HPI_BUILD_EXCLUDE_DEPRECATED
#define HPI_BUILD_KERNEL_MODE
/******************************************************************************/
@@ -213,7 +195,7 @@
/** RTP stream input node - This node is a destination for
packets of RTP audio samples from other devices. */
HPI_SOURCENODE_RTP_DESTINATION = 112,
- HPI_SOURCENODE_GP_IN = 113, /**< general purpose input. */
+ HPI_SOURCENODE_INTERNAL = 113, /**< node internal to the device. */
/* !!!Update this AND hpidebug.h if you add a new sourcenode type!!! */
HPI_SOURCENODE_LAST_INDEX = 113 /**< largest ID */
/* AX6 max sourcenode types = 15 */
@@ -242,9 +224,8 @@
/** RTP stream output node - This node is a source for
packets of RTP audio samples that are sent to other devices. */
HPI_DESTNODE_RTP_SOURCE = 208,
- HPI_DESTNODE_GP_OUT = 209, /**< general purpose output node. */
/* !!!Update this AND hpidebug.h if you add a new destnode type!!! */
- HPI_DESTNODE_LAST_INDEX = 209 /**< largest ID */
+ HPI_DESTNODE_LAST_INDEX = 208 /**< largest ID */
/* AX6 max destnode types = 15 */
};
@@ -450,7 +431,19 @@
across the host bus. Note, this does not imply that interrupts are
enabled. Instead it indicates that they can be enabled.
*/
- HPI_ADAPTER_PROPERTY_SUPPORTS_IRQ = 272
+ HPI_ADAPTER_PROPERTY_SUPPORTS_IRQ = 272,
+/** Readonly supports firmware updating.
+Indicates that the adapter implements an interface to update firmware
+on the adapter.
+*/
+ HPI_ADAPTER_PROPERTY_SUPPORTS_FW_UPDATE = 273,
+/** Readonly Firmware IDs
+Identifiy firmware independent of individual adapter type.
+May be used as a filter for firmware update images.
+Property 1 = Bootloader ID
+Property 2 = Main program ID
+*/
+ HPI_ADAPTER_PROPERTY_FIRMWARE_ID = 274
};
/** Adapter mode commands
@@ -638,7 +631,7 @@
HPI_MIXER_STORE_ENABLE = 4,
/** Disable auto storage of some control settings. */
HPI_MIXER_STORE_DISABLE = 5,
-/** Save the attributes of a single control. */
+/** Unimplemented - save the attributes of a single control. */
HPI_MIXER_STORE_SAVE_SINGLE = 6
};
@@ -941,7 +934,7 @@
HPI_ERROR_BAD_ADAPTER_NUMBER = 202,
/** 2 adapters with the same adapter number. */
HPI_ERROR_DUPLICATE_ADAPTER_NUMBER = 203,
- /** DSP code failed to bootload. (unused?) */
+ /** DSP code failed to bootload. Usually a DSP memory test failure. */
HPI_ERROR_DSP_BOOTLOAD = 204,
/** Couldn't find or open the DSP code file. */
HPI_ERROR_DSP_FILE_NOT_FOUND = 206,
@@ -978,6 +971,9 @@
HPI_ERROR_FLASH_VERIFY = 225,
HPI_ERROR_FLASH_TYPE = 226,
HPI_ERROR_FLASH_START = 227,
+ HPI_ERROR_FLASH_READ = 228,
+ HPI_ERROR_FLASH_READ_NO_FILE = 229,
+ HPI_ERROR_FLASH_SIZE = 230,
/** Reserved for OEMs. */
HPI_ERROR_RESERVED_1 = 290,
@@ -1020,6 +1016,8 @@
HPI_ERROR_NO_INTERDSP_GROUPS = 315,
/** Stream wait cancelled before threshold reached. */
HPI_ERROR_WAIT_CANCELLED = 316,
+ /** A character string is invalid. */
+ HPI_ERROR_INVALID_STRING = 317,
/** Invalid mixer node for this adapter. */
HPI_ERROR_INVALID_NODE = 400,
@@ -1046,11 +1044,15 @@
/** I2C */
HPI_ERROR_I2C_BAD_ADR = 460,
- /** Entity errors */
+ /** Entity type did not match requested type */
HPI_ERROR_ENTITY_TYPE_MISMATCH = 470,
+ /** Entity item count did not match requested count */
HPI_ERROR_ENTITY_ITEM_COUNT = 471,
+ /** Entity type is not one of the valid types */
HPI_ERROR_ENTITY_TYPE_INVALID = 472,
+ /** Entity role is not one of the valid roles */
HPI_ERROR_ENTITY_ROLE_INVALID = 473,
+ /** Entity size doesn't match target size */
HPI_ERROR_ENTITY_SIZE_MISMATCH = 474,
/* AES18 specific errors were 500..507 */
@@ -1078,8 +1080,7 @@
/** \defgroup maximums HPI maximum values
\{
*/
-/** Maximum number of adapters per HPI sub-system
- WARNING: modifying this value changes the response structure size.*/
+/** Maximum number of PCI HPI adapters */
#define HPI_MAX_ADAPTERS 20
/** Maximum number of in or out streams per adapter */
#define HPI_MAX_STREAMS 16
@@ -1090,6 +1091,9 @@
#define HPI_MAX_ANC_BYTES_PER_FRAME (64)
#define HPI_STRING_LEN 16
+/** Networked adapters have index >= 100 */
+#define HPI_MIN_NETWORK_ADAPTER_IDX 100
+
/** Velocity units */
#define HPI_OSTREAM_VELOCITY_UNITS 4096
/** OutStream timescale units */
@@ -1111,14 +1115,14 @@
struct hpi_format {
u32 sample_rate;
/**< 11025, 32000, 44100 ... */
- u32 bit_rate; /**< for MPEG */
+ u32 bit_rate; /**< for MPEG */
u32 attributes;
/**< Stereo/JointStereo/Mono */
u16 mode_legacy;
/**< Legacy ancillary mode or idle bit */
- u16 unused; /**< Unused */
- u16 channels; /**< 1,2..., (or ancillary mode or idle bit */
- u16 format; /**< HPI_FORMAT_PCM16, _MPEG etc. see #HPI_FORMATS. */
+ u16 unused; /**< Unused */
+ u16 channels; /**< 1,2..., (or ancillary mode or idle bit */
+ u16 format; /**< HPI_FORMAT_PCM16, _MPEG etc. see #HPI_FORMATS. */
};
struct hpi_anc_frame {
@@ -1144,9 +1148,6 @@
} u;
};
-/* skip host side function declarations for
- DSP compile and documentation extraction */
-
#ifndef DISABLE_PRAGMA_PACK1
#pragma pack(pop)
#endif
@@ -1357,7 +1358,7 @@
u16 hpi_volume_query_range(u32 h_control, short *min_gain_01dB,
short *max_gain_01dB, short *step_gain_01dB);
-u16 hpi_volume_query_channels(const u32 h_volume, u32 *p_channels);
+u16 hpi_volume_query_channels(const u32 h_control, u32 *p_channels);
u16 hpi_volume_auto_fade(u32 h_control,
short an_stop_gain0_01dB[HPI_MAX_CHANNELS], u32 duration_ms);
@@ -1366,6 +1367,9 @@
short an_stop_gain0_01dB[HPI_MAX_CHANNELS], u32 duration_ms,
u16 profile);
+u16 hpi_volume_query_auto_fade_profile(const u32 h_control, const u32 i,
+ u16 *profile);
+
/*****************/
/* Level control */
/*****************/
diff --git a/sound/pci/asihpi/hpi6000.c b/sound/pci/asihpi/hpi6000.c
index 3cc6f11..2414d7a 100644
--- a/sound/pci/asihpi/hpi6000.c
+++ b/sound/pci/asihpi/hpi6000.c
@@ -1,7 +1,7 @@
/******************************************************************************
AudioScience HPI driver
- Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
+ Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com>
This program is free software; you can redistribute it and/or modify
it under the terms of version 2 of the GNU General Public License as
@@ -231,6 +231,8 @@
static void control_message(struct hpi_adapter_obj *pao,
struct hpi_message *phm, struct hpi_response *phr)
{
+ struct hpi_hw_obj *phw = pao->priv;
+
switch (phm->function) {
case HPI_CONTROL_GET_STATE:
if (pao->has_control_cache) {
@@ -248,17 +250,14 @@
break;
}
- if (hpi_check_control_cache(((struct hpi_hw_obj *)
- pao->priv)->p_cache, phm,
- phr))
+ if (hpi_check_control_cache(phw->p_cache, phm, phr))
break;
}
hw_message(pao, phm, phr);
break;
case HPI_CONTROL_SET_STATE:
hw_message(pao, phm, phr);
- hpi_cmn_control_cache_sync_to_msg(((struct hpi_hw_obj *)pao->
- priv)->p_cache, phm, phr);
+ hpi_cmn_control_cache_sync_to_msg(phw->p_cache, phm, phr);
break;
case HPI_CONTROL_GET_INFO:
@@ -451,11 +450,11 @@
}
for (dsp_index = 0; dsp_index < MAX_DSPS; dsp_index++) {
- struct hpi_hw_obj *phw = (struct hpi_hw_obj *)pao->priv;
+ struct hpi_hw_obj *phw = pao->priv;
phw->ado[dsp_index].pa_parent_adapter = pao;
}
- phr->u.s.adapter_type = ao.adapter_type;
+ phr->u.s.adapter_type = ao.type;
phr->u.s.adapter_index = ao.index;
phr->error = 0;
}
@@ -476,7 +475,7 @@
u32 dsp_index = 0;
u32 control_cache_size = 0;
u32 control_cache_count = 0;
- struct hpi_hw_obj *phw = (struct hpi_hw_obj *)pao->priv;
+ struct hpi_hw_obj *phw = pao->priv;
/* The PCI2040 has the following address map */
/* BAR0 - 4K = HPI control and status registers on PCI2040 (HPI CSR) */
@@ -559,7 +558,7 @@
if (error)
return error;
}
- pao->adapter_type = hr0.u.ax.info.adapter_type;
+ pao->type = hr0.u.ax.info.adapter_type;
pao->index = hr0.u.ax.info.adapter_index;
}
@@ -584,9 +583,8 @@
pao->has_control_cache = 1;
}
- HPI_DEBUG_LOG(DEBUG, "get adapter info ASI%04X index %d\n",
- pao->adapter_type, pao->index);
- pao->open = 0; /* upon creation the adapter is closed */
+ HPI_DEBUG_LOG(DEBUG, "get adapter info ASI%04X index %d\n", pao->type,
+ pao->index);
if (phw->p_cache)
phw->p_cache->adap_idx = pao->index;
@@ -596,7 +594,7 @@
static void delete_adapter_obj(struct hpi_adapter_obj *pao)
{
- struct hpi_hw_obj *phw = (struct hpi_hw_obj *)pao->priv;
+ struct hpi_hw_obj *phw = pao->priv;
if (pao->has_control_cache)
hpi_free_control_cache(phw->p_cache);
@@ -639,7 +637,7 @@
static short hpi6000_adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
u32 *pos_error_code)
{
- struct hpi_hw_obj *phw = (struct hpi_hw_obj *)pao->priv;
+ struct hpi_hw_obj *phw = pao->priv;
short error;
u32 timeout;
u32 read = 0;
@@ -1220,8 +1218,8 @@
static u16 hpi6000_dsp_block_write32(struct hpi_adapter_obj *pao,
u16 dsp_index, u32 hpi_address, u32 *source, u32 count)
{
- struct dsp_obj *pdo =
- &(*(struct hpi_hw_obj *)pao->priv).ado[dsp_index];
+ struct hpi_hw_obj *phw = pao->priv;
+ struct dsp_obj *pdo = &phw->ado[dsp_index];
u32 time_out = PCI_TIMEOUT;
int c6711_burst_size = 128;
u32 local_hpi_address = hpi_address;
@@ -1258,8 +1256,8 @@
static u16 hpi6000_dsp_block_read32(struct hpi_adapter_obj *pao,
u16 dsp_index, u32 hpi_address, u32 *dest, u32 count)
{
- struct dsp_obj *pdo =
- &(*(struct hpi_hw_obj *)pao->priv).ado[dsp_index];
+ struct hpi_hw_obj *phw = pao->priv;
+ struct dsp_obj *pdo = &phw->ado[dsp_index];
u32 time_out = PCI_TIMEOUT;
int c6711_burst_size = 16;
u32 local_hpi_address = hpi_address;
@@ -1298,7 +1296,7 @@
static short hpi6000_message_response_sequence(struct hpi_adapter_obj *pao,
u16 dsp_index, struct hpi_message *phm, struct hpi_response *phr)
{
- struct hpi_hw_obj *phw = (struct hpi_hw_obj *)pao->priv;
+ struct hpi_hw_obj *phw = pao->priv;
struct dsp_obj *pdo = &phw->ado[dsp_index];
u32 timeout;
u16 ack;
@@ -1414,8 +1412,8 @@
static short hpi6000_send_data(struct hpi_adapter_obj *pao, u16 dsp_index,
struct hpi_message *phm, struct hpi_response *phr)
{
- struct dsp_obj *pdo =
- &(*(struct hpi_hw_obj *)pao->priv).ado[dsp_index];
+ struct hpi_hw_obj *phw = pao->priv;
+ struct dsp_obj *pdo = &phw->ado[dsp_index];
u32 data_sent = 0;
u16 ack;
u32 length, address;
@@ -1487,8 +1485,8 @@
static short hpi6000_get_data(struct hpi_adapter_obj *pao, u16 dsp_index,
struct hpi_message *phm, struct hpi_response *phr)
{
- struct dsp_obj *pdo =
- &(*(struct hpi_hw_obj *)pao->priv).ado[dsp_index];
+ struct hpi_hw_obj *phw = pao->priv;
+ struct dsp_obj *pdo = &phw->ado[dsp_index];
u32 data_got = 0;
u16 ack;
u32 length, address;
@@ -1551,8 +1549,8 @@
static short hpi6000_send_host_command(struct hpi_adapter_obj *pao,
u16 dsp_index, u32 host_cmd)
{
- struct dsp_obj *pdo =
- &(*(struct hpi_hw_obj *)pao->priv).ado[dsp_index];
+ struct hpi_hw_obj *phw = pao->priv;
+ struct dsp_obj *pdo = &phw->ado[dsp_index];
u32 timeout = TIMEOUT;
/* set command */
@@ -1577,7 +1575,7 @@
{
u32 hPI_error;
- struct hpi_hw_obj *phw = (struct hpi_hw_obj *)pao->priv;
+ struct hpi_hw_obj *phw = pao->priv;
/* read the error bits from the PCI2040 */
hPI_error = ioread32(phw->dw2040_HPICSR + HPI_ERROR_REPORT);
@@ -1597,8 +1595,8 @@
static short hpi6000_wait_dsp_ack(struct hpi_adapter_obj *pao, u16 dsp_index,
u32 ack_value)
{
- struct dsp_obj *pdo =
- &(*(struct hpi_hw_obj *)pao->priv).ado[dsp_index];
+ struct hpi_hw_obj *phw = pao->priv;
+ struct dsp_obj *pdo = &phw->ado[dsp_index];
u32 ack = 0L;
u32 timeout;
u32 hPIC = 0L;
@@ -1640,7 +1638,7 @@
struct hpi_message *phm)
{
const u16 dsp_index = 0;
- struct hpi_hw_obj *phw = (struct hpi_hw_obj *)pao->priv;
+ struct hpi_hw_obj *phw = pao->priv;
struct dsp_obj *pdo = &phw->ado[dsp_index];
u32 timeout;
u32 cache_dirty_flag;
@@ -1740,7 +1738,8 @@
{
u16 error = 0;
u16 dsp_index = 0;
- u16 num_dsp = ((struct hpi_hw_obj *)pao->priv)->num_dsp;
+ struct hpi_hw_obj *phw = pao->priv;
+ u16 num_dsp = phw->num_dsp;
if (num_dsp < 2)
dsp_index = 0;
diff --git a/sound/pci/asihpi/hpi6000.h b/sound/pci/asihpi/hpi6000.h
index 4c7d507..7e0deef 100644
--- a/sound/pci/asihpi/hpi6000.h
+++ b/sound/pci/asihpi/hpi6000.h
@@ -1,7 +1,7 @@
/*****************************************************************************
AudioScience HPI driver
- Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
+ Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com>
This program is free software; you can redistribute it and/or modify
it under the terms of version 2 of the GNU General Public License as
diff --git a/sound/pci/asihpi/hpi6205.c b/sound/pci/asihpi/hpi6205.c
index e041a6a..4f28738 100644
--- a/sound/pci/asihpi/hpi6205.c
+++ b/sound/pci/asihpi/hpi6205.c
@@ -1,7 +1,7 @@
/******************************************************************************
AudioScience HPI driver
- Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
+ Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com>
This program is free software; you can redistribute it and/or modify
it under the terms of version 2 of the GNU General Public License as
@@ -45,18 +45,21 @@
#define HPI6205_ERROR_MSG_RESP_TIMEOUT 1016
/* initialization/bootload errors */
-#define HPI6205_ERROR_6205_NO_IRQ 1002
-#define HPI6205_ERROR_6205_INIT_FAILED 1003
-#define HPI6205_ERROR_6205_REG 1006
-#define HPI6205_ERROR_6205_DSPPAGE 1007
-#define HPI6205_ERROR_C6713_HPIC 1009
-#define HPI6205_ERROR_C6713_HPIA 1010
-#define HPI6205_ERROR_C6713_PLL 1011
-#define HPI6205_ERROR_DSP_INTMEM 1012
-#define HPI6205_ERROR_DSP_EXTMEM 1013
-#define HPI6205_ERROR_DSP_PLD 1014
-#define HPI6205_ERROR_6205_EEPROM 1017
-#define HPI6205_ERROR_DSP_EMIF 1018
+#define HPI6205_ERROR_6205_NO_IRQ 1002
+#define HPI6205_ERROR_6205_INIT_FAILED 1003
+#define HPI6205_ERROR_6205_REG 1006
+#define HPI6205_ERROR_6205_DSPPAGE 1007
+#define HPI6205_ERROR_C6713_HPIC 1009
+#define HPI6205_ERROR_C6713_HPIA 1010
+#define HPI6205_ERROR_C6713_PLL 1011
+#define HPI6205_ERROR_DSP_INTMEM 1012
+#define HPI6205_ERROR_DSP_EXTMEM 1013
+#define HPI6205_ERROR_DSP_PLD 1014
+#define HPI6205_ERROR_6205_EEPROM 1017
+#define HPI6205_ERROR_DSP_EMIF1 1018
+#define HPI6205_ERROR_DSP_EMIF2 1019
+#define HPI6205_ERROR_DSP_EMIF3 1020
+#define HPI6205_ERROR_DSP_EMIF4 1021
/*****************************************************************************/
/* for C6205 PCI i/f */
@@ -488,7 +491,7 @@
return;
}
- phr->u.s.adapter_type = ao.adapter_type;
+ phr->u.s.adapter_type = ao.type;
phr->u.s.adapter_index = ao.index;
phr->error = 0;
}
@@ -503,7 +506,7 @@
phr->error = HPI_ERROR_INVALID_OBJ_INDEX;
return;
}
- phw = (struct hpi_hw_obj *)pao->priv;
+ phw = pao->priv;
/* reset adapter h/w */
/* Reset C6713 #1 */
boot_loader_write_mem32(pao, 0, C6205_BAR0_TIMER1_CTL, 0);
@@ -652,7 +655,7 @@
if (hr.error)
return hr.error;
- pao->adapter_type = hr.u.ax.info.adapter_type;
+ pao->type = hr.u.ax.info.adapter_type;
pao->index = hr.u.ax.info.adapter_index;
max_streams =
@@ -665,8 +668,6 @@
hr.u.ax.info.serial_number);
}
- pao->open = 0; /* upon creation the adapter is closed */
-
if (phw->p_cache)
phw->p_cache->adap_idx = pao->index;
@@ -803,8 +804,8 @@
obj_index];
status->samples_processed = 0;
status->stream_state = HPI_STATE_STOPPED;
- status->dSP_index = 0;
- status->host_index = status->dSP_index;
+ status->dsp_index = 0;
+ status->host_index = status->dsp_index;
status->size_in_bytes = phm->u.d.u.buffer.buffer_size;
status->auxiliary_data_available = 0;
@@ -878,7 +879,7 @@
static u32 outstream_get_space_available(struct hpi_hostbuffer_status *status)
{
return status->size_in_bytes - (status->host_index -
- status->dSP_index);
+ status->dsp_index);
}
static void outstream_write(struct hpi_adapter_obj *pao,
@@ -1080,8 +1081,8 @@
obj_index];
status->samples_processed = 0;
status->stream_state = HPI_STATE_STOPPED;
- status->dSP_index = 0;
- status->host_index = status->dSP_index;
+ status->dsp_index = 0;
+ status->host_index = status->dsp_index;
status->size_in_bytes = phm->u.d.u.buffer.buffer_size;
status->auxiliary_data_available = 0;
@@ -1162,7 +1163,7 @@
static u32 instream_get_bytes_available(struct hpi_hostbuffer_status *status)
{
- return status->dSP_index - status->host_index;
+ return status->dsp_index - status->host_index;
}
static void instream_read(struct hpi_adapter_obj *pao,
@@ -1614,7 +1615,7 @@
boot_loader_write_mem32(pao, dsp_index, 0x01800008, setting);
if (setting != boot_loader_read_mem32(pao, dsp_index,
0x01800008))
- return HPI6205_ERROR_DSP_EMIF;
+ return HPI6205_ERROR_DSP_EMIF1;
/* EMIF CE1 setup - 32 bit async. This is 6713 #1 HPI, */
/* which occupies D15..0. 6713 starts at 27MHz, so need */
@@ -1627,7 +1628,7 @@
boot_loader_write_mem32(pao, dsp_index, 0x01800004, setting);
if (setting != boot_loader_read_mem32(pao, dsp_index,
0x01800004))
- return HPI6205_ERROR_DSP_EMIF;
+ return HPI6205_ERROR_DSP_EMIF2;
/* EMIF CE2 setup - 32 bit async. This is 6713 #2 HPI, */
/* which occupies D15..0. 6713 starts at 27MHz, so need */
@@ -1639,7 +1640,7 @@
boot_loader_write_mem32(pao, dsp_index, 0x01800010, setting);
if (setting != boot_loader_read_mem32(pao, dsp_index,
0x01800010))
- return HPI6205_ERROR_DSP_EMIF;
+ return HPI6205_ERROR_DSP_EMIF3;
/* EMIF CE3 setup - 32 bit async. */
/* This is the PLD on the ASI5000 cards only */
@@ -1650,7 +1651,7 @@
boot_loader_write_mem32(pao, dsp_index, 0x01800014, setting);
if (setting != boot_loader_read_mem32(pao, dsp_index,
0x01800014))
- return HPI6205_ERROR_DSP_EMIF;
+ return HPI6205_ERROR_DSP_EMIF4;
/* set EMIF SDRAM control for 2Mx32 SDRAM (512x32x4 bank) */
/* need to use this else DSP code crashes? */
diff --git a/sound/pci/asihpi/hpi_internal.h b/sound/pci/asihpi/hpi_internal.h
index d497030..4cc315d 100644
--- a/sound/pci/asihpi/hpi_internal.h
+++ b/sound/pci/asihpi/hpi_internal.h
@@ -25,6 +25,7 @@
#define _HPI_INTERNAL_H_
#include "hpi.h"
+
/** maximum number of memory regions mapped to an adapter */
#define HPI_MAX_ADAPTER_MEM_SPACES (2)
@@ -220,8 +221,6 @@
HPI_COBRANET_SET = HPI_CTL_ATTR(COBRANET, 1),
HPI_COBRANET_GET = HPI_CTL_ATTR(COBRANET, 2),
- /*HPI_COBRANET_SET_DATA = HPI_CTL_ATTR(COBRANET, 3), */
- /*HPI_COBRANET_GET_DATA = HPI_CTL_ATTR(COBRANET, 4), */
HPI_COBRANET_GET_STATUS = HPI_CTL_ATTR(COBRANET, 5),
HPI_COBRANET_SEND_PACKET = HPI_CTL_ATTR(COBRANET, 6),
HPI_COBRANET_GET_PACKET = HPI_CTL_ATTR(COBRANET, 7),
@@ -241,7 +240,9 @@
HPI_PAD_PROGRAM_TYPE = HPI_CTL_ATTR(PAD, 5),
HPI_PAD_PROGRAM_ID = HPI_CTL_ATTR(PAD, 6),
HPI_PAD_TA_SUPPORT = HPI_CTL_ATTR(PAD, 7),
- HPI_PAD_TA_ACTIVE = HPI_CTL_ATTR(PAD, 8)
+ HPI_PAD_TA_ACTIVE = HPI_CTL_ATTR(PAD, 8),
+
+ HPI_UNIVERSAL_ENTITY = HPI_CTL_ATTR(UNIVERSAL, 1)
};
#define HPI_POLARITY_POSITIVE 0
@@ -393,14 +394,10 @@
HPI_SUBSYS_OPEN = HPI_FUNC_ID(SUBSYSTEM, 1),
HPI_SUBSYS_GET_VERSION = HPI_FUNC_ID(SUBSYSTEM, 2),
HPI_SUBSYS_GET_INFO = HPI_FUNC_ID(SUBSYSTEM, 3),
- /* HPI_SUBSYS_FIND_ADAPTERS = HPI_FUNC_ID(SUBSYSTEM, 4), */
HPI_SUBSYS_CREATE_ADAPTER = HPI_FUNC_ID(SUBSYSTEM, 5),
HPI_SUBSYS_CLOSE = HPI_FUNC_ID(SUBSYSTEM, 6),
- /* HPI_SUBSYS_DELETE_ADAPTER = HPI_FUNC_ID(SUBSYSTEM, 7), */
HPI_SUBSYS_DRIVER_LOAD = HPI_FUNC_ID(SUBSYSTEM, 8),
HPI_SUBSYS_DRIVER_UNLOAD = HPI_FUNC_ID(SUBSYSTEM, 9),
- /* HPI_SUBSYS_READ_PORT_8 = HPI_FUNC_ID(SUBSYSTEM, 10), */
- /* HPI_SUBSYS_WRITE_PORT_8 = HPI_FUNC_ID(SUBSYSTEM, 11), */
HPI_SUBSYS_GET_NUM_ADAPTERS = HPI_FUNC_ID(SUBSYSTEM, 12),
HPI_SUBSYS_GET_ADAPTER = HPI_FUNC_ID(SUBSYSTEM, 13),
HPI_SUBSYS_SET_NETWORK_INTERFACE = HPI_FUNC_ID(SUBSYSTEM, 14),
@@ -430,7 +427,10 @@
HPI_ADAPTER_IRQ_QUERY_AND_CLEAR = HPI_FUNC_ID(ADAPTER, 19),
HPI_ADAPTER_IRQ_CALLBACK = HPI_FUNC_ID(ADAPTER, 20),
HPI_ADAPTER_DELETE = HPI_FUNC_ID(ADAPTER, 21),
-#define HPI_ADAPTER_FUNCTION_COUNT 21
+ HPI_ADAPTER_READ_FLASH = HPI_FUNC_ID(ADAPTER, 22),
+ HPI_ADAPTER_END_FLASH = HPI_FUNC_ID(ADAPTER, 23),
+ HPI_ADAPTER_FILESTORE_DELETE_ALL = HPI_FUNC_ID(ADAPTER, 24),
+#define HPI_ADAPTER_FUNCTION_COUNT 24
HPI_OSTREAM_OPEN = HPI_FUNC_ID(OSTREAM, 1),
HPI_OSTREAM_CLOSE = HPI_FUNC_ID(OSTREAM, 2),
@@ -495,7 +495,9 @@
HPI_MIXER_GET_CONTROL_MULTIPLE_VALUES = HPI_FUNC_ID(MIXER, 10),
HPI_MIXER_STORE = HPI_FUNC_ID(MIXER, 11),
HPI_MIXER_GET_CACHE_INFO = HPI_FUNC_ID(MIXER, 12),
-#define HPI_MIXER_FUNCTION_COUNT 12
+ HPI_MIXER_GET_BLOCK_HANDLE = HPI_FUNC_ID(MIXER, 13),
+ HPI_MIXER_GET_PARAMETER_HANDLE = HPI_FUNC_ID(MIXER, 14),
+#define HPI_MIXER_FUNCTION_COUNT 14
HPI_CONTROL_GET_INFO = HPI_FUNC_ID(CONTROL, 1),
HPI_CONTROL_GET_STATE = HPI_FUNC_ID(CONTROL, 2),
@@ -618,7 +620,7 @@
u32 auxiliary_data_available;
u32 stream_state;
/* DSP index in to the host bus master buffer. */
- u32 dSP_index;
+ u32 dsp_index;
/* Host index in to the host bus master buffer. */
u32 host_index;
u32 size_in_bytes;
@@ -661,13 +663,6 @@
u16 index;
} module_info;
struct {
- u32 checksum;
- u16 sequence;
- u16 length;
- u16 offset; /**< offset from start of msg to data */
- u16 unused;
- } program_flash;
- struct {
u16 index;
u16 what;
u16 property_index;
@@ -678,25 +673,18 @@
u16 parameter2;
} property_set;
struct {
- u32 offset;
- } query_flash;
- struct {
u32 pad32;
u16 key1;
u16 key2;
} restart;
struct {
- u32 offset;
- u32 length;
- u32 key;
- } start_flash;
- struct {
u32 pad32;
u16 value;
} test_assert;
struct {
u32 yes;
} irq_query;
+ u32 pad[3];
};
struct hpi_adapter_res {
@@ -724,18 +712,10 @@
u32 adapter_mode;
} mode;
struct {
- u16 sequence;
- } program_flash;
- struct {
u16 parameter1;
u16 parameter2;
} property_get;
struct {
- u32 checksum;
- u32 length;
- u32 version;
- } query_flash;
- struct {
u32 yes;
} irq_query;
};
@@ -1150,74 +1130,9 @@
struct hpi_adapter_res p;
};
-/* padding is so these are same size as v0 hpi_message */
-struct hpi_msg_adapter_query_flash {
- struct hpi_message_header h;
- u32 offset;
- u8 pad_to_version0_size[sizeof(struct hpi_message) - /* V0 res */
- sizeof(struct hpi_message_header) - 1 * sizeof(u32)];
-};
-
-/* padding is so these are same size as v0 hpi_response */
-struct hpi_res_adapter_query_flash {
- struct hpi_response_header h;
- u32 checksum;
- u32 length;
- u32 version;
- u8 pad_to_version0_size[sizeof(struct hpi_response) - /* V0 res */
- sizeof(struct hpi_response_header) - 3 * sizeof(u32)];
-};
-
-struct hpi_msg_adapter_start_flash {
- struct hpi_message_header h;
- u32 offset;
- u32 length;
- u32 key;
- u8 pad_to_version0_size[sizeof(struct hpi_message) - /* V0 res */
- sizeof(struct hpi_message_header) - 3 * sizeof(u32)];
-};
-
-struct hpi_res_adapter_start_flash {
- struct hpi_response_header h;
- u8 pad_to_version0_size[sizeof(struct hpi_response) - /* V0 res */
- sizeof(struct hpi_response_header)];
-};
-
-struct hpi_msg_adapter_program_flash_payload {
- u32 checksum;
- u16 sequence;
- u16 length;
- u16 offset; /**< offset from start of msg to data */
- u16 unused;
- /* ensure sizeof(header + payload) == sizeof(hpi_message_V0)
- because old firmware expects data after message of this size */
- u8 pad_to_version0_size[sizeof(struct hpi_message) - /* V0 message */
- sizeof(struct hpi_message_header) - sizeof(u32) -
- 4 * sizeof(u16)];
-};
-
-struct hpi_msg_adapter_program_flash {
- struct hpi_message_header h;
- struct hpi_msg_adapter_program_flash_payload p;
- u32 data[256];
-};
-
-struct hpi_res_adapter_program_flash {
- struct hpi_response_header h;
- u16 sequence;
- u8 pad_to_version0_size[sizeof(struct hpi_response) - /* V0 res */
- sizeof(struct hpi_response_header) - sizeof(u16)];
-};
-
-struct hpi_msg_adapter_debug_read {
- struct hpi_message_header h;
- u32 dsp_address;
- u32 count_bytes;
-};
-
struct hpi_res_adapter_debug_read {
struct hpi_response_header h;
- u8 bytes[256];
+ u8 bytes[1024];
};
struct hpi_msg_cobranet_hmi {
@@ -1461,7 +1376,7 @@
/* 2^N sized FIFO buffer (internal to HPI<->DSP interaction) */
struct hpi_fifo_buffer {
u32 size;
- u32 dSP_index;
+ u32 dsp_index;
u32 host_index;
};
diff --git a/sound/pci/asihpi/hpi_version.h b/sound/pci/asihpi/hpi_version.h
new file mode 100644
index 0000000..e9146e5
--- /dev/null
+++ b/sound/pci/asihpi/hpi_version.h
@@ -0,0 +1,32 @@
+/** HPI Version Definitions
+Development releases have odd minor version.
+Production releases have even minor version.
+
+\file hpi_version.h
+*/
+
+#ifndef _HPI_VERSION_H
+#define _HPI_VERSION_H
+
+/* Use single digits for versions less that 10 to avoid octal. */
+/* *** HPI_VER is the only edit required to update version *** */
+/** HPI version */
+#define HPI_VER HPI_VERSION_CONSTRUCTOR(4, 10, 1)
+
+/** HPI version string in dotted decimal format */
+#define HPI_VER_STRING "4.10.01"
+
+/** Library version as documented in hpi-api-versions.txt */
+#define HPI_LIB_VER HPI_VERSION_CONSTRUCTOR(10, 2, 0)
+
+/** Construct hpi version number from major, minor, release numbers */
+#define HPI_VERSION_CONSTRUCTOR(maj, min, r) ((maj << 16) + (min << 8) + r)
+
+/** Extract major version from hpi version number */
+#define HPI_VER_MAJOR(v) ((int)(v >> 16))
+/** Extract minor version from hpi version number */
+#define HPI_VER_MINOR(v) ((int)((v >> 8) & 0xFF))
+/** Extract release from hpi version number */
+#define HPI_VER_RELEASE(v) ((int)(v & 0xFF))
+
+#endif
diff --git a/sound/pci/asihpi/hpicmn.c b/sound/pci/asihpi/hpicmn.c
index bd47521..7ed5c26 100644
--- a/sound/pci/asihpi/hpicmn.c
+++ b/sound/pci/asihpi/hpicmn.c
@@ -1,7 +1,7 @@
/******************************************************************************
AudioScience HPI driver
- Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
+ Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com>
This program is free software; you can redistribute it and/or modify
it under the terms of version 2 of the GNU General Public License as
@@ -68,7 +68,7 @@
u16 hpi_add_adapter(struct hpi_adapter_obj *pao)
{
u16 retval = 0;
- /*HPI_ASSERT(pao->wAdapterType); */
+ /*HPI_ASSERT(pao->type); */
hpios_alistlock_lock(&adapters);
@@ -77,13 +77,13 @@
goto unlock;
}
- if (adapters.adapter[pao->index].adapter_type) {
+ if (adapters.adapter[pao->index].type) {
int a;
for (a = HPI_MAX_ADAPTERS - 1; a >= 0; a--) {
- if (!adapters.adapter[a].adapter_type) {
+ if (!adapters.adapter[a].type) {
HPI_DEBUG_LOG(WARNING,
"ASI%X duplicate index %d moved to %d\n",
- pao->adapter_type, pao->index, a);
+ pao->type, pao->index, a);
pao->index = a;
break;
}
@@ -104,13 +104,13 @@
void hpi_delete_adapter(struct hpi_adapter_obj *pao)
{
- if (!pao->adapter_type) {
+ if (!pao->type) {
HPI_DEBUG_LOG(ERROR, "removing null adapter?\n");
return;
}
hpios_alistlock_lock(&adapters);
- if (adapters.adapter[pao->index].adapter_type)
+ if (adapters.adapter[pao->index].type)
adapters.gw_num_adapters--;
memset(&adapters.adapter[pao->index], 0, sizeof(adapters.adapter[0]));
hpios_alistlock_unlock(&adapters);
@@ -132,7 +132,7 @@
}
pao = &adapters.adapter[adapter_index];
- if (pao->adapter_type != 0) {
+ if (pao->type != 0) {
/*
HPI_DEBUG_LOG(VERBOSE, "Found adapter index %d\n",
wAdapterIndex);
@@ -165,7 +165,7 @@
/* find the nCount'th nonzero adapter in array */
for (index = 0; index < HPI_MAX_ADAPTERS; index++) {
- if (adapters.adapter[index].adapter_type) {
+ if (adapters.adapter[index].type) {
if (!count)
break;
count--;
@@ -174,11 +174,11 @@
if (index < HPI_MAX_ADAPTERS) {
phr->u.s.adapter_index = adapters.adapter[index].index;
- phr->u.s.adapter_type = adapters.adapter[index].adapter_type;
+ phr->u.s.adapter_type = adapters.adapter[index].type;
} else {
phr->u.s.adapter_index = 0;
phr->u.s.adapter_type = 0;
- phr->error = HPI_ERROR_BAD_ADAPTER_NUMBER;
+ phr->error = HPI_ERROR_INVALID_OBJ_INDEX;
}
}
@@ -324,6 +324,8 @@
}
phr->error = 0;
+ phr->specific_error = 0;
+ phr->version = 0;
/* set the default response size */
response_size =
@@ -531,8 +533,12 @@
found ? "Cached" : "Uncached", phm->adapter_index,
pI->control_index, pI->control_type, phm->u.c.attribute);
- if (found)
+ if (found) {
phr->size = (u16)response_size;
+ phr->type = HPI_TYPE_RESPONSE;
+ phr->object = phm->object;
+ phr->function = phm->function;
+ }
return found;
}
@@ -631,7 +637,7 @@
if (!p_cache)
return NULL;
- p_cache->p_info = kzalloc(sizeof(*p_cache->p_info) * control_count,
+ p_cache->p_info = kcalloc(control_count, sizeof(*p_cache->p_info),
GFP_KERNEL);
if (!p_cache->p_info) {
kfree(p_cache);
diff --git a/sound/pci/asihpi/hpicmn.h b/sound/pci/asihpi/hpicmn.h
index d53cdf6..e441212 100644
--- a/sound/pci/asihpi/hpicmn.h
+++ b/sound/pci/asihpi/hpicmn.h
@@ -1,7 +1,7 @@
/**
AudioScience HPI driver
- Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
+ Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com>
This program is free software; you can redistribute it and/or modify
it under the terms of version 2 of the GNU General Public License as
@@ -18,12 +18,15 @@
*/
+struct hpi_adapter_obj;
+
+/* a function that takes an adapter obj and returns an int */
+typedef int adapter_int_func(struct hpi_adapter_obj *pao);
+
struct hpi_adapter_obj {
struct hpi_pci pci; /* PCI info - bus#,dev#,address etc */
- u16 adapter_type; /* ASI6701 etc */
- u16 index; /* */
- u16 open; /* =1 when adapter open */
- u16 mixer_open;
+ u16 type; /* 0x6644 == ASI6644 etc */
+ u16 index;
struct hpios_spinlock dsp_lock;
diff --git a/sound/pci/asihpi/hpidebug.c b/sound/pci/asihpi/hpidebug.c
index b52baf6..ac86a1f 100644
--- a/sound/pci/asihpi/hpidebug.c
+++ b/sound/pci/asihpi/hpidebug.c
@@ -1,7 +1,7 @@
/************************************************************************
AudioScience HPI driver
- Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
+ Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com>
This program is free software; you can redistribute it and/or modify
it under the terms of version 2 of the GNU General Public License as
diff --git a/sound/pci/asihpi/hpidebug.h b/sound/pci/asihpi/hpidebug.h
index 940f54c..2c9af23 100644
--- a/sound/pci/asihpi/hpidebug.h
+++ b/sound/pci/asihpi/hpidebug.h
@@ -1,7 +1,7 @@
/*****************************************************************************
AudioScience HPI driver
- Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
+ Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com>
This program is free software; you can redistribute it and/or modify
it under the terms of version 2 of the GNU General Public License as
diff --git a/sound/pci/asihpi/hpidspcd.c b/sound/pci/asihpi/hpidspcd.c
index 71d32c8..456a758 100644
--- a/sound/pci/asihpi/hpidspcd.c
+++ b/sound/pci/asihpi/hpidspcd.c
@@ -25,6 +25,7 @@
#define SOURCEFILE_NAME "hpidspcd.c"
#include "hpidspcd.h"
#include "hpidebug.h"
+#include "hpi_version.h"
struct dsp_code_private {
/** Firmware descriptor */
@@ -32,9 +33,6 @@
struct pci_dev *dev;
};
-#define HPI_VER_DECIMAL ((int)(HPI_VER_MAJOR(HPI_VER) * 10000 + \
- HPI_VER_MINOR(HPI_VER) * 100 + HPI_VER_RELEASE(HPI_VER)))
-
/*-------------------------------------------------------------------*/
short hpi_dsp_code_open(u32 adapter, void *os_data, struct dsp_code *dsp_code,
u32 *os_error_code)
@@ -66,22 +64,25 @@
if ((header.type != 0x45444F43) || /* "CODE" */
(header.adapter != adapter)
|| (header.size != firmware->size)) {
- dev_printk(KERN_ERR, &dev->dev, "Invalid firmware file\n");
+ dev_printk(KERN_ERR, &dev->dev,
+ "Invalid firmware header size %d != file %zd\n",
+ header.size, firmware->size);
goto error2;
}
- if ((header.version / 100 & ~1) != (HPI_VER_DECIMAL / 100 & ~1)) {
+ if ((header.version >> 9) != (HPI_VER >> 9)) {
+ /* Consider even and subsequent odd minor versions to be compatible */
dev_printk(KERN_ERR, &dev->dev,
"Incompatible firmware version "
- "DSP image %d != Driver %d\n", header.version,
- HPI_VER_DECIMAL);
+ "DSP image %X != Driver %X\n", header.version,
+ HPI_VER);
goto error2;
}
- if (header.version != HPI_VER_DECIMAL) {
- dev_printk(KERN_WARNING, &dev->dev,
- "Firmware: release version mismatch DSP image %d != Driver %d\n",
- header.version, HPI_VER_DECIMAL);
+ if (header.version != HPI_VER) {
+ dev_printk(KERN_INFO, &dev->dev,
+ "Firmware: release version mismatch DSP image %X != Driver %X\n",
+ header.version, HPI_VER);
}
HPI_DEBUG_LOG(DEBUG, "dsp code %s opened\n", fw_name);
@@ -108,11 +109,8 @@
/*-------------------------------------------------------------------*/
void hpi_dsp_code_close(struct dsp_code *dsp_code)
{
- if (dsp_code->pvt->firmware) {
- HPI_DEBUG_LOG(DEBUG, "dsp code closed\n");
- release_firmware(dsp_code->pvt->firmware);
- dsp_code->pvt->firmware = NULL;
- }
+ HPI_DEBUG_LOG(DEBUG, "dsp code closed\n");
+ release_firmware(dsp_code->pvt->firmware);
kfree(dsp_code->pvt);
}
diff --git a/sound/pci/asihpi/hpidspcd.h b/sound/pci/asihpi/hpidspcd.h
index b228811..659d19c 100644
--- a/sound/pci/asihpi/hpidspcd.h
+++ b/sound/pci/asihpi/hpidspcd.h
@@ -27,10 +27,6 @@
#include "hpi_internal.h"
-/** Code header version is decimal encoded e.g. 4.06.10 is 40601 */
-#define HPI_VER_DECIMAL ((int)(HPI_VER_MAJOR(HPI_VER) * 10000 + \
-HPI_VER_MINOR(HPI_VER) * 100 + HPI_VER_RELEASE(HPI_VER)))
-
/** Header structure for dsp firmware file
This structure must match that used in s2bin.c for generation of asidsp.bin
*/
diff --git a/sound/pci/asihpi/hpifunc.c b/sound/pci/asihpi/hpifunc.c
index ebb568d..510e56c 100644
--- a/sound/pci/asihpi/hpifunc.c
+++ b/sound/pci/asihpi/hpifunc.c
@@ -2826,6 +2826,16 @@
duration_ms, HPI_VOLUME_AUTOFADE_LOG);
}
+u16 hpi_volume_query_auto_fade_profile(const u32 h_volume, const u32 i,
+ u16 *profile)
+{
+ u16 e;
+ u32 u;
+ e = hpi_control_query(h_volume, HPI_VOLUME_AUTOFADE, i, 0, &u);
+ *profile = (u16)u;
+ return e;
+}
+
u16 hpi_vox_set_threshold(u32 h_control, short an_gain0_01dB)
{
struct hpi_message hm;
diff --git a/sound/pci/asihpi/hpimsginit.c b/sound/pci/asihpi/hpimsginit.c
index 52400a6..032d563 100644
--- a/sound/pci/asihpi/hpimsginit.c
+++ b/sound/pci/asihpi/hpimsginit.c
@@ -1,7 +1,7 @@
/******************************************************************************
AudioScience HPI driver
- Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
+ Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com>
This program is free software; you can redistribute it and/or modify
it under the terms of version 2 of the GNU General Public License as
diff --git a/sound/pci/asihpi/hpimsginit.h b/sound/pci/asihpi/hpimsginit.h
index bfd330d..5b48708 100644
--- a/sound/pci/asihpi/hpimsginit.h
+++ b/sound/pci/asihpi/hpimsginit.h
@@ -1,7 +1,7 @@
/******************************************************************************
AudioScience HPI driver
- Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
+ Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com>
This program is free software; you can redistribute it and/or modify
it under the terms of version 2 of the GNU General Public License as
diff --git a/sound/pci/asihpi/hpimsgx.c b/sound/pci/asihpi/hpimsgx.c
index 2e77942..d4790dd 100644
--- a/sound/pci/asihpi/hpimsgx.c
+++ b/sound/pci/asihpi/hpimsgx.c
@@ -1,7 +1,7 @@
/******************************************************************************
AudioScience HPI driver
- Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
+ Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com>
This program is free software; you can redistribute it and/or modify
it under the terms of version 2 of the GNU General Public License as
@@ -22,6 +22,7 @@
*****************************************************************************/
#define SOURCEFILE_NAME "hpimsgx.c"
#include "hpi_internal.h"
+#include "hpi_version.h"
#include "hpimsginit.h"
#include "hpicmn.h"
#include "hpimsgx.h"
diff --git a/sound/pci/asihpi/hpimsgx.h b/sound/pci/asihpi/hpimsgx.h
index fd49e75..37f3efd 100644
--- a/sound/pci/asihpi/hpimsgx.h
+++ b/sound/pci/asihpi/hpimsgx.h
@@ -1,7 +1,7 @@
/******************************************************************************
AudioScience HPI driver
- Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
+ Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com>
This program is free software; you can redistribute it and/or modify
it under the terms of version 2 of the GNU General Public License as
diff --git a/sound/pci/asihpi/hpioctl.c b/sound/pci/asihpi/hpioctl.c
index f6b9517..6091562 100644
--- a/sound/pci/asihpi/hpioctl.c
+++ b/sound/pci/asihpi/hpioctl.c
@@ -21,6 +21,7 @@
#define SOURCEFILE_NAME "hpioctl.c"
#include "hpi_internal.h"
+#include "hpi_version.h"
#include "hpimsginit.h"
#include "hpidebug.h"
#include "hpimsgx.h"
@@ -65,9 +66,7 @@
static void hpi_send_recv_f(struct hpi_message *phm, struct hpi_response *phr,
struct file *file)
{
- int adapter = phm->adapter_index;
-
- if ((adapter >= HPI_MAX_ADAPTERS || adapter < 0)
+ if ((phm->adapter_index >= HPI_MAX_ADAPTERS)
&& (phm->object != HPI_OBJ_SUBSYSTEM))
phr->error = HPI_ERROR_INVALID_OBJ_INDEX;
else
@@ -178,19 +177,14 @@
} else {
u16 __user *ptr = NULL;
u32 size = 0;
- u32 adapter_present;
/* -1=no data 0=read from user mem, 1=write to user mem */
int wrflag = -1;
- struct hpi_adapter *pa;
+ struct hpi_adapter *pa = NULL;
- if (hm->h.adapter_index < HPI_MAX_ADAPTERS) {
+ if (hm->h.adapter_index < ARRAY_SIZE(adapters))
pa = &adapters[hm->h.adapter_index];
- adapter_present = pa->type;
- } else {
- adapter_present = 0;
- }
- if (!adapter_present) {
+ if (!pa || !pa->adapter || !pa->adapter->type) {
hpi_init_response(&hr->r0, hm->h.object,
hm->h.function, HPI_ERROR_BAD_ADAPTER_NUMBER);
@@ -317,6 +311,7 @@
const struct pci_device_id *pci_id)
{
int idx, nm;
+ int adapter_index;
unsigned int memlen;
struct hpi_message hm;
struct hpi_response hr;
@@ -345,8 +340,6 @@
hm.adapter_index = HPI_ADAPTER_INDEX_INVALID;
- adapter.pci = pci_dev;
-
nm = HPI_MAX_ADAPTER_MEM_SPACES;
for (idx = 0; idx < nm; idx++) {
@@ -355,18 +348,16 @@
if (pci_resource_flags(pci_dev, idx) & IORESOURCE_MEM) {
memlen = pci_resource_len(pci_dev, idx);
- adapter.ap_remapped_mem_base[idx] =
+ pci.ap_mem_base[idx] =
ioremap(pci_resource_start(pci_dev, idx),
memlen);
- if (!adapter.ap_remapped_mem_base[idx]) {
+ if (!pci.ap_mem_base[idx]) {
HPI_DEBUG_LOG(ERROR,
"ioremap failed, aborting\n");
/* unmap previously mapped pci mem space */
goto err;
}
}
-
- pci.ap_mem_base[idx] = adapter.ap_remapped_mem_base[idx];
}
pci.pci_dev = pci_dev;
@@ -378,6 +369,9 @@
if (hr.error)
goto err;
+ adapter_index = hr.u.s.adapter_index;
+ adapter.adapter = hpi_find_adapter(adapter_index);
+
if (prealloc_stream_buf) {
adapter.p_buffer = vmalloc(prealloc_stream_buf);
if (!adapter.p_buffer) {
@@ -389,36 +383,32 @@
}
}
- adapter.index = hr.u.s.adapter_index;
- adapter.type = hr.u.s.adapter_type;
-
hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
HPI_ADAPTER_OPEN);
- hm.adapter_index = adapter.index;
+ hm.adapter_index = adapter.adapter->index;
hpi_send_recv_ex(&hm, &hr, HOWNER_KERNEL);
if (hr.error)
goto err;
- adapter.snd_card_asihpi = NULL;
/* WARNING can't init mutex in 'adapter'
* and then copy it to adapters[] ?!?!
*/
- adapters[adapter.index] = adapter;
- mutex_init(&adapters[adapter.index].mutex);
- pci_set_drvdata(pci_dev, &adapters[adapter.index]);
+ adapters[adapter_index] = adapter;
+ mutex_init(&adapters[adapter_index].mutex);
+ pci_set_drvdata(pci_dev, &adapters[adapter_index]);
dev_printk(KERN_INFO, &pci_dev->dev,
- "probe succeeded for ASI%04X HPI index %d\n", adapter.type,
- adapter.index);
+ "probe succeeded for ASI%04X HPI index %d\n",
+ adapter.adapter->type, adapter_index);
return 0;
err:
for (idx = 0; idx < HPI_MAX_ADAPTER_MEM_SPACES; idx++) {
- if (adapter.ap_remapped_mem_base[idx]) {
- iounmap(adapter.ap_remapped_mem_base[idx]);
- adapter.ap_remapped_mem_base[idx] = NULL;
+ if (pci.ap_mem_base[idx]) {
+ iounmap(pci.ap_mem_base[idx]);
+ pci.ap_mem_base[idx] = NULL;
}
}
@@ -437,19 +427,20 @@
struct hpi_message hm;
struct hpi_response hr;
struct hpi_adapter *pa;
+ struct hpi_pci pci;
+
pa = pci_get_drvdata(pci_dev);
+ pci = pa->adapter->pci;
hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
HPI_ADAPTER_DELETE);
- hm.adapter_index = pa->index;
+ hm.adapter_index = pa->adapter->index;
hpi_send_recv_ex(&hm, &hr, HOWNER_KERNEL);
/* unmap PCI memory space, mapped during device init. */
for (idx = 0; idx < HPI_MAX_ADAPTER_MEM_SPACES; idx++) {
- if (pa->ap_remapped_mem_base[idx]) {
- iounmap(pa->ap_remapped_mem_base[idx]);
- pa->ap_remapped_mem_base[idx] = NULL;
- }
+ if (pci.ap_mem_base[idx])
+ iounmap(pci.ap_mem_base[idx]);
}
if (pa->p_buffer)
@@ -461,7 +452,7 @@
"remove %04x:%04x,%04x:%04x,%04x," " HPI index %d.\n",
pci_dev->vendor, pci_dev->device,
pci_dev->subsystem_vendor, pci_dev->subsystem_device,
- pci_dev->devfn, pa->index);
+ pci_dev->devfn, pa->adapter->index);
memset(pa, 0, sizeof(*pa));
}
diff --git a/sound/pci/asihpi/hpioctl.h b/sound/pci/asihpi/hpioctl.h
index 847f72f..2614aff 100644
--- a/sound/pci/asihpi/hpioctl.h
+++ b/sound/pci/asihpi/hpioctl.h
@@ -1,7 +1,7 @@
/*******************************************************************************
AudioScience HPI driver
- Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
+ Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com>
This program is free software; you can redistribute it and/or modify
it under the terms of version 2 of the GNU General Public License as
diff --git a/sound/pci/asihpi/hpios.c b/sound/pci/asihpi/hpios.c
index ff2a19b..2d7d1c2 100644
--- a/sound/pci/asihpi/hpios.c
+++ b/sound/pci/asihpi/hpios.c
@@ -1,7 +1,7 @@
/******************************************************************************
AudioScience HPI driver
- Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
+ Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com>
This program is free software; you can redistribute it and/or modify
it under the terms of version 2 of the GNU General Public License as
diff --git a/sound/pci/asihpi/hpios.h b/sound/pci/asihpi/hpios.h
index 2f605e3..c5cef11 100644
--- a/sound/pci/asihpi/hpios.h
+++ b/sound/pci/asihpi/hpios.h
@@ -1,7 +1,7 @@
/******************************************************************************
AudioScience HPI driver
- Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
+ Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com>
This program is free software; you can redistribute it and/or modify
it under the terms of version 2 of the GNU General Public License as
@@ -149,20 +149,18 @@
#define hpios_alistlock_lock(obj) spin_lock(&((obj)->list_lock.lock))
#define hpios_alistlock_unlock(obj) spin_unlock(&((obj)->list_lock.lock))
+struct snd_card;
+
+/** pci drvdata points to an instance of this struct */
struct hpi_adapter {
+ struct hpi_adapter_obj *adapter;
+ struct snd_card *snd_card;
+
/* mutex prevents contention for one card
between multiple user programs (via ioctl) */
struct mutex mutex;
- u16 index;
- u16 type;
-
- /* ALSA card structure */
- void *snd_card_asihpi;
-
char *p_buffer;
size_t buffer_size;
- struct pci_dev *pci;
- void __iomem *ap_remapped_mem_base[HPI_MAX_ADAPTER_MEM_SPACES];
};
#endif
diff --git a/sound/pci/asihpi/hpipcida.h b/sound/pci/asihpi/hpipcida.h
index bb30868..db570dd 100644
--- a/sound/pci/asihpi/hpipcida.h
+++ b/sound/pci/asihpi/hpipcida.h
@@ -1,7 +1,7 @@
/******************************************************************************
AudioScience HPI driver
- Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
+ Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com>
This program is free software; you can redistribute it and/or modify
it under the terms of version 2 of the GNU General Public License as
diff --git a/sound/pci/atiixp.c b/sound/pci/atiixp.c
index 15e4e5e..590682f 100644
--- a/sound/pci/atiixp.c
+++ b/sound/pci/atiixp.c
@@ -43,7 +43,7 @@
static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */
static int ac97_clock = 48000;
static char *ac97_quirk;
-static int spdif_aclink = 1;
+static bool spdif_aclink = 1;
static int ac97_codec = -1;
module_param(index, int, 0444);
@@ -60,7 +60,7 @@
MODULE_PARM_DESC(spdif_aclink, "S/PDIF over AC-link.");
/* just for backward compatibility */
-static int enable;
+static bool enable;
module_param(enable, bool, 0444);
diff --git a/sound/pci/atiixp_modem.c b/sound/pci/atiixp_modem.c
index 57bf8f4..524d35f 100644
--- a/sound/pci/atiixp_modem.c
+++ b/sound/pci/atiixp_modem.c
@@ -51,7 +51,7 @@
MODULE_PARM_DESC(ac97_clock, "AC'97 codec clock (default 48000Hz).");
/* just for backward compatibility */
-static int enable;
+static bool enable;
module_param(enable, bool, 0444);
diff --git a/sound/pci/au88x0/au88x0.c b/sound/pci/au88x0/au88x0.c
index dc326be..762bb10 100644
--- a/sound/pci/au88x0/au88x0.c
+++ b/sound/pci/au88x0/au88x0.c
@@ -26,7 +26,7 @@
// module parameters (see "Module Parameters")
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 bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
static int pcifix[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 255 };
module_param_array(index, int, NULL, 0444);
diff --git a/sound/pci/au88x0/au88x0_core.c b/sound/pci/au88x0/au88x0_core.c
index 4891503..6933a27 100644
--- a/sound/pci/au88x0/au88x0_core.c
+++ b/sound/pci/au88x0/au88x0_core.c
@@ -805,7 +805,7 @@
}
static void
-vortex_fifo_setadbctrl(vortex_t * vortex, int fifo, int b, int priority,
+vortex_fifo_setadbctrl(vortex_t * vortex, int fifo, int stereo, int priority,
int empty, int valid, int f)
{
int temp, lifeboat = 0;
@@ -837,7 +837,7 @@
#else
temp = (this_4 & 0x3f) << 0xc;
#endif
- temp = (temp & 0xfffffffd) | ((b & 1) << 1);
+ temp = (temp & 0xfffffffd) | ((stereo & 1) << 1);
temp = (temp & 0xfffffff3) | ((priority & 3) << 2);
temp = (temp & 0xffffffef) | ((valid & 1) << 4);
temp |= FIFO_U1;
@@ -1148,11 +1148,11 @@
static void
vortex_adbdma_setmode(vortex_t * vortex, int adbdma, int ie, int dir,
- int fmt, int d, u32 offset)
+ int fmt, int stereo, u32 offset)
{
stream_t *dma = &vortex->dma_adb[adbdma];
- dma->dma_unknown = d;
+ dma->dma_unknown = stereo;
dma->dma_ctrl =
((offset & OFFSET_MASK) | (dma->dma_ctrl & ~OFFSET_MASK));
/* Enable PCMOUT interrupts. */
@@ -1336,7 +1336,6 @@
dma->fifo_status = FIFO_PAUSE;
}
-#if 0 // Using pause instead
static void vortex_adbdma_stopfifo(vortex_t * vortex, int adbdma)
{
stream_t *dma = &vortex->dma_adb[adbdma];
@@ -1351,7 +1350,6 @@
dma->fifo_enabled = 0;
}
-#endif
/* WTDMA */
#ifndef CHIP_AU8810
diff --git a/sound/pci/au88x0/au88x0_pcm.c b/sound/pci/au88x0/au88x0_pcm.c
index c5f7ae4..0488633 100644
--- a/sound/pci/au88x0/au88x0_pcm.c
+++ b/sound/pci/au88x0/au88x0_pcm.c
@@ -307,8 +307,8 @@
fmt = vortex_alsafmt_aspfmt(runtime->format);
spin_lock_irq(&chip->lock);
if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT) {
- vortex_adbdma_setmode(chip, dma, 1, dir, fmt, 0 /*? */ ,
- 0);
+ vortex_adbdma_setmode(chip, dma, 1, dir, fmt,
+ runtime->channels == 1 ? 0 : 1, 0);
vortex_adbdma_setstartbuffer(chip, dma, 0);
if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_SPDIF)
vortex_adb_setsrc(chip, dma, runtime->rate, dir);
@@ -353,8 +353,7 @@
//printk(KERN_INFO "vortex: stop %d\n", dma);
stream->fifo_enabled = 0;
if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT)
- vortex_adbdma_pausefifo(chip, dma);
- //vortex_adbdma_stopfifo(chip, dma);
+ vortex_adbdma_stopfifo(chip, dma);
#ifndef CHIP_AU8810
else {
printk(KERN_INFO "vortex: wt stop %d\n", dma);
diff --git a/sound/pci/au88x0/au88x0_xtalk.c b/sound/pci/au88x0/au88x0_xtalk.c
index b4151e2..b278e28 100644
--- a/sound/pci/au88x0/au88x0_xtalk.c
+++ b/sound/pci/au88x0/au88x0_xtalk.c
@@ -48,43 +48,61 @@
static unsigned short const wXtalkNarrowRightDelay = 0x7;
static xtalk_gains_t const asXtalkGainsDefault = {
- 0x4000, 0x4000, 4000, 0x4000, 4000, 0x4000, 4000, 0x4000, 4000,
- 0x4000
+ 0x4000, 0x4000, 0x4000, 0x4000, 0x4000,
+ 0x4000, 0x4000, 0x4000, 0x4000, 0x4000
};
static xtalk_gains_t const asXtalkGainsTest = {
- 0x8000, 0x7FFF, 0, 0xFFFF, 0x0001, 0xC000, 0x4000, 0xFFFE, 0x0002,
- 0
+ 0x7fff, 0x8000, 0x0000, 0x0000, 0x0001,
+ 0xffff, 0x4000, 0xc000, 0x0002, 0xfffe
};
+
static xtalk_gains_t const asXtalkGains1Chan = {
- 0x7FFF, 0, 0, 0, 0x7FFF, 0, 0, 0, 0, 0
+ 0x7FFF, 0, 0, 0, 0,
+ 0x7FFF, 0, 0, 0, 0,
};
// Input gain for 4 A3D slices. One possible input pair is left zero.
static xtalk_gains_t const asXtalkGainsAllChan = {
- 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF,
- 0
- //0x7FFF,0x7FFF,0x7FFF,0x7FFF,0x7fff,0x7FFF,0x7FFF,0x7FFF,0x7FFF,0x7fff
+ 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0,
+ 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0
};
-static xtalk_gains_t const asXtalkGainsZeros;
-static xtalk_dline_t const alXtalkDlineZeros;
+static xtalk_gains_t const asXtalkGainsZeros = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static xtalk_dline_t const alXtalkDlineZeros = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
static xtalk_dline_t const alXtalkDlineTest = {
- 0xFC18, 0x03E8FFFF, 0x186A0, 0x7960FFFE, 1, 0xFFFFFFFF,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0x0000fc18, 0xfff03e8, 0x000186a0, 0xfffe7960, 1, 0xffffffff, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static xtalk_instate_t const asXtalkInStateZeros = {
0, 0, 0, 0
};
-static xtalk_instate_t const asXtalkInStateZeros;
-static xtalk_instate_t const asXtalkInStateTest =
- { 0xFF80, 0x0080, 0xFFFF, 0x0001 };
-static xtalk_state_t const asXtalkOutStateZeros;
+static xtalk_instate_t const asXtalkInStateTest = {
+ 0x0080, 0xff80, 0x0001, 0xffff
+};
+
+static xtalk_state_t const asXtalkOutStateZeros = {
+ {0, 0, 0, 0},
+ {0, 0, 0, 0},
+ {0, 0, 0, 0},
+ {0, 0, 0, 0},
+ {0, 0, 0, 0}
+};
static short const sDiamondKLeftEq = 0x401d;
static short const sDiamondKRightEq = 0x401d;
static short const sDiamondKLeftXt = 0xF90E;
static short const sDiamondKRightXt = 0xF90E;
-static short const sDiamondShiftLeftEq = 1; /* 0xF90E Is this a bug ??? */
+static short const sDiamondShiftLeftEq = 1;
static short const sDiamondShiftRightEq = 1;
static short const sDiamondShiftLeftXt = 0;
static short const sDiamondShiftRightXt = 0;
@@ -94,29 +112,29 @@
static xtalk_coefs_t const asXtalkWideCoefsLeftEq = {
{0xEC4C, 0xDCE9, 0xFDC2, 0xFEEC, 0},
{0x5F60, 0xCBCB, 0xFC26, 0x0305, 0},
- {0x340B, 0xf504, 0x6CE8, 0x0D23, 0x00E4},
- {0xD500, 0x8D76, 0xACC7, 0x5B05, 0x00FA},
+ {0x340B, 0xe8f5, 0x236c, 0xe40d, 0},
+ {0x76d5, 0xc78d, 0x05ac, 0xfa5b, 0},
{0x7F04, 0xC0FA, 0x0263, 0xFDA2, 0}
};
static xtalk_coefs_t const asXtalkWideCoefsRightEq = {
{0xEC4C, 0xDCE9, 0xFDC2, 0xFEEC, 0},
{0x5F60, 0xCBCB, 0xFC26, 0x0305, 0},
- {0x340B, 0xF504, 0x6CE8, 0x0D23, 0x00E4},
- {0xD500, 0x8D76, 0xACC7, 0x5B05, 0x00FA},
+ {0x340B, 0xe8f5, 0x236c, 0xe40d, 0},
+ {0x76d5, 0xc78d, 0x05ac, 0xfa5b, 0},
{0x7F04, 0xC0FA, 0x0263, 0xFDA2, 0}
};
static xtalk_coefs_t const asXtalkWideCoefsLeftXt = {
- {0x86C3, 0x7B55, 0x89C3, 0x005B, 0x0047},
- {0x6000, 0x206A, 0xC6CA, 0x40FF, 0},
- {0x1100, 0x1164, 0xA1D7, 0x90FC, 0x0001},
- {0xDC00, 0x9E77, 0xB8C7, 0x0AFF, 0},
+ {0x55c6, 0xc97b, 0x005b, 0x0047, 0},
+ {0x6a60, 0xca20, 0xffc6, 0x0040, 0},
+ {0x6411, 0xd711, 0xfca1, 0x0190, 0},
+ {0x77dc, 0xc79e, 0xffb8, 0x000a, 0},
{0, 0, 0, 0, 0}
};
static xtalk_coefs_t const asXtalkWideCoefsRightXt = {
- {0x86C3, 0x7B55, 0x89C3, 0x005B, 0x0047},
- {0x6000, 0x206A, 0xC6CA, 0x40FF, 0},
- {0x1100, 0x1164, 0xA1D7, 0x90FC, 0x0001},
- {0xDC00, 0x9E77, 0xB8C7, 0x0AFF, 0},
+ {0x55c6, 0xc97b, 0x005b, 0x0047, 0},
+ {0x6a60, 0xca20, 0xffc6, 0x0040, 0},
+ {0x6411, 0xd711, 0xfca1, 0x0190, 0},
+ {0x77dc, 0xc79e, 0xffb8, 0x000a, 0},
{0, 0, 0, 0, 0}
};
static xtalk_coefs_t const asXtalkNarrowCoefsLeftEq = {
@@ -151,7 +169,14 @@
{0, 0, 0, 0, 0}
};
-static xtalk_coefs_t const asXtalkCoefsZeros;
+static xtalk_coefs_t const asXtalkCoefsZeros = {
+ {0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0}
+};
+
static xtalk_coefs_t const asXtalkCoefsPipe = {
{0, 0, 0x0FA0, 0, 0},
{0, 0, 0x0FA0, 0, 0},
@@ -186,7 +211,7 @@
static xtalk_state_t const asXtalkOutStateTest = {
{0x7FFF, 0x0004, 0xFFFC, 0},
{0xFE00, 0x0008, 0xFFF8, 0x4000},
- {0x200, 0x0010, 0xFFF0, 0xC000},
+ {0x0200, 0x0010, 0xFFF0, 0xC000},
{0x8000, 0x0020, 0xFFE0, 0},
{0, 0, 0, 0}
};
@@ -306,10 +331,10 @@
hwwrite(vortex->mmio, 0x2421C + i * 0x24, coefs[i][2]);
hwwrite(vortex->mmio, 0x24220 + i * 0x24, coefs[i][3]);
}
- hwwrite(vortex->mmio, 0x244F8 + i * 0x24, arg_0[0]);
- hwwrite(vortex->mmio, 0x244FC + i * 0x24, arg_0[1]);
- hwwrite(vortex->mmio, 0x24500 + i * 0x24, arg_0[2]);
- hwwrite(vortex->mmio, 0x24504 + i * 0x24, arg_0[3]);
+ hwwrite(vortex->mmio, 0x244F8, arg_0[0]);
+ hwwrite(vortex->mmio, 0x244FC, arg_0[1]);
+ hwwrite(vortex->mmio, 0x24500, arg_0[2]);
+ hwwrite(vortex->mmio, 0x24504, arg_0[3]);
}
static void
@@ -325,10 +350,10 @@
hwwrite(vortex->mmio, 0x242D0 + i * 0x24, coefs[i][2]);
hwwrite(vortex->mmio, 0x244D4 + i * 0x24, coefs[i][3]);
}
- hwwrite(vortex->mmio, 0x24508 + i * 0x24, arg_0[0]);
- hwwrite(vortex->mmio, 0x2450C + i * 0x24, arg_0[1]);
- hwwrite(vortex->mmio, 0x24510 + i * 0x24, arg_0[2]);
- hwwrite(vortex->mmio, 0x24514 + i * 0x24, arg_0[3]);
+ hwwrite(vortex->mmio, 0x24508, arg_0[0]);
+ hwwrite(vortex->mmio, 0x2450C, arg_0[1]);
+ hwwrite(vortex->mmio, 0x24510, arg_0[2]);
+ hwwrite(vortex->mmio, 0x24514, arg_0[3]);
}
static void
@@ -344,10 +369,10 @@
hwwrite(vortex->mmio, 0x24384 + i * 0x24, coefs[i][2]);
hwwrite(vortex->mmio, 0x24388 + i * 0x24, coefs[i][3]);
}
- hwwrite(vortex->mmio, 0x24518 + i * 0x24, arg_0[0]);
- hwwrite(vortex->mmio, 0x2451C + i * 0x24, arg_0[1]);
- hwwrite(vortex->mmio, 0x24520 + i * 0x24, arg_0[2]);
- hwwrite(vortex->mmio, 0x24524 + i * 0x24, arg_0[3]);
+ hwwrite(vortex->mmio, 0x24518, arg_0[0]);
+ hwwrite(vortex->mmio, 0x2451C, arg_0[1]);
+ hwwrite(vortex->mmio, 0x24520, arg_0[2]);
+ hwwrite(vortex->mmio, 0x24524, arg_0[3]);
}
static void
@@ -363,10 +388,10 @@
hwwrite(vortex->mmio, 0x24438 + i * 0x24, coefs[i][2]);
hwwrite(vortex->mmio, 0x2443C + i * 0x24, coefs[i][3]);
}
- hwwrite(vortex->mmio, 0x24528 + i * 0x24, arg_0[0]);
- hwwrite(vortex->mmio, 0x2452C + i * 0x24, arg_0[1]);
- hwwrite(vortex->mmio, 0x24530 + i * 0x24, arg_0[2]);
- hwwrite(vortex->mmio, 0x24534 + i * 0x24, arg_0[3]);
+ hwwrite(vortex->mmio, 0x24528, arg_0[0]);
+ hwwrite(vortex->mmio, 0x2452C, arg_0[1]);
+ hwwrite(vortex->mmio, 0x24530, arg_0[2]);
+ hwwrite(vortex->mmio, 0x24534, arg_0[3]);
}
#if 0
@@ -450,10 +475,10 @@
coefs[i][2] = hwread(vortex->mmio, 0x2421C + i * 0x24);
coefs[i][3] = hwread(vortex->mmio, 0x24220 + i * 0x24);
}
- arg_0[0] = hwread(vortex->mmio, 0x244F8 + i * 0x24);
- arg_0[1] = hwread(vortex->mmio, 0x244FC + i * 0x24);
- arg_0[2] = hwread(vortex->mmio, 0x24500 + i * 0x24);
- arg_0[3] = hwread(vortex->mmio, 0x24504 + i * 0x24);
+ arg_0[0] = hwread(vortex->mmio, 0x244F8);
+ arg_0[1] = hwread(vortex->mmio, 0x244FC);
+ arg_0[2] = hwread(vortex->mmio, 0x24500);
+ arg_0[3] = hwread(vortex->mmio, 0x24504);
}
static void
@@ -468,10 +493,10 @@
coefs[i][2] = hwread(vortex->mmio, 0x242D0 + i * 0x24);
coefs[i][3] = hwread(vortex->mmio, 0x242D4 + i * 0x24);
}
- arg_0[0] = hwread(vortex->mmio, 0x24508 + i * 0x24);
- arg_0[1] = hwread(vortex->mmio, 0x2450C + i * 0x24);
- arg_0[2] = hwread(vortex->mmio, 0x24510 + i * 0x24);
- arg_0[3] = hwread(vortex->mmio, 0x24514 + i * 0x24);
+ arg_0[0] = hwread(vortex->mmio, 0x24508);
+ arg_0[1] = hwread(vortex->mmio, 0x2450C);
+ arg_0[2] = hwread(vortex->mmio, 0x24510);
+ arg_0[3] = hwread(vortex->mmio, 0x24514);
}
static void
@@ -486,10 +511,10 @@
coefs[i][2] = hwread(vortex->mmio, 0x24384 + i * 0x24);
coefs[i][3] = hwread(vortex->mmio, 0x24388 + i * 0x24);
}
- arg_0[0] = hwread(vortex->mmio, 0x24518 + i * 0x24);
- arg_0[1] = hwread(vortex->mmio, 0x2451C + i * 0x24);
- arg_0[2] = hwread(vortex->mmio, 0x24520 + i * 0x24);
- arg_0[3] = hwread(vortex->mmio, 0x24524 + i * 0x24);
+ arg_0[0] = hwread(vortex->mmio, 0x24518);
+ arg_0[1] = hwread(vortex->mmio, 0x2451C);
+ arg_0[2] = hwread(vortex->mmio, 0x24520);
+ arg_0[3] = hwread(vortex->mmio, 0x24524);
}
static void
@@ -504,10 +529,10 @@
coefs[i][2] = hwread(vortex->mmio, 0x24438 + i * 0x24);
coefs[i][3] = hwread(vortex->mmio, 0x2443C + i * 0x24);
}
- arg_0[0] = hwread(vortex->mmio, 0x24528 + i * 0x24);
- arg_0[1] = hwread(vortex->mmio, 0x2452C + i * 0x24);
- arg_0[2] = hwread(vortex->mmio, 0x24530 + i * 0x24);
- arg_0[3] = hwread(vortex->mmio, 0x24534 + i * 0x24);
+ arg_0[0] = hwread(vortex->mmio, 0x24528);
+ arg_0[1] = hwread(vortex->mmio, 0x2452C);
+ arg_0[2] = hwread(vortex->mmio, 0x24530);
+ arg_0[3] = hwread(vortex->mmio, 0x24534);
}
#endif
diff --git a/sound/pci/aw2/aw2-alsa.c b/sound/pci/aw2/aw2-alsa.c
index 7a58115..1c523193 100644
--- a/sound/pci/aw2/aw2-alsa.c
+++ b/sound/pci/aw2/aw2-alsa.c
@@ -153,7 +153,7 @@
********************************/
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 bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
module_param_array(index, int, NULL, 0444);
MODULE_PARM_DESC(index, "Index value for Audiowerk2 soundcard.");
diff --git a/sound/pci/azt3328.c b/sound/pci/azt3328.c
index bc1e683..95ffa6a 100644
--- a/sound/pci/azt3328.c
+++ b/sound/pci/azt3328.c
@@ -301,7 +301,7 @@
module_param_array(id, charp, NULL, 0444);
MODULE_PARM_DESC(id, "ID string for AZF3328 soundcard.");
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
+static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
module_param_array(enable, bool, NULL, 0444);
MODULE_PARM_DESC(enable, "Enable AZF3328 soundcard.");
diff --git a/sound/pci/bt87x.c b/sound/pci/bt87x.c
index c1c2d0c..62d6163 100644
--- a/sound/pci/bt87x.c
+++ b/sound/pci/bt87x.c
@@ -42,9 +42,9 @@
static int index[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = -2}; /* Exclude the first card */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
+static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
static int digital_rate[SNDRV_CARDS]; /* digital input rate */
-static int load_all; /* allow to load the non-whitelisted cards */
+static bool load_all; /* allow to load the non-whitelisted cards */
module_param_array(index, int, NULL, 0444);
MODULE_PARM_DESC(index, "Index value for Bt87x soundcard");
diff --git a/sound/pci/ca0106/ca0106_main.c b/sound/pci/ca0106/ca0106_main.c
index fe99fde..08d6ebf 100644
--- a/sound/pci/ca0106/ca0106_main.c
+++ b/sound/pci/ca0106/ca0106_main.c
@@ -156,7 +156,7 @@
// module parameters (see "Module Parameters")
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 bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
static uint subsystem[SNDRV_CARDS]; /* Force card subsystem model */
module_param_array(index, int, NULL, 0444);
diff --git a/sound/pci/cmipci.c b/sound/pci/cmipci.c
index 954c993..19b0626 100644
--- a/sound/pci/cmipci.c
+++ b/sound/pci/cmipci.c
@@ -54,10 +54,10 @@
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable switches */
+static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable switches */
static long mpu_port[SNDRV_CARDS];
static long fm_port[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)]=1};
-static int soft_ac3[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)]=1};
+static bool soft_ac3[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)]=1};
#ifdef SUPPORT_JOYSTICK
static int joystick_port[SNDRV_CARDS];
#endif
diff --git a/sound/pci/cs4281.c b/sound/pci/cs4281.c
index a6c6c5c..a9f368f 100644
--- a/sound/pci/cs4281.c
+++ b/sound/pci/cs4281.c
@@ -44,8 +44,8 @@
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable switches */
-static int dual_codec[SNDRV_CARDS]; /* dual codec */
+static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable switches */
+static bool dual_codec[SNDRV_CARDS]; /* dual codec */
module_param_array(index, int, NULL, 0444);
MODULE_PARM_DESC(index, "Index value for CS4281 soundcard.");
diff --git a/sound/pci/cs46xx/cs46xx.c b/sound/pci/cs46xx/cs46xx.c
index a4ecb40..819d79d 100644
--- a/sound/pci/cs46xx/cs46xx.c
+++ b/sound/pci/cs46xx/cs46xx.c
@@ -46,10 +46,10 @@
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
-static int external_amp[SNDRV_CARDS];
-static int thinkpad[SNDRV_CARDS];
-static int mmap_valid[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1};
+static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
+static bool external_amp[SNDRV_CARDS];
+static bool thinkpad[SNDRV_CARDS];
+static bool mmap_valid[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1};
module_param_array(index, int, NULL, 0444);
MODULE_PARM_DESC(index, "Index value for the CS46xx soundcard.");
diff --git a/sound/pci/cs5530.c b/sound/pci/cs5530.c
index 958f494..c47cabf 100644
--- a/sound/pci/cs5530.c
+++ b/sound/pci/cs5530.c
@@ -50,7 +50,14 @@
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 bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
+
+module_param_array(index, int, NULL, 0444);
+MODULE_PARM_DESC(index, "Index value for CS5530 Audio driver.");
+module_param_array(id, charp, NULL, 0444);
+MODULE_PARM_DESC(id, "ID string for CS5530 Audio driver.");
+module_param_array(enable, bool, NULL, 0444);
+MODULE_PARM_DESC(enable, "Enable CS5530 Audio driver.");
struct snd_cs5530 {
struct snd_card *card;
diff --git a/sound/pci/cs5535audio/cs5535audio.c b/sound/pci/cs5535audio/cs5535audio.c
index b8959d2..a2fb217 100644
--- a/sound/pci/cs5535audio/cs5535audio.c
+++ b/sound/pci/cs5535audio/cs5535audio.c
@@ -57,7 +57,7 @@
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 bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
module_param_array(index, int, NULL, 0444);
MODULE_PARM_DESC(index, "Index value for " DRIVER_NAME);
diff --git a/sound/pci/ctxfi/ctsrc.c b/sound/pci/ctxfi/ctsrc.c
index e134b3a..6e77e86 100644
--- a/sound/pci/ctxfi/ctsrc.c
+++ b/sound/pci/ctxfi/ctsrc.c
@@ -437,7 +437,7 @@
/* Allocate mem for master src resource */
if (MEMRD == desc->mode)
- src = kzalloc(sizeof(*src)*desc->multi, GFP_KERNEL);
+ src = kcalloc(desc->multi, sizeof(*src), GFP_KERNEL);
else
src = kzalloc(sizeof(*src), GFP_KERNEL);
diff --git a/sound/pci/ctxfi/cttimer.c b/sound/pci/ctxfi/cttimer.c
index 93b0aed..03fb909 100644
--- a/sound/pci/ctxfi/cttimer.c
+++ b/sound/pci/ctxfi/cttimer.c
@@ -15,8 +15,8 @@
#include "cthardware.h"
#include "cttimer.h"
-static int use_system_timer;
-MODULE_PARM_DESC(use_system_timer, "Foce to use system-timer");
+static bool use_system_timer;
+MODULE_PARM_DESC(use_system_timer, "Force to use system-timer");
module_param(use_system_timer, bool, S_IRUGO);
struct ct_timer_ops {
diff --git a/sound/pci/ctxfi/xfi.c b/sound/pci/ctxfi/xfi.c
index 33931ef..15d95d2 100644
--- a/sound/pci/ctxfi/xfi.c
+++ b/sound/pci/ctxfi/xfi.c
@@ -32,7 +32,7 @@
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 bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
static unsigned int subsystem[SNDRV_CARDS];
module_param_array(index, int, NULL, 0444);
diff --git a/sound/pci/echoaudio/echoaudio.c b/sound/pci/echoaudio/echoaudio.c
index 9fd694c..595c11f 100644
--- a/sound/pci/echoaudio/echoaudio.c
+++ b/sound/pci/echoaudio/echoaudio.c
@@ -26,7 +26,7 @@
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 bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
module_param_array(index, int, NULL, 0444);
MODULE_PARM_DESC(index, "Index value for " ECHOCARD_NAME " soundcard.");
diff --git a/sound/pci/emu10k1/emu10k1.c b/sound/pci/emu10k1/emu10k1.c
index eaa198e..790c65d 100644
--- a/sound/pci/emu10k1/emu10k1.c
+++ b/sound/pci/emu10k1/emu10k1.c
@@ -44,13 +44,13 @@
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
+static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
static int extin[SNDRV_CARDS];
static int extout[SNDRV_CARDS];
static int seq_ports[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 4};
static int max_synth_voices[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 64};
static int max_buffer_size[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 128};
-static int enable_ir[SNDRV_CARDS];
+static bool enable_ir[SNDRV_CARDS];
static uint subsystem[SNDRV_CARDS]; /* Force card subsystem model */
static uint delay_pcm_irq[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 2};
diff --git a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c
index 6a3e567..7549240 100644
--- a/sound/pci/emu10k1/emu10k1_main.c
+++ b/sound/pci/emu10k1/emu10k1_main.c
@@ -1480,6 +1480,18 @@
.spdif_bug = 1,
.invert_shared_spdif = 1, /* digital/analog switch swapped */
.ac97_chip = 1} ,
+ /* 0x20051102 also has SB0350 written on it, treated as Audigy 2 ZS by
+ Creative's Windows driver */
+ {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x20051102,
+ .driver = "Audigy2", .name = "SB Audigy 2 ZS [SB0350a]",
+ .id = "Audigy2",
+ .emu10k2_chip = 1,
+ .ca0102_chip = 1,
+ .ca0151_chip = 1,
+ .spk71 = 1,
+ .spdif_bug = 1,
+ .invert_shared_spdif = 1, /* digital/analog switch swapped */
+ .ac97_chip = 1} ,
{.vendor = 0x1102, .device = 0x0004, .subsystem = 0x20021102,
.driver = "Audigy2", .name = "SB Audigy 2 ZS [SB0350]",
.id = "Audigy2",
diff --git a/sound/pci/emu10k1/emu10k1x.c b/sound/pci/emu10k1/emu10k1x.c
index 2228be9..47a651c 100644
--- a/sound/pci/emu10k1/emu10k1x.c
+++ b/sound/pci/emu10k1/emu10k1x.c
@@ -50,7 +50,7 @@
// module parameters (see "Module Parameters")
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 bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
module_param_array(index, int, NULL, 0444);
MODULE_PARM_DESC(index, "Index value for the EMU10K1X soundcard.");
diff --git a/sound/pci/ens1370.c b/sound/pci/ens1370.c
index d085ad0..47a245e 100644
--- a/sound/pci/ens1370.c
+++ b/sound/pci/ens1370.c
@@ -83,12 +83,12 @@
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable switches */
+static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable switches */
#ifdef SUPPORT_JOYSTICK
#ifdef CHIP1371
static int joystick_port[SNDRV_CARDS];
#else
-static int joystick[SNDRV_CARDS];
+static bool joystick[SNDRV_CARDS];
#endif
#endif
#ifdef CHIP1371
diff --git a/sound/pci/es1938.c b/sound/pci/es1938.c
index 04cc21f..53eb76b 100644
--- a/sound/pci/es1938.c
+++ b/sound/pci/es1938.c
@@ -79,7 +79,7 @@
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
+static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
module_param_array(index, int, NULL, 0444);
MODULE_PARM_DESC(index, "Index value for ESS Solo-1 soundcard.");
diff --git a/sound/pci/es1968.c b/sound/pci/es1968.c
index 297a151..cb557c6 100644
--- a/sound/pci/es1968.c
+++ b/sound/pci/es1968.c
@@ -132,7 +132,7 @@
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 1-MAX */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
+static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
static int total_bufsize[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1024 };
static int pcm_substreams_p[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 4 };
static int pcm_substreams_c[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1 };
@@ -140,7 +140,7 @@
static int use_pm[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 2};
static int enable_mpu[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 2};
#ifdef SUPPORT_JOYSTICK
-static int joystick[SNDRV_CARDS];
+static bool joystick[SNDRV_CARDS];
#endif
module_param_array(index, int, NULL, 0444);
diff --git a/sound/pci/fm801.c b/sound/pci/fm801.c
index ec05ef5..9597ef1 100644
--- a/sound/pci/fm801.c
+++ b/sound/pci/fm801.c
@@ -48,7 +48,7 @@
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
+static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
/*
* Enable TEA575x tuner
* 1 = MediaForte 256-PCS
diff --git a/sound/pci/hda/Kconfig b/sound/pci/hda/Kconfig
index bb7e102d6..163b6b5 100644
--- a/sound/pci/hda/Kconfig
+++ b/sound/pci/hda/Kconfig
@@ -2,6 +2,7 @@
tristate "Intel HD Audio"
select SND_PCM
select SND_VMASTER
+ select SND_KCTL_JACK
help
Say Y here to include support for Intel "High Definition
Audio" (Azalia) and its compatible devices.
diff --git a/sound/pci/hda/Makefile b/sound/pci/hda/Makefile
index f928d66..ace157c 100644
--- a/sound/pci/hda/Makefile
+++ b/sound/pci/hda/Makefile
@@ -1,6 +1,6 @@
snd-hda-intel-objs := hda_intel.o
-snd-hda-codec-y := hda_codec.o
+snd-hda-codec-y := hda_codec.o hda_jack.o
snd-hda-codec-$(CONFIG_SND_HDA_GENERIC) += hda_generic.o
snd-hda-codec-$(CONFIG_PROC_FS) += hda_proc.o
snd-hda-codec-$(CONFIG_SND_HDA_HWDEP) += hda_hwdep.o
diff --git a/sound/pci/hda/alc262_quirks.c b/sound/pci/hda/alc262_quirks.c
deleted file mode 100644
index 7894b2b..0000000
--- a/sound/pci/hda/alc262_quirks.c
+++ /dev/null
@@ -1,875 +0,0 @@
-/*
- * ALC262 quirk models
- * included by patch_realtek.c
- */
-
-/* ALC262 models */
-enum {
- ALC262_AUTO,
- ALC262_BASIC,
- ALC262_HIPPO,
- ALC262_HIPPO_1,
- ALC262_FUJITSU,
- ALC262_BENQ_ED8,
- ALC262_BENQ_T31,
- ALC262_ULTRA,
- ALC262_LENOVO_3000,
- ALC262_NEC,
- ALC262_TOSHIBA_S06,
- ALC262_TOSHIBA_RX1,
- ALC262_TYAN,
- ALC262_MODEL_LAST /* last tag */
-};
-
-#define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
-#define ALC262_DIGIN_NID ALC880_DIGIN_NID
-
-#define alc262_dac_nids alc260_dac_nids
-#define alc262_adc_nids alc882_adc_nids
-#define alc262_adc_nids_alt alc882_adc_nids_alt
-#define alc262_capsrc_nids alc882_capsrc_nids
-#define alc262_capsrc_nids_alt alc882_capsrc_nids_alt
-
-#define alc262_modes alc260_modes
-#define alc262_capture_source alc882_capture_source
-
-static const hda_nid_t alc262_dmic_adc_nids[1] = {
- /* ADC0 */
- 0x09
-};
-
-static const hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
-
-static const struct snd_kcontrol_new alc262_base_mixer[] = {
- HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
- HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
- HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
- HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
- HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
- HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
- HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
- HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
- HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
- HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
- HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
- { } /* end */
-};
-
-/* bind hp and internal speaker mute (with plug check) as master switch */
-
-static int alc262_hippo_master_sw_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct alc_spec *spec = codec->spec;
- *ucontrol->value.integer.value = !spec->master_mute;
- return 0;
-}
-
-static int alc262_hippo_master_sw_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct alc_spec *spec = codec->spec;
- int val = !*ucontrol->value.integer.value;
-
- if (val == spec->master_mute)
- return 0;
- spec->master_mute = val;
- update_outputs(codec);
- return 1;
-}
-
-#define ALC262_HIPPO_MASTER_SWITCH \
- { \
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
- .name = "Master Playback Switch", \
- .info = snd_ctl_boolean_mono_info, \
- .get = alc262_hippo_master_sw_get, \
- .put = alc262_hippo_master_sw_put, \
- }, \
- { \
- .iface = NID_MAPPING, \
- .name = "Master Playback Switch", \
- .subdevice = SUBDEV_HP(0) | (SUBDEV_LINE(0) << 8) | \
- (SUBDEV_SPEAKER(0) << 16), \
- }
-
-#define alc262_hp_master_sw_get alc262_hippo_master_sw_get
-#define alc262_hp_master_sw_put alc262_hippo_master_sw_put
-
-static const struct snd_kcontrol_new alc262_hippo_mixer[] = {
- ALC262_HIPPO_MASTER_SWITCH,
- HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
- HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
- HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
- HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
- HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
- HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
- HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
- HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
- HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
- HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
- HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
- { } /* end */
-};
-
-static const struct snd_kcontrol_new alc262_hippo1_mixer[] = {
- HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
- ALC262_HIPPO_MASTER_SWITCH,
- HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
- HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
- HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
- HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
- HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
- HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
- HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
- HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
- HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
- HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
- { } /* end */
-};
-
-/* mute/unmute internal speaker according to the hp jack and mute state */
-static void alc262_hippo_setup(struct hda_codec *codec)
-{
- struct alc_spec *spec = codec->spec;
-
- spec->autocfg.hp_pins[0] = 0x15;
- spec->autocfg.speaker_pins[0] = 0x14;
- alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP);
-}
-
-static void alc262_hippo1_setup(struct hda_codec *codec)
-{
- struct alc_spec *spec = codec->spec;
-
- spec->autocfg.hp_pins[0] = 0x1b;
- spec->autocfg.speaker_pins[0] = 0x14;
- alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP);
-}
-
-
-static const struct snd_kcontrol_new alc262_sony_mixer[] = {
- HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
- ALC262_HIPPO_MASTER_SWITCH,
- HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
- HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
- HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
- HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
- { } /* end */
-};
-
-static const struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
- HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
- ALC262_HIPPO_MASTER_SWITCH,
- HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
- HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
- HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
- HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
- { } /* end */
-};
-
-static const struct snd_kcontrol_new alc262_tyan_mixer[] = {
- HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
- HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
- HDA_CODEC_VOLUME("Aux Playback Volume", 0x0b, 0x06, HDA_INPUT),
- HDA_CODEC_MUTE("Aux Playback Switch", 0x0b, 0x06, HDA_INPUT),
- HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
- HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
- HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
- HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
- HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
- HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
- HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
- HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
- { } /* end */
-};
-
-static const struct hda_verb alc262_tyan_verbs[] = {
- /* Headphone automute */
- {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
- {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
- {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
-
- /* P11 AUX_IN, white 4-pin connector */
- {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
- {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, 0xe1},
- {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, 0x93},
- {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0x19},
-
- {}
-};
-
-/* unsolicited event for HP jack sensing */
-static void alc262_tyan_setup(struct hda_codec *codec)
-{
- struct alc_spec *spec = codec->spec;
-
- spec->autocfg.hp_pins[0] = 0x1b;
- spec->autocfg.speaker_pins[0] = 0x15;
- alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP);
-}
-
-
-#define alc262_capture_mixer alc882_capture_mixer
-#define alc262_capture_alt_mixer alc882_capture_alt_mixer
-
-/*
- * generic initialization of ADC, input mixers and output mixers
- */
-static const struct hda_verb alc262_init_verbs[] = {
- /*
- * Unmute ADC0-2 and set the default input to mic-in
- */
- {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
- {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
- {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
- {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
- {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
- {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-
- /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
- * mixer widget
- * Note: PASD motherboards uses the Line In 2 as the input for
- * front panel mic (mic 2)
- */
- /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
- {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
- {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
- {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
- {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
- {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
-
- /*
- * Set up output mixers (0x0c - 0x0e)
- */
- /* set vol=0 to output mixers */
- {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
- {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
- {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
- /* set up input amps for analog loopback */
- /* Amp Indices: DAC = 0, mixer = 1 */
- {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
- {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
- {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
- {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
- {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
- {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
-
- {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
- {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
- {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
- {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
- {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
- {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
-
- {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
- {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
- {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
- {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
- {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
-
- {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
- {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
-
- /* FIXME: use matrix-type input source selection */
- /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
- /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
- {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
- {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
- {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
- {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
- /* Input mixer2 */
- {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
- {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
- {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
- {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
- /* Input mixer3 */
- {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
- {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
- {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
- {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
-
- { }
-};
-
-static const struct hda_verb alc262_eapd_verbs[] = {
- {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
- {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
- { }
-};
-
-static const struct hda_verb alc262_hippo1_unsol_verbs[] = {
- {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
- {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
- {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
-
- {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
- {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
- {}
-};
-
-static const struct hda_verb alc262_sony_unsol_verbs[] = {
- {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
- {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
- {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
-
- {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
- {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
- {}
-};
-
-static const struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
- HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
- HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
- { } /* end */
-};
-
-static const struct hda_verb alc262_toshiba_s06_verbs[] = {
- {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
- {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
- {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
- {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
- {0x22, AC_VERB_SET_CONNECT_SEL, 0x09},
- {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
- {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
- {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
- {}
-};
-
-static void alc262_toshiba_s06_setup(struct hda_codec *codec)
-{
- struct alc_spec *spec = codec->spec;
-
- spec->autocfg.hp_pins[0] = 0x15;
- spec->autocfg.speaker_pins[0] = 0x14;
- spec->ext_mic_pin = 0x18;
- spec->int_mic_pin = 0x12;
- spec->auto_mic = 1;
- alc_simple_setup_automute(spec, ALC_AUTOMUTE_PIN);
-}
-
-/*
- * nec model
- * 0x15 = headphone
- * 0x16 = internal speaker
- * 0x18 = external mic
- */
-
-static const struct snd_kcontrol_new alc262_nec_mixer[] = {
- HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT),
-
- HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
- HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
- HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
-
- HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
- { } /* end */
-};
-
-static const struct hda_verb alc262_nec_verbs[] = {
- /* Unmute Speaker */
- {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-
- /* Headphone */
- {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
- {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-
- /* External mic to headphone */
- {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
- /* External mic to speaker */
- {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
- {}
-};
-
-/*
- * fujitsu model
- * 0x14 = headphone/spdif-out, 0x15 = internal speaker,
- * 0x1b = port replicator headphone out
- */
-
-static const struct hda_verb alc262_fujitsu_unsol_verbs[] = {
- {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
- {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
- {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
- {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
- {}
-};
-
-static const struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
- {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
- {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
- {}
-};
-
-static const struct hda_verb alc262_lenovo_3000_init_verbs[] = {
- /* Front Mic pin: input vref at 50% */
- {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
- {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
- {}
-};
-
-static const struct hda_input_mux alc262_fujitsu_capture_source = {
- .num_items = 3,
- .items = {
- { "Mic", 0x0 },
- { "Internal Mic", 0x1 },
- { "CD", 0x4 },
- },
-};
-
-static void alc262_fujitsu_setup(struct hda_codec *codec)
-{
- struct alc_spec *spec = codec->spec;
-
- spec->autocfg.hp_pins[0] = 0x14;
- spec->autocfg.hp_pins[1] = 0x1b;
- spec->autocfg.speaker_pins[0] = 0x15;
- alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP);
-}
-
-/* bind volumes of both NID 0x0c and 0x0d */
-static const struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
- .ops = &snd_hda_bind_vol,
- .values = {
- HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
- HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
- 0
- },
-};
-
-static const struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
- HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Master Playback Switch",
- .subdevice = HDA_SUBDEV_NID_FLAG | 0x14,
- .info = snd_ctl_boolean_mono_info,
- .get = alc262_hp_master_sw_get,
- .put = alc262_hp_master_sw_put,
- },
- {
- .iface = NID_MAPPING,
- .name = "Master Playback Switch",
- .private_value = 0x1b,
- },
- HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
- HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
- HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
- HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
- HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
- HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
- HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
- HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
- { } /* end */
-};
-
-static void alc262_lenovo_3000_setup(struct hda_codec *codec)
-{
- struct alc_spec *spec = codec->spec;
-
- spec->autocfg.hp_pins[0] = 0x1b;
- spec->autocfg.speaker_pins[0] = 0x14;
- spec->autocfg.speaker_pins[1] = 0x16;
- alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP);
-}
-
-static const struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
- HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Master Playback Switch",
- .subdevice = HDA_SUBDEV_NID_FLAG | 0x1b,
- .info = snd_ctl_boolean_mono_info,
- .get = alc262_hp_master_sw_get,
- .put = alc262_hp_master_sw_put,
- },
- HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
- HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
- HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
- HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
- HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
- HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
- HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
- HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
- { } /* end */
-};
-
-static const struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
- HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
- ALC262_HIPPO_MASTER_SWITCH,
- HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
- HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
- HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
- HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
- HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
- HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
- { } /* end */
-};
-
-/* additional init verbs for Benq laptops */
-static const struct hda_verb alc262_EAPD_verbs[] = {
- {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
- {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
- {}
-};
-
-static const struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
- {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
- {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
-
- {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
- {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
- {}
-};
-
-/* Samsung Q1 Ultra Vista model setup */
-static const struct snd_kcontrol_new alc262_ultra_mixer[] = {
- HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
- HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
- HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
- HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
- HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
- HDA_CODEC_VOLUME("Headphone Mic Boost Volume", 0x15, 0, HDA_INPUT),
- { } /* end */
-};
-
-static const struct hda_verb alc262_ultra_verbs[] = {
- /* output mixer */
- {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
- {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
- {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
- /* speaker */
- {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
- {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
- {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
- {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
- /* HP */
- {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
- {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
- {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
- {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
- {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
- /* internal mic */
- {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
- {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
- /* ADC, choose mic */
- {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
- {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
- {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
- {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
- {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
- {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
- {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
- {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
- {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
- {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
- {}
-};
-
-/* mute/unmute internal speaker according to the hp jack and mute state */
-static void alc262_ultra_automute(struct hda_codec *codec)
-{
- struct alc_spec *spec = codec->spec;
- unsigned int mute;
-
- mute = 0;
- /* auto-mute only when HP is used as HP */
- if (!spec->cur_mux[0]) {
- spec->hp_jack_present = snd_hda_jack_detect(codec, 0x15);
- if (spec->hp_jack_present)
- mute = HDA_AMP_MUTE;
- }
- /* mute/unmute internal speaker */
- snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
- HDA_AMP_MUTE, mute);
- /* mute/unmute HP */
- snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
- HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
-}
-
-/* unsolicited event for HP jack sensing */
-static void alc262_ultra_unsol_event(struct hda_codec *codec,
- unsigned int res)
-{
- if ((res >> 26) != ALC_HP_EVENT)
- return;
- alc262_ultra_automute(codec);
-}
-
-static const struct hda_input_mux alc262_ultra_capture_source = {
- .num_items = 2,
- .items = {
- { "Mic", 0x1 },
- { "Headphone", 0x7 },
- },
-};
-
-static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct alc_spec *spec = codec->spec;
- int ret;
-
- ret = alc_mux_enum_put(kcontrol, ucontrol);
- if (!ret)
- return 0;
- /* reprogram the HP pin as mic or HP according to the input source */
- snd_hda_codec_write_cache(codec, 0x15, 0,
- AC_VERB_SET_PIN_WIDGET_CONTROL,
- spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
- alc262_ultra_automute(codec); /* mute/unmute HP */
- return ret;
-}
-
-static const struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
- HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
- HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Capture Source",
- .info = alc_mux_enum_info,
- .get = alc_mux_enum_get,
- .put = alc262_ultra_mux_enum_put,
- },
- {
- .iface = NID_MAPPING,
- .name = "Capture Source",
- .private_value = 0x15,
- },
- { } /* end */
-};
-
-static const struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {
-
- {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */
- {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
- {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
-
- {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* MIC jack */
- {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
- {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
- {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
-
- {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP jack */
- {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
- {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
- {}
-};
-
-/*
- * configuration and preset
- */
-static const char * const alc262_models[ALC262_MODEL_LAST] = {
- [ALC262_BASIC] = "basic",
- [ALC262_HIPPO] = "hippo",
- [ALC262_HIPPO_1] = "hippo_1",
- [ALC262_FUJITSU] = "fujitsu",
- [ALC262_BENQ_ED8] = "benq",
- [ALC262_BENQ_T31] = "benq-t31",
- [ALC262_TOSHIBA_S06] = "toshiba-s06",
- [ALC262_TOSHIBA_RX1] = "toshiba-rx1",
- [ALC262_ULTRA] = "ultra",
- [ALC262_LENOVO_3000] = "lenovo-3000",
- [ALC262_NEC] = "nec",
- [ALC262_TYAN] = "tyan",
- [ALC262_AUTO] = "auto",
-};
-
-static const struct snd_pci_quirk alc262_cfg_tbl[] = {
- SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
- SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
- SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
- ALC262_TOSHIBA_RX1),
- SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06),
- SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
- SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
- SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_TYAN),
- SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc032, "Samsung Q1",
- ALC262_ULTRA),
- SND_PCI_QUIRK(0x144d, 0xc510, "Samsung Q45", ALC262_HIPPO),
- SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
- SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
- SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
- SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
- {}
-};
-
-static const struct alc_config_preset alc262_presets[] = {
- [ALC262_BASIC] = {
- .mixers = { alc262_base_mixer },
- .init_verbs = { alc262_init_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,
- },
- [ALC262_HIPPO] = {
- .mixers = { alc262_hippo_mixer },
- .init_verbs = { alc262_init_verbs, alc_hp15_unsol_verbs},
- .num_dacs = ARRAY_SIZE(alc262_dac_nids),
- .dac_nids = alc262_dac_nids,
- .hp_nid = 0x03,
- .dig_out_nid = ALC262_DIGOUT_NID,
- .num_channel_mode = ARRAY_SIZE(alc262_modes),
- .channel_mode = alc262_modes,
- .input_mux = &alc262_capture_source,
- .unsol_event = alc_sku_unsol_event,
- .setup = alc262_hippo_setup,
- .init_hook = alc_inithook,
- },
- [ALC262_HIPPO_1] = {
- .mixers = { alc262_hippo1_mixer },
- .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
- .num_dacs = ARRAY_SIZE(alc262_dac_nids),
- .dac_nids = alc262_dac_nids,
- .hp_nid = 0x02,
- .dig_out_nid = ALC262_DIGOUT_NID,
- .num_channel_mode = ARRAY_SIZE(alc262_modes),
- .channel_mode = alc262_modes,
- .input_mux = &alc262_capture_source,
- .unsol_event = alc_sku_unsol_event,
- .setup = alc262_hippo1_setup,
- .init_hook = alc_inithook,
- },
- [ALC262_FUJITSU] = {
- .mixers = { alc262_fujitsu_mixer },
- .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
- alc262_fujitsu_unsol_verbs },
- .num_dacs = ARRAY_SIZE(alc262_dac_nids),
- .dac_nids = alc262_dac_nids,
- .hp_nid = 0x03,
- .dig_out_nid = ALC262_DIGOUT_NID,
- .num_channel_mode = ARRAY_SIZE(alc262_modes),
- .channel_mode = alc262_modes,
- .input_mux = &alc262_fujitsu_capture_source,
- .unsol_event = alc_sku_unsol_event,
- .setup = alc262_fujitsu_setup,
- .init_hook = alc_inithook,
- },
- [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,
- },
- [ALC262_BENQ_T31] = {
- .mixers = { alc262_benq_t31_mixer },
- .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs,
- alc_hp15_unsol_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,
- .unsol_event = alc_sku_unsol_event,
- .setup = alc262_hippo_setup,
- .init_hook = alc_inithook,
- },
- [ALC262_ULTRA] = {
- .mixers = { alc262_ultra_mixer },
- .cap_mixer = alc262_ultra_capture_mixer,
- .init_verbs = { alc262_ultra_verbs },
- .num_dacs = ARRAY_SIZE(alc262_dac_nids),
- .dac_nids = alc262_dac_nids,
- .num_channel_mode = ARRAY_SIZE(alc262_modes),
- .channel_mode = alc262_modes,
- .input_mux = &alc262_ultra_capture_source,
- .adc_nids = alc262_adc_nids, /* ADC0 */
- .capsrc_nids = alc262_capsrc_nids,
- .num_adc_nids = 1, /* single ADC */
- .unsol_event = alc262_ultra_unsol_event,
- .init_hook = alc262_ultra_automute,
- },
- [ALC262_LENOVO_3000] = {
- .mixers = { alc262_lenovo_3000_mixer },
- .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
- alc262_lenovo_3000_unsol_verbs,
- alc262_lenovo_3000_init_verbs },
- .num_dacs = ARRAY_SIZE(alc262_dac_nids),
- .dac_nids = alc262_dac_nids,
- .hp_nid = 0x03,
- .dig_out_nid = ALC262_DIGOUT_NID,
- .num_channel_mode = ARRAY_SIZE(alc262_modes),
- .channel_mode = alc262_modes,
- .input_mux = &alc262_fujitsu_capture_source,
- .unsol_event = alc_sku_unsol_event,
- .setup = alc262_lenovo_3000_setup,
- .init_hook = alc_inithook,
- },
- [ALC262_NEC] = {
- .mixers = { alc262_nec_mixer },
- .init_verbs = { alc262_nec_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,
- },
- [ALC262_TOSHIBA_S06] = {
- .mixers = { alc262_toshiba_s06_mixer },
- .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
- alc262_eapd_verbs },
- .num_dacs = ARRAY_SIZE(alc262_dac_nids),
- .capsrc_nids = alc262_dmic_capsrc_nids,
- .dac_nids = alc262_dac_nids,
- .adc_nids = alc262_dmic_adc_nids, /* ADC0 */
- .num_adc_nids = 1, /* single ADC */
- .dig_out_nid = ALC262_DIGOUT_NID,
- .num_channel_mode = ARRAY_SIZE(alc262_modes),
- .channel_mode = alc262_modes,
- .unsol_event = alc_sku_unsol_event,
- .setup = alc262_toshiba_s06_setup,
- .init_hook = alc_inithook,
- },
- [ALC262_TOSHIBA_RX1] = {
- .mixers = { alc262_toshiba_rx1_mixer },
- .init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_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,
- .unsol_event = alc_sku_unsol_event,
- .setup = alc262_hippo_setup,
- .init_hook = alc_inithook,
- },
- [ALC262_TYAN] = {
- .mixers = { alc262_tyan_mixer },
- .init_verbs = { alc262_init_verbs, alc262_tyan_verbs},
- .num_dacs = ARRAY_SIZE(alc262_dac_nids),
- .dac_nids = alc262_dac_nids,
- .hp_nid = 0x02,
- .dig_out_nid = ALC262_DIGOUT_NID,
- .num_channel_mode = ARRAY_SIZE(alc262_modes),
- .channel_mode = alc262_modes,
- .input_mux = &alc262_capture_source,
- .unsol_event = alc_sku_unsol_event,
- .setup = alc262_tyan_setup,
- .init_hook = alc_hp_automute,
- },
-};
-
diff --git a/sound/pci/hda/alc880_quirks.c b/sound/pci/hda/alc880_quirks.c
index bea22ed..5b68435 100644
--- a/sound/pci/hda/alc880_quirks.c
+++ b/sound/pci/hda/alc880_quirks.c
@@ -26,8 +26,6 @@
ALC880_CLEVO,
ALC880_TCL_S700,
ALC880_LG,
- ALC880_LG_LW,
- ALC880_MEDION_RIM,
#ifdef CONFIG_SND_DEBUG
ALC880_TEST,
#endif
@@ -1052,163 +1050,6 @@
alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP);
}
-/*
- * LG LW20
- *
- * Pin assignment:
- * Speaker-out: 0x14
- * Mic-In: 0x18
- * Built-in Mic-In: 0x19
- * Line-In: 0x1b
- * HP-Out: 0x1a
- * SPDIF-Out: 0x1e
- */
-
-static const struct hda_input_mux alc880_lg_lw_capture_source = {
- .num_items = 3,
- .items = {
- { "Mic", 0x0 },
- { "Internal Mic", 0x1 },
- { "Line In", 0x2 },
- },
-};
-
-#define alc880_lg_lw_modes alc880_threestack_modes
-
-static const struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
- HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
- HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
- HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
- HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
- HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
- HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
- HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
- HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
- HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
- HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
- HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
- HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
- HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Channel Mode",
- .info = alc_ch_mode_info,
- .get = alc_ch_mode_get,
- .put = alc_ch_mode_put,
- },
- { } /* end */
-};
-
-static const struct hda_verb alc880_lg_lw_init_verbs[] = {
- {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
- {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
- {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
-
- /* set capture source to mic-in */
- {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
- {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
- {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
- {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
- /* speaker-out */
- {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
- {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
- /* HP-out */
- {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
- {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
- /* mic-in to input */
- {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
- {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
- /* built-in mic */
- {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
- {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
- /* jack sense */
- {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
- { }
-};
-
-/* toggle speaker-output according to the hp-jack state */
-static void alc880_lg_lw_setup(struct hda_codec *codec)
-{
- struct alc_spec *spec = codec->spec;
-
- spec->autocfg.hp_pins[0] = 0x1b;
- spec->autocfg.speaker_pins[0] = 0x14;
- alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP);
-}
-
-static const struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
- HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
- HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
- HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
- HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
- HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
- HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT),
- { } /* end */
-};
-
-static const struct hda_input_mux alc880_medion_rim_capture_source = {
- .num_items = 2,
- .items = {
- { "Mic", 0x0 },
- { "Internal Mic", 0x1 },
- },
-};
-
-static const struct hda_verb alc880_medion_rim_init_verbs[] = {
- {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
-
- {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
- {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-
- /* Mic1 (rear panel) pin widget for input and vref at 80% */
- {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
- {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
- /* Mic2 (as headphone out) for HP output */
- {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
- {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
- /* Internal Speaker */
- {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
- {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-
- {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
- {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
-
- {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
- { }
-};
-
-/* toggle speaker-output according to the hp-jack state */
-static void alc880_medion_rim_automute(struct hda_codec *codec)
-{
- struct alc_spec *spec = codec->spec;
- alc_hp_automute(codec);
- /* toggle EAPD */
- if (spec->hp_jack_present)
- snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
- else
- snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2);
-}
-
-static void alc880_medion_rim_unsol_event(struct hda_codec *codec,
- unsigned int res)
-{
- /* Looks like the unsol event is incompatible with the standard
- * definition. 4bit tag is placed at 28 bit!
- */
- if ((res >> 28) == ALC_HP_EVENT)
- alc880_medion_rim_automute(codec);
-}
-
-static void alc880_medion_rim_setup(struct hda_codec *codec)
-{
- struct alc_spec *spec = codec->spec;
-
- spec->autocfg.hp_pins[0] = 0x14;
- spec->autocfg.speaker_pins[0] = 0x1b;
- alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP);
-}
-
#ifdef CONFIG_SND_HDA_POWER_SAVE
static const struct hda_amp_list alc880_lg_loopbacks[] = {
{ 0x0b, HDA_INPUT, 1 },
@@ -1505,8 +1346,6 @@
[ALC880_FUJITSU] = "fujitsu",
[ALC880_F1734] = "F1734",
[ALC880_LG] = "lg",
- [ALC880_LG_LW] = "lg-lw",
- [ALC880_MEDION_RIM] = "medion",
#ifdef CONFIG_SND_DEBUG
[ALC880_TEST] = "test",
#endif
@@ -1557,18 +1396,15 @@
SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
- SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM),
SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_F1734),
SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
- SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
SND_PCI_QUIRK(0x1854, 0x005f, "LG P1 Express", ALC880_LG),
SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
- SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
@@ -1848,35 +1684,6 @@
.loopbacks = alc880_lg_loopbacks,
#endif
},
- [ALC880_LG_LW] = {
- .mixers = { alc880_lg_lw_mixer },
- .init_verbs = { alc880_volume_init_verbs,
- alc880_lg_lw_init_verbs },
- .num_dacs = ARRAY_SIZE(alc880_dac_nids),
- .dac_nids = alc880_dac_nids,
- .dig_out_nid = ALC880_DIGOUT_NID,
- .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
- .channel_mode = alc880_lg_lw_modes,
- .input_mux = &alc880_lg_lw_capture_source,
- .unsol_event = alc_sku_unsol_event,
- .setup = alc880_lg_lw_setup,
- .init_hook = alc_hp_automute,
- },
- [ALC880_MEDION_RIM] = {
- .mixers = { alc880_medion_rim_mixer },
- .init_verbs = { alc880_volume_init_verbs,
- alc880_medion_rim_init_verbs,
- alc_gpio2_init_verbs },
- .num_dacs = ARRAY_SIZE(alc880_dac_nids),
- .dac_nids = alc880_dac_nids,
- .dig_out_nid = ALC880_DIGOUT_NID,
- .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
- .channel_mode = alc880_2_jack_modes,
- .input_mux = &alc880_medion_rim_capture_source,
- .unsol_event = alc880_medion_rim_unsol_event,
- .setup = alc880_medion_rim_setup,
- .init_hook = alc880_medion_rim_automute,
- },
#ifdef CONFIG_SND_DEBUG
[ALC880_TEST] = {
.mixers = { alc880_test_mixer },
diff --git a/sound/pci/hda/alc882_quirks.c b/sound/pci/hda/alc882_quirks.c
index e251514..bdf0ed4 100644
--- a/sound/pci/hda/alc882_quirks.c
+++ b/sound/pci/hda/alc882_quirks.c
@@ -6,509 +6,15 @@
/* ALC882 models */
enum {
ALC882_AUTO,
- ALC882_3ST_DIG,
- ALC882_6ST_DIG,
- ALC882_ARIMA,
- ALC882_W2JC,
- ALC882_TARGA,
- ALC882_ASUS_A7J,
- ALC882_ASUS_A7M,
- ALC885_MACPRO,
ALC885_MBA21,
ALC885_MBP3,
ALC885_MB5,
ALC885_MACMINI3,
- ALC885_IMAC24,
ALC885_IMAC91,
- ALC883_3ST_2ch_DIG,
- ALC883_3ST_6ch_DIG,
- ALC883_3ST_6ch,
- ALC883_6ST_DIG,
- ALC883_TARGA_DIG,
- ALC883_TARGA_2ch_DIG,
- ALC883_TARGA_8ch_DIG,
- ALC883_ACER,
- ALC883_ACER_ASPIRE,
- ALC888_ACER_ASPIRE_4930G,
- ALC888_ACER_ASPIRE_6530G,
- ALC888_ACER_ASPIRE_8930G,
- ALC888_ACER_ASPIRE_7730G,
- ALC883_MEDION,
- ALC883_MEDION_WIM2160,
- ALC883_LAPTOP_EAPD,
- ALC883_LENOVO_101E_2ch,
- ALC883_LENOVO_NB0763,
- ALC888_LENOVO_MS7195_DIG,
- ALC888_LENOVO_SKY,
- ALC883_HAIER_W66,
- ALC888_3ST_HP,
- ALC888_6ST_DELL,
- ALC883_MITAC,
- ALC883_CLEVO_M540R,
- ALC883_CLEVO_M720,
- ALC883_FUJITSU_PI2515,
- ALC888_FUJITSU_XA3530,
- ALC883_3ST_6ch_INTEL,
- ALC889A_INTEL,
- ALC889_INTEL,
- ALC888_ASUS_M90V,
- ALC888_ASUS_EEE1601,
ALC889A_MB31,
- ALC1200_ASUS_P5Q,
- ALC883_SONY_VAIO_TT,
ALC882_MODEL_LAST,
};
-/*
- * 2ch mode
- */
-static const struct hda_verb alc888_4ST_ch2_intel_init[] = {
-/* Mic-in jack as mic in */
- { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
- { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
-/* Line-in jack as Line in */
- { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
- { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
-/* Line-Out as Front */
- { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
- { } /* end */
-};
-
-/*
- * 4ch mode
- */
-static const struct hda_verb alc888_4ST_ch4_intel_init[] = {
-/* Mic-in jack as mic in */
- { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
- { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
-/* Line-in jack as Surround */
- { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
- { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
-/* Line-Out as Front */
- { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
- { } /* end */
-};
-
-/*
- * 6ch mode
- */
-static const struct hda_verb alc888_4ST_ch6_intel_init[] = {
-/* Mic-in jack as CLFE */
- { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
- { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
-/* Line-in jack as Surround */
- { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
- { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
-/* Line-Out as CLFE (workaround because Mic-in is not loud enough) */
- { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
- { } /* end */
-};
-
-/*
- * 8ch mode
- */
-static const struct hda_verb alc888_4ST_ch8_intel_init[] = {
-/* Mic-in jack as CLFE */
- { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
- { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
-/* Line-in jack as Surround */
- { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
- { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
-/* Line-Out as Side */
- { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
- { } /* end */
-};
-
-static const struct hda_channel_mode alc888_4ST_8ch_intel_modes[4] = {
- { 2, alc888_4ST_ch2_intel_init },
- { 4, alc888_4ST_ch4_intel_init },
- { 6, alc888_4ST_ch6_intel_init },
- { 8, alc888_4ST_ch8_intel_init },
-};
-
-/*
- * ALC888 Fujitsu Siemens Amillo xa3530
- */
-
-static const struct hda_verb alc888_fujitsu_xa3530_verbs[] = {
-/* Front Mic: set to PIN_IN (empty by default) */
- {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-/* Connect Internal HP to Front */
- {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
- {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
- {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
-/* Connect Bass HP to Front */
- {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
- {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
- {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
-/* Connect Line-Out side jack (SPDIF) to Side */
- {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
- {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
- {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
-/* Connect Mic jack to CLFE */
- {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
- {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
- {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
-/* Connect Line-in jack to Surround */
- {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
- {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
- {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
-/* Connect HP out jack to Front */
- {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
- {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
- {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
-/* Enable unsolicited event for HP jack and Line-out jack */
- {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
- {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
- {}
-};
-
-static void alc889_automute_setup(struct hda_codec *codec)
-{
- struct alc_spec *spec = codec->spec;
-
- spec->autocfg.hp_pins[0] = 0x15;
- spec->autocfg.speaker_pins[0] = 0x14;
- spec->autocfg.speaker_pins[1] = 0x16;
- spec->autocfg.speaker_pins[2] = 0x17;
- spec->autocfg.speaker_pins[3] = 0x19;
- spec->autocfg.speaker_pins[4] = 0x1a;
- alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP);
-}
-
-static void alc889_intel_init_hook(struct hda_codec *codec)
-{
- alc889_coef_init(codec);
- alc_hp_automute(codec);
-}
-
-static void alc888_fujitsu_xa3530_setup(struct hda_codec *codec)
-{
- struct alc_spec *spec = codec->spec;
-
- spec->autocfg.hp_pins[0] = 0x17; /* line-out */
- spec->autocfg.hp_pins[1] = 0x1b; /* hp */
- spec->autocfg.speaker_pins[0] = 0x14; /* speaker */
- spec->autocfg.speaker_pins[1] = 0x15; /* bass */
- alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP);
-}
-
-/*
- * ALC888 Acer Aspire 4930G model
- */
-
-static const struct hda_verb alc888_acer_aspire_4930g_verbs[] = {
-/* Front Mic: set to PIN_IN (empty by default) */
- {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-/* Unselect Front Mic by default in input mixer 3 */
- {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
-/* Enable unsolicited event for HP jack */
- {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
-/* Connect Internal HP to front */
- {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
- {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
- {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
-/* Connect HP out to front */
- {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
- {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
- {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
- {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
- { }
-};
-
-/*
- * ALC888 Acer Aspire 6530G model
- */
-
-static const struct hda_verb alc888_acer_aspire_6530g_verbs[] = {
-/* Route to built-in subwoofer as well as speakers */
- {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
- {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
- {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
- {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
-/* Bias voltage on for external mic port */
- {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
-/* Front Mic: set to PIN_IN (empty by default) */
- {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-/* Unselect Front Mic by default in input mixer 3 */
- {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
-/* Enable unsolicited event for HP jack */
- {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
-/* Enable speaker output */
- {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
- {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
- {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
-/* Enable headphone output */
- {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
- {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
- {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
- {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
- { }
-};
-
-/*
- *ALC888 Acer Aspire 7730G model
- */
-
-static const struct hda_verb alc888_acer_aspire_7730G_verbs[] = {
-/* Bias voltage on for external mic port */
- {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
-/* Front Mic: set to PIN_IN (empty by default) */
- {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-/* Unselect Front Mic by default in input mixer 3 */
- {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
-/* Enable unsolicited event for HP jack */
- {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
-/* Enable speaker output */
- {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
- {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
- {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
-/* Enable headphone output */
- {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
- {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
- {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
- {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
-/*Enable internal subwoofer */
- {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
- {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
- {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
- {0x17, AC_VERB_SET_EAPD_BTLENABLE, 2},
- { }
-};
-
-/*
- * ALC889 Acer Aspire 8930G model
- */
-
-static const struct hda_verb alc889_acer_aspire_8930g_verbs[] = {
-/* Front Mic: set to PIN_IN (empty by default) */
- {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-/* Unselect Front Mic by default in input mixer 3 */
- {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
-/* Enable unsolicited event for HP jack */
- {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
-/* Connect Internal Front to Front */
- {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
- {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
- {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
-/* Connect Internal Rear to Rear */
- {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
- {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
- {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
-/* Connect Internal CLFE to CLFE */
- {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
- {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
- {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
-/* Connect HP out to Front */
- {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
- {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
- {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
-/* Enable all DACs */
-/* DAC DISABLE/MUTE 1? */
-/* setting bits 1-5 disables DAC nids 0x02-0x06 apparently. Init=0x38 */
- {0x20, AC_VERB_SET_COEF_INDEX, 0x03},
- {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
-/* DAC DISABLE/MUTE 2? */
-/* some bit here disables the other DACs. Init=0x4900 */
- {0x20, AC_VERB_SET_COEF_INDEX, 0x08},
- {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
-/* DMIC fix
- * This laptop has a stereo digital microphone. The mics are only 1cm apart
- * which makes the stereo useless. However, either the mic or the ALC889
- * makes the signal become a difference/sum signal instead of standard
- * stereo, which is annoying. So instead we flip this bit which makes the
- * codec replicate the sum signal to both channels, turning it into a
- * normal mono mic.
- */
-/* DMIC_CONTROL? Init value = 0x0001 */
- {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
- {0x20, AC_VERB_SET_PROC_COEF, 0x0003},
- { }
-};
-
-static const struct hda_input_mux alc888_2_capture_sources[2] = {
- /* Front mic only available on one ADC */
- {
- .num_items = 4,
- .items = {
- { "Mic", 0x0 },
- { "Line", 0x2 },
- { "CD", 0x4 },
- { "Front Mic", 0xb },
- },
- },
- {
- .num_items = 3,
- .items = {
- { "Mic", 0x0 },
- { "Line", 0x2 },
- { "CD", 0x4 },
- },
- }
-};
-
-static const struct hda_input_mux alc888_acer_aspire_6530_sources[2] = {
- /* Interal mic only available on one ADC */
- {
- .num_items = 5,
- .items = {
- { "Mic", 0x0 },
- { "Line In", 0x2 },
- { "CD", 0x4 },
- { "Input Mix", 0xa },
- { "Internal Mic", 0xb },
- },
- },
- {
- .num_items = 4,
- .items = {
- { "Mic", 0x0 },
- { "Line In", 0x2 },
- { "CD", 0x4 },
- { "Input Mix", 0xa },
- },
- }
-};
-
-static const struct hda_input_mux alc889_capture_sources[3] = {
- /* Digital mic only available on first "ADC" */
- {
- .num_items = 5,
- .items = {
- { "Mic", 0x0 },
- { "Line", 0x2 },
- { "CD", 0x4 },
- { "Front Mic", 0xb },
- { "Input Mix", 0xa },
- },
- },
- {
- .num_items = 4,
- .items = {
- { "Mic", 0x0 },
- { "Line", 0x2 },
- { "CD", 0x4 },
- { "Input Mix", 0xa },
- },
- },
- {
- .num_items = 4,
- .items = {
- { "Mic", 0x0 },
- { "Line", 0x2 },
- { "CD", 0x4 },
- { "Input Mix", 0xa },
- },
- }
-};
-
-static const struct snd_kcontrol_new alc888_base_mixer[] = {
- HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
- HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
- HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
- HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
- HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
- HDA_OUTPUT),
- HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
- HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
- HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
- HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
- HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
- HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
- HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
- HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
- HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
- HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
- HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
- HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
- { } /* end */
-};
-
-static const struct snd_kcontrol_new alc888_acer_aspire_4930g_mixer[] = {
- HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
- HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
- HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
- HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
- HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
- HDA_OUTPUT),
- HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
- HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
- HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
- HDA_CODEC_VOLUME_MONO("Internal LFE Playback Volume", 0x0f, 1, 0x0, HDA_OUTPUT),
- HDA_BIND_MUTE_MONO("Internal LFE Playback Switch", 0x0f, 1, 2, HDA_INPUT),
- HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
- HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
- HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
- HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
- HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
- HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
- HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
- { } /* end */
-};
-
-static const struct snd_kcontrol_new alc889_acer_aspire_8930g_mixer[] = {
- HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
- HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
- HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
- HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
- HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
- HDA_OUTPUT),
- HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
- HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
- HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
- HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
- HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
- HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
- HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
- HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
- { } /* end */
-};
-
-
-static void alc888_acer_aspire_4930g_setup(struct hda_codec *codec)
-{
- struct alc_spec *spec = codec->spec;
-
- spec->autocfg.hp_pins[0] = 0x15;
- spec->autocfg.speaker_pins[0] = 0x14;
- spec->autocfg.speaker_pins[1] = 0x16;
- spec->autocfg.speaker_pins[2] = 0x17;
- alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP);
-}
-
-static void alc888_acer_aspire_6530g_setup(struct hda_codec *codec)
-{
- struct alc_spec *spec = codec->spec;
-
- spec->autocfg.hp_pins[0] = 0x15;
- spec->autocfg.speaker_pins[0] = 0x14;
- spec->autocfg.speaker_pins[1] = 0x16;
- spec->autocfg.speaker_pins[2] = 0x17;
- alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP);
-}
-
-static void alc888_acer_aspire_7730g_setup(struct hda_codec *codec)
-{
- struct alc_spec *spec = codec->spec;
-
- spec->autocfg.hp_pins[0] = 0x15;
- spec->autocfg.speaker_pins[0] = 0x14;
- spec->autocfg.speaker_pins[1] = 0x16;
- spec->autocfg.speaker_pins[2] = 0x17;
- alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP);
-}
-
-static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec)
-{
- struct alc_spec *spec = codec->spec;
-
- spec->autocfg.hp_pins[0] = 0x15;
- spec->autocfg.speaker_pins[0] = 0x14;
- spec->autocfg.speaker_pins[1] = 0x16;
- spec->autocfg.speaker_pins[2] = 0x1b;
- alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP);
-}
-
#define ALC882_DIGOUT_NID 0x06
#define ALC882_DIGIN_NID 0x0a
#define ALC883_DIGOUT_NID ALC882_DIGOUT_NID
@@ -531,15 +37,9 @@
#define alc882_adc_nids alc880_adc_nids
#define alc882_adc_nids_alt alc880_adc_nids_alt
#define alc883_adc_nids alc882_adc_nids_alt
-static const hda_nid_t alc883_adc_nids_alt[1] = { 0x08 };
-static const hda_nid_t alc883_adc_nids_rev[2] = { 0x09, 0x08 };
-#define alc889_adc_nids alc880_adc_nids
-static const hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
static const hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
#define alc883_capsrc_nids alc882_capsrc_nids_alt
-static const hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 };
-#define alc889_capsrc_nids alc882_capsrc_nids
/* input MUX */
/* FIXME: should be a matrix-type input source selection */
@@ -556,15 +56,6 @@
#define alc883_capture_source alc882_capture_source
-static const struct hda_input_mux alc889_capture_source = {
- .num_items = 3,
- .items = {
- { "Front Mic", 0x0 },
- { "Mic", 0x3 },
- { "Line", 0x2 },
- },
-};
-
static const struct hda_input_mux mb5_capture_source = {
.num_items = 3,
.items = {
@@ -592,49 +83,6 @@
},
};
-static const struct hda_input_mux alc883_lenovo_101e_capture_source = {
- .num_items = 2,
- .items = {
- { "Mic", 0x1 },
- { "Line", 0x2 },
- },
-};
-
-static const struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
- .num_items = 4,
- .items = {
- { "Mic", 0x0 },
- { "Internal Mic", 0x1 },
- { "Line", 0x2 },
- { "CD", 0x4 },
- },
-};
-
-static const struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
- .num_items = 2,
- .items = {
- { "Mic", 0x0 },
- { "Internal Mic", 0x1 },
- },
-};
-
-static const struct hda_input_mux alc883_lenovo_sky_capture_source = {
- .num_items = 3,
- .items = {
- { "Mic", 0x0 },
- { "Front Mic", 0x1 },
- { "Line", 0x4 },
- },
-};
-
-static const struct hda_input_mux alc883_asus_eee1601_capture_source = {
- .num_items = 2,
- .items = {
- { "Mic", 0x0 },
- { "Line", 0x2 },
- },
-};
-
static const struct hda_input_mux alc889A_mb31_capture_source = {
.num_items = 2,
.items = {
@@ -654,131 +102,6 @@
},
};
-/*
- * 2ch mode
- */
-static const struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
- { 2, NULL }
-};
-
-/*
- * 2ch mode
- */
-static const struct hda_verb alc882_3ST_ch2_init[] = {
- { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
- { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
- { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
- { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
- { } /* end */
-};
-
-/*
- * 4ch mode
- */
-static const struct hda_verb alc882_3ST_ch4_init[] = {
- { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
- { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
- { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
- { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
- { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
- { } /* end */
-};
-
-/*
- * 6ch mode
- */
-static const struct hda_verb alc882_3ST_ch6_init[] = {
- { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
- { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
- { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
- { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
- { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
- { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
- { } /* end */
-};
-
-static const struct hda_channel_mode alc882_3ST_6ch_modes[3] = {
- { 2, alc882_3ST_ch2_init },
- { 4, alc882_3ST_ch4_init },
- { 6, alc882_3ST_ch6_init },
-};
-
-#define alc883_3ST_6ch_modes alc882_3ST_6ch_modes
-
-/*
- * 2ch mode
- */
-static const struct hda_verb alc883_3ST_ch2_clevo_init[] = {
- { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
- { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
- { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
- { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
- { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
- { } /* end */
-};
-
-/*
- * 4ch mode
- */
-static const struct hda_verb alc883_3ST_ch4_clevo_init[] = {
- { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
- { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
- { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
- { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
- { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
- { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
- { } /* end */
-};
-
-/*
- * 6ch mode
- */
-static const struct hda_verb alc883_3ST_ch6_clevo_init[] = {
- { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
- { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
- { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
- { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
- { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
- { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
- { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
- { } /* end */
-};
-
-static const struct hda_channel_mode alc883_3ST_6ch_clevo_modes[3] = {
- { 2, alc883_3ST_ch2_clevo_init },
- { 4, alc883_3ST_ch4_clevo_init },
- { 6, alc883_3ST_ch6_clevo_init },
-};
-
-
-/*
- * 6ch mode
- */
-static const struct hda_verb alc882_sixstack_ch6_init[] = {
- { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
- { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
- { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
- { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
- { } /* end */
-};
-
-/*
- * 8ch mode
- */
-static const struct hda_verb alc882_sixstack_ch8_init[] = {
- { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
- { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
- { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
- { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
- { } /* end */
-};
-
-static const struct hda_channel_mode alc882_sixstack_modes[2] = {
- { 6, alc882_sixstack_ch6_init },
- { 8, alc882_sixstack_ch8_init },
-};
-
-
/* Macbook Air 2,1 */
static const struct hda_channel_mode alc885_mba21_ch_modes[1] = {
@@ -847,216 +170,6 @@
#define alc885_macmini3_6ch_modes alc885_mb5_6ch_modes
-/*
- * 2ch mode
- */
-static const struct hda_verb alc883_4ST_ch2_init[] = {
- { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
- { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
- { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
- { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
- { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
- { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
- { } /* end */
-};
-
-/*
- * 4ch mode
- */
-static const struct hda_verb alc883_4ST_ch4_init[] = {
- { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
- { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
- { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
- { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
- { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
- { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
- { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
- { } /* end */
-};
-
-/*
- * 6ch mode
- */
-static const struct hda_verb alc883_4ST_ch6_init[] = {
- { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
- { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
- { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
- { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
- { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
- { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
- { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
- { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
- { } /* end */
-};
-
-/*
- * 8ch mode
- */
-static const struct hda_verb alc883_4ST_ch8_init[] = {
- { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
- { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
- { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
- { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
- { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
- { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
- { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
- { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
- { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
- { } /* end */
-};
-
-static const struct hda_channel_mode alc883_4ST_8ch_modes[4] = {
- { 2, alc883_4ST_ch2_init },
- { 4, alc883_4ST_ch4_init },
- { 6, alc883_4ST_ch6_init },
- { 8, alc883_4ST_ch8_init },
-};
-
-
-/*
- * 2ch mode
- */
-static const struct hda_verb alc883_3ST_ch2_intel_init[] = {
- { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
- { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
- { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
- { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
- { } /* end */
-};
-
-/*
- * 4ch mode
- */
-static const struct hda_verb alc883_3ST_ch4_intel_init[] = {
- { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
- { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
- { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
- { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
- { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
- { } /* end */
-};
-
-/*
- * 6ch mode
- */
-static const struct hda_verb alc883_3ST_ch6_intel_init[] = {
- { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
- { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
- { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
- { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
- { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
- { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
- { } /* end */
-};
-
-static const struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
- { 2, alc883_3ST_ch2_intel_init },
- { 4, alc883_3ST_ch4_intel_init },
- { 6, alc883_3ST_ch6_intel_init },
-};
-
-/*
- * 2ch mode
- */
-static const struct hda_verb alc889_ch2_intel_init[] = {
- { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
- { 0x19, AC_VERB_SET_CONNECT_SEL, 0x00 },
- { 0x16, AC_VERB_SET_CONNECT_SEL, 0x00 },
- { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00 },
- { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
- { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
- { } /* end */
-};
-
-/*
- * 6ch mode
- */
-static const struct hda_verb alc889_ch6_intel_init[] = {
- { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
- { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
- { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
- { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
- { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
- { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
- { } /* end */
-};
-
-/*
- * 8ch mode
- */
-static const struct hda_verb alc889_ch8_intel_init[] = {
- { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
- { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
- { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
- { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
- { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x03 },
- { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
- { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
- { } /* end */
-};
-
-static const struct hda_channel_mode alc889_8ch_intel_modes[3] = {
- { 2, alc889_ch2_intel_init },
- { 6, alc889_ch6_intel_init },
- { 8, alc889_ch8_intel_init },
-};
-
-/*
- * 6ch mode
- */
-static const struct hda_verb alc883_sixstack_ch6_init[] = {
- { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
- { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
- { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
- { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
- { } /* end */
-};
-
-/*
- * 8ch mode
- */
-static const struct hda_verb alc883_sixstack_ch8_init[] = {
- { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
- { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
- { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
- { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
- { } /* end */
-};
-
-static const struct hda_channel_mode alc883_sixstack_modes[2] = {
- { 6, alc883_sixstack_ch6_init },
- { 8, alc883_sixstack_ch8_init },
-};
-
-
-/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
- * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
- */
-static const struct snd_kcontrol_new alc882_base_mixer[] = {
- HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
- HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
- HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
- HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
- HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
- HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
- HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
- HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
- HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
- HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
- HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
- HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
- HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
- HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
- HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
- HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
- HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
- HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
- HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
- { } /* end */
-};
-
/* Macbook Air 2,1 same control for HP and internal Speaker */
static const struct snd_kcontrol_new alc885_mba21_mixer[] = {
@@ -1121,70 +234,6 @@
};
-static const struct snd_kcontrol_new alc882_w2jc_mixer[] = {
- HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
- HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
- HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
- HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
- HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
- HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
- HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
- HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
- HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
- { } /* end */
-};
-
-static const struct snd_kcontrol_new alc882_targa_mixer[] = {
- HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
- HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
- HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
- HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
- HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
- HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
- HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
- HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
- HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
- HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
- HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
- HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
- { } /* end */
-};
-
-/* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
- * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
- */
-static const struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
- HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
- HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
- HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
- HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
- HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
- HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
- HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
- HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
- HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
- { } /* end */
-};
-
-static const struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
- HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
- HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
- HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
- HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
- HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
- HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
- HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
- HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
- HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
- { } /* end */
-};
-
static const struct snd_kcontrol_new alc882_chmode_mixer[] = {
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -1258,179 +307,8 @@
{ }
};
-static const struct hda_verb alc882_adc1_init_verbs[] = {
- /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
- {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
- {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
- {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
- {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
- /* ADC1: mute amp left and right */
- {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
- {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
- { }
-};
-
-static const struct hda_verb alc882_eapd_verbs[] = {
- /* change to EAPD mode */
- {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
- {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
- { }
-};
-
-static const struct hda_verb alc889_eapd_verbs[] = {
- {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
- {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
- { }
-};
-
-static const struct hda_verb alc_hp15_unsol_verbs[] = {
- {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
- {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
- {}
-};
-
-static const struct hda_verb alc885_init_verbs[] = {
- /* Front mixer: unmute input/output amp left and right (volume = 0) */
- {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
- {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
- /* Rear mixer */
- {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
- {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
- /* CLFE mixer */
- {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
- {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
- /* Side mixer */
- {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
- {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
-
- /* Front HP Pin: output 0 (0x0c) */
- {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
- {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
- {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
- /* Front Pin: output 0 (0x0c) */
- {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
- {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
- {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
- /* Rear Pin: output 1 (0x0d) */
- {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
- {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
- {0x19, AC_VERB_SET_CONNECT_SEL, 0x01},
- /* CLFE Pin: output 2 (0x0e) */
- {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
- {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
- {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
- /* Side Pin: output 3 (0x0f) */
- {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
- {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
- {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
- /* Mic (rear) pin: input vref at 80% */
- {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
- {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
- /* Front Mic pin: input vref at 80% */
- {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
- {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
- /* Line In pin: input */
- {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
- {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
-
- /* Mixer elements: 0x18, , 0x1a, 0x1b */
- /* Input mixer1 */
- {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
- /* Input mixer2 */
- {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
- /* Input mixer3 */
- {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
- /* ADC2: mute amp left and right */
- {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
- /* ADC3: mute amp left and right */
- {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-
- { }
-};
-
-static const struct hda_verb alc885_init_input_verbs[] = {
- {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
- {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
- {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
- { }
-};
-
-
-/* Unmute Selector 24h and set the default input to front mic */
-static const struct hda_verb alc889_init_input_verbs[] = {
- {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
- {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
- { }
-};
-
-
#define alc883_init_verbs alc882_base_init_verbs
-/* Mac Pro test */
-static const struct snd_kcontrol_new alc882_macpro_mixer[] = {
- HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
- HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
- HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
- HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
- /* FIXME: this looks suspicious...
- HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x02, HDA_INPUT),
- HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x02, HDA_INPUT),
- */
- { } /* end */
-};
-
-static const struct hda_verb alc882_macpro_init_verbs[] = {
- /* Front mixer: unmute input/output amp left and right (volume = 0) */
- {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
- {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
- {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
- /* Front Pin: output 0 (0x0c) */
- {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
- {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
- {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
- /* Front Mic pin: input vref at 80% */
- {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
- {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
- /* Speaker: output */
- {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
- {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
- {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
- /* Headphone output (output 0 - 0x0c) */
- {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
- {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
- {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
-
- /* FIXME: use matrix-type input source selection */
- /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
- /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
- {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
- {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
- {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
- {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
- /* Input mixer2 */
- {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
- {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
- {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
- {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
- /* Input mixer3 */
- {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
- {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
- {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
- {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
- /* ADC1: mute amp left and right */
- {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
- {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
- /* ADC2: mute amp left and right */
- {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
- {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
- /* ADC3: mute amp left and right */
- {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
- {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
-
- { }
-};
-
/* Macbook 5,1 */
static const struct hda_verb alc885_mb5_init_verbs[] = {
/* DACs */
@@ -1669,34 +547,6 @@
{ }
};
-/* iMac 24 mixer. */
-static const struct snd_kcontrol_new alc885_imac24_mixer[] = {
- HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
- HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
- { } /* end */
-};
-
-/* iMac 24 init verbs. */
-static const struct hda_verb alc885_imac24_init_verbs[] = {
- /* Internal speakers: output 0 (0x0c) */
- {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
- {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
- {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
- /* Internal speakers: output 0 (0x0c) */
- {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
- {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
- {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
- /* Headphone: output 0 (0x0c) */
- {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
- {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
- {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
- {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
- /* Front Mic: input vref at 80% */
- {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
- {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
- { }
-};
-
/* Toggle speaker-output according to the hp-jack state */
static void alc885_imac24_setup(struct hda_codec *codec)
{
@@ -1742,127 +592,6 @@
alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP);
}
-static const struct hda_verb alc882_targa_verbs[] = {
- {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
- {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
-
- {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
- {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-
- {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
- {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
- {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
-
- {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
- { } /* end */
-};
-
-/* toggle speaker-output according to the hp-jack state */
-static void alc882_targa_automute(struct hda_codec *codec)
-{
- struct alc_spec *spec = codec->spec;
- alc_hp_automute(codec);
- snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
- spec->hp_jack_present ? 1 : 3);
-}
-
-static void alc882_targa_setup(struct hda_codec *codec)
-{
- struct alc_spec *spec = codec->spec;
-
- spec->autocfg.hp_pins[0] = 0x14;
- spec->autocfg.speaker_pins[0] = 0x1b;
- alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP);
-}
-
-static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
-{
- if ((res >> 26) == ALC_HP_EVENT)
- alc882_targa_automute(codec);
-}
-
-static const struct hda_verb alc882_asus_a7j_verbs[] = {
- {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
- {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
-
- {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
- {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
- {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-
- {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
- {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
- {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
-
- {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
- {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
- {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
- { } /* end */
-};
-
-static const struct hda_verb alc882_asus_a7m_verbs[] = {
- {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
- {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
-
- {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
- {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
- {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-
- {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
- {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
- {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
-
- {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
- {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
- {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
- { } /* end */
-};
-
-static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
-{
- unsigned int gpiostate, gpiomask, gpiodir;
-
- gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
- AC_VERB_GET_GPIO_DATA, 0);
-
- if (!muted)
- gpiostate |= (1 << pin);
- else
- gpiostate &= ~(1 << pin);
-
- gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
- AC_VERB_GET_GPIO_MASK, 0);
- gpiomask |= (1 << pin);
-
- gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
- AC_VERB_GET_GPIO_DIRECTION, 0);
- gpiodir |= (1 << pin);
-
-
- snd_hda_codec_write(codec, codec->afg, 0,
- AC_VERB_SET_GPIO_MASK, gpiomask);
- snd_hda_codec_write(codec, codec->afg, 0,
- AC_VERB_SET_GPIO_DIRECTION, gpiodir);
-
- msleep(1);
-
- snd_hda_codec_write(codec, codec->afg, 0,
- AC_VERB_SET_GPIO_DATA, gpiostate);
-}
-
-/* set up GPIO at initialization */
-static void alc885_macpro_init_hook(struct hda_codec *codec)
-{
- alc882_gpio_mute(codec, 0, 0);
- alc882_gpio_mute(codec, 1, 0);
-}
-
-/* set up GPIO and update auto-muting at initialization */
-static void alc885_imac24_init_hook(struct hda_codec *codec)
-{
- alc885_macpro_init_hook(codec);
- alc_hp_automute(codec);
-}
-
/* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */
static const struct hda_verb alc889A_mb31_ch2_init[] = {
{0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
@@ -1906,77 +635,6 @@
{ 6, alc889A_mb31_ch6_init },
};
-static const struct hda_verb alc883_medion_eapd_verbs[] = {
- /* eanable EAPD on medion laptop */
- {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
- {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
- { }
-};
-
-#define alc883_base_mixer alc882_base_mixer
-
-static const struct snd_kcontrol_new alc883_mitac_mixer[] = {
- HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
- HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
- HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
- HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
- HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
- HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
- HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
- HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
- HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
- HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
- HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
- { } /* end */
-};
-
-static const struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
- HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
- HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
- HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
- HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
- HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
- HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
- HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
- HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
- HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
- HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
- { } /* end */
-};
-
-static const struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
- HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
- HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
- HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
- HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
- HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
- HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
- HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
- HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
- HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
- HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
- { } /* end */
-};
-
-static const struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
- HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
- HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
- HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
- HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
- HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
- HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
- HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
- HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
- HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
- HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
- HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
- HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
- { } /* end */
-};
-
static const struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
@@ -2000,235 +658,6 @@
{ } /* end */
};
-static const struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
- HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
- HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
- HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
- HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
- HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
- HDA_OUTPUT),
- HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
- HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
- HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
- HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
- HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
- HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
- HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
- HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
- HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
- HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
- HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
- HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x18, 0, HDA_INPUT),
- HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
- { } /* end */
-};
-
-static const struct snd_kcontrol_new alc885_8ch_intel_mixer[] = {
- HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
- HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
- HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
- HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
- HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
- HDA_OUTPUT),
- HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
- HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
- HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
- HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
- HDA_BIND_MUTE("Speaker Playback Switch", 0x0f, 2, HDA_INPUT),
- HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
- HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
- HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
- HDA_CODEC_VOLUME("Mic Boost Volume", 0x1b, 0, HDA_INPUT),
- HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
- HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
- HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x18, 0, HDA_INPUT),
- HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
- { } /* end */
-};
-
-static const struct snd_kcontrol_new alc883_fivestack_mixer[] = {
- HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
- HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
- HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
- HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
- HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
- HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
- HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
- HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
- HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
- HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
- HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
- HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
- HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
- HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
- HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
- HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
- HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
- { } /* end */
-};
-
-static const struct snd_kcontrol_new alc883_targa_mixer[] = {
- HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
- HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
- HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
- HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
- HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
- HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
- HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
- HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
- HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
- HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
- HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
- HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
- HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
- HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
- { } /* end */
-};
-
-static const struct snd_kcontrol_new alc883_targa_2ch_mixer[] = {
- HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
- HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
- HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
- HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
- HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
- HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
- HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
- HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
- HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
- HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
- { } /* end */
-};
-
-static const struct snd_kcontrol_new alc883_targa_8ch_mixer[] = {
- HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
- HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
- HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
- HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
- HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
- { } /* end */
-};
-
-static const struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
- HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
- HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
- HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
- HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
- HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
- HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
- HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
- { } /* end */
-};
-
-static const struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
- HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
- HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
- HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
- HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
- HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
- HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
- HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
- HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
- { } /* end */
-};
-
-static const struct snd_kcontrol_new alc883_medion_wim2160_mixer[] = {
- HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
- HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
- HDA_CODEC_MUTE("Speaker Playback Switch", 0x15, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("Line Playback Volume", 0x08, 0x0, HDA_INPUT),
- HDA_CODEC_MUTE("Line Playback Switch", 0x08, 0x0, HDA_INPUT),
- { } /* end */
-};
-
-static const struct hda_verb alc883_medion_wim2160_verbs[] = {
- /* Unmute front mixer */
- {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
- {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
-
- /* Set speaker pin to front mixer */
- {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
-
- /* Init headphone pin */
- {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
- {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
- {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
- {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
-
- { } /* end */
-};
-
-/* toggle speaker-output according to the hp-jack state */
-static void alc883_medion_wim2160_setup(struct hda_codec *codec)
-{
- struct alc_spec *spec = codec->spec;
-
- spec->autocfg.hp_pins[0] = 0x1a;
- spec->autocfg.speaker_pins[0] = 0x15;
- alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP);
-}
-
-static const struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
- HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
- HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
- HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
- HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
- HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
- HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
- HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
- { } /* end */
-};
-
-static const struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = {
- HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("LFE Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
- HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
- HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
- HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
- HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
- HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
- HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
- { } /* end */
-};
-
-static const struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
- HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
- HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
- HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
- HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
- HDA_CODEC_VOLUME_MONO("Center Playback Volume",
- 0x0d, 1, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
- HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
- HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
- HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
- HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
- HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
- HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
- HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
- HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
- HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
- HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
- HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
- HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
- HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
- HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
- { } /* end */
-};
-
static const struct snd_kcontrol_new alc889A_mb31_mixer[] = {
/* Output mixers */
HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
@@ -2255,61 +684,6 @@
{ } /* end */
};
-static const struct snd_kcontrol_new alc883_vaiott_mixer[] = {
- HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
- HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
- HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
- HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
- HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
- { } /* end */
-};
-
-static const struct hda_bind_ctls alc883_bind_cap_vol = {
- .ops = &snd_hda_bind_vol,
- .values = {
- HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
- HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
- 0
- },
-};
-
-static const struct hda_bind_ctls alc883_bind_cap_switch = {
- .ops = &snd_hda_bind_sw,
- .values = {
- HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
- HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
- 0
- },
-};
-
-static const struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
- HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
- HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
- HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
- HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
- HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
- HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
- HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
- { } /* end */
-};
-
-static const struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = {
- HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
- HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- /* .name = "Capture Source", */
- .name = "Input Source",
- .count = 1,
- .info = alc_mux_enum_info,
- .get = alc_mux_enum_get,
- .put = alc_mux_enum_put,
- },
- { } /* end */
-};
-
static const struct snd_kcontrol_new alc883_chmode_mixer[] = {
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -2321,423 +695,6 @@
{ } /* end */
};
-/* toggle speaker-output according to the hp-jack state */
-static void alc883_mitac_setup(struct hda_codec *codec)
-{
- struct alc_spec *spec = codec->spec;
-
- spec->autocfg.hp_pins[0] = 0x15;
- spec->autocfg.speaker_pins[0] = 0x14;
- spec->autocfg.speaker_pins[1] = 0x17;
- alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP);
-}
-
-static const struct hda_verb alc883_mitac_verbs[] = {
- /* HP */
- {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
- {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
- /* Subwoofer */
- {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
- {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-
- /* enable unsolicited event */
- {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
- /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_MIC_EVENT | AC_USRSP_EN}, */
-
- { } /* end */
-};
-
-static const struct hda_verb alc883_clevo_m540r_verbs[] = {
- /* HP */
- {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
- {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
- /* Int speaker */
- /*{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},*/
-
- /* enable unsolicited event */
- /*
- {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
- {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_MIC_EVENT | AC_USRSP_EN},
- */
-
- { } /* end */
-};
-
-static const struct hda_verb alc883_clevo_m720_verbs[] = {
- /* HP */
- {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
- {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
- /* Int speaker */
- {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
- {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-
- /* enable unsolicited event */
- {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
- {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_MIC_EVENT | AC_USRSP_EN},
-
- { } /* end */
-};
-
-static const struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
- /* HP */
- {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
- {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
- /* Subwoofer */
- {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
- {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-
- /* enable unsolicited event */
- {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
-
- { } /* end */
-};
-
-static const struct hda_verb alc883_targa_verbs[] = {
- {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
- {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
-
- {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
- {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-
-/* Connect Line-Out side jack (SPDIF) to Side */
- {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
- {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
- {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
-/* Connect Mic jack to CLFE */
- {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
- {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
- {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
-/* Connect Line-in jack to Surround */
- {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
- {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
- {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
-/* Connect HP out jack to Front */
- {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
- {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
- {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
-
- {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
-
- { } /* end */
-};
-
-static const struct hda_verb alc883_lenovo_101e_verbs[] = {
- {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
- {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_FRONT_EVENT|AC_USRSP_EN},
- {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT|AC_USRSP_EN},
- { } /* end */
-};
-
-static const struct hda_verb alc883_lenovo_nb0763_verbs[] = {
- {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
- {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
- {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
- {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
- { } /* end */
-};
-
-static const struct hda_verb alc888_lenovo_ms7195_verbs[] = {
- {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
- {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
- {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
- {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_FRONT_EVENT | AC_USRSP_EN},
- {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
- { } /* end */
-};
-
-static const struct hda_verb alc883_haier_w66_verbs[] = {
- {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
- {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
-
- {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-
- {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
- {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
- {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
- {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
- { } /* end */
-};
-
-static const struct hda_verb alc888_lenovo_sky_verbs[] = {
- {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
- {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
- {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
- {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
- {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
- {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
- {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
- {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
- { } /* end */
-};
-
-static const struct hda_verb alc888_6st_dell_verbs[] = {
- {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
- { }
-};
-
-static const struct hda_verb alc883_vaiott_verbs[] = {
- /* HP */
- {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
- {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
-
- /* enable unsolicited event */
- {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
-
- { } /* end */
-};
-
-static void alc888_3st_hp_setup(struct hda_codec *codec)
-{
- struct alc_spec *spec = codec->spec;
-
- spec->autocfg.hp_pins[0] = 0x1b;
- spec->autocfg.speaker_pins[0] = 0x14;
- spec->autocfg.speaker_pins[1] = 0x16;
- spec->autocfg.speaker_pins[2] = 0x18;
- alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP);
-}
-
-static const struct hda_verb alc888_3st_hp_verbs[] = {
- {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
- {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
- {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
- {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
- { } /* end */
-};
-
-/*
- * 2ch mode
- */
-static const struct hda_verb alc888_3st_hp_2ch_init[] = {
- { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
- { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
- { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
- { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
- { } /* end */
-};
-
-/*
- * 4ch mode
- */
-static const struct hda_verb alc888_3st_hp_4ch_init[] = {
- { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
- { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
- { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
- { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
- { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
- { } /* end */
-};
-
-/*
- * 6ch mode
- */
-static const struct hda_verb alc888_3st_hp_6ch_init[] = {
- { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
- { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
- { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
- { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
- { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
- { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
- { } /* end */
-};
-
-static const struct hda_channel_mode alc888_3st_hp_modes[3] = {
- { 2, alc888_3st_hp_2ch_init },
- { 4, alc888_3st_hp_4ch_init },
- { 6, alc888_3st_hp_6ch_init },
-};
-
-static void alc888_lenovo_ms7195_setup(struct hda_codec *codec)
-{
- struct alc_spec *spec = codec->spec;
-
- spec->autocfg.hp_pins[0] = 0x1b;
- spec->autocfg.line_out_pins[0] = 0x14;
- spec->autocfg.speaker_pins[0] = 0x15;
- alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP);
-}
-
-/* toggle speaker-output according to the hp-jack state */
-static void alc883_lenovo_nb0763_setup(struct hda_codec *codec)
-{
- struct alc_spec *spec = codec->spec;
-
- spec->autocfg.hp_pins[0] = 0x14;
- spec->autocfg.speaker_pins[0] = 0x15;
- alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP);
-}
-
-/* toggle speaker-output according to the hp-jack state */
-#define alc883_targa_init_hook alc882_targa_init_hook
-#define alc883_targa_unsol_event alc882_targa_unsol_event
-
-static void alc883_clevo_m720_setup(struct hda_codec *codec)
-{
- struct alc_spec *spec = codec->spec;
-
- spec->autocfg.hp_pins[0] = 0x15;
- spec->autocfg.speaker_pins[0] = 0x14;
- alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP);
-}
-
-static void alc883_clevo_m720_init_hook(struct hda_codec *codec)
-{
- alc_hp_automute(codec);
- alc88x_simple_mic_automute(codec);
-}
-
-static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
- unsigned int res)
-{
- switch (res >> 26) {
- case ALC_MIC_EVENT:
- alc88x_simple_mic_automute(codec);
- break;
- default:
- alc_sku_unsol_event(codec, res);
- break;
- }
-}
-
-/* toggle speaker-output according to the hp-jack state */
-static void alc883_2ch_fujitsu_pi2515_setup(struct hda_codec *codec)
-{
- struct alc_spec *spec = codec->spec;
-
- spec->autocfg.hp_pins[0] = 0x14;
- spec->autocfg.speaker_pins[0] = 0x15;
- alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP);
-}
-
-static void alc883_haier_w66_setup(struct hda_codec *codec)
-{
- struct alc_spec *spec = codec->spec;
-
- spec->autocfg.hp_pins[0] = 0x1b;
- spec->autocfg.speaker_pins[0] = 0x14;
- alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP);
-}
-
-static void alc883_lenovo_101e_setup(struct hda_codec *codec)
-{
- struct alc_spec *spec = codec->spec;
-
- spec->autocfg.hp_pins[0] = 0x1b;
- spec->autocfg.line_out_pins[0] = 0x14;
- spec->autocfg.speaker_pins[0] = 0x15;
- alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP);
-}
-
-/* toggle speaker-output according to the hp-jack state */
-static void alc883_acer_aspire_setup(struct hda_codec *codec)
-{
- struct alc_spec *spec = codec->spec;
-
- spec->autocfg.hp_pins[0] = 0x14;
- spec->autocfg.speaker_pins[0] = 0x15;
- spec->autocfg.speaker_pins[1] = 0x16;
- alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP);
-}
-
-static const struct hda_verb alc883_acer_eapd_verbs[] = {
- /* HP Pin: output 0 (0x0c) */
- {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
- {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
- {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
- /* Front Pin: output 0 (0x0c) */
- {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
- {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
- {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
- {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
- /* eanable EAPD on medion laptop */
- {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
- {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
- /* enable unsolicited event */
- {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
- { }
-};
-
-static void alc888_6st_dell_setup(struct hda_codec *codec)
-{
- struct alc_spec *spec = codec->spec;
-
- spec->autocfg.hp_pins[0] = 0x1b;
- spec->autocfg.speaker_pins[0] = 0x14;
- spec->autocfg.speaker_pins[1] = 0x15;
- spec->autocfg.speaker_pins[2] = 0x16;
- spec->autocfg.speaker_pins[3] = 0x17;
- alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP);
-}
-
-static void alc888_lenovo_sky_setup(struct hda_codec *codec)
-{
- struct alc_spec *spec = codec->spec;
-
- spec->autocfg.hp_pins[0] = 0x1b;
- spec->autocfg.speaker_pins[0] = 0x14;
- spec->autocfg.speaker_pins[1] = 0x15;
- spec->autocfg.speaker_pins[2] = 0x16;
- spec->autocfg.speaker_pins[3] = 0x17;
- spec->autocfg.speaker_pins[4] = 0x1a;
- alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP);
-}
-
-static void alc883_vaiott_setup(struct hda_codec *codec)
-{
- struct alc_spec *spec = codec->spec;
-
- spec->autocfg.hp_pins[0] = 0x15;
- spec->autocfg.speaker_pins[0] = 0x14;
- spec->autocfg.speaker_pins[1] = 0x17;
- alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP);
-}
-
-static const struct hda_verb alc888_asus_m90v_verbs[] = {
- {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
- {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
- {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
- /* enable unsolicited event */
- {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
- {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_MIC_EVENT | AC_USRSP_EN},
- { } /* end */
-};
-
-static void alc883_mode2_setup(struct hda_codec *codec)
-{
- struct alc_spec *spec = codec->spec;
-
- spec->autocfg.hp_pins[0] = 0x1b;
- spec->autocfg.speaker_pins[0] = 0x14;
- spec->autocfg.speaker_pins[1] = 0x15;
- spec->autocfg.speaker_pins[2] = 0x16;
- spec->ext_mic_pin = 0x18;
- spec->int_mic_pin = 0x19;
- spec->auto_mic = 1;
- alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP);
-}
-
-static const struct hda_verb alc888_asus_eee1601_verbs[] = {
- {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
- {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
- {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
- {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
- {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
- {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
- {0x20, AC_VERB_SET_PROC_COEF, 0x0838},
- /* enable unsolicited event */
- {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
- { } /* end */
-};
-
-static void alc883_eee1601_inithook(struct hda_codec *codec)
-{
- struct alc_spec *spec = codec->spec;
-
- spec->autocfg.hp_pins[0] = 0x14;
- spec->autocfg.speaker_pins[0] = 0x1b;
- alc_hp_automute(codec);
-}
-
static const struct hda_verb alc889A_mb31_verbs[] = {
/* Init rear pin (used as headphone output) */
{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, /* Apple Headphones */
@@ -2773,211 +730,30 @@
alc889A_mb31_automute(codec);
}
-static const hda_nid_t alc883_slave_dig_outs[] = {
- ALC1200_DIGOUT_NID, 0,
-};
-
-static const hda_nid_t alc1200_slave_dig_outs[] = {
- ALC883_DIGOUT_NID, 0,
-};
-
/*
* configuration and preset
*/
static const char * const alc882_models[ALC882_MODEL_LAST] = {
- [ALC882_3ST_DIG] = "3stack-dig",
- [ALC882_6ST_DIG] = "6stack-dig",
- [ALC882_ARIMA] = "arima",
- [ALC882_W2JC] = "w2jc",
- [ALC882_TARGA] = "targa",
- [ALC882_ASUS_A7J] = "asus-a7j",
- [ALC882_ASUS_A7M] = "asus-a7m",
- [ALC885_MACPRO] = "macpro",
[ALC885_MB5] = "mb5",
[ALC885_MACMINI3] = "macmini3",
[ALC885_MBA21] = "mba21",
[ALC885_MBP3] = "mbp3",
- [ALC885_IMAC24] = "imac24",
[ALC885_IMAC91] = "imac91",
- [ALC883_3ST_2ch_DIG] = "3stack-2ch-dig",
- [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
- [ALC883_3ST_6ch] = "3stack-6ch",
- [ALC883_6ST_DIG] = "alc883-6stack-dig",
- [ALC883_TARGA_DIG] = "targa-dig",
- [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
- [ALC883_TARGA_8ch_DIG] = "targa-8ch-dig",
- [ALC883_ACER] = "acer",
- [ALC883_ACER_ASPIRE] = "acer-aspire",
- [ALC888_ACER_ASPIRE_4930G] = "acer-aspire-4930g",
- [ALC888_ACER_ASPIRE_6530G] = "acer-aspire-6530g",
- [ALC888_ACER_ASPIRE_8930G] = "acer-aspire-8930g",
- [ALC888_ACER_ASPIRE_7730G] = "acer-aspire-7730g",
- [ALC883_MEDION] = "medion",
- [ALC883_MEDION_WIM2160] = "medion-wim2160",
- [ALC883_LAPTOP_EAPD] = "laptop-eapd",
- [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
- [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
- [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
- [ALC888_LENOVO_SKY] = "lenovo-sky",
- [ALC883_HAIER_W66] = "haier-w66",
- [ALC888_3ST_HP] = "3stack-hp",
- [ALC888_6ST_DELL] = "6stack-dell",
- [ALC883_MITAC] = "mitac",
- [ALC883_CLEVO_M540R] = "clevo-m540r",
- [ALC883_CLEVO_M720] = "clevo-m720",
- [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
- [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530",
- [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel",
- [ALC889A_INTEL] = "intel-alc889a",
- [ALC889_INTEL] = "intel-x58",
- [ALC1200_ASUS_P5Q] = "asus-p5q",
[ALC889A_MB31] = "mb31",
- [ALC883_SONY_VAIO_TT] = "sony-vaio-tt",
[ALC882_AUTO] = "auto",
};
-static const struct snd_pci_quirk alc882_cfg_tbl[] = {
- SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
-
- SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
- SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE),
- SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_ACER_ASPIRE),
- SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
- SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
- SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
- SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
- ALC888_ACER_ASPIRE_4930G),
- SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
- ALC888_ACER_ASPIRE_4930G),
- SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G",
- ALC888_ACER_ASPIRE_8930G),
- SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G",
- ALC888_ACER_ASPIRE_8930G),
- SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC882_AUTO),
- SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC882_AUTO),
- SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
- ALC888_ACER_ASPIRE_6530G),
- SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
- ALC888_ACER_ASPIRE_6530G),
- SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G",
- ALC888_ACER_ASPIRE_7730G),
- /* default Acer -- disabled as it causes more problems.
- * model=auto should work fine now
- */
- /* SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER), */
-
- SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
-
- SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavilion", ALC883_6ST_DIG),
- SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
- SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
- SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
- SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP),
- SND_PCI_QUIRK(0x103c, 0x2a72, "HP Educ.ar", ALC888_3ST_HP),
-
- SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
- SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
- SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
- SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
- SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
- SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
- SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
- SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
- SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG),
- SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q),
- SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
-
- SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC883_SONY_VAIO_TT),
- SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
- SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
- SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC),
- SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
- SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
- SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
- SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
- SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
-
- SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
- SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
- SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
- SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
- SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC882_AUTO),
- SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
- SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
- SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
- SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
- SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
- SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
- SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
- SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
- SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
- SND_PCI_QUIRK(0x1462, 0x42cd, "MSI", ALC883_TARGA_DIG),
- SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
- SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
- SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
- SND_PCI_QUIRK(0x1462, 0x4570, "MSI Wind Top AE2220", ALC883_TARGA_DIG),
- SND_PCI_QUIRK(0x1462, 0x6510, "MSI GX620", ALC883_TARGA_8ch_DIG),
- SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
- SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
- SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
- SND_PCI_QUIRK(0x1462, 0x7260, "MSI 7260", ALC883_TARGA_DIG),
- SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
- SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
- SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
- SND_PCI_QUIRK(0x1462, 0x7350, "MSI", ALC883_6ST_DIG),
- SND_PCI_QUIRK(0x1462, 0x7437, "MSI NetOn AP1900", ALC883_TARGA_DIG),
- SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
- SND_PCI_QUIRK(0x1462, 0xaa08, "MSI", ALC883_TARGA_2ch_DIG),
-
- SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
- SND_PCI_QUIRK(0x1558, 0x0571, "Clevo laptop M570U", ALC883_3ST_6ch_DIG),
- SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
- SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
- SND_PCI_QUIRK(0x1558, 0x5409, "Clevo laptop M540R", ALC883_CLEVO_M540R),
- SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD),
- SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
- /* SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA), */
- SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
- SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1100, "FSC AMILO Xi/Pi25xx",
- ALC883_FUJITSU_PI2515),
- SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1130, "Fujitsu AMILO Xa35xx",
- ALC888_FUJITSU_XA3530),
- SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
- SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
- SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
- SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
- SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
- SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG),
- SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
- SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
-
- SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
- SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
- SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC),
- SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_INTEL),
- SND_PCI_QUIRK(0x8086, 0x0021, "Intel IbexPeak", ALC889A_INTEL),
- SND_PCI_QUIRK(0x8086, 0x3b56, "Intel IbexPeak", ALC889A_INTEL),
- SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC882_6ST_DIG),
-
- {}
-};
-
/* codec SSID table for Intel Mac */
static const struct snd_pci_quirk alc882_ssid_cfg_tbl[] = {
SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC885_MBP3),
SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC885_MBP3),
SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC885_MBP3),
- SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC885_MACPRO),
- SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_IMAC24),
- SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_IMAC24),
SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC885_MBP3),
SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889A_MB31),
- SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_ASUS_A7M),
SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC885_MBP3),
SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC885_MBA21),
SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889A_MB31),
SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC885_MBP3),
- SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_IMAC24),
SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC885_IMAC91),
SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC885_MB5),
SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC885_MB5),
@@ -2991,53 +767,6 @@
};
static const struct alc_config_preset alc882_presets[] = {
- [ALC882_3ST_DIG] = {
- .mixers = { alc882_base_mixer },
- .init_verbs = { alc882_base_init_verbs,
- alc882_adc1_init_verbs },
- .num_dacs = ARRAY_SIZE(alc882_dac_nids),
- .dac_nids = alc882_dac_nids,
- .dig_out_nid = ALC882_DIGOUT_NID,
- .dig_in_nid = ALC882_DIGIN_NID,
- .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
- .channel_mode = alc882_ch_modes,
- .need_dac_fix = 1,
- .input_mux = &alc882_capture_source,
- },
- [ALC882_6ST_DIG] = {
- .mixers = { alc882_base_mixer, alc882_chmode_mixer },
- .init_verbs = { alc882_base_init_verbs,
- alc882_adc1_init_verbs },
- .num_dacs = ARRAY_SIZE(alc882_dac_nids),
- .dac_nids = alc882_dac_nids,
- .dig_out_nid = ALC882_DIGOUT_NID,
- .dig_in_nid = ALC882_DIGIN_NID,
- .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
- .channel_mode = alc882_sixstack_modes,
- .input_mux = &alc882_capture_source,
- },
- [ALC882_ARIMA] = {
- .mixers = { alc882_base_mixer, alc882_chmode_mixer },
- .init_verbs = { alc882_base_init_verbs, alc882_adc1_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,
- },
- [ALC882_W2JC] = {
- .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
- .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
- alc882_eapd_verbs, alc880_gpio1_init_verbs },
- .num_dacs = ARRAY_SIZE(alc882_dac_nids),
- .dac_nids = alc882_dac_nids,
- .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
- .channel_mode = alc880_threestack_modes,
- .need_dac_fix = 1,
- .input_mux = &alc882_capture_source,
- .dig_out_nid = ALC882_DIGOUT_NID,
- },
[ALC885_MBA21] = {
.mixers = { alc885_mba21_mixer },
.init_verbs = { alc885_mba21_init_verbs, alc880_gpio1_init_verbs },
@@ -3096,32 +825,6 @@
.setup = alc885_macmini3_setup,
.init_hook = alc_hp_automute,
},
- [ALC885_MACPRO] = {
- .mixers = { alc882_macpro_mixer },
- .init_verbs = { alc882_macpro_init_verbs },
- .num_dacs = ARRAY_SIZE(alc882_dac_nids),
- .dac_nids = alc882_dac_nids,
- .dig_out_nid = ALC882_DIGOUT_NID,
- .dig_in_nid = ALC882_DIGIN_NID,
- .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
- .channel_mode = alc882_ch_modes,
- .input_mux = &alc882_capture_source,
- .init_hook = alc885_macpro_init_hook,
- },
- [ALC885_IMAC24] = {
- .mixers = { alc885_imac24_mixer },
- .init_verbs = { alc885_imac24_init_verbs },
- .num_dacs = ARRAY_SIZE(alc882_dac_nids),
- .dac_nids = alc882_dac_nids,
- .dig_out_nid = ALC882_DIGOUT_NID,
- .dig_in_nid = ALC882_DIGIN_NID,
- .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
- .channel_mode = alc882_ch_modes,
- .input_mux = &alc882_capture_source,
- .unsol_event = alc_sku_unsol_event,
- .setup = alc885_imac24_setup,
- .init_hook = alc885_imac24_init_hook,
- },
[ALC885_IMAC91] = {
.mixers = {alc885_imac91_mixer},
.init_verbs = { alc885_imac91_init_verbs,
@@ -3137,564 +840,6 @@
.setup = alc885_imac91_setup,
.init_hook = alc_hp_automute,
},
- [ALC882_TARGA] = {
- .mixers = { alc882_targa_mixer, alc882_chmode_mixer },
- .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
- alc880_gpio3_init_verbs, alc882_targa_verbs},
- .num_dacs = ARRAY_SIZE(alc882_dac_nids),
- .dac_nids = alc882_dac_nids,
- .dig_out_nid = ALC882_DIGOUT_NID,
- .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
- .adc_nids = alc882_adc_nids,
- .capsrc_nids = alc882_capsrc_nids,
- .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
- .channel_mode = alc882_3ST_6ch_modes,
- .need_dac_fix = 1,
- .input_mux = &alc882_capture_source,
- .unsol_event = alc_sku_unsol_event,
- .setup = alc882_targa_setup,
- .init_hook = alc882_targa_automute,
- },
- [ALC882_ASUS_A7J] = {
- .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer },
- .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
- alc882_asus_a7j_verbs},
- .num_dacs = ARRAY_SIZE(alc882_dac_nids),
- .dac_nids = alc882_dac_nids,
- .dig_out_nid = ALC882_DIGOUT_NID,
- .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
- .adc_nids = alc882_adc_nids,
- .capsrc_nids = alc882_capsrc_nids,
- .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
- .channel_mode = alc882_3ST_6ch_modes,
- .need_dac_fix = 1,
- .input_mux = &alc882_capture_source,
- },
- [ALC882_ASUS_A7M] = {
- .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
- .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
- alc882_eapd_verbs, alc880_gpio1_init_verbs,
- alc882_asus_a7m_verbs },
- .num_dacs = ARRAY_SIZE(alc882_dac_nids),
- .dac_nids = alc882_dac_nids,
- .dig_out_nid = ALC882_DIGOUT_NID,
- .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
- .channel_mode = alc880_threestack_modes,
- .need_dac_fix = 1,
- .input_mux = &alc882_capture_source,
- },
- [ALC883_3ST_2ch_DIG] = {
- .mixers = { alc883_3ST_2ch_mixer },
- .init_verbs = { alc883_init_verbs },
- .num_dacs = ARRAY_SIZE(alc883_dac_nids),
- .dac_nids = alc883_dac_nids,
- .dig_out_nid = ALC883_DIGOUT_NID,
- .dig_in_nid = ALC883_DIGIN_NID,
- .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
- .channel_mode = alc883_3ST_2ch_modes,
- .input_mux = &alc883_capture_source,
- },
- [ALC883_3ST_6ch_DIG] = {
- .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
- .init_verbs = { alc883_init_verbs },
- .num_dacs = ARRAY_SIZE(alc883_dac_nids),
- .dac_nids = alc883_dac_nids,
- .dig_out_nid = ALC883_DIGOUT_NID,
- .dig_in_nid = ALC883_DIGIN_NID,
- .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
- .channel_mode = alc883_3ST_6ch_modes,
- .need_dac_fix = 1,
- .input_mux = &alc883_capture_source,
- },
- [ALC883_3ST_6ch] = {
- .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
- .init_verbs = { alc883_init_verbs },
- .num_dacs = ARRAY_SIZE(alc883_dac_nids),
- .dac_nids = alc883_dac_nids,
- .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
- .channel_mode = alc883_3ST_6ch_modes,
- .need_dac_fix = 1,
- .input_mux = &alc883_capture_source,
- },
- [ALC883_3ST_6ch_INTEL] = {
- .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer },
- .init_verbs = { alc883_init_verbs },
- .num_dacs = ARRAY_SIZE(alc883_dac_nids),
- .dac_nids = alc883_dac_nids,
- .dig_out_nid = ALC883_DIGOUT_NID,
- .dig_in_nid = ALC883_DIGIN_NID,
- .slave_dig_outs = alc883_slave_dig_outs,
- .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
- .channel_mode = alc883_3ST_6ch_intel_modes,
- .need_dac_fix = 1,
- .input_mux = &alc883_3stack_6ch_intel,
- },
- [ALC889A_INTEL] = {
- .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
- .init_verbs = { alc885_init_verbs, alc885_init_input_verbs,
- alc_hp15_unsol_verbs },
- .num_dacs = ARRAY_SIZE(alc883_dac_nids),
- .dac_nids = alc883_dac_nids,
- .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
- .adc_nids = alc889_adc_nids,
- .dig_out_nid = ALC883_DIGOUT_NID,
- .dig_in_nid = ALC883_DIGIN_NID,
- .slave_dig_outs = alc883_slave_dig_outs,
- .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
- .channel_mode = alc889_8ch_intel_modes,
- .capsrc_nids = alc889_capsrc_nids,
- .input_mux = &alc889_capture_source,
- .setup = alc889_automute_setup,
- .init_hook = alc_hp_automute,
- .unsol_event = alc_sku_unsol_event,
- .need_dac_fix = 1,
- },
- [ALC889_INTEL] = {
- .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
- .init_verbs = { alc885_init_verbs, alc889_init_input_verbs,
- alc889_eapd_verbs, alc_hp15_unsol_verbs},
- .num_dacs = ARRAY_SIZE(alc883_dac_nids),
- .dac_nids = alc883_dac_nids,
- .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
- .adc_nids = alc889_adc_nids,
- .dig_out_nid = ALC883_DIGOUT_NID,
- .dig_in_nid = ALC883_DIGIN_NID,
- .slave_dig_outs = alc883_slave_dig_outs,
- .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
- .channel_mode = alc889_8ch_intel_modes,
- .capsrc_nids = alc889_capsrc_nids,
- .input_mux = &alc889_capture_source,
- .setup = alc889_automute_setup,
- .init_hook = alc889_intel_init_hook,
- .unsol_event = alc_sku_unsol_event,
- .need_dac_fix = 1,
- },
- [ALC883_6ST_DIG] = {
- .mixers = { alc883_base_mixer, alc883_chmode_mixer },
- .init_verbs = { alc883_init_verbs },
- .num_dacs = ARRAY_SIZE(alc883_dac_nids),
- .dac_nids = alc883_dac_nids,
- .dig_out_nid = ALC883_DIGOUT_NID,
- .dig_in_nid = ALC883_DIGIN_NID,
- .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
- .channel_mode = alc883_sixstack_modes,
- .input_mux = &alc883_capture_source,
- },
- [ALC883_TARGA_DIG] = {
- .mixers = { alc883_targa_mixer, alc883_chmode_mixer },
- .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
- alc883_targa_verbs},
- .num_dacs = ARRAY_SIZE(alc883_dac_nids),
- .dac_nids = alc883_dac_nids,
- .dig_out_nid = ALC883_DIGOUT_NID,
- .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
- .channel_mode = alc883_3ST_6ch_modes,
- .need_dac_fix = 1,
- .input_mux = &alc883_capture_source,
- .unsol_event = alc883_targa_unsol_event,
- .setup = alc882_targa_setup,
- .init_hook = alc882_targa_automute,
- },
- [ALC883_TARGA_2ch_DIG] = {
- .mixers = { alc883_targa_2ch_mixer},
- .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
- alc883_targa_verbs},
- .num_dacs = ARRAY_SIZE(alc883_dac_nids),
- .dac_nids = alc883_dac_nids,
- .adc_nids = alc883_adc_nids_alt,
- .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
- .capsrc_nids = alc883_capsrc_nids,
- .dig_out_nid = ALC883_DIGOUT_NID,
- .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
- .channel_mode = alc883_3ST_2ch_modes,
- .input_mux = &alc883_capture_source,
- .unsol_event = alc883_targa_unsol_event,
- .setup = alc882_targa_setup,
- .init_hook = alc882_targa_automute,
- },
- [ALC883_TARGA_8ch_DIG] = {
- .mixers = { alc883_targa_mixer, alc883_targa_8ch_mixer,
- alc883_chmode_mixer },
- .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
- alc883_targa_verbs },
- .num_dacs = ARRAY_SIZE(alc883_dac_nids),
- .dac_nids = alc883_dac_nids,
- .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
- .adc_nids = alc883_adc_nids_rev,
- .capsrc_nids = alc883_capsrc_nids_rev,
- .dig_out_nid = ALC883_DIGOUT_NID,
- .dig_in_nid = ALC883_DIGIN_NID,
- .num_channel_mode = ARRAY_SIZE(alc883_4ST_8ch_modes),
- .channel_mode = alc883_4ST_8ch_modes,
- .need_dac_fix = 1,
- .input_mux = &alc883_capture_source,
- .unsol_event = alc883_targa_unsol_event,
- .setup = alc882_targa_setup,
- .init_hook = alc882_targa_automute,
- },
- [ALC883_ACER] = {
- .mixers = { alc883_base_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_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
- .channel_mode = alc883_3ST_2ch_modes,
- .input_mux = &alc883_capture_source,
- },
- [ALC883_ACER_ASPIRE] = {
- .mixers = { alc883_acer_aspire_mixer },
- .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
- .num_dacs = ARRAY_SIZE(alc883_dac_nids),
- .dac_nids = alc883_dac_nids,
- .dig_out_nid = ALC883_DIGOUT_NID,
- .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
- .channel_mode = alc883_3ST_2ch_modes,
- .input_mux = &alc883_capture_source,
- .unsol_event = alc_sku_unsol_event,
- .setup = alc883_acer_aspire_setup,
- .init_hook = alc_hp_automute,
- },
- [ALC888_ACER_ASPIRE_4930G] = {
- .mixers = { alc888_acer_aspire_4930g_mixer,
- alc883_chmode_mixer },
- .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
- alc888_acer_aspire_4930g_verbs },
- .num_dacs = ARRAY_SIZE(alc883_dac_nids),
- .dac_nids = alc883_dac_nids,
- .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
- .adc_nids = alc883_adc_nids_rev,
- .capsrc_nids = alc883_capsrc_nids_rev,
- .dig_out_nid = ALC883_DIGOUT_NID,
- .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
- .channel_mode = alc883_3ST_6ch_modes,
- .need_dac_fix = 1,
- .const_channel_count = 6,
- .num_mux_defs =
- ARRAY_SIZE(alc888_2_capture_sources),
- .input_mux = alc888_2_capture_sources,
- .unsol_event = alc_sku_unsol_event,
- .setup = alc888_acer_aspire_4930g_setup,
- .init_hook = alc_hp_automute,
- },
- [ALC888_ACER_ASPIRE_6530G] = {
- .mixers = { alc888_acer_aspire_6530_mixer },
- .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
- alc888_acer_aspire_6530g_verbs },
- .num_dacs = ARRAY_SIZE(alc883_dac_nids),
- .dac_nids = alc883_dac_nids,
- .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
- .adc_nids = alc883_adc_nids_rev,
- .capsrc_nids = alc883_capsrc_nids_rev,
- .dig_out_nid = ALC883_DIGOUT_NID,
- .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
- .channel_mode = alc883_3ST_2ch_modes,
- .num_mux_defs =
- ARRAY_SIZE(alc888_2_capture_sources),
- .input_mux = alc888_acer_aspire_6530_sources,
- .unsol_event = alc_sku_unsol_event,
- .setup = alc888_acer_aspire_6530g_setup,
- .init_hook = alc_hp_automute,
- },
- [ALC888_ACER_ASPIRE_8930G] = {
- .mixers = { alc889_acer_aspire_8930g_mixer,
- alc883_chmode_mixer },
- .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
- alc889_acer_aspire_8930g_verbs,
- alc889_eapd_verbs},
- .num_dacs = ARRAY_SIZE(alc883_dac_nids),
- .dac_nids = alc883_dac_nids,
- .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
- .adc_nids = alc889_adc_nids,
- .capsrc_nids = alc889_capsrc_nids,
- .dig_out_nid = ALC883_DIGOUT_NID,
- .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
- .channel_mode = alc883_3ST_6ch_modes,
- .need_dac_fix = 1,
- .const_channel_count = 6,
- .num_mux_defs =
- ARRAY_SIZE(alc889_capture_sources),
- .input_mux = alc889_capture_sources,
- .unsol_event = alc_sku_unsol_event,
- .setup = alc889_acer_aspire_8930g_setup,
- .init_hook = alc_hp_automute,
-#ifdef CONFIG_SND_HDA_POWER_SAVE
- .power_hook = alc_power_eapd,
-#endif
- },
- [ALC888_ACER_ASPIRE_7730G] = {
- .mixers = { alc883_3ST_6ch_mixer,
- alc883_chmode_mixer },
- .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
- alc888_acer_aspire_7730G_verbs },
- .num_dacs = ARRAY_SIZE(alc883_dac_nids),
- .dac_nids = alc883_dac_nids,
- .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
- .adc_nids = alc883_adc_nids_rev,
- .capsrc_nids = alc883_capsrc_nids_rev,
- .dig_out_nid = ALC883_DIGOUT_NID,
- .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
- .channel_mode = alc883_3ST_6ch_modes,
- .need_dac_fix = 1,
- .const_channel_count = 6,
- .input_mux = &alc883_capture_source,
- .unsol_event = alc_sku_unsol_event,
- .setup = alc888_acer_aspire_7730g_setup,
- .init_hook = alc_hp_automute,
- },
- [ALC883_MEDION] = {
- .mixers = { alc883_fivestack_mixer,
- alc883_chmode_mixer },
- .init_verbs = { alc883_init_verbs,
- alc883_medion_eapd_verbs },
- .num_dacs = ARRAY_SIZE(alc883_dac_nids),
- .dac_nids = alc883_dac_nids,
- .adc_nids = alc883_adc_nids_alt,
- .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
- .capsrc_nids = alc883_capsrc_nids,
- .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
- .channel_mode = alc883_sixstack_modes,
- .input_mux = &alc883_capture_source,
- },
- [ALC883_MEDION_WIM2160] = {
- .mixers = { alc883_medion_wim2160_mixer },
- .init_verbs = { alc883_init_verbs, alc883_medion_wim2160_verbs },
- .num_dacs = ARRAY_SIZE(alc883_dac_nids),
- .dac_nids = alc883_dac_nids,
- .dig_out_nid = ALC883_DIGOUT_NID,
- .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,
- .unsol_event = alc_sku_unsol_event,
- .setup = alc883_medion_wim2160_setup,
- .init_hook = alc_hp_automute,
- },
- [ALC883_LAPTOP_EAPD] = {
- .mixers = { alc883_base_mixer },
- .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
- .num_dacs = ARRAY_SIZE(alc883_dac_nids),
- .dac_nids = alc883_dac_nids,
- .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
- .channel_mode = alc883_3ST_2ch_modes,
- .input_mux = &alc883_capture_source,
- },
- [ALC883_CLEVO_M540R] = {
- .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
- .init_verbs = { alc883_init_verbs, alc883_clevo_m540r_verbs },
- .num_dacs = ARRAY_SIZE(alc883_dac_nids),
- .dac_nids = alc883_dac_nids,
- .dig_out_nid = ALC883_DIGOUT_NID,
- .dig_in_nid = ALC883_DIGIN_NID,
- .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_clevo_modes),
- .channel_mode = alc883_3ST_6ch_clevo_modes,
- .need_dac_fix = 1,
- .input_mux = &alc883_capture_source,
- /* This machine has the hardware HP auto-muting, thus
- * we need no software mute via unsol event
- */
- },
- [ALC883_CLEVO_M720] = {
- .mixers = { alc883_clevo_m720_mixer },
- .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
- .num_dacs = ARRAY_SIZE(alc883_dac_nids),
- .dac_nids = alc883_dac_nids,
- .dig_out_nid = ALC883_DIGOUT_NID,
- .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
- .channel_mode = alc883_3ST_2ch_modes,
- .input_mux = &alc883_capture_source,
- .unsol_event = alc883_clevo_m720_unsol_event,
- .setup = alc883_clevo_m720_setup,
- .init_hook = alc883_clevo_m720_init_hook,
- },
- [ALC883_LENOVO_101E_2ch] = {
- .mixers = { alc883_lenovo_101e_2ch_mixer},
- .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
- .num_dacs = ARRAY_SIZE(alc883_dac_nids),
- .dac_nids = alc883_dac_nids,
- .adc_nids = alc883_adc_nids_alt,
- .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
- .capsrc_nids = alc883_capsrc_nids,
- .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
- .channel_mode = alc883_3ST_2ch_modes,
- .input_mux = &alc883_lenovo_101e_capture_source,
- .setup = alc883_lenovo_101e_setup,
- .unsol_event = alc_sku_unsol_event,
- .init_hook = alc_inithook,
- },
- [ALC883_LENOVO_NB0763] = {
- .mixers = { alc883_lenovo_nb0763_mixer },
- .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
- .num_dacs = ARRAY_SIZE(alc883_dac_nids),
- .dac_nids = alc883_dac_nids,
- .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
- .channel_mode = alc883_3ST_2ch_modes,
- .need_dac_fix = 1,
- .input_mux = &alc883_lenovo_nb0763_capture_source,
- .unsol_event = alc_sku_unsol_event,
- .setup = alc883_lenovo_nb0763_setup,
- .init_hook = alc_hp_automute,
- },
- [ALC888_LENOVO_MS7195_DIG] = {
- .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
- .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
- .num_dacs = ARRAY_SIZE(alc883_dac_nids),
- .dac_nids = alc883_dac_nids,
- .dig_out_nid = ALC883_DIGOUT_NID,
- .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
- .channel_mode = alc883_3ST_6ch_modes,
- .need_dac_fix = 1,
- .input_mux = &alc883_capture_source,
- .unsol_event = alc_sku_unsol_event,
- .setup = alc888_lenovo_ms7195_setup,
- .init_hook = alc_inithook,
- },
- [ALC883_HAIER_W66] = {
- .mixers = { alc883_targa_2ch_mixer},
- .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
- .num_dacs = ARRAY_SIZE(alc883_dac_nids),
- .dac_nids = alc883_dac_nids,
- .dig_out_nid = ALC883_DIGOUT_NID,
- .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
- .channel_mode = alc883_3ST_2ch_modes,
- .input_mux = &alc883_capture_source,
- .unsol_event = alc_sku_unsol_event,
- .setup = alc883_haier_w66_setup,
- .init_hook = alc_hp_automute,
- },
- [ALC888_3ST_HP] = {
- .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
- .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
- .num_dacs = ARRAY_SIZE(alc883_dac_nids),
- .dac_nids = alc883_dac_nids,
- .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
- .channel_mode = alc888_3st_hp_modes,
- .need_dac_fix = 1,
- .input_mux = &alc883_capture_source,
- .unsol_event = alc_sku_unsol_event,
- .setup = alc888_3st_hp_setup,
- .init_hook = alc_hp_automute,
- },
- [ALC888_6ST_DELL] = {
- .mixers = { alc883_base_mixer, alc883_chmode_mixer },
- .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
- .num_dacs = ARRAY_SIZE(alc883_dac_nids),
- .dac_nids = alc883_dac_nids,
- .dig_out_nid = ALC883_DIGOUT_NID,
- .dig_in_nid = ALC883_DIGIN_NID,
- .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
- .channel_mode = alc883_sixstack_modes,
- .input_mux = &alc883_capture_source,
- .unsol_event = alc_sku_unsol_event,
- .setup = alc888_6st_dell_setup,
- .init_hook = alc_hp_automute,
- },
- [ALC883_MITAC] = {
- .mixers = { alc883_mitac_mixer },
- .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
- .num_dacs = ARRAY_SIZE(alc883_dac_nids),
- .dac_nids = alc883_dac_nids,
- .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
- .channel_mode = alc883_3ST_2ch_modes,
- .input_mux = &alc883_capture_source,
- .unsol_event = alc_sku_unsol_event,
- .setup = alc883_mitac_setup,
- .init_hook = alc_hp_automute,
- },
- [ALC883_FUJITSU_PI2515] = {
- .mixers = { alc883_2ch_fujitsu_pi2515_mixer },
- .init_verbs = { alc883_init_verbs,
- alc883_2ch_fujitsu_pi2515_verbs},
- .num_dacs = ARRAY_SIZE(alc883_dac_nids),
- .dac_nids = alc883_dac_nids,
- .dig_out_nid = ALC883_DIGOUT_NID,
- .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
- .channel_mode = alc883_3ST_2ch_modes,
- .input_mux = &alc883_fujitsu_pi2515_capture_source,
- .unsol_event = alc_sku_unsol_event,
- .setup = alc883_2ch_fujitsu_pi2515_setup,
- .init_hook = alc_hp_automute,
- },
- [ALC888_FUJITSU_XA3530] = {
- .mixers = { alc888_base_mixer, alc883_chmode_mixer },
- .init_verbs = { alc883_init_verbs,
- alc888_fujitsu_xa3530_verbs },
- .num_dacs = ARRAY_SIZE(alc883_dac_nids),
- .dac_nids = alc883_dac_nids,
- .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
- .adc_nids = alc883_adc_nids_rev,
- .capsrc_nids = alc883_capsrc_nids_rev,
- .dig_out_nid = ALC883_DIGOUT_NID,
- .num_channel_mode = ARRAY_SIZE(alc888_4ST_8ch_intel_modes),
- .channel_mode = alc888_4ST_8ch_intel_modes,
- .num_mux_defs =
- ARRAY_SIZE(alc888_2_capture_sources),
- .input_mux = alc888_2_capture_sources,
- .unsol_event = alc_sku_unsol_event,
- .setup = alc888_fujitsu_xa3530_setup,
- .init_hook = alc_hp_automute,
- },
- [ALC888_LENOVO_SKY] = {
- .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
- .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs},
- .num_dacs = ARRAY_SIZE(alc883_dac_nids),
- .dac_nids = alc883_dac_nids,
- .dig_out_nid = ALC883_DIGOUT_NID,
- .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
- .channel_mode = alc883_sixstack_modes,
- .need_dac_fix = 1,
- .input_mux = &alc883_lenovo_sky_capture_source,
- .unsol_event = alc_sku_unsol_event,
- .setup = alc888_lenovo_sky_setup,
- .init_hook = alc_hp_automute,
- },
- [ALC888_ASUS_M90V] = {
- .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
- .init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs },
- .num_dacs = ARRAY_SIZE(alc883_dac_nids),
- .dac_nids = alc883_dac_nids,
- .dig_out_nid = ALC883_DIGOUT_NID,
- .dig_in_nid = ALC883_DIGIN_NID,
- .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
- .channel_mode = alc883_3ST_6ch_modes,
- .need_dac_fix = 1,
- .input_mux = &alc883_fujitsu_pi2515_capture_source,
- .unsol_event = alc_sku_unsol_event,
- .setup = alc883_mode2_setup,
- .init_hook = alc_inithook,
- },
- [ALC888_ASUS_EEE1601] = {
- .mixers = { alc883_asus_eee1601_mixer },
- .cap_mixer = alc883_asus_eee1601_cap_mixer,
- .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs },
- .num_dacs = ARRAY_SIZE(alc883_dac_nids),
- .dac_nids = alc883_dac_nids,
- .dig_out_nid = ALC883_DIGOUT_NID,
- .dig_in_nid = ALC883_DIGIN_NID,
- .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
- .channel_mode = alc883_3ST_2ch_modes,
- .need_dac_fix = 1,
- .input_mux = &alc883_asus_eee1601_capture_source,
- .unsol_event = alc_sku_unsol_event,
- .init_hook = alc883_eee1601_inithook,
- },
- [ALC1200_ASUS_P5Q] = {
- .mixers = { alc883_base_mixer, alc883_chmode_mixer },
- .init_verbs = { alc883_init_verbs },
- .num_dacs = ARRAY_SIZE(alc883_dac_nids),
- .dac_nids = alc883_dac_nids,
- .dig_out_nid = ALC1200_DIGOUT_NID,
- .dig_in_nid = ALC883_DIGIN_NID,
- .slave_dig_outs = alc1200_slave_dig_outs,
- .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
- .channel_mode = alc883_sixstack_modes,
- .input_mux = &alc883_capture_source,
- },
[ALC889A_MB31] = {
.mixers = { alc889A_mb31_mixer, alc883_chmode_mixer},
.init_verbs = { alc883_init_verbs, alc889A_mb31_verbs,
@@ -3711,18 +856,6 @@
.unsol_event = alc889A_mb31_unsol_event,
.init_hook = alc889A_mb31_automute,
},
- [ALC883_SONY_VAIO_TT] = {
- .mixers = { alc883_vaiott_mixer },
- .init_verbs = { alc883_init_verbs, alc883_vaiott_verbs },
- .num_dacs = ARRAY_SIZE(alc883_dac_nids),
- .dac_nids = alc883_dac_nids,
- .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
- .channel_mode = alc883_3ST_2ch_modes,
- .input_mux = &alc883_capture_source,
- .unsol_event = alc_sku_unsol_event,
- .setup = alc883_vaiott_setup,
- .init_hook = alc_hp_automute,
- },
};
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 4562e9d..4df72c0 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -33,6 +33,7 @@
#include <sound/jack.h>
#include "hda_local.h"
#include "hda_beep.h"
+#include "hda_jack.h"
#include <sound/hda_hwdep.h>
#define CREATE_TRACE_POINTS
@@ -1723,43 +1724,6 @@
}
EXPORT_SYMBOL_HDA(snd_hda_override_pin_caps);
-/**
- * snd_hda_pin_sense - execute pin sense measurement
- * @codec: the CODEC to sense
- * @nid: the pin NID to sense
- *
- * Execute necessary pin sense measurement and return its Presence Detect,
- * Impedance, ELD Valid etc. status bits.
- */
-u32 snd_hda_pin_sense(struct hda_codec *codec, hda_nid_t nid)
-{
- u32 pincap;
-
- if (!codec->no_trigger_sense) {
- pincap = snd_hda_query_pin_caps(codec, nid);
- if (pincap & AC_PINCAP_TRIG_REQ) /* need trigger? */
- snd_hda_codec_read(codec, nid, 0,
- AC_VERB_SET_PIN_SENSE, 0);
- }
- return snd_hda_codec_read(codec, nid, 0,
- AC_VERB_GET_PIN_SENSE, 0);
-}
-EXPORT_SYMBOL_HDA(snd_hda_pin_sense);
-
-/**
- * snd_hda_jack_detect - query pin Presence Detect status
- * @codec: the CODEC to sense
- * @nid: the pin NID to sense
- *
- * Query and return the pin's Presence Detect status.
- */
-int snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid)
-{
- u32 sense = snd_hda_pin_sense(codec, nid);
- return !!(sense & AC_PINSENSE_PRESENCE);
-}
-EXPORT_SYMBOL_HDA(snd_hda_jack_detect);
-
/*
* read the current volume to info
* if the cache exists, read the cache value.
@@ -2308,6 +2272,7 @@
}
if (codec->patch_ops.free)
codec->patch_ops.free(codec);
+ snd_hda_jack_tbl_clear(codec);
codec->proc_widget_hook = NULL;
codec->spec = NULL;
free_hda_cache(&codec->amp_cache);
@@ -3364,6 +3329,7 @@
restore_pincfgs(codec); /* restore all current pin configs */
restore_shutup_pins(codec);
hda_exec_init_verbs(codec);
+ snd_hda_jack_set_dirty_all(codec);
if (codec->patch_ops.resume)
codec->patch_ops.resume(codec);
else {
@@ -3850,6 +3816,12 @@
if (!test_and_set_bit(audio_idx[type][i], bus->pcm_dev_bits))
return audio_idx[type][i];
+ /* non-fixed slots starting from 10 */
+ for (i = 10; i < 32; i++) {
+ if (!test_and_set_bit(i, bus->pcm_dev_bits))
+ return i;
+ }
+
snd_printk(KERN_WARNING "Too many %s devices\n",
snd_hda_pcm_type_name[type]);
return -EAGAIN;
@@ -5004,8 +4976,8 @@
* "Rear", "Internal".
*/
-const char *hda_get_input_pin_label(struct hda_codec *codec, hda_nid_t pin,
- int check_location)
+static const char *hda_get_input_pin_label(struct hda_codec *codec,
+ hda_nid_t pin, bool check_location)
{
unsigned int def_conf;
static const char * const mic_names[] = {
@@ -5044,7 +5016,6 @@
return "Misc";
}
}
-EXPORT_SYMBOL_HDA(hda_get_input_pin_label);
/* Check whether the location prefix needs to be added to the label.
* If all mic-jacks are in the same location (e.g. rear panel), we don't
@@ -5101,6 +5072,149 @@
}
EXPORT_SYMBOL_HDA(hda_get_autocfg_input_label);
+/* return the position of NID in the list, or -1 if not found */
+static int find_idx_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums)
+{
+ int i;
+ for (i = 0; i < nums; i++)
+ if (list[i] == nid)
+ return i;
+ return -1;
+}
+
+/* get a unique suffix or an index number */
+static const char *check_output_sfx(hda_nid_t nid, const hda_nid_t *pins,
+ int num_pins, int *indexp)
+{
+ static const char * const channel_sfx[] = {
+ " Front", " Surround", " CLFE", " Side"
+ };
+ int i;
+
+ i = find_idx_in_nid_list(nid, pins, num_pins);
+ if (i < 0)
+ return NULL;
+ if (num_pins == 1)
+ return "";
+ if (num_pins > ARRAY_SIZE(channel_sfx)) {
+ if (indexp)
+ *indexp = i;
+ return "";
+ }
+ return channel_sfx[i];
+}
+
+static int fill_audio_out_name(struct hda_codec *codec, hda_nid_t nid,
+ const struct auto_pin_cfg *cfg,
+ const char *name, char *label, int maxlen,
+ int *indexp)
+{
+ unsigned int def_conf = snd_hda_codec_get_pincfg(codec, nid);
+ int attr = snd_hda_get_input_pin_attr(def_conf);
+ const char *pfx = "", *sfx = "";
+
+ /* handle as a speaker if it's a fixed line-out */
+ if (!strcmp(name, "Line-Out") && attr == INPUT_PIN_ATTR_INT)
+ name = "Speaker";
+ /* check the location */
+ switch (attr) {
+ case INPUT_PIN_ATTR_DOCK:
+ pfx = "Dock ";
+ break;
+ case INPUT_PIN_ATTR_FRONT:
+ pfx = "Front ";
+ break;
+ }
+ if (cfg) {
+ /* try to give a unique suffix if needed */
+ sfx = check_output_sfx(nid, cfg->line_out_pins, cfg->line_outs,
+ indexp);
+ if (!sfx)
+ sfx = check_output_sfx(nid, cfg->speaker_pins, cfg->speaker_outs,
+ indexp);
+ if (!sfx) {
+ /* don't add channel suffix for Headphone controls */
+ int idx = find_idx_in_nid_list(nid, cfg->hp_pins,
+ cfg->hp_outs);
+ if (idx >= 0)
+ *indexp = idx;
+ sfx = "";
+ }
+ }
+ snprintf(label, maxlen, "%s%s%s", pfx, name, sfx);
+ return 1;
+}
+
+/**
+ * snd_hda_get_pin_label - Get a label for the given I/O pin
+ *
+ * Get a label for the given pin. This function works for both input and
+ * output pins. When @cfg is given as non-NULL, the function tries to get
+ * an optimized label using hda_get_autocfg_input_label().
+ *
+ * This function tries to give a unique label string for the pin as much as
+ * possible. For example, when the multiple line-outs are present, it adds
+ * the channel suffix like "Front", "Surround", etc (only when @cfg is given).
+ * If no unique name with a suffix is available and @indexp is non-NULL, the
+ * index number is stored in the pointer.
+ */
+int snd_hda_get_pin_label(struct hda_codec *codec, hda_nid_t nid,
+ const struct auto_pin_cfg *cfg,
+ char *label, int maxlen, int *indexp)
+{
+ unsigned int def_conf = snd_hda_codec_get_pincfg(codec, nid);
+ const char *name = NULL;
+ int i;
+
+ if (indexp)
+ *indexp = 0;
+ if (get_defcfg_connect(def_conf) == AC_JACK_PORT_NONE)
+ return 0;
+
+ switch (get_defcfg_device(def_conf)) {
+ case AC_JACK_LINE_OUT:
+ return fill_audio_out_name(codec, nid, cfg, "Line-Out",
+ label, maxlen, indexp);
+ case AC_JACK_SPEAKER:
+ return fill_audio_out_name(codec, nid, cfg, "Speaker",
+ label, maxlen, indexp);
+ case AC_JACK_HP_OUT:
+ return fill_audio_out_name(codec, nid, cfg, "Headphone",
+ label, maxlen, indexp);
+ case AC_JACK_SPDIF_OUT:
+ case AC_JACK_DIG_OTHER_OUT:
+ if (get_defcfg_location(def_conf) == AC_JACK_LOC_HDMI)
+ name = "HDMI";
+ else
+ name = "SPDIF";
+ if (cfg && indexp) {
+ i = find_idx_in_nid_list(nid, cfg->dig_out_pins,
+ cfg->dig_outs);
+ if (i >= 0)
+ *indexp = i;
+ }
+ break;
+ default:
+ if (cfg) {
+ for (i = 0; i < cfg->num_inputs; i++) {
+ if (cfg->inputs[i].pin != nid)
+ continue;
+ name = hda_get_autocfg_input_label(codec, cfg, i);
+ if (name)
+ break;
+ }
+ }
+ if (!name)
+ name = hda_get_input_pin_label(codec, nid, true);
+ break;
+ }
+ if (!name)
+ return 0;
+ strlcpy(label, name, maxlen);
+ return 1;
+}
+EXPORT_SYMBOL_HDA(snd_hda_get_pin_label);
+
/**
* snd_hda_add_imux_item - Add an item to input_mux
*
@@ -5252,113 +5366,5 @@
}
EXPORT_SYMBOL_HDA(snd_print_pcm_bits);
-#ifdef CONFIG_SND_HDA_INPUT_JACK
-/*
- * Input-jack notification support
- */
-struct hda_jack_item {
- hda_nid_t nid;
- int type;
- struct snd_jack *jack;
-};
-
-static const char *get_jack_default_name(struct hda_codec *codec, hda_nid_t nid,
- int type)
-{
- switch (type) {
- case SND_JACK_HEADPHONE:
- return "Headphone";
- case SND_JACK_MICROPHONE:
- return "Mic";
- case SND_JACK_LINEOUT:
- return "Line-out";
- case SND_JACK_LINEIN:
- return "Line-in";
- case SND_JACK_HEADSET:
- return "Headset";
- case SND_JACK_VIDEOOUT:
- return "HDMI/DP";
- default:
- return "Misc";
- }
-}
-
-static void hda_free_jack_priv(struct snd_jack *jack)
-{
- struct hda_jack_item *jacks = jack->private_data;
- jacks->nid = 0;
- jacks->jack = NULL;
-}
-
-int snd_hda_input_jack_add(struct hda_codec *codec, hda_nid_t nid, int type,
- const char *name)
-{
- struct hda_jack_item *jack;
- int err;
-
- snd_array_init(&codec->jacks, sizeof(*jack), 32);
- jack = snd_array_new(&codec->jacks);
- if (!jack)
- return -ENOMEM;
-
- jack->nid = nid;
- jack->type = type;
- if (!name)
- name = get_jack_default_name(codec, nid, type);
- err = snd_jack_new(codec->bus->card, name, type, &jack->jack);
- if (err < 0) {
- jack->nid = 0;
- return err;
- }
- jack->jack->private_data = jack;
- jack->jack->private_free = hda_free_jack_priv;
- return 0;
-}
-EXPORT_SYMBOL_HDA(snd_hda_input_jack_add);
-
-void snd_hda_input_jack_report(struct hda_codec *codec, hda_nid_t nid)
-{
- struct hda_jack_item *jacks = codec->jacks.list;
- int i;
-
- if (!jacks)
- return;
-
- for (i = 0; i < codec->jacks.used; i++, jacks++) {
- unsigned int pin_ctl;
- unsigned int present;
- int type;
-
- if (jacks->nid != nid)
- continue;
- present = snd_hda_jack_detect(codec, nid);
- type = jacks->type;
- if (type == (SND_JACK_HEADPHONE | SND_JACK_LINEOUT)) {
- pin_ctl = snd_hda_codec_read(codec, nid, 0,
- AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
- type = (pin_ctl & AC_PINCTL_HP_EN) ?
- SND_JACK_HEADPHONE : SND_JACK_LINEOUT;
- }
- snd_jack_report(jacks->jack, present ? type : 0);
- }
-}
-EXPORT_SYMBOL_HDA(snd_hda_input_jack_report);
-
-/* free jack instances manually when clearing/reconfiguring */
-void snd_hda_input_jack_free(struct hda_codec *codec)
-{
- if (!codec->bus->shutdown && codec->jacks.list) {
- struct hda_jack_item *jacks = codec->jacks.list;
- int i;
- for (i = 0; i < codec->jacks.used; i++, jacks++) {
- if (jacks->jack)
- snd_device_free(codec->bus->card, jacks->jack);
- }
- }
- snd_array_free(&codec->jacks);
-}
-EXPORT_SYMBOL_HDA(snd_hda_input_jack_free);
-#endif /* CONFIG_SND_HDA_INPUT_JACK */
-
MODULE_DESCRIPTION("HDA codec core");
MODULE_LICENSE("GPL");
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index 5644711..e9f71dc 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -547,9 +547,6 @@
/* max. codec address */
#define HDA_MAX_CODEC_ADDRESS 0x0f
-/* max number of PCM devics per card */
-#define HDA_MAX_PCMS 10
-
/*
* generic arrays
*/
@@ -869,6 +866,9 @@
void (*proc_widget_hook)(struct snd_info_buffer *buffer,
struct hda_codec *codec, hda_nid_t nid);
+ /* jack detection */
+ struct snd_array jacktbl;
+
#ifdef CONFIG_SND_HDA_INPUT_JACK
/* jack detection */
struct snd_array jacks;
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index c2f79e6..0852e20 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -58,13 +58,13 @@
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 bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
static char *model[SNDRV_CARDS];
static int position_fix[SNDRV_CARDS];
static int bdl_pos_adj[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = -1};
static int probe_mask[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = -1};
static int probe_only[SNDRV_CARDS];
-static int single_cmd;
+static bool single_cmd;
static int enable_msi = -1;
#ifdef CONFIG_SND_HDA_PATCH_LOADER
static char *patch[SNDRV_CARDS];
@@ -116,12 +116,12 @@
* this may give more power-saving, but will take longer time to
* wake up.
*/
-static int power_save_controller = 1;
+static bool power_save_controller = 1;
module_param(power_save_controller, bool, 0644);
MODULE_PARM_DESC(power_save_controller, "Reset controller in power save mode.");
#endif
-static int align_buffer_size = 1;
+static bool align_buffer_size = 1;
module_param(align_buffer_size, bool, 0644);
MODULE_PARM_DESC(align_buffer_size,
"Force buffer and period sizes to be multiple of 128 bytes.");
@@ -407,6 +407,14 @@
u32 res[AZX_MAX_CODECS]; /* last read value */
};
+struct azx_pcm {
+ struct azx *chip;
+ struct snd_pcm *pcm;
+ struct hda_codec *codec;
+ struct hda_pcm_stream *hinfo[2];
+ struct list_head list;
+};
+
struct azx {
struct snd_card *card;
struct pci_dev *pci;
@@ -434,7 +442,7 @@
struct azx_dev *azx_dev;
/* PCM */
- struct snd_pcm *pcm[HDA_MAX_PCMS];
+ struct list_head pcm_list; /* azx_pcm list */
/* HD codec */
unsigned short codec_mask;
@@ -479,6 +487,7 @@
AZX_DRIVER_SCH,
AZX_DRIVER_ATI,
AZX_DRIVER_ATIHDMI,
+ AZX_DRIVER_ATIHDMI_NS,
AZX_DRIVER_VIA,
AZX_DRIVER_SIS,
AZX_DRIVER_ULI,
@@ -525,6 +534,7 @@
[AZX_DRIVER_SCH] = "HDA Intel MID",
[AZX_DRIVER_ATI] = "HDA ATI SB",
[AZX_DRIVER_ATIHDMI] = "HDA ATI HDMI",
+ [AZX_DRIVER_ATIHDMI_NS] = "HDA ATI HDMI",
[AZX_DRIVER_VIA] = "HDA VIA VT82xx",
[AZX_DRIVER_SIS] = "HDA SIS966",
[AZX_DRIVER_ULI] = "HDA ULI M5461",
@@ -1143,16 +1153,6 @@
static void azx_init_pci(struct azx *chip)
{
- /* force to non-snoop mode for a new VIA controller when BIOS is set */
- if (chip->snoop && chip->driver_type == AZX_DRIVER_VIA) {
- u8 snoop;
- pci_read_config_byte(chip->pci, 0x42, &snoop);
- if (!(snoop & 0x80) && chip->pci->revision == 0x30) {
- chip->snoop = 0;
- snd_printdd(SFX "Force to non-snoop mode\n");
- }
- }
-
/* Clear bits 0-2 of PCI register TCSEL (at offset 0x44)
* TCSEL == Traffic Class Select Register, which sets PCI express QOS
* Ensuring these bits are 0 clears playback static on some HD Audio
@@ -1486,10 +1486,9 @@
azx_init_chip(chip, 1);
#ifdef CONFIG_PM
if (chip->initialized) {
- int i;
-
- for (i = 0; i < HDA_MAX_PCMS; i++)
- snd_pcm_suspend_all(chip->pcm[i]);
+ struct azx_pcm *p;
+ list_for_each_entry(p, &chip->pcm_list, list)
+ snd_pcm_suspend_all(p->pcm);
snd_hda_suspend(chip->bus);
snd_hda_resume(chip->bus);
}
@@ -1667,12 +1666,6 @@
.fifo_size = 0,
};
-struct azx_pcm {
- struct azx *chip;
- struct hda_codec *codec;
- struct hda_pcm_stream *hinfo[2];
-};
-
static int azx_pcm_open(struct snd_pcm_substream *substream)
{
struct azx_pcm *apcm = snd_pcm_substream_chip(substream);
@@ -2197,7 +2190,7 @@
{
struct azx_pcm *apcm = pcm->private_data;
if (apcm) {
- apcm->chip->pcm[pcm->device] = NULL;
+ list_del(&apcm->list);
kfree(apcm);
}
}
@@ -2215,14 +2208,11 @@
unsigned int size;
int s, err;
- if (pcm_dev >= HDA_MAX_PCMS) {
- snd_printk(KERN_ERR SFX "Invalid PCM device number %d\n",
- pcm_dev);
- return -EINVAL;
- }
- if (chip->pcm[pcm_dev]) {
- snd_printk(KERN_ERR SFX "PCM %d already exists\n", pcm_dev);
- return -EBUSY;
+ list_for_each_entry(apcm, &chip->pcm_list, list) {
+ if (apcm->pcm->device == pcm_dev) {
+ snd_printk(KERN_ERR SFX "PCM %d already exists\n", pcm_dev);
+ return -EBUSY;
+ }
}
err = snd_pcm_new(chip->card, cpcm->name, pcm_dev,
cpcm->stream[SNDRV_PCM_STREAM_PLAYBACK].substreams,
@@ -2235,12 +2225,13 @@
if (apcm == NULL)
return -ENOMEM;
apcm->chip = chip;
+ apcm->pcm = pcm;
apcm->codec = codec;
pcm->private_data = apcm;
pcm->private_free = azx_pcm_free;
if (cpcm->pcm_type == HDA_PCM_TYPE_MODEM)
pcm->dev_class = SNDRV_PCM_CLASS_MODEM;
- chip->pcm[pcm_dev] = pcm;
+ list_add_tail(&apcm->list, &chip->pcm_list);
cpcm->pcm = pcm;
for (s = 0; s < 2; s++) {
apcm->hinfo[s] = &cpcm->stream[s];
@@ -2370,12 +2361,12 @@
{
struct snd_card *card = pci_get_drvdata(pci);
struct azx *chip = card->private_data;
- int i;
+ struct azx_pcm *p;
snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
azx_clear_irq_pending(chip);
- for (i = 0; i < HDA_MAX_PCMS; i++)
- snd_pcm_suspend_all(chip->pcm[i]);
+ list_for_each_entry(p, &chip->pcm_list, list)
+ snd_pcm_suspend_all(p->pcm);
if (chip->initialized)
snd_hda_suspend(chip->bus);
azx_stop_chip(chip);
@@ -2502,12 +2493,10 @@
static struct snd_pci_quirk position_fix_list[] __devinitdata = {
SND_PCI_QUIRK(0x1028, 0x01cc, "Dell D820", POS_FIX_LPIB),
SND_PCI_QUIRK(0x1028, 0x01de, "Dell Precision 390", POS_FIX_LPIB),
- SND_PCI_QUIRK(0x1028, 0x02c6, "Dell Inspiron 1010", POS_FIX_LPIB),
SND_PCI_QUIRK(0x103c, 0x306d, "HP dv3", POS_FIX_LPIB),
SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", POS_FIX_LPIB),
SND_PCI_QUIRK(0x1043, 0x81b3, "ASUS", POS_FIX_LPIB),
SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS M2V", POS_FIX_LPIB),
- SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS 1101HA", POS_FIX_LPIB),
SND_PCI_QUIRK(0x104d, 0x9069, "Sony VPCS11V9E", POS_FIX_LPIB),
SND_PCI_QUIRK(0x1297, 0x3166, "Shuttle", POS_FIX_LPIB),
SND_PCI_QUIRK(0x1458, 0xa022, "ga-ma770-ud3", POS_FIX_LPIB),
@@ -2634,6 +2623,35 @@
}
}
+/* check the snoop mode availability */
+static void __devinit azx_check_snoop_available(struct azx *chip)
+{
+ bool snoop = chip->snoop;
+
+ switch (chip->driver_type) {
+ case AZX_DRIVER_VIA:
+ /* force to non-snoop mode for a new VIA controller
+ * when BIOS is set
+ */
+ if (snoop) {
+ u8 val;
+ pci_read_config_byte(chip->pci, 0x42, &val);
+ if (!(val & 0x80) && chip->pci->revision == 0x30)
+ snoop = false;
+ }
+ break;
+ case AZX_DRIVER_ATIHDMI_NS:
+ /* new ATI HDMI requires non-snoop */
+ snoop = false;
+ break;
+ }
+
+ if (snoop != chip->snoop) {
+ snd_printk(KERN_INFO SFX "Force to %s mode\n",
+ snoop ? "snoop" : "non-snoop");
+ chip->snoop = snoop;
+ }
+}
/*
* constructor
@@ -2672,6 +2690,7 @@
check_msi(chip);
chip->dev_index = dev;
INIT_WORK(&chip->irq_pending_work, azx_irq_pending_work);
+ INIT_LIST_HEAD(&chip->pcm_list);
chip->position_fix[0] = chip->position_fix[1] =
check_position_fix(chip, position_fix[dev]);
@@ -2679,6 +2698,7 @@
chip->single_cmd = single_cmd;
chip->snoop = hda_snoop;
+ azx_check_snoop_available(chip);
if (bdl_pos_adj[dev] < 0) {
switch (chip->driver_type) {
@@ -2777,6 +2797,7 @@
chip->capture_streams = ULI_NUM_CAPTURE;
break;
case AZX_DRIVER_ATIHDMI:
+ case AZX_DRIVER_ATIHDMI_NS:
chip->playback_streams = ATIHDMI_NUM_PLAYBACK;
chip->capture_streams = ATIHDMI_NUM_CAPTURE;
break;
@@ -2972,6 +2993,9 @@
{ PCI_DEVICE(0x8086, 0x811b),
.driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP |
AZX_DCAPS_BUFSIZE | AZX_DCAPS_POSFIX_LPIB }, /* Poulsbo */
+ { PCI_DEVICE(0x8086, 0x080a),
+ .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP |
+ AZX_DCAPS_BUFSIZE | AZX_DCAPS_POSFIX_LPIB }, /* Oaktrail */
/* ICH */
{ PCI_DEVICE(0x8086, 0x2668),
.driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC |
@@ -3039,6 +3063,14 @@
.driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
{ PCI_DEVICE(0x1002, 0xaa48),
.driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
+ { PCI_DEVICE(0x1002, 0x9902),
+ .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI },
+ { PCI_DEVICE(0x1002, 0xaaa0),
+ .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI },
+ { PCI_DEVICE(0x1002, 0xaaa8),
+ .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI },
+ { PCI_DEVICE(0x1002, 0xaab0),
+ .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI },
/* VIA VT8251/VT8237A */
{ PCI_DEVICE(0x1106, 0x3288),
.driver_data = AZX_DRIVER_VIA | AZX_DCAPS_POSFIX_VIA },
diff --git a/sound/pci/hda/hda_jack.c b/sound/pci/hda/hda_jack.c
new file mode 100644
index 0000000..d8a35da
--- /dev/null
+++ b/sound/pci/hda/hda_jack.c
@@ -0,0 +1,353 @@
+/*
+ * Jack-detection handling for HD-audio
+ *
+ * Copyright (c) 2011 Takashi Iwai <tiwai@suse.de>
+ *
+ * This driver 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.
+ */
+
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/export.h>
+#include <sound/core.h>
+#include <sound/control.h>
+#include <sound/jack.h>
+#include "hda_codec.h"
+#include "hda_local.h"
+#include "hda_jack.h"
+
+/* execute pin sense measurement */
+static u32 read_pin_sense(struct hda_codec *codec, hda_nid_t nid)
+{
+ u32 pincap;
+
+ if (!codec->no_trigger_sense) {
+ pincap = snd_hda_query_pin_caps(codec, nid);
+ if (pincap & AC_PINCAP_TRIG_REQ) /* need trigger? */
+ snd_hda_codec_read(codec, nid, 0,
+ AC_VERB_SET_PIN_SENSE, 0);
+ }
+ return snd_hda_codec_read(codec, nid, 0,
+ AC_VERB_GET_PIN_SENSE, 0);
+}
+
+/**
+ * snd_hda_jack_tbl_get - query the jack-table entry for the given NID
+ */
+struct hda_jack_tbl *
+snd_hda_jack_tbl_get(struct hda_codec *codec, hda_nid_t nid)
+{
+ struct hda_jack_tbl *jack = codec->jacktbl.list;
+ int i;
+
+ if (!nid || !jack)
+ return NULL;
+ for (i = 0; i < codec->jacktbl.used; i++, jack++)
+ if (jack->nid == nid)
+ return jack;
+ return NULL;
+}
+EXPORT_SYMBOL_HDA(snd_hda_jack_tbl_get);
+
+/**
+ * snd_hda_jack_tbl_get_from_tag - query the jack-table entry for the given tag
+ */
+struct hda_jack_tbl *
+snd_hda_jack_tbl_get_from_tag(struct hda_codec *codec, unsigned char tag)
+{
+ struct hda_jack_tbl *jack = codec->jacktbl.list;
+ int i;
+
+ if (!tag || !jack)
+ return NULL;
+ for (i = 0; i < codec->jacktbl.used; i++, jack++)
+ if (jack->tag == tag)
+ return jack;
+ return NULL;
+}
+EXPORT_SYMBOL_HDA(snd_hda_jack_tbl_get_from_tag);
+
+/**
+ * snd_hda_jack_tbl_new - create a jack-table entry for the given NID
+ */
+struct hda_jack_tbl *
+snd_hda_jack_tbl_new(struct hda_codec *codec, hda_nid_t nid)
+{
+ struct hda_jack_tbl *jack = snd_hda_jack_tbl_get(codec, nid);
+ if (jack)
+ return jack;
+ snd_array_init(&codec->jacktbl, sizeof(*jack), 16);
+ jack = snd_array_new(&codec->jacktbl);
+ if (!jack)
+ return NULL;
+ jack->nid = nid;
+ jack->jack_dirty = 1;
+ jack->tag = codec->jacktbl.used;
+ return jack;
+}
+EXPORT_SYMBOL_HDA(snd_hda_jack_tbl_new);
+
+void snd_hda_jack_tbl_clear(struct hda_codec *codec)
+{
+#ifdef CONFIG_SND_HDA_INPUT_JACK
+ /* free jack instances manually when clearing/reconfiguring */
+ if (!codec->bus->shutdown && codec->jacktbl.list) {
+ struct hda_jack_tbl *jack = codec->jacktbl.list;
+ int i;
+ for (i = 0; i < codec->jacktbl.used; i++, jack++) {
+ if (jack->jack)
+ snd_device_free(codec->bus->card, jack->jack);
+ }
+ }
+#endif
+ snd_array_free(&codec->jacktbl);
+}
+
+/* update the cached value and notification flag if needed */
+static void jack_detect_update(struct hda_codec *codec,
+ struct hda_jack_tbl *jack)
+{
+ if (jack->jack_dirty || !jack->jack_detect) {
+ jack->pin_sense = read_pin_sense(codec, jack->nid);
+ jack->jack_dirty = 0;
+ }
+}
+
+/**
+ * snd_hda_set_dirty_all - Mark all the cached as dirty
+ *
+ * This function sets the dirty flag to all entries of jack table.
+ * It's called from the resume path in hda_codec.c.
+ */
+void snd_hda_jack_set_dirty_all(struct hda_codec *codec)
+{
+ struct hda_jack_tbl *jack = codec->jacktbl.list;
+ int i;
+
+ for (i = 0; i < codec->jacktbl.used; i++, jack++)
+ if (jack->nid)
+ jack->jack_dirty = 1;
+}
+EXPORT_SYMBOL_HDA(snd_hda_jack_set_dirty_all);
+
+/**
+ * snd_hda_pin_sense - execute pin sense measurement
+ * @codec: the CODEC to sense
+ * @nid: the pin NID to sense
+ *
+ * Execute necessary pin sense measurement and return its Presence Detect,
+ * Impedance, ELD Valid etc. status bits.
+ */
+u32 snd_hda_pin_sense(struct hda_codec *codec, hda_nid_t nid)
+{
+ struct hda_jack_tbl *jack = snd_hda_jack_tbl_get(codec, nid);
+ if (jack) {
+ jack_detect_update(codec, jack);
+ return jack->pin_sense;
+ }
+ return read_pin_sense(codec, nid);
+}
+EXPORT_SYMBOL_HDA(snd_hda_pin_sense);
+
+#define get_jack_plug_state(sense) !!(sense & AC_PINSENSE_PRESENCE)
+
+/**
+ * snd_hda_jack_detect - query pin Presence Detect status
+ * @codec: the CODEC to sense
+ * @nid: the pin NID to sense
+ *
+ * Query and return the pin's Presence Detect status.
+ */
+int snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid)
+{
+ u32 sense = snd_hda_pin_sense(codec, nid);
+ return get_jack_plug_state(sense);
+}
+EXPORT_SYMBOL_HDA(snd_hda_jack_detect);
+
+/**
+ * snd_hda_jack_detect_enable - enable the jack-detection
+ */
+int snd_hda_jack_detect_enable(struct hda_codec *codec, hda_nid_t nid,
+ unsigned char action)
+{
+ struct hda_jack_tbl *jack = snd_hda_jack_tbl_new(codec, nid);
+ if (!jack)
+ return -ENOMEM;
+ if (jack->jack_detect)
+ return 0; /* already registered */
+ jack->jack_detect = 1;
+ if (action)
+ jack->action = action;
+ return snd_hda_codec_write_cache(codec, nid, 0,
+ AC_VERB_SET_UNSOLICITED_ENABLE,
+ AC_USRSP_EN | jack->tag);
+}
+EXPORT_SYMBOL_HDA(snd_hda_jack_detect_enable);
+
+/**
+ * snd_hda_jack_report_sync - sync the states of all jacks and report if changed
+ */
+void snd_hda_jack_report_sync(struct hda_codec *codec)
+{
+ struct hda_jack_tbl *jack = codec->jacktbl.list;
+ int i, state;
+
+ for (i = 0; i < codec->jacktbl.used; i++, jack++)
+ if (jack->nid) {
+ jack_detect_update(codec, jack);
+ if (!jack->kctl)
+ continue;
+ state = get_jack_plug_state(jack->pin_sense);
+ snd_kctl_jack_report(codec->bus->card, jack->kctl, state);
+#ifdef CONFIG_SND_HDA_INPUT_JACK
+ if (jack->jack)
+ snd_jack_report(jack->jack,
+ state ? jack->type : 0);
+#endif
+ }
+}
+EXPORT_SYMBOL_HDA(snd_hda_jack_report_sync);
+
+#ifdef CONFIG_SND_HDA_INPUT_JACK
+/* guess the jack type from the pin-config */
+static int get_input_jack_type(struct hda_codec *codec, hda_nid_t nid)
+{
+ unsigned int def_conf = snd_hda_codec_get_pincfg(codec, nid);
+ switch (get_defcfg_device(def_conf)) {
+ case AC_JACK_LINE_OUT:
+ case AC_JACK_SPEAKER:
+ return SND_JACK_LINEOUT;
+ case AC_JACK_HP_OUT:
+ return SND_JACK_HEADPHONE;
+ case AC_JACK_SPDIF_OUT:
+ case AC_JACK_DIG_OTHER_OUT:
+ return SND_JACK_AVOUT;
+ case AC_JACK_MIC_IN:
+ return SND_JACK_MICROPHONE;
+ default:
+ return SND_JACK_LINEIN;
+ }
+}
+
+static void hda_free_jack_priv(struct snd_jack *jack)
+{
+ struct hda_jack_tbl *jacks = jack->private_data;
+ jacks->nid = 0;
+ jacks->jack = NULL;
+}
+#endif
+
+/**
+ * snd_hda_jack_add_kctl - Add a kctl for the given pin
+ *
+ * This assigns a jack-detection kctl to the given pin. The kcontrol
+ * will have the given name and index.
+ */
+int snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid,
+ const char *name, int idx)
+{
+ struct hda_jack_tbl *jack;
+ struct snd_kcontrol *kctl;
+ int err, state;
+
+ jack = snd_hda_jack_tbl_new(codec, nid);
+ if (!jack)
+ return 0;
+ if (jack->kctl)
+ return 0; /* already created */
+ kctl = snd_kctl_jack_new(name, idx, codec);
+ if (!kctl)
+ return -ENOMEM;
+ err = snd_hda_ctl_add(codec, nid, kctl);
+ if (err < 0)
+ return err;
+ jack->kctl = kctl;
+ state = snd_hda_jack_detect(codec, nid);
+ snd_kctl_jack_report(codec->bus->card, kctl, state);
+#ifdef CONFIG_SND_HDA_INPUT_JACK
+ jack->type = get_input_jack_type(codec, nid);
+ err = snd_jack_new(codec->bus->card, name, jack->type, &jack->jack);
+ if (err < 0)
+ return err;
+ jack->jack->private_data = jack;
+ jack->jack->private_free = hda_free_jack_priv;
+ snd_jack_report(jack->jack, state ? jack->type : 0);
+#endif
+ return 0;
+}
+EXPORT_SYMBOL_HDA(snd_hda_jack_add_kctl);
+
+static int add_jack_kctl(struct hda_codec *codec, hda_nid_t nid,
+ const struct auto_pin_cfg *cfg)
+{
+ unsigned int def_conf, conn;
+ char name[44];
+ int idx, err;
+
+ if (!nid)
+ return 0;
+ if (!is_jack_detectable(codec, nid))
+ return 0;
+ def_conf = snd_hda_codec_get_pincfg(codec, nid);
+ conn = get_defcfg_connect(def_conf);
+ if (conn != AC_JACK_PORT_COMPLEX)
+ return 0;
+
+ snd_hda_get_pin_label(codec, nid, cfg, name, sizeof(name), &idx);
+ err = snd_hda_jack_add_kctl(codec, nid, name, idx);
+ if (err < 0)
+ return err;
+ return snd_hda_jack_detect_enable(codec, nid, 0);
+}
+
+/**
+ * snd_hda_jack_add_kctls - Add kctls for all pins included in the given pincfg
+ */
+int snd_hda_jack_add_kctls(struct hda_codec *codec,
+ const struct auto_pin_cfg *cfg)
+{
+ const hda_nid_t *p;
+ int i, err;
+
+ for (i = 0, p = cfg->line_out_pins; i < cfg->line_outs; i++, p++) {
+ err = add_jack_kctl(codec, *p, cfg);
+ if (err < 0)
+ return err;
+ }
+ for (i = 0, p = cfg->hp_pins; i < cfg->hp_outs; i++, p++) {
+ if (*p == *cfg->line_out_pins) /* might be duplicated */
+ break;
+ err = add_jack_kctl(codec, *p, cfg);
+ if (err < 0)
+ return err;
+ }
+ for (i = 0, p = cfg->speaker_pins; i < cfg->speaker_outs; i++, p++) {
+ if (*p == *cfg->line_out_pins) /* might be duplicated */
+ break;
+ err = add_jack_kctl(codec, *p, cfg);
+ if (err < 0)
+ return err;
+ }
+ for (i = 0; i < cfg->num_inputs; i++) {
+ err = add_jack_kctl(codec, cfg->inputs[i].pin, cfg);
+ if (err < 0)
+ return err;
+ }
+ for (i = 0, p = cfg->dig_out_pins; i < cfg->dig_outs; i++, p++) {
+ err = add_jack_kctl(codec, *p, cfg);
+ if (err < 0)
+ return err;
+ }
+ err = add_jack_kctl(codec, cfg->dig_in_pin, cfg);
+ if (err < 0)
+ return err;
+ err = add_jack_kctl(codec, cfg->mono_out_pin, cfg);
+ if (err < 0)
+ return err;
+ return 0;
+}
+EXPORT_SYMBOL_HDA(snd_hda_jack_add_kctls);
diff --git a/sound/pci/hda/hda_jack.h b/sound/pci/hda/hda_jack.h
new file mode 100644
index 0000000..f8f97c7
--- /dev/null
+++ b/sound/pci/hda/hda_jack.h
@@ -0,0 +1,86 @@
+/*
+ * Jack-detection handling for HD-audio
+ *
+ * Copyright (c) 2011 Takashi Iwai <tiwai@suse.de>
+ *
+ * This driver 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.
+ */
+
+#ifndef __SOUND_HDA_JACK_H
+#define __SOUND_HDA_JACK_H
+
+struct hda_jack_tbl {
+ hda_nid_t nid;
+ unsigned char action; /* event action (0 = none) */
+ unsigned char tag; /* unsol event tag */
+ unsigned int private_data; /* arbitrary data */
+ /* jack-detection stuff */
+ unsigned int pin_sense; /* cached pin-sense value */
+ unsigned int jack_detect:1; /* capable of jack-detection? */
+ unsigned int jack_dirty:1; /* needs to update? */
+ struct snd_kcontrol *kctl; /* assigned kctl for jack-detection */
+#ifdef CONFIG_SND_HDA_INPUT_JACK
+ int type;
+ struct snd_jack *jack;
+#endif
+};
+
+struct hda_jack_tbl *
+snd_hda_jack_tbl_get(struct hda_codec *codec, hda_nid_t nid);
+struct hda_jack_tbl *
+snd_hda_jack_tbl_get_from_tag(struct hda_codec *codec, unsigned char tag);
+
+struct hda_jack_tbl *
+snd_hda_jack_tbl_new(struct hda_codec *codec, hda_nid_t nid);
+void snd_hda_jack_tbl_clear(struct hda_codec *codec);
+
+/**
+ * snd_hda_jack_get_action - get jack-tbl entry for the tag
+ *
+ * Call this from the unsol event handler to get the assigned action for the
+ * event. This will mark the dirty flag for the later reporting, too.
+ */
+static inline unsigned char
+snd_hda_jack_get_action(struct hda_codec *codec, unsigned int tag)
+{
+ struct hda_jack_tbl *jack = snd_hda_jack_tbl_get_from_tag(codec, tag);
+ if (jack) {
+ jack->jack_dirty = 1;
+ return jack->action;
+ }
+ return 0;
+}
+
+void snd_hda_jack_set_dirty_all(struct hda_codec *codec);
+
+int snd_hda_jack_detect_enable(struct hda_codec *codec, hda_nid_t nid,
+ unsigned char action);
+
+u32 snd_hda_pin_sense(struct hda_codec *codec, hda_nid_t nid);
+int snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid);
+
+static inline bool is_jack_detectable(struct hda_codec *codec, hda_nid_t nid)
+{
+ if (!(snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_PRES_DETECT))
+ return false;
+ if (!codec->ignore_misc_bit &&
+ (get_defcfg_misc(snd_hda_codec_get_pincfg(codec, nid)) &
+ AC_DEFCFG_MISC_NO_PRESENCE))
+ return false;
+ if (!(get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP))
+ return false;
+ return true;
+}
+
+int snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid,
+ const char *name, int idx);
+int snd_hda_jack_add_kctls(struct hda_codec *codec,
+ const struct auto_pin_cfg *cfg);
+
+void snd_hda_jack_report_sync(struct hda_codec *codec);
+
+
+#endif /* __SOUND_HDA_JACK_H */
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h
index 618ddad..aca8d31 100644
--- a/sound/pci/hda/hda_local.h
+++ b/sound/pci/hda/hda_local.h
@@ -394,11 +394,12 @@
};
struct auto_pin_cfg;
-const char *hda_get_input_pin_label(struct hda_codec *codec, hda_nid_t pin,
- int check_location);
const char *hda_get_autocfg_input_label(struct hda_codec *codec,
const struct auto_pin_cfg *cfg,
int input);
+int snd_hda_get_pin_label(struct hda_codec *codec, hda_nid_t nid,
+ const struct auto_pin_cfg *cfg,
+ char *label, int maxlen, int *indexp);
int snd_hda_add_imux_item(struct hda_input_mux *imux, const char *label,
int index, int *type_index_ret);
@@ -487,7 +488,12 @@
}
/* get the widget type from widget capability bits */
-#define get_wcaps_type(wcaps) (((wcaps) & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT)
+static inline int get_wcaps_type(unsigned int wcaps)
+{
+ if (!wcaps)
+ return -1; /* invalid type */
+ return (wcaps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
+}
static inline unsigned int get_wcaps_channels(u32 wcaps)
{
@@ -505,21 +511,6 @@
u32 snd_hda_query_pin_caps(struct hda_codec *codec, hda_nid_t nid);
int snd_hda_override_pin_caps(struct hda_codec *codec, hda_nid_t nid,
unsigned int caps);
-u32 snd_hda_pin_sense(struct hda_codec *codec, hda_nid_t nid);
-int snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid);
-
-static inline bool is_jack_detectable(struct hda_codec *codec, hda_nid_t nid)
-{
- if (!(snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_PRES_DETECT))
- return false;
- if (!codec->ignore_misc_bit &&
- (get_defcfg_misc(snd_hda_codec_get_pincfg(codec, nid)) &
- AC_DEFCFG_MISC_NO_PRESENCE))
- return false;
- if (!(get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP))
- return false;
- return true;
-}
/* flags for hda_nid_item */
#define HDA_NID_ITEM_AMP (1<<0)
@@ -688,28 +679,4 @@
#define SND_PRINT_CHANNEL_ALLOCATION_ADVISED_BUFSIZE 80
void snd_print_channel_allocation(int spk_alloc, char *buf, int buflen);
-/*
- * Input-jack notification support
- */
-#ifdef CONFIG_SND_HDA_INPUT_JACK
-int snd_hda_input_jack_add(struct hda_codec *codec, hda_nid_t nid, int type,
- const char *name);
-void snd_hda_input_jack_report(struct hda_codec *codec, hda_nid_t nid);
-void snd_hda_input_jack_free(struct hda_codec *codec);
-#else /* CONFIG_SND_HDA_INPUT_JACK */
-static inline int snd_hda_input_jack_add(struct hda_codec *codec,
- hda_nid_t nid, int type,
- const char *name)
-{
- return 0;
-}
-static inline void snd_hda_input_jack_report(struct hda_codec *codec,
- hda_nid_t nid)
-{
-}
-static inline void snd_hda_input_jack_free(struct hda_codec *codec)
-{
-}
-#endif /* CONFIG_SND_HDA_INPUT_JACK */
-
#endif /* __SOUND_HDA_LOCAL_H */
diff --git a/sound/pci/hda/hda_proc.c b/sound/pci/hda/hda_proc.c
index 2c981b5..254ab52 100644
--- a/sound/pci/hda/hda_proc.c
+++ b/sound/pci/hda/hda_proc.c
@@ -54,6 +54,8 @@
[AC_WID_BEEP] = "Beep Generator Widget",
[AC_WID_VENDOR] = "Vendor Defined Widget",
};
+ if (wid_value == -1)
+ return "UNKNOWN Widget";
wid_value &= 0xf;
if (names[wid_value])
return names[wid_value];
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
index bcb3310..9cb14b4 100644
--- a/sound/pci/hda/patch_analog.c
+++ b/sound/pci/hda/patch_analog.c
@@ -29,6 +29,7 @@
#include "hda_codec.h"
#include "hda_local.h"
#include "hda_beep.h"
+#include "hda_jack.h"
struct ad198x_spec {
const struct snd_kcontrol_new *mixers[6];
diff --git a/sound/pci/hda/patch_ca0110.c b/sound/pci/hda/patch_ca0110.c
index 993757b..09ccfab 100644
--- a/sound/pci/hda/patch_ca0110.c
+++ b/sound/pci/hda/patch_ca0110.c
@@ -41,7 +41,7 @@
hda_nid_t dig_out;
hda_nid_t dig_in;
unsigned int num_inputs;
- const char *input_labels[AUTO_PIN_LAST];
+ char input_labels[AUTO_PIN_LAST][32];
struct hda_pcm pcm_rec[2]; /* PCM information */
};
@@ -476,7 +476,9 @@
if (j >= cfg->num_inputs)
continue;
spec->input_pins[n] = pin;
- spec->input_labels[n] = hda_get_input_pin_label(codec, pin, 1);
+ snd_hda_get_pin_label(codec, pin, cfg,
+ spec->input_labels[n],
+ sizeof(spec->input_labels[n]), NULL);
spec->adcs[n] = nid;
n++;
}
diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c
index 70a7abd..0e99357 100644
--- a/sound/pci/hda/patch_cirrus.c
+++ b/sound/pci/hda/patch_cirrus.c
@@ -26,6 +26,7 @@
#include <sound/core.h>
#include "hda_codec.h"
#include "hda_local.h"
+#include "hda_jack.h"
#include <sound/tlv.h>
/*
@@ -78,6 +79,7 @@
CS420X_MBP53,
CS420X_MBP55,
CS420X_IMAC27,
+ CS420X_IMAC27_122,
CS420X_APPLE,
CS420X_AUTO,
CS420X_MODELS
@@ -137,7 +139,7 @@
*/
#define CS4210_DAC_NID 0x02
#define CS4210_ADC_NID 0x03
-#define CS421X_VENDOR_NID 0x0B
+#define CS4210_VENDOR_NID 0x0B
#define CS421X_DMIC_PIN_NID 0x09 /* Port E */
#define CS421X_SPDIF_PIN_NID 0x0A /* Port H */
@@ -148,6 +150,10 @@
#define SPDIF_EVENT 0x04
+/* Cirrus Logic CS4213 is like CS4210 but does not have SPDIF input/output */
+#define CS4213_VENDOR_NID 0x09
+
+
static inline int cs_vendor_coef_get(struct hda_codec *codec, unsigned int idx)
{
struct cs_spec *spec = codec->spec;
@@ -721,8 +727,9 @@
if (uinfo->value.enumerated.item >= spec->num_inputs)
uinfo->value.enumerated.item = spec->num_inputs - 1;
idx = spec->input_idx[uinfo->value.enumerated.item];
- strcpy(uinfo->value.enumerated.name,
- hda_get_input_pin_label(codec, cfg->inputs[idx].pin, 1));
+ snd_hda_get_pin_label(codec, cfg->inputs[idx].pin, cfg,
+ uinfo->value.enumerated.name,
+ sizeof(uinfo->value.enumerated.name), NULL);
return 0;
}
@@ -920,16 +927,14 @@
/* mute speakers if spdif or hp jack is plugged in */
for (i = 0; i < cfg->speaker_outs; i++) {
+ int pin_ctl = hp_present ? 0 : PIN_OUT;
+ /* detect on spdif is specific to CS4210 */
+ if (spdif_present && (spec->vendor_nid == CS4210_VENDOR_NID))
+ pin_ctl = 0;
+
nid = cfg->speaker_pins[i];
snd_hda_codec_write(codec, nid, 0,
- AC_VERB_SET_PIN_WIDGET_CONTROL,
- hp_present ? 0 : PIN_OUT);
- /* detect on spdif is specific to CS421x */
- if (spec->vendor_nid == CS421X_VENDOR_NID) {
- snd_hda_codec_write(codec, nid, 0,
- AC_VERB_SET_PIN_WIDGET_CONTROL,
- spdif_present ? 0 : PIN_OUT);
- }
+ AC_VERB_SET_PIN_WIDGET_CONTROL, pin_ctl);
}
if (spec->gpio_eapd_hp) {
unsigned int gpio = hp_present ?
@@ -938,8 +943,8 @@
AC_VERB_SET_GPIO_DATA, gpio);
}
- /* specific to CS421x */
- if (spec->vendor_nid == CS421X_VENDOR_NID) {
+ /* specific to CS4210 */
+ if (spec->vendor_nid == CS4210_VENDOR_NID) {
/* mute HPs if spdif jack (SENSE_B) is present */
for (i = 0; i < cfg->hp_outs; i++) {
nid = cfg->hp_pins[i];
@@ -976,7 +981,12 @@
present = snd_hda_jack_detect(codec, nid);
/* specific to CS421x, single ADC */
- if (spec->vendor_nid == CS421X_VENDOR_NID) {
+ if (spec->vendor_nid == CS420X_VENDOR_NID) {
+ if (present)
+ change_cur_input(codec, spec->automic_idx, 0);
+ else
+ change_cur_input(codec, !spec->automic_idx, 0);
+ } else {
if (present) {
spec->last_input = spec->cur_input;
spec->cur_input = spec->automic_idx;
@@ -984,11 +994,6 @@
spec->cur_input = spec->last_input;
}
cs_update_input_select(codec);
- } else {
- if (present)
- change_cur_input(codec, spec->automic_idx, 0);
- else
- change_cur_input(codec, !spec->automic_idx, 0);
}
}
@@ -1027,9 +1032,7 @@
if (!cfg->speaker_outs)
continue;
if (get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP) {
- snd_hda_codec_write(codec, nid, 0,
- AC_VERB_SET_UNSOLICITED_ENABLE,
- AC_USRSP_EN | HP_EVENT);
+ snd_hda_jack_detect_enable(codec, nid, HP_EVENT);
spec->hp_detect = 1;
}
}
@@ -1070,19 +1073,10 @@
AC_VERB_SET_AMP_GAIN_MUTE,
AMP_IN_MUTE(spec->adc_idx[i]));
if (spec->mic_detect && spec->automic_idx == i)
- snd_hda_codec_write(codec, pin, 0,
- AC_VERB_SET_UNSOLICITED_ENABLE,
- AC_USRSP_EN | MIC_EVENT);
+ snd_hda_jack_detect_enable(codec, pin, MIC_EVENT);
}
- /* specific to CS421x */
- if (spec->vendor_nid == CS421X_VENDOR_NID) {
- if (spec->mic_detect)
- cs_automic(codec);
- else {
- spec->cur_adc = spec->adc_nid[spec->cur_input];
- cs_update_input_select(codec);
- }
- } else {
+ /* CS420x has multiple ADC, CS421x has single ADC */
+ if (spec->vendor_nid == CS420X_VENDOR_NID) {
change_cur_input(codec, spec->cur_input, 1);
if (spec->mic_detect)
cs_automic(codec);
@@ -1096,6 +1090,13 @@
* selected in IDX_SPDIF_CTL.
*/
cs_vendor_coef_set(codec, IDX_ADC_CFG, coef);
+ } else {
+ if (spec->mic_detect)
+ cs_automic(codec);
+ else {
+ spec->cur_adc = spec->adc_nid[spec->cur_input];
+ cs_update_input_select(codec);
+ }
}
}
@@ -1200,11 +1201,14 @@
init_output(codec);
init_input(codec);
init_digital(codec);
+ snd_hda_jack_report_sync(codec);
+
return 0;
}
static int cs_build_controls(struct hda_codec *codec)
{
+ struct cs_spec *spec = codec->spec;
int err;
err = build_output(codec);
@@ -1219,7 +1223,15 @@
err = build_digital_input(codec);
if (err < 0)
return err;
- return cs_init(codec);
+ err = cs_init(codec);
+ if (err < 0)
+ return err;
+
+ err = snd_hda_jack_add_kctls(codec, &spec->autocfg);
+ if (err < 0)
+ return err;
+
+ return 0;
}
static void cs_free(struct hda_codec *codec)
@@ -1232,7 +1244,7 @@
static void cs_unsol_event(struct hda_codec *codec, unsigned int res)
{
- switch ((res >> 26) & 0x7f) {
+ switch (snd_hda_jack_get_action(codec, res >> 26)) {
case HP_EVENT:
cs_automute(codec);
break;
@@ -1240,6 +1252,7 @@
cs_automic(codec);
break;
}
+ snd_hda_jack_report_sync(codec);
}
static const struct hda_codec_ops cs_patch_ops = {
@@ -1278,6 +1291,7 @@
[CS420X_MBP53] = "mbp53",
[CS420X_MBP55] = "mbp55",
[CS420X_IMAC27] = "imac27",
+ [CS420X_IMAC27_122] = "imac27_122",
[CS420X_APPLE] = "apple",
[CS420X_AUTO] = "auto",
};
@@ -1294,6 +1308,7 @@
};
static const struct snd_pci_quirk cs420x_codec_cfg_tbl[] = {
+ SND_PCI_QUIRK(0x106b, 0x2000, "iMac 12,2", CS420X_IMAC27_122),
SND_PCI_QUIRK_VENDOR(0x106b, "Apple", CS420X_APPLE),
{} /* terminator */
};
@@ -1393,6 +1408,12 @@
spec->gpio_mask = spec->gpio_dir =
spec->gpio_eapd_hp | spec->gpio_eapd_speaker;
break;
+ case CS420X_IMAC27_122:
+ spec->gpio_eapd_hp = 4; /* GPIO2 = headphones */
+ spec->gpio_eapd_speaker = 8; /* GPIO3 = speakers */
+ spec->gpio_mask = spec->gpio_dir =
+ spec->gpio_eapd_hp | spec->gpio_eapd_speaker;
+ break;
}
err = cs_parse_auto_config(codec);
@@ -1557,7 +1578,7 @@
.tlv = { .p = cs421x_speaker_boost_db_scale },
};
-static void cs421x_pinmux_init(struct hda_codec *codec)
+static void cs4210_pinmux_init(struct hda_codec *codec)
{
struct cs_spec *spec = codec->spec;
unsigned int def_conf, coef;
@@ -1602,10 +1623,7 @@
if (!cfg->speaker_outs)
continue;
if (get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP) {
-
- snd_hda_codec_write(codec, nid, 0,
- AC_VERB_SET_UNSOLICITED_ENABLE,
- AC_USRSP_EN | SPDIF_EVENT);
+ snd_hda_jack_detect_enable(codec, nid, SPDIF_EVENT);
spec->spdif_detect = 1;
}
}
@@ -1615,10 +1633,11 @@
{
struct cs_spec *spec = codec->spec;
- snd_hda_sequence_write(codec, cs421x_coef_init_verbs);
- snd_hda_sequence_write(codec, cs421x_coef_init_verbs_A1_silicon_fixes);
-
- cs421x_pinmux_init(codec);
+ if (spec->vendor_nid == CS4210_VENDOR_NID) {
+ snd_hda_sequence_write(codec, cs421x_coef_init_verbs);
+ snd_hda_sequence_write(codec, cs421x_coef_init_verbs_A1_silicon_fixes);
+ cs4210_pinmux_init(codec);
+ }
if (spec->gpio_mask) {
snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_MASK,
@@ -1632,6 +1651,7 @@
init_output(codec);
init_input(codec);
init_cs421x_digital(codec);
+ snd_hda_jack_report_sync(codec);
return 0;
}
@@ -1771,32 +1791,21 @@
struct auto_pin_cfg *cfg = &spec->autocfg;
struct snd_kcontrol *kctl;
int err;
- char *name = "HP/Speakers";
+ char *name = "Master";
fix_volume_caps(codec, dac);
- if (!spec->vmaster_sw) {
- err = add_vmaster(codec, dac);
- if (err < 0)
- return err;
- }
err = add_mute(codec, name, 0,
HDA_COMPOSE_AMP_VAL(dac, 3, 0, HDA_OUTPUT), 0, &kctl);
if (err < 0)
return err;
- err = snd_ctl_add_slave(spec->vmaster_sw, kctl);
- if (err < 0)
- return err;
err = add_volume(codec, name, 0,
HDA_COMPOSE_AMP_VAL(dac, 3, 0, HDA_OUTPUT), 0, &kctl);
if (err < 0)
return err;
- err = snd_ctl_add_slave(spec->vmaster_vol, kctl);
- if (err < 0)
- return err;
- if (cfg->speaker_outs) {
+ if (cfg->speaker_outs && (spec->vendor_nid == CS4210_VENDOR_NID)) {
err = snd_hda_ctl_add(codec, 0,
snd_ctl_new1(&cs421x_speaker_bost_ctl, codec));
if (err < 0)
@@ -1807,6 +1816,7 @@
static int cs421x_build_controls(struct hda_codec *codec)
{
+ struct cs_spec *spec = codec->spec;
int err;
err = build_cs421x_output(codec);
@@ -1818,12 +1828,20 @@
err = build_digital_output(codec);
if (err < 0)
return err;
- return cs421x_init(codec);
+ err = cs421x_init(codec);
+ if (err < 0)
+ return err;
+
+ err = snd_hda_jack_add_kctls(codec, &spec->autocfg);
+ if (err < 0)
+ return err;
+
+ return 0;
}
static void cs421x_unsol_event(struct hda_codec *codec, unsigned int res)
{
- switch ((res >> 26) & 0x3f) {
+ switch (snd_hda_jack_get_action(codec, res >> 26)) {
case HP_EVENT:
case SPDIF_EVENT:
cs_automute(codec);
@@ -1833,6 +1851,7 @@
cs_automic(codec);
break;
}
+ snd_hda_jack_report_sync(codec);
}
static int parse_cs421x_input(struct hda_codec *codec)
@@ -1883,6 +1902,7 @@
*/
static int cs421x_suspend(struct hda_codec *codec, pm_message_t state)
{
+ struct cs_spec *spec = codec->spec;
unsigned int coef;
snd_hda_shutup_pins(codec);
@@ -1892,15 +1912,17 @@
snd_hda_codec_write(codec, CS4210_ADC_NID, 0,
AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
- coef = cs_vendor_coef_get(codec, CS421X_IDX_DEV_CFG);
- coef |= 0x0004; /* PDREF */
- cs_vendor_coef_set(codec, CS421X_IDX_DEV_CFG, coef);
+ if (spec->vendor_nid == CS4210_VENDOR_NID) {
+ coef = cs_vendor_coef_get(codec, CS421X_IDX_DEV_CFG);
+ coef |= 0x0004; /* PDREF */
+ cs_vendor_coef_set(codec, CS421X_IDX_DEV_CFG, coef);
+ }
return 0;
}
#endif
-static struct hda_codec_ops cs4210_patch_ops = {
+static struct hda_codec_ops cs421x_patch_ops = {
.build_controls = cs421x_build_controls,
.build_pcms = cs_build_pcms,
.init = cs421x_init,
@@ -1911,7 +1933,7 @@
#endif
};
-static int patch_cs421x(struct hda_codec *codec)
+static int patch_cs4210(struct hda_codec *codec)
{
struct cs_spec *spec;
int err;
@@ -1921,7 +1943,7 @@
return -ENOMEM;
codec->spec = spec;
- spec->vendor_nid = CS421X_VENDOR_NID;
+ spec->vendor_nid = CS4210_VENDOR_NID;
spec->board_config =
snd_hda_check_board_config(codec, CS421X_MODELS,
@@ -1949,13 +1971,13 @@
is auto-parsed. If GPIO or SENSE_B is forced, DMIC input
is disabled.
*/
- cs421x_pinmux_init(codec);
+ cs4210_pinmux_init(codec);
err = cs421x_parse_auto_config(codec);
if (err < 0)
goto error;
- codec->patch_ops = cs4210_patch_ops;
+ codec->patch_ops = cs421x_patch_ops;
return 0;
@@ -1965,6 +1987,31 @@
return err;
}
+static int patch_cs4213(struct hda_codec *codec)
+{
+ struct cs_spec *spec;
+ int err;
+
+ spec = kzalloc(sizeof(*spec), GFP_KERNEL);
+ if (!spec)
+ return -ENOMEM;
+ codec->spec = spec;
+
+ spec->vendor_nid = CS4213_VENDOR_NID;
+
+ err = cs421x_parse_auto_config(codec);
+ if (err < 0)
+ goto error;
+
+ codec->patch_ops = cs421x_patch_ops;
+ return 0;
+
+ error:
+ kfree(codec->spec);
+ codec->spec = NULL;
+ return err;
+}
+
/*
* patch entries
@@ -1972,13 +2019,15 @@
static const struct hda_codec_preset snd_hda_preset_cirrus[] = {
{ .id = 0x10134206, .name = "CS4206", .patch = patch_cs420x },
{ .id = 0x10134207, .name = "CS4207", .patch = patch_cs420x },
- { .id = 0x10134210, .name = "CS4210", .patch = patch_cs421x },
+ { .id = 0x10134210, .name = "CS4210", .patch = patch_cs4210 },
+ { .id = 0x10134213, .name = "CS4213", .patch = patch_cs4213 },
{} /* terminator */
};
MODULE_ALIAS("snd-hda-codec-id:10134206");
MODULE_ALIAS("snd-hda-codec-id:10134207");
MODULE_ALIAS("snd-hda-codec-id:10134210");
+MODULE_ALIAS("snd-hda-codec-id:10134213");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Cirrus Logic HD-audio codec");
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index 0de2119..8a32a69 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -31,6 +31,7 @@
#include "hda_codec.h"
#include "hda_local.h"
#include "hda_beep.h"
+#include "hda_jack.h"
#define CXT_PIN_DIR_IN 0x00
#define CXT_PIN_DIR_OUT 0x01
@@ -415,40 +416,6 @@
&spec->cur_mux[adc_idx]);
}
-static int conexant_init_jacks(struct hda_codec *codec)
-{
-#ifdef CONFIG_SND_HDA_INPUT_JACK
- struct conexant_spec *spec = codec->spec;
- int i;
-
- for (i = 0; i < spec->num_init_verbs; i++) {
- const struct hda_verb *hv;
-
- hv = spec->init_verbs[i];
- while (hv->nid) {
- int err = 0;
- switch (hv->param ^ AC_USRSP_EN) {
- case CONEXANT_HP_EVENT:
- err = snd_hda_input_jack_add(codec, hv->nid,
- SND_JACK_HEADPHONE, NULL);
- snd_hda_input_jack_report(codec, hv->nid);
- break;
- case CXT5051_PORTC_EVENT:
- case CONEXANT_MIC_EVENT:
- err = snd_hda_input_jack_add(codec, hv->nid,
- SND_JACK_MICROPHONE, NULL);
- snd_hda_input_jack_report(codec, hv->nid);
- break;
- }
- if (err < 0)
- return err;
- ++hv;
- }
- }
-#endif /* CONFIG_SND_HDA_INPUT_JACK */
- return 0;
-}
-
static void conexant_set_power(struct hda_codec *codec, hda_nid_t fg,
unsigned int power_state)
{
@@ -474,7 +441,6 @@
static void conexant_free(struct hda_codec *codec)
{
- snd_hda_input_jack_free(codec);
snd_hda_detach_beep_device(codec);
kfree(codec->spec);
}
@@ -1120,8 +1086,6 @@
static const struct snd_pci_quirk cxt5045_cfg_tbl[] = {
SND_PCI_QUIRK(0x103c, 0x30d5, "HP 530", CXT5045_LAPTOP_HP530),
- SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP DV Series",
- CXT5045_LAPTOP_HPSENSE),
SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba P105", CXT5045_LAPTOP_MICSENSE),
SND_PCI_QUIRK(0x152d, 0x0753, "Benq R55E", CXT5045_BENQ),
SND_PCI_QUIRK(0x1734, 0x10ad, "Fujitsu Si1520", CXT5045_LAPTOP_MICSENSE),
@@ -1750,7 +1714,6 @@
static void cxt5051_hp_unsol_event(struct hda_codec *codec,
unsigned int res)
{
- int nid = (res & AC_UNSOL_RES_SUBTAG) >> 20;
switch (res >> 26) {
case CONEXANT_HP_EVENT:
cxt5051_hp_automute(codec);
@@ -1762,7 +1725,6 @@
cxt5051_portc_automic(codec);
break;
}
- snd_hda_input_jack_report(codec, nid);
}
static const struct snd_kcontrol_new cxt5051_playback_mixers[] = {
@@ -1901,8 +1863,6 @@
snd_hda_codec_write(codec, nid, 0,
AC_VERB_SET_UNSOLICITED_ENABLE,
AC_USRSP_EN | event);
- snd_hda_input_jack_add(codec, nid, SND_JACK_MICROPHONE, NULL);
- snd_hda_input_jack_report(codec, nid);
}
static const struct hda_verb cxt5051_ideapad_init_verbs[] = {
@@ -1918,7 +1878,6 @@
struct conexant_spec *spec = codec->spec;
conexant_init(codec);
- conexant_init_jacks(codec);
if (spec->auto_mic & AUTO_MIC_PORTB)
cxt5051_init_mic_port(codec, 0x17, CXT5051_PORTB_EVENT);
@@ -3450,7 +3409,6 @@
hda_nid_t nid = pins[i];
if (!nid || !is_jack_detectable(codec, nid))
break;
- snd_hda_input_jack_report(codec, nid);
present |= snd_hda_jack_detect(codec, nid);
}
return present;
@@ -3755,8 +3713,7 @@
static void cx_auto_unsol_event(struct hda_codec *codec, unsigned int res)
{
- int nid = (res & AC_UNSOL_RES_SUBTAG) >> 20;
- switch (res >> 26) {
+ switch (snd_hda_jack_get_action(codec, res >> 26)) {
case CONEXANT_HP_EVENT:
cx_auto_hp_automute(codec);
break;
@@ -3765,9 +3722,9 @@
break;
case CONEXANT_MIC_EVENT:
cx_auto_automic(codec);
- snd_hda_input_jack_report(codec, nid);
break;
}
+ snd_hda_jack_report_sync(codec);
}
/* check whether the pin config is suitable for auto-mic switching;
@@ -3979,13 +3936,11 @@
}
static void enable_unsol_pins(struct hda_codec *codec, int num_pins,
- hda_nid_t *pins, unsigned int tag)
+ hda_nid_t *pins, unsigned int action)
{
int i;
for (i = 0; i < num_pins; i++)
- snd_hda_codec_write(codec, pins[i], 0,
- AC_VERB_SET_UNSOLICITED_ENABLE,
- AC_USRSP_EN | tag);
+ snd_hda_jack_detect_enable(codec, pins[i], action);
}
static void cx_auto_init_output(struct hda_codec *codec)
@@ -4060,16 +4015,14 @@
if (spec->auto_mic) {
if (spec->auto_mic_ext >= 0) {
- snd_hda_codec_write(codec,
- cfg->inputs[spec->auto_mic_ext].pin, 0,
- AC_VERB_SET_UNSOLICITED_ENABLE,
- AC_USRSP_EN | CONEXANT_MIC_EVENT);
+ snd_hda_jack_detect_enable(codec,
+ cfg->inputs[spec->auto_mic_ext].pin,
+ CONEXANT_MIC_EVENT);
}
if (spec->auto_mic_dock >= 0) {
- snd_hda_codec_write(codec,
- cfg->inputs[spec->auto_mic_dock].pin, 0,
- AC_VERB_SET_UNSOLICITED_ENABLE,
- AC_USRSP_EN | CONEXANT_MIC_EVENT);
+ snd_hda_jack_detect_enable(codec,
+ cfg->inputs[spec->auto_mic_dock].pin,
+ CONEXANT_MIC_EVENT);
}
cx_auto_automic(codec);
} else {
@@ -4097,6 +4050,7 @@
cx_auto_init_output(codec);
cx_auto_init_input(codec);
cx_auto_init_digital(codec);
+ snd_hda_jack_report_sync(codec);
return 0;
}
@@ -4326,6 +4280,7 @@
static int cx_auto_build_controls(struct hda_codec *codec)
{
+ struct conexant_spec *spec = codec->spec;
int err;
err = cx_auto_build_output_controls(codec);
@@ -4334,7 +4289,13 @@
err = cx_auto_build_input_controls(codec);
if (err < 0)
return err;
- return conexant_build_controls(codec);
+ err = conexant_build_controls(codec);
+ if (err < 0)
+ return err;
+ err = snd_hda_jack_add_kctls(codec, &spec->autocfg);
+ if (err < 0)
+ return err;
+ return 0;
}
static int cx_auto_search_adcs(struct hda_codec *codec)
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
index c505fd5..1168ebd 100644
--- a/sound/pci/hda/patch_hdmi.c
+++ b/sound/pci/hda/patch_hdmi.c
@@ -36,6 +36,7 @@
#include <sound/jack.h>
#include "hda_codec.h"
#include "hda_local.h"
+#include "hda_jack.h"
static bool static_hdmi_pcm;
module_param(static_hdmi_pcm, bool, 0644);
@@ -48,8 +49,8 @@
*
* The HDA correspondence of pipes/ports are converter/pin nodes.
*/
-#define MAX_HDMI_CVTS 4
-#define MAX_HDMI_PINS 4
+#define MAX_HDMI_CVTS 8
+#define MAX_HDMI_PINS 8
struct hdmi_spec_per_cvt {
hda_nid_t cvt_nid;
@@ -754,10 +755,18 @@
static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res)
{
struct hdmi_spec *spec = codec->spec;
- int pin_nid = res >> AC_UNSOL_RES_TAG_SHIFT;
+ int tag = res >> AC_UNSOL_RES_TAG_SHIFT;
+ int pin_nid;
int pd = !!(res & AC_UNSOL_RES_PD);
int eldv = !!(res & AC_UNSOL_RES_ELDV);
int pin_idx;
+ struct hda_jack_tbl *jack;
+
+ jack = snd_hda_jack_tbl_get_from_tag(codec, tag);
+ if (!jack)
+ return;
+ pin_nid = jack->nid;
+ jack->jack_dirty = 1;
printk(KERN_INFO
"HDMI hot plug event: Codec=%d Pin=%d Presence_Detect=%d ELD_Valid=%d\n",
@@ -768,6 +777,7 @@
return;
hdmi_present_sense(&spec->pins[pin_idx], 1);
+ snd_hda_jack_report_sync(codec);
}
static void hdmi_non_intrinsic_event(struct hda_codec *codec, unsigned int res)
@@ -795,11 +805,10 @@
static void hdmi_unsol_event(struct hda_codec *codec, unsigned int res)
{
- struct hdmi_spec *spec = codec->spec;
int tag = res >> AC_UNSOL_RES_TAG_SHIFT;
int subtag = (res & AC_UNSOL_RES_SUBTAG) >> AC_UNSOL_RES_SUBTAG_SHIFT;
- if (pin_nid_to_pin_index(spec, tag) < 0) {
+ if (!snd_hda_jack_tbl_get_from_tag(codec, tag)) {
snd_printd(KERN_INFO "Unexpected HDMI event tag 0x%x\n", tag);
return;
}
@@ -996,8 +1005,6 @@
msecs_to_jiffies(300));
}
}
-
- snd_hda_input_jack_report(codec, pin_nid);
}
static void hdmi_repoll_eld(struct work_struct *work)
@@ -1126,12 +1133,12 @@
/*
*/
-static char *generic_hdmi_pcm_names[MAX_HDMI_PINS] = {
- "HDMI 0",
- "HDMI 1",
- "HDMI 2",
- "HDMI 3",
-};
+static char *get_hdmi_pcm_name(int idx)
+{
+ static char names[MAX_HDMI_PINS][8];
+ sprintf(&names[idx][0], "HDMI %d", idx);
+ return &names[idx][0];
+}
/*
* HDMI callbacks
@@ -1209,7 +1216,7 @@
struct hda_pcm_stream *pstr;
info = &spec->pcm_rec[pin_idx];
- info->name = generic_hdmi_pcm_names[pin_idx];
+ info->name = get_hdmi_pcm_name(pin_idx);
info->pcm_type = HDA_PCM_TYPE_HDMI;
pstr = &info->stream[SNDRV_PCM_STREAM_PLAYBACK];
@@ -1226,21 +1233,15 @@
static int generic_hdmi_build_jack(struct hda_codec *codec, int pin_idx)
{
- int err;
- char hdmi_str[32];
+ char hdmi_str[32] = "HDMI/DP";
struct hdmi_spec *spec = codec->spec;
struct hdmi_spec_per_pin *per_pin = &spec->pins[pin_idx];
int pcmdev = spec->pcm_rec[pin_idx].device;
- snprintf(hdmi_str, sizeof(hdmi_str), "HDMI/DP,pcm=%d", pcmdev);
+ if (pcmdev > 0)
+ sprintf(hdmi_str + strlen(hdmi_str), ",pcm=%d", pcmdev);
- err = snd_hda_input_jack_add(codec, per_pin->pin_nid,
- SND_JACK_VIDEOOUT, pcmdev > 0 ? hdmi_str : NULL);
- if (err < 0)
- return err;
-
- hdmi_present_sense(per_pin, 0);
- return 0;
+ return snd_hda_jack_add_kctl(codec, per_pin->pin_nid, hdmi_str, 0);
}
static int generic_hdmi_build_controls(struct hda_codec *codec)
@@ -1270,6 +1271,8 @@
if (err < 0)
return err;
+
+ hdmi_present_sense(per_pin, 0);
}
return 0;
@@ -1286,14 +1289,13 @@
struct hdmi_eld *eld = &per_pin->sink_eld;
hdmi_init_pin(codec, pin_nid);
- snd_hda_codec_write(codec, pin_nid, 0,
- AC_VERB_SET_UNSOLICITED_ENABLE,
- AC_USRSP_EN | pin_nid);
+ snd_hda_jack_detect_enable(codec, pin_nid, pin_nid);
per_pin->codec = codec;
INIT_DELAYED_WORK(&per_pin->work, hdmi_repoll_eld);
snd_hda_eld_proc_new(codec, eld, pin_idx);
}
+ snd_hda_jack_report_sync(codec);
return 0;
}
@@ -1309,7 +1311,6 @@
cancel_delayed_work(&per_pin->work);
snd_hda_eld_proc_free(codec, eld);
}
- snd_hda_input_jack_free(codec);
flush_workqueue(codec->bus->workq);
kfree(spec);
@@ -1364,7 +1365,7 @@
chans = get_wcaps(codec, spec->cvts[i].cvt_nid);
chans = get_wcaps_channels(chans);
- info->name = generic_hdmi_pcm_names[i];
+ info->name = get_hdmi_pcm_name(i);
info->pcm_type = HDA_PCM_TYPE_HDMI;
pstr = &info->stream[SNDRV_PCM_STREAM_PLAYBACK];
snd_BUG_ON(!spec->pcm_playback);
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 1d07e8f..5e82acf 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -33,6 +33,7 @@
#include "hda_codec.h"
#include "hda_local.h"
#include "hda_beep.h"
+#include "hda_jack.h"
/* unsol event tags */
#define ALC_FRONT_EVENT 0x01
@@ -183,6 +184,8 @@
unsigned int single_input_src:1;
unsigned int vol_in_capsrc:1; /* use capsrc volume (ADC has no vol) */
unsigned int parse_flags; /* passed to snd_hda_parse_pin_defcfg() */
+ unsigned int shared_mic_hp:1; /* HP/Mic-in sharing */
+ unsigned int use_jack_tbl:1; /* 1 for model=auto */
/* auto-mute control */
int automute_mode;
@@ -283,6 +286,8 @@
spec->capsrc_nids[idx] : spec->adc_nids[idx];
}
+static void call_update_outputs(struct hda_codec *codec);
+
/* select the given imux item; either unmute exclusively or select the route */
static int alc_mux_select(struct hda_codec *codec, unsigned int adc_idx,
unsigned int idx, bool force)
@@ -306,6 +311,19 @@
return 0;
spec->cur_mux[adc_idx] = idx;
+ /* for shared I/O, change the pin-control accordingly */
+ if (spec->shared_mic_hp) {
+ /* NOTE: this assumes that there are only two inputs, the
+ * first is the real internal mic and the second is HP jack.
+ */
+ snd_hda_codec_write(codec, spec->autocfg.inputs[1].pin, 0,
+ AC_VERB_SET_PIN_WIDGET_CONTROL,
+ spec->cur_mux[adc_idx] ?
+ PIN_VREF80 : PIN_HP);
+ spec->automute_speaker = !spec->cur_mux[adc_idx];
+ call_update_outputs(codec);
+ }
+
if (spec->dyn_adc_switch) {
alc_dyn_adc_pcm_resetup(codec, idx);
adc_idx = spec->dyn_adc_idx[idx];
@@ -450,46 +468,6 @@
}
/*
- * Jack-reporting via input-jack layer
- */
-
-/* initialization of jacks; currently checks only a few known pins */
-static int alc_init_jacks(struct hda_codec *codec)
-{
-#ifdef CONFIG_SND_HDA_INPUT_JACK
- struct alc_spec *spec = codec->spec;
- int err;
- unsigned int hp_nid = spec->autocfg.hp_pins[0];
- unsigned int mic_nid = spec->ext_mic_pin;
- unsigned int dock_nid = spec->dock_mic_pin;
-
- if (hp_nid) {
- err = snd_hda_input_jack_add(codec, hp_nid,
- SND_JACK_HEADPHONE, NULL);
- if (err < 0)
- return err;
- snd_hda_input_jack_report(codec, hp_nid);
- }
-
- if (mic_nid) {
- err = snd_hda_input_jack_add(codec, mic_nid,
- SND_JACK_MICROPHONE, NULL);
- if (err < 0)
- return err;
- snd_hda_input_jack_report(codec, mic_nid);
- }
- if (dock_nid) {
- err = snd_hda_input_jack_add(codec, dock_nid,
- SND_JACK_MICROPHONE, NULL);
- if (err < 0)
- return err;
- snd_hda_input_jack_report(codec, dock_nid);
- }
-#endif /* CONFIG_SND_HDA_INPUT_JACK */
- return 0;
-}
-
-/*
* Jack detections for HP auto-mute and mic-switch
*/
@@ -502,7 +480,6 @@
hda_nid_t nid = pins[i];
if (!nid)
break;
- snd_hda_input_jack_report(codec, nid);
present |= snd_hda_jack_detect(codec, nid);
}
return present;
@@ -554,7 +531,8 @@
* in general, HP pins/amps control should be enabled in all cases,
* but currently set only for master_mute, just to be safe
*/
- do_automute(codec, ARRAY_SIZE(spec->autocfg.hp_pins),
+ if (!spec->shared_mic_hp) /* don't change HP-pin when shared with mic */
+ do_automute(codec, ARRAY_SIZE(spec->autocfg.hp_pins),
spec->autocfg.hp_pins, spec->master_mute, true);
if (!spec->automute_speaker)
@@ -641,19 +619,18 @@
alc_mux_select(codec, 0, spec->dock_mic_idx, false);
else
alc_mux_select(codec, 0, spec->int_mic_idx, false);
-
- snd_hda_input_jack_report(codec, pins[spec->ext_mic_idx]);
- if (spec->dock_mic_idx >= 0)
- snd_hda_input_jack_report(codec, pins[spec->dock_mic_idx]);
}
/* unsolicited event for HP jack sensing */
static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
{
+ struct alc_spec *spec = codec->spec;
if (codec->vendor_id == 0x10ec0880)
res >>= 28;
else
res >>= 26;
+ if (spec->use_jack_tbl)
+ res = snd_hda_jack_get_action(codec, res);
switch (res) {
case ALC_HP_EVENT:
alc_hp_automute(codec);
@@ -665,6 +642,7 @@
alc_mic_automute(codec);
break;
}
+ snd_hda_jack_report_sync(codec);
}
/* call init functions of standard auto-mute helpers */
@@ -954,9 +932,7 @@
continue;
snd_printdd("realtek: Enable HP auto-muting on NID 0x%x\n",
nid);
- snd_hda_codec_write_cache(codec, nid, 0,
- AC_VERB_SET_UNSOLICITED_ENABLE,
- AC_USRSP_EN | ALC_HP_EVENT);
+ snd_hda_jack_detect_enable(codec, nid, ALC_HP_EVENT);
spec->detect_hp = 1;
}
@@ -968,9 +944,8 @@
continue;
snd_printdd("realtek: Enable Line-Out "
"auto-muting on NID 0x%x\n", nid);
- snd_hda_codec_write_cache(codec, nid, 0,
- AC_VERB_SET_UNSOLICITED_ENABLE,
- AC_USRSP_EN | ALC_FRONT_EVENT);
+ snd_hda_jack_detect_enable(codec, nid,
+ ALC_FRONT_EVENT);
spec->detect_lo = 1;
}
spec->automute_lo_possible = spec->detect_hp;
@@ -1109,13 +1084,10 @@
return false; /* no corresponding imux */
}
- snd_hda_codec_write_cache(codec, spec->ext_mic_pin, 0,
- AC_VERB_SET_UNSOLICITED_ENABLE,
- AC_USRSP_EN | ALC_MIC_EVENT);
+ snd_hda_jack_detect_enable(codec, spec->ext_mic_pin, ALC_MIC_EVENT);
if (spec->dock_mic_pin)
- snd_hda_codec_write_cache(codec, spec->dock_mic_pin, 0,
- AC_VERB_SET_UNSOLICITED_ENABLE,
- AC_USRSP_EN | ALC_MIC_EVENT);
+ snd_hda_jack_detect_enable(codec, spec->dock_mic_pin,
+ ALC_MIC_EVENT);
spec->auto_mic_valid_imux = 1;
spec->auto_mic = 1;
@@ -1133,6 +1105,9 @@
hda_nid_t fixed, ext, dock;
int i;
+ if (spec->shared_mic_hp)
+ return; /* no auto-mic for the shared I/O */
+
spec->ext_mic_idx = spec->int_mic_idx = spec->dock_mic_idx = -1;
fixed = ext = dock = 0;
@@ -1524,6 +1499,7 @@
const struct alc_fixup *fixlist)
{
struct alc_spec *spec = codec->spec;
+ const struct snd_pci_quirk *q;
int id = -1;
const char *name = NULL;
@@ -1538,14 +1514,27 @@
}
}
if (id < 0) {
- quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
- if (quirk) {
- id = quirk->value;
+ q = snd_pci_quirk_lookup(codec->bus->pci, quirk);
+ if (q) {
+ id = q->value;
#ifdef CONFIG_SND_DEBUG_VERBOSE
- name = quirk->name;
+ name = q->name;
#endif
}
}
+ if (id < 0) {
+ for (q = quirk; q->subvendor; q++) {
+ unsigned int vendorid =
+ q->subdevice | (q->subvendor << 16);
+ if (vendorid == codec->subsystem_id) {
+ id = q->value;
+#ifdef CONFIG_SND_DEBUG_VERBOSE
+ name = q->name;
+#endif
+ break;
+ }
+ }
+ }
spec->fixup_id = id;
if (id >= 0) {
@@ -2040,6 +2029,10 @@
alc_free_kctls(codec); /* no longer needed */
+ err = snd_hda_jack_add_kctls(codec, &spec->autocfg);
+ if (err < 0)
+ return err;
+
return 0;
}
@@ -2067,6 +2060,8 @@
alc_apply_fixup(codec, ALC_FIXUP_ACT_INIT);
+ snd_hda_jack_report_sync(codec);
+
hda_call_check_power_status(codec, 0x01);
return 0;
}
@@ -2450,7 +2445,6 @@
return;
alc_shutup(codec);
- snd_hda_input_jack_free(codec);
alc_free_kctls(codec);
alc_free_bind_ctls(codec);
kfree(spec);
@@ -2685,6 +2679,9 @@
int max_nums = ARRAY_SIZE(spec->private_adc_nids);
int i, nums = 0;
+ if (spec->shared_mic_hp)
+ max_nums = 1; /* no multi streams with the shared HP/mic */
+
nid = codec->start_nid;
for (i = 0; i < codec->num_nodes; i++, nid++) {
hda_nid_t src;
@@ -2747,6 +2744,8 @@
continue;
label = hda_get_autocfg_input_label(codec, cfg, i);
+ if (spec->shared_mic_hp && !strcmp(label, "Misc"))
+ label = "Headphone Mic";
if (prev_label && !strcmp(label, prev_label))
type_idx++;
else
@@ -2781,6 +2780,39 @@
return 0;
}
+/* create a shared input with the headphone out */
+static int alc_auto_create_shared_input(struct hda_codec *codec)
+{
+ struct alc_spec *spec = codec->spec;
+ struct auto_pin_cfg *cfg = &spec->autocfg;
+ unsigned int defcfg;
+ hda_nid_t nid;
+
+ /* only one internal input pin? */
+ if (cfg->num_inputs != 1)
+ return 0;
+ defcfg = snd_hda_codec_get_pincfg(codec, cfg->inputs[0].pin);
+ if (snd_hda_get_input_pin_attr(defcfg) != INPUT_PIN_ATTR_INT)
+ return 0;
+
+ if (cfg->hp_outs == 1 && cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
+ nid = cfg->hp_pins[0]; /* OK, we have a single HP-out */
+ else if (cfg->line_outs == 1 && cfg->line_out_type == AUTO_PIN_HP_OUT)
+ nid = cfg->line_out_pins[0]; /* OK, we have a single line-out */
+ else
+ return 0; /* both not available */
+
+ if (!(snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_IN))
+ return 0; /* no input */
+
+ cfg->inputs[1].pin = nid;
+ cfg->inputs[1].type = AUTO_PIN_MIC;
+ cfg->num_inputs = 2;
+ spec->shared_mic_hp = 1;
+ snd_printdd("realtek: Enable shared I/O jack on NID 0x%x\n", nid);
+ return 0;
+}
+
static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
unsigned int pin_type)
{
@@ -2919,6 +2951,23 @@
return 0;
}
+/* check whether the DAC is reachable from the pin */
+static bool alc_auto_is_dac_reachable(struct hda_codec *codec,
+ hda_nid_t pin, hda_nid_t dac)
+{
+ hda_nid_t srcs[5];
+ int i, num;
+
+ pin = alc_go_down_to_selector(codec, pin);
+ num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs));
+ for (i = 0; i < num; i++) {
+ hda_nid_t nid = alc_auto_mix_to_dac(codec, srcs[i]);
+ if (nid == dac)
+ return true;
+ }
+ return false;
+}
+
static hda_nid_t get_dac_if_single(struct hda_codec *codec, hda_nid_t pin)
{
hda_nid_t sel = alc_go_down_to_selector(codec, pin);
@@ -2949,13 +2998,17 @@
}
static int alc_auto_fill_multi_ios(struct hda_codec *codec,
- unsigned int location);
+ unsigned int location, int offset);
+static hda_nid_t alc_look_for_out_vol_nid(struct hda_codec *codec,
+ hda_nid_t pin, hda_nid_t dac);
/* fill in the dac_nids table from the parsed pin configuration */
static int alc_auto_fill_dac_nids(struct hda_codec *codec)
{
struct alc_spec *spec = codec->spec;
struct auto_pin_cfg *cfg = &spec->autocfg;
+ unsigned int location, defcfg;
+ int num_pins;
bool redone = false;
int i;
@@ -3010,13 +3063,10 @@
if (cfg->line_outs == 1 && cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
/* try to fill multi-io first */
- unsigned int location, defcfg;
- int num_pins;
-
defcfg = snd_hda_codec_get_pincfg(codec, cfg->line_out_pins[0]);
location = get_defcfg_location(defcfg);
- num_pins = alc_auto_fill_multi_ios(codec, location);
+ num_pins = alc_auto_fill_multi_ios(codec, location, 0);
if (num_pins > 0) {
spec->multi_ios = num_pins;
spec->ext_channel_count = 2;
@@ -3050,6 +3100,25 @@
}
}
+ if (!spec->multi_ios &&
+ cfg->line_out_type == AUTO_PIN_SPEAKER_OUT &&
+ cfg->hp_outs) {
+ /* try multi-ios with HP + inputs */
+ defcfg = snd_hda_codec_get_pincfg(codec, cfg->hp_pins[0]);
+ location = get_defcfg_location(defcfg);
+
+ num_pins = alc_auto_fill_multi_ios(codec, location, 1);
+ if (num_pins > 0) {
+ spec->multi_ios = num_pins;
+ spec->ext_channel_count = 2;
+ spec->multiout.num_dacs = num_pins + 1;
+ }
+ }
+
+ if (cfg->line_out_pins[0])
+ spec->vmaster_nid =
+ alc_look_for_out_vol_nid(codec, cfg->line_out_pins[0],
+ spec->multiout.dac_nids[0]);
return 0;
}
@@ -3081,8 +3150,15 @@
val);
}
-#define alc_auto_add_stereo_vol(codec, pfx, cidx, nid) \
- alc_auto_add_vol_ctl(codec, pfx, cidx, nid, 3)
+static int alc_auto_add_stereo_vol(struct hda_codec *codec,
+ const char *pfx, int cidx,
+ hda_nid_t nid)
+{
+ int chs = 1;
+ if (get_wcaps(codec, nid) & AC_WCAP_STEREO)
+ chs = 3;
+ return alc_auto_add_vol_ctl(codec, pfx, cidx, nid, chs);
+}
/* create a mute-switch for the given mixer widget;
* if it has multiple sources (e.g. DAC and loopback), create a bind-mute
@@ -3114,8 +3190,14 @@
return __add_pb_sw_ctrl(codec->spec, type, pfx, cidx, val);
}
-#define alc_auto_add_stereo_sw(codec, pfx, cidx, nid) \
- alc_auto_add_sw_ctl(codec, pfx, cidx, nid, 3)
+static int alc_auto_add_stereo_sw(struct hda_codec *codec, const char *pfx,
+ int cidx, hda_nid_t nid)
+{
+ int chs = 1;
+ if (get_wcaps(codec, nid) & AC_WCAP_STEREO)
+ chs = 3;
+ return alc_auto_add_sw_ctl(codec, pfx, cidx, nid, chs);
+}
static hda_nid_t alc_look_for_out_mute_nid(struct hda_codec *codec,
hda_nid_t pin, hda_nid_t dac)
@@ -3441,17 +3523,19 @@
* multi-io helper
*/
static int alc_auto_fill_multi_ios(struct hda_codec *codec,
- unsigned int location)
+ unsigned int location,
+ int offset)
{
struct alc_spec *spec = codec->spec;
struct auto_pin_cfg *cfg = &spec->autocfg;
hda_nid_t prime_dac = spec->private_dac_nids[0];
- int type, i, num_pins = 0;
+ int type, i, dacs, num_pins = 0;
+ dacs = spec->multiout.num_dacs;
for (type = AUTO_PIN_LINE_IN; type >= AUTO_PIN_MIC; type--) {
for (i = 0; i < cfg->num_inputs; i++) {
hda_nid_t nid = cfg->inputs[i].pin;
- hda_nid_t dac;
+ hda_nid_t dac = 0;
unsigned int defcfg, caps;
if (cfg->inputs[i].type != type)
continue;
@@ -3463,7 +3547,13 @@
caps = snd_hda_query_pin_caps(codec, nid);
if (!(caps & AC_PINCAP_OUT))
continue;
- dac = alc_auto_look_for_dac(codec, nid);
+ if (offset && offset + num_pins < dacs) {
+ dac = spec->private_dac_nids[offset + num_pins];
+ if (!alc_auto_is_dac_reachable(codec, nid, dac))
+ dac = 0;
+ }
+ if (!dac)
+ dac = alc_auto_look_for_dac(codec, nid);
if (!dac)
continue;
spec->multi_io[num_pins].pin = nid;
@@ -3472,11 +3562,11 @@
spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
}
}
- spec->multiout.num_dacs = 1;
+ spec->multiout.num_dacs = dacs;
if (num_pins < 2) {
/* clear up again */
- memset(spec->private_dac_nids, 0,
- sizeof(spec->private_dac_nids));
+ memset(spec->private_dac_nids + dacs, 0,
+ sizeof(hda_nid_t) * (AUTO_CFG_MAX_OUTS - dacs));
spec->private_dac_nids[0] = prime_dac;
return 0;
}
@@ -3700,6 +3790,8 @@
char boost_label[32];
label = hda_get_autocfg_input_label(codec, cfg, i);
+ if (spec->shared_mic_hp && !strcmp(label, "Misc"))
+ label = "Headphone Mic";
if (prev_label && !strcmp(label, prev_label))
type_idx++;
else
@@ -3812,6 +3904,7 @@
static void alc_auto_init_std(struct hda_codec *codec)
{
struct alc_spec *spec = codec->spec;
+ spec->use_jack_tbl = 1;
alc_auto_init_multi_out(codec);
alc_auto_init_extra_out(codec);
alc_auto_init_analog_input(codec);
@@ -3904,6 +3997,9 @@
err = alc_auto_create_speaker_out(codec);
if (err < 0)
return err;
+ err = alc_auto_create_shared_input(codec);
+ if (err < 0)
+ return err;
err = alc_auto_create_input_ctls(codec);
if (err < 0)
return err;
@@ -3951,6 +4047,37 @@
#endif
/*
+ * ALC880 fix-ups
+ */
+enum {
+ ALC880_FIXUP_GPIO2,
+ ALC880_FIXUP_MEDION_RIM,
+};
+
+static const struct alc_fixup alc880_fixups[] = {
+ [ALC880_FIXUP_GPIO2] = {
+ .type = ALC_FIXUP_VERBS,
+ .v.verbs = alc_gpio2_init_verbs,
+ },
+ [ALC880_FIXUP_MEDION_RIM] = {
+ .type = ALC_FIXUP_VERBS,
+ .v.verbs = (const struct hda_verb[]) {
+ { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
+ { 0x20, AC_VERB_SET_PROC_COEF, 0x3060 },
+ { }
+ },
+ .chained = true,
+ .chain_id = ALC880_FIXUP_GPIO2,
+ },
+};
+
+static const struct snd_pci_quirk alc880_fixup_tbl[] = {
+ SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_FIXUP_MEDION_RIM),
+ {}
+};
+
+
+/*
* board setups
*/
#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
@@ -3996,6 +4123,11 @@
}
if (board_config == ALC_MODEL_AUTO) {
+ alc_pick_fixup(codec, NULL, alc880_fixup_tbl, alc880_fixups);
+ alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
+ }
+
+ if (board_config == ALC_MODEL_AUTO) {
/* automatic parse from the BIOS config */
err = alc880_parse_auto_config(codec);
if (err < 0)
@@ -4010,8 +4142,10 @@
#endif
}
- if (board_config != ALC_MODEL_AUTO)
+ if (board_config != ALC_MODEL_AUTO) {
+ spec->vmaster_nid = 0x0c;
setup_preset(codec, &alc880_presets[board_config]);
+ }
if (!spec->no_analog && !spec->adc_nids) {
alc_auto_fill_adc_caps(codec);
@@ -4029,7 +4163,7 @@
set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
}
- spec->vmaster_nid = 0x0c;
+ alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
codec->patch_ops = alc_patch_ops;
if (board_config == ALC_MODEL_AUTO)
@@ -4137,8 +4271,10 @@
#endif
}
- if (board_config != ALC_MODEL_AUTO)
+ if (board_config != ALC_MODEL_AUTO) {
setup_preset(codec, &alc260_presets[board_config]);
+ spec->vmaster_nid = 0x08;
+ }
if (!spec->no_analog && !spec->adc_nids) {
alc_auto_fill_adc_caps(codec);
@@ -4158,8 +4294,6 @@
alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
- spec->vmaster_nid = 0x08;
-
codec->patch_ops = alc_patch_ops;
if (board_config == ALC_MODEL_AUTO)
spec->init_hook = alc_auto_init_std;
@@ -4196,15 +4330,78 @@
* Pin config fixes
*/
enum {
- PINFIX_ABIT_AW9D_MAX,
- PINFIX_LENOVO_Y530,
- PINFIX_PB_M5210,
- PINFIX_ACER_ASPIRE_7736,
- PINFIX_ASUS_W90V,
+ ALC882_FIXUP_ABIT_AW9D_MAX,
+ ALC882_FIXUP_LENOVO_Y530,
+ ALC882_FIXUP_PB_M5210,
+ ALC882_FIXUP_ACER_ASPIRE_7736,
+ ALC882_FIXUP_ASUS_W90V,
+ ALC889_FIXUP_VAIO_TT,
+ ALC888_FIXUP_EEE1601,
+ ALC882_FIXUP_EAPD,
+ ALC883_FIXUP_EAPD,
+ ALC883_FIXUP_ACER_EAPD,
+ ALC882_FIXUP_GPIO3,
+ ALC889_FIXUP_COEF,
+ ALC882_FIXUP_ASUS_W2JC,
+ ALC882_FIXUP_ACER_ASPIRE_4930G,
+ ALC882_FIXUP_ACER_ASPIRE_8930G,
+ ALC882_FIXUP_ASPIRE_8930G_VERBS,
+ ALC885_FIXUP_MACPRO_GPIO,
};
+static void alc889_fixup_coef(struct hda_codec *codec,
+ const struct alc_fixup *fix, int action)
+{
+ if (action != ALC_FIXUP_ACT_INIT)
+ return;
+ alc889_coef_init(codec);
+}
+
+/* toggle speaker-output according to the hp-jack state */
+static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
+{
+ unsigned int gpiostate, gpiomask, gpiodir;
+
+ gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
+ AC_VERB_GET_GPIO_DATA, 0);
+
+ if (!muted)
+ gpiostate |= (1 << pin);
+ else
+ gpiostate &= ~(1 << pin);
+
+ gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
+ AC_VERB_GET_GPIO_MASK, 0);
+ gpiomask |= (1 << pin);
+
+ gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
+ AC_VERB_GET_GPIO_DIRECTION, 0);
+ gpiodir |= (1 << pin);
+
+
+ snd_hda_codec_write(codec, codec->afg, 0,
+ AC_VERB_SET_GPIO_MASK, gpiomask);
+ snd_hda_codec_write(codec, codec->afg, 0,
+ AC_VERB_SET_GPIO_DIRECTION, gpiodir);
+
+ msleep(1);
+
+ snd_hda_codec_write(codec, codec->afg, 0,
+ AC_VERB_SET_GPIO_DATA, gpiostate);
+}
+
+/* set up GPIO at initialization */
+static void alc885_fixup_macpro_gpio(struct hda_codec *codec,
+ const struct alc_fixup *fix, int action)
+{
+ if (action != ALC_FIXUP_ACT_INIT)
+ return;
+ alc882_gpio_mute(codec, 0, 0);
+ alc882_gpio_mute(codec, 1, 0);
+}
+
static const struct alc_fixup alc882_fixups[] = {
- [PINFIX_ABIT_AW9D_MAX] = {
+ [ALC882_FIXUP_ABIT_AW9D_MAX] = {
.type = ALC_FIXUP_PINS,
.v.pins = (const struct alc_pincfg[]) {
{ 0x15, 0x01080104 }, /* side */
@@ -4213,7 +4410,7 @@
{ }
}
},
- [PINFIX_LENOVO_Y530] = {
+ [ALC882_FIXUP_LENOVO_Y530] = {
.type = ALC_FIXUP_PINS,
.v.pins = (const struct alc_pincfg[]) {
{ 0x15, 0x99130112 }, /* rear int speakers */
@@ -4221,32 +4418,180 @@
{ }
}
},
- [PINFIX_PB_M5210] = {
+ [ALC882_FIXUP_PB_M5210] = {
.type = ALC_FIXUP_VERBS,
.v.verbs = (const struct hda_verb[]) {
{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50 },
{}
}
},
- [PINFIX_ACER_ASPIRE_7736] = {
+ [ALC882_FIXUP_ACER_ASPIRE_7736] = {
.type = ALC_FIXUP_SKU,
.v.sku = ALC_FIXUP_SKU_IGNORE,
},
- [PINFIX_ASUS_W90V] = {
+ [ALC882_FIXUP_ASUS_W90V] = {
.type = ALC_FIXUP_PINS,
.v.pins = (const struct alc_pincfg[]) {
{ 0x16, 0x99130110 }, /* fix sequence for CLFE */
{ }
}
},
+ [ALC889_FIXUP_VAIO_TT] = {
+ .type = ALC_FIXUP_PINS,
+ .v.pins = (const struct alc_pincfg[]) {
+ { 0x17, 0x90170111 }, /* hidden surround speaker */
+ { }
+ }
+ },
+ [ALC888_FIXUP_EEE1601] = {
+ .type = ALC_FIXUP_VERBS,
+ .v.verbs = (const struct hda_verb[]) {
+ { 0x20, AC_VERB_SET_COEF_INDEX, 0x0b },
+ { 0x20, AC_VERB_SET_PROC_COEF, 0x0838 },
+ { }
+ }
+ },
+ [ALC882_FIXUP_EAPD] = {
+ .type = ALC_FIXUP_VERBS,
+ .v.verbs = (const struct hda_verb[]) {
+ /* change to EAPD mode */
+ { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
+ { 0x20, AC_VERB_SET_PROC_COEF, 0x3060 },
+ { }
+ }
+ },
+ [ALC883_FIXUP_EAPD] = {
+ .type = ALC_FIXUP_VERBS,
+ .v.verbs = (const struct hda_verb[]) {
+ /* change to EAPD mode */
+ { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
+ { 0x20, AC_VERB_SET_PROC_COEF, 0x3070 },
+ { }
+ }
+ },
+ [ALC883_FIXUP_ACER_EAPD] = {
+ .type = ALC_FIXUP_VERBS,
+ .v.verbs = (const struct hda_verb[]) {
+ /* eanable EAPD on Acer laptops */
+ { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
+ { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 },
+ { }
+ }
+ },
+ [ALC882_FIXUP_GPIO3] = {
+ .type = ALC_FIXUP_VERBS,
+ .v.verbs = alc_gpio3_init_verbs,
+ },
+ [ALC882_FIXUP_ASUS_W2JC] = {
+ .type = ALC_FIXUP_VERBS,
+ .v.verbs = alc_gpio1_init_verbs,
+ .chained = true,
+ .chain_id = ALC882_FIXUP_EAPD,
+ },
+ [ALC889_FIXUP_COEF] = {
+ .type = ALC_FIXUP_FUNC,
+ .v.func = alc889_fixup_coef,
+ },
+ [ALC882_FIXUP_ACER_ASPIRE_4930G] = {
+ .type = ALC_FIXUP_PINS,
+ .v.pins = (const struct alc_pincfg[]) {
+ { 0x16, 0x99130111 }, /* CLFE speaker */
+ { 0x17, 0x99130112 }, /* surround speaker */
+ { }
+ }
+ },
+ [ALC882_FIXUP_ACER_ASPIRE_8930G] = {
+ .type = ALC_FIXUP_PINS,
+ .v.pins = (const struct alc_pincfg[]) {
+ { 0x16, 0x99130111 }, /* CLFE speaker */
+ { 0x1b, 0x99130112 }, /* surround speaker */
+ { }
+ },
+ .chained = true,
+ .chain_id = ALC882_FIXUP_ASPIRE_8930G_VERBS,
+ },
+ [ALC882_FIXUP_ASPIRE_8930G_VERBS] = {
+ /* additional init verbs for Acer Aspire 8930G */
+ .type = ALC_FIXUP_VERBS,
+ .v.verbs = (const struct hda_verb[]) {
+ /* Enable all DACs */
+ /* DAC DISABLE/MUTE 1? */
+ /* setting bits 1-5 disables DAC nids 0x02-0x06
+ * apparently. Init=0x38 */
+ { 0x20, AC_VERB_SET_COEF_INDEX, 0x03 },
+ { 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
+ /* DAC DISABLE/MUTE 2? */
+ /* some bit here disables the other DACs.
+ * Init=0x4900 */
+ { 0x20, AC_VERB_SET_COEF_INDEX, 0x08 },
+ { 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
+ /* DMIC fix
+ * This laptop has a stereo digital microphone.
+ * The mics are only 1cm apart which makes the stereo
+ * useless. However, either the mic or the ALC889
+ * makes the signal become a difference/sum signal
+ * instead of standard stereo, which is annoying.
+ * So instead we flip this bit which makes the
+ * codec replicate the sum signal to both channels,
+ * turning it into a normal mono mic.
+ */
+ /* DMIC_CONTROL? Init value = 0x0001 */
+ { 0x20, AC_VERB_SET_COEF_INDEX, 0x0b },
+ { 0x20, AC_VERB_SET_PROC_COEF, 0x0003 },
+ { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
+ { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 },
+ { }
+ }
+ },
+ [ALC885_FIXUP_MACPRO_GPIO] = {
+ .type = ALC_FIXUP_FUNC,
+ .v.func = alc885_fixup_macpro_gpio,
+ },
};
static const struct snd_pci_quirk alc882_fixup_tbl[] = {
- SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", PINFIX_PB_M5210),
- SND_PCI_QUIRK(0x1043, 0x1873, "ASUS W90V", PINFIX_ASUS_W90V),
- SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Y530", PINFIX_LENOVO_Y530),
- SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
- SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", PINFIX_ACER_ASPIRE_7736),
+ SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_FIXUP_ACER_EAPD),
+ SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_FIXUP_ACER_EAPD),
+ SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_FIXUP_ACER_EAPD),
+ SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_FIXUP_ACER_EAPD),
+ SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_FIXUP_ACER_EAPD),
+ SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_FIXUP_ACER_EAPD),
+ SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
+ ALC882_FIXUP_ACER_ASPIRE_4930G),
+ SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
+ ALC882_FIXUP_ACER_ASPIRE_4930G),
+ SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G",
+ ALC882_FIXUP_ACER_ASPIRE_8930G),
+ SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G",
+ ALC882_FIXUP_ACER_ASPIRE_8930G),
+ SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
+ ALC882_FIXUP_ACER_ASPIRE_4930G),
+ SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
+ ALC882_FIXUP_ACER_ASPIRE_4930G),
+ SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G",
+ ALC882_FIXUP_ACER_ASPIRE_4930G),
+ SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", ALC882_FIXUP_PB_M5210),
+ SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", ALC882_FIXUP_ACER_ASPIRE_7736),
+ SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_FIXUP_EAPD),
+ SND_PCI_QUIRK(0x1043, 0x1873, "ASUS W90V", ALC882_FIXUP_ASUS_W90V),
+ SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_FIXUP_ASUS_W2JC),
+ SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_FIXUP_EEE1601),
+ SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC889_FIXUP_VAIO_TT),
+
+ /* All Apple entries are in codec SSIDs */
+ SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC885_FIXUP_MACPRO_GPIO),
+ SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_FIXUP_MACPRO_GPIO),
+ SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_FIXUP_MACPRO_GPIO),
+ SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_FIXUP_EAPD),
+ SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_FIXUP_MACPRO_GPIO),
+
+ SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC882_FIXUP_EAPD),
+ SND_PCI_QUIRK_VENDOR(0x1462, "MSI", ALC882_FIXUP_GPIO3),
+ SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", ALC882_FIXUP_ABIT_AW9D_MAX),
+ SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC882_FIXUP_EAPD),
+ SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_FIXUP_EAPD),
+ SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Y530", ALC882_FIXUP_LENOVO_Y530),
+ SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_FIXUP_COEF),
{}
};
@@ -4295,8 +4640,7 @@
goto error;
board_config = alc_board_config(codec, ALC882_MODEL_LAST,
- alc882_models, alc882_cfg_tbl);
-
+ alc882_models, NULL);
if (board_config < 0)
board_config = alc_board_codec_sid_config(codec,
ALC882_MODEL_LAST, alc882_models, alc882_ssid_cfg_tbl);
@@ -4319,18 +4663,12 @@
err = alc882_parse_auto_config(codec);
if (err < 0)
goto error;
-#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
- else if (!err) {
- printk(KERN_INFO
- "hda_codec: Cannot set up configuration "
- "from BIOS. Using base mode...\n");
- board_config = ALC882_3ST_DIG;
- }
-#endif
}
- if (board_config != ALC_MODEL_AUTO)
+ if (board_config != ALC_MODEL_AUTO) {
setup_preset(codec, &alc882_presets[board_config]);
+ spec->vmaster_nid = 0x0c;
+ }
if (!spec->no_analog && !spec->adc_nids) {
alc_auto_fill_adc_caps(codec);
@@ -4350,13 +4688,10 @@
alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
- spec->vmaster_nid = 0x0c;
-
codec->patch_ops = alc_patch_ops;
if (board_config == ALC_MODEL_AUTO)
spec->init_hook = alc_auto_init_std;
- alc_init_jacks(codec);
#ifdef CONFIG_SND_HDA_POWER_SAVE
if (!spec->loopback.amplist)
spec->loopback.amplist = alc882_loopbacks;
@@ -4384,12 +4719,17 @@
* Pin config fixes
*/
enum {
- PINFIX_FSC_H270,
- PINFIX_HP_Z200,
+ ALC262_FIXUP_FSC_H270,
+ ALC262_FIXUP_HP_Z200,
+ ALC262_FIXUP_TYAN,
+ ALC262_FIXUP_TOSHIBA_RX1,
+ ALC262_FIXUP_LENOVO_3000,
+ ALC262_FIXUP_BENQ,
+ ALC262_FIXUP_BENQ_T31,
};
static const struct alc_fixup alc262_fixups[] = {
- [PINFIX_FSC_H270] = {
+ [ALC262_FIXUP_FSC_H270] = {
.type = ALC_FIXUP_PINS,
.v.pins = (const struct alc_pincfg[]) {
{ 0x14, 0x99130110 }, /* speaker */
@@ -4398,18 +4738,68 @@
{ }
}
},
- [PINFIX_HP_Z200] = {
+ [ALC262_FIXUP_HP_Z200] = {
.type = ALC_FIXUP_PINS,
.v.pins = (const struct alc_pincfg[]) {
{ 0x16, 0x99130120 }, /* internal speaker */
{ }
}
},
+ [ALC262_FIXUP_TYAN] = {
+ .type = ALC_FIXUP_PINS,
+ .v.pins = (const struct alc_pincfg[]) {
+ { 0x14, 0x1993e1f0 }, /* int AUX */
+ { }
+ }
+ },
+ [ALC262_FIXUP_TOSHIBA_RX1] = {
+ .type = ALC_FIXUP_PINS,
+ .v.pins = (const struct alc_pincfg[]) {
+ { 0x14, 0x90170110 }, /* speaker */
+ { 0x15, 0x0421101f }, /* HP */
+ { 0x1a, 0x40f000f0 }, /* N/A */
+ { 0x1b, 0x40f000f0 }, /* N/A */
+ { 0x1e, 0x40f000f0 }, /* N/A */
+ }
+ },
+ [ALC262_FIXUP_LENOVO_3000] = {
+ .type = ALC_FIXUP_VERBS,
+ .v.verbs = (const struct hda_verb[]) {
+ { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50 },
+ {}
+ },
+ .chained = true,
+ .chain_id = ALC262_FIXUP_BENQ,
+ },
+ [ALC262_FIXUP_BENQ] = {
+ .type = ALC_FIXUP_VERBS,
+ .v.verbs = (const struct hda_verb[]) {
+ { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
+ { 0x20, AC_VERB_SET_PROC_COEF, 0x3070 },
+ {}
+ }
+ },
+ [ALC262_FIXUP_BENQ_T31] = {
+ .type = ALC_FIXUP_VERBS,
+ .v.verbs = (const struct hda_verb[]) {
+ { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
+ { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 },
+ {}
+ }
+ },
};
static const struct snd_pci_quirk alc262_fixup_tbl[] = {
- SND_PCI_QUIRK(0x103c, 0x170b, "HP Z200", PINFIX_HP_Z200),
- SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", PINFIX_FSC_H270),
+ SND_PCI_QUIRK(0x103c, 0x170b, "HP Z200", ALC262_FIXUP_HP_Z200),
+ SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FIXUP_BENQ),
+ SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FIXUP_BENQ),
+ SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_FIXUP_TYAN),
+ SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
+ ALC262_FIXUP_TOSHIBA_RX1),
+ SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", ALC262_FIXUP_FSC_H270),
+ SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000", ALC262_FIXUP_LENOVO_3000),
+ SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_FIXUP_BENQ),
+ SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_FIXUP_BENQ_T31),
{}
};
@@ -4420,14 +4810,9 @@
/*
*/
-#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
-#include "alc262_quirks.c"
-#endif
-
static int patch_alc262(struct hda_codec *codec)
{
struct alc_spec *spec;
- int board_config;
int err;
spec = kzalloc(sizeof(*spec), GFP_KERNEL);
@@ -4454,37 +4839,13 @@
alc_fix_pll_init(codec, 0x20, 0x0a, 10);
- board_config = alc_board_config(codec, ALC262_MODEL_LAST,
- alc262_models, alc262_cfg_tbl);
+ alc_pick_fixup(codec, NULL, alc262_fixup_tbl, alc262_fixups);
+ alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
- if (board_config < 0) {
- printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
- codec->chip_name);
- board_config = ALC_MODEL_AUTO;
- }
-
- if (board_config == ALC_MODEL_AUTO) {
- alc_pick_fixup(codec, NULL, alc262_fixup_tbl, alc262_fixups);
- alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
- }
-
- if (board_config == ALC_MODEL_AUTO) {
- /* automatic parse from the BIOS config */
- err = alc262_parse_auto_config(codec);
- if (err < 0)
- goto error;
-#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
- else if (!err) {
- printk(KERN_INFO
- "hda_codec: Cannot set up configuration "
- "from BIOS. Using base mode...\n");
- board_config = ALC262_BASIC;
- }
-#endif
- }
-
- if (board_config != ALC_MODEL_AUTO)
- setup_preset(codec, &alc262_presets[board_config]);
+ /* automatic parse from the BIOS config */
+ err = alc262_parse_auto_config(codec);
+ if (err < 0)
+ goto error;
if (!spec->no_analog && !spec->adc_nids) {
alc_auto_fill_adc_caps(codec);
@@ -4504,14 +4865,10 @@
alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
- spec->vmaster_nid = 0x0c;
-
codec->patch_ops = alc_patch_ops;
- if (board_config == ALC_MODEL_AUTO)
- spec->init_hook = alc_auto_init_std;
+ spec->init_hook = alc_auto_init_std;
spec->shutup = alc_eapd_shutup;
- alc_init_jacks(codec);
#ifdef CONFIG_SND_HDA_POWER_SAVE
if (!spec->loopback.amplist)
spec->loopback.amplist = alc262_loopbacks;
@@ -4618,14 +4975,10 @@
if (!spec->no_analog && !spec->cap_mixer)
set_capture_mixer(codec);
- spec->vmaster_nid = 0x02;
-
codec->patch_ops = alc_patch_ops;
spec->init_hook = alc_auto_init_std;
spec->shutup = alc_eapd_shutup;
- alc_init_jacks(codec);
-
return 0;
error:
@@ -4967,7 +5320,7 @@
{ }
},
},
- [ALC269_FIXUP_DMIC] = {
+ [ALC269VB_FIXUP_DMIC] = {
.type = ALC_FIXUP_PINS,
.v.pins = (const struct alc_pincfg[]) {
{ 0x12, 0x99a3092f }, /* int-mic */
@@ -5174,8 +5527,6 @@
alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
- spec->vmaster_nid = 0x02;
-
codec->patch_ops = alc_patch_ops;
#ifdef CONFIG_PM
codec->patch_ops.resume = alc269_resume;
@@ -5183,7 +5534,6 @@
spec->init_hook = alc_auto_init_std;
spec->shutup = alc269_shutup;
- alc_init_jacks(codec);
#ifdef CONFIG_SND_HDA_POWER_SAVE
if (!spec->loopback.amplist)
spec->loopback.amplist = alc269_loopbacks;
@@ -5280,8 +5630,6 @@
set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
}
- spec->vmaster_nid = 0x03;
-
alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
codec->patch_ops = alc_patch_ops;
@@ -5406,8 +5754,6 @@
set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
}
- spec->vmaster_nid = 0x02;
-
alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
codec->patch_ops = alc_patch_ops;
@@ -5790,7 +6136,6 @@
break;
}
}
- spec->vmaster_nid = 0x02;
alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
@@ -5798,8 +6143,6 @@
spec->init_hook = alc_auto_init_std;
spec->shutup = alc_eapd_shutup;
- alc_init_jacks(codec);
-
#ifdef CONFIG_SND_HDA_POWER_SAVE
if (!spec->loopback.amplist)
spec->loopback.amplist = alc662_loopbacks;
@@ -5846,8 +6189,6 @@
if (!spec->no_analog && !spec->cap_mixer)
set_capture_mixer(codec);
- spec->vmaster_nid = 0x02;
-
codec->patch_ops = alc_patch_ops;
spec->init_hook = alc_auto_init_std;
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index 616678f..87e684f 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -37,6 +37,7 @@
#include "hda_codec.h"
#include "hda_local.h"
#include "hda_beep.h"
+#include "hda_jack.h"
enum {
STAC_VREF_EVENT = 1,
@@ -96,7 +97,6 @@
STAC_92HD83XXX_PWR_REF,
STAC_DELL_S14,
STAC_DELL_VOSTRO_3500,
- STAC_92HD83XXX_HP,
STAC_92HD83XXX_HP_cNB11_INTQUAD,
STAC_HP_DV7_4000,
STAC_92HD83XXX_MODELS
@@ -176,13 +176,6 @@
STAC_9872_MODELS
};
-struct sigmatel_event {
- hda_nid_t nid;
- unsigned char type;
- unsigned char tag;
- int data;
-};
-
struct sigmatel_mic_route {
hda_nid_t pin;
signed char mux_idx;
@@ -231,9 +224,6 @@
const hda_nid_t *pwr_nids;
const hda_nid_t *dac_list;
- /* events */
- struct snd_array events;
-
/* playback */
struct hda_input_mux *mono_mux;
unsigned int cur_mmux;
@@ -1094,13 +1084,10 @@
};
static void stac92xx_free_kctls(struct hda_codec *codec);
-static int stac92xx_add_jack(struct hda_codec *codec, hda_nid_t nid, int type);
static int stac92xx_build_controls(struct hda_codec *codec)
{
struct sigmatel_spec *spec = codec->spec;
- struct auto_pin_cfg *cfg = &spec->autocfg;
- hda_nid_t nid;
int err;
int i;
@@ -1186,31 +1173,9 @@
stac92xx_free_kctls(codec); /* no longer needed */
- /* create jack input elements */
- if (spec->hp_detect) {
- for (i = 0; i < cfg->hp_outs; i++) {
- int type = SND_JACK_HEADPHONE;
- nid = cfg->hp_pins[i];
- /* jack detection */
- if (cfg->hp_outs == i)
- type |= SND_JACK_LINEOUT;
- err = stac92xx_add_jack(codec, nid, type);
- if (err < 0)
- return err;
- }
- }
- for (i = 0; i < cfg->line_outs; i++) {
- err = stac92xx_add_jack(codec, cfg->line_out_pins[i],
- SND_JACK_LINEOUT);
- if (err < 0)
- return err;
- }
- for (i = 0; i < cfg->num_inputs; i++) {
- nid = cfg->inputs[i].pin;
- err = stac92xx_add_jack(codec, nid, SND_JACK_MICROPHONE);
- if (err < 0)
- return err;
- }
+ err = snd_hda_jack_add_kctls(codec, &spec->autocfg);
+ if (err < 0)
+ return err;
return 0;
}
@@ -1692,7 +1657,6 @@
[STAC_92HD83XXX_PWR_REF] = "mic-ref",
[STAC_DELL_S14] = "dell-s14",
[STAC_DELL_VOSTRO_3500] = "dell-vostro-3500",
- [STAC_92HD83XXX_HP] = "hp",
[STAC_92HD83XXX_HP_cNB11_INTQUAD] = "hp_cNB11_intquad",
[STAC_HP_DV7_4000] = "hp-dv7-4000",
};
@@ -1707,8 +1671,6 @@
"unknown Dell", STAC_DELL_S14),
SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x1028,
"Dell Vostro 3500", STAC_DELL_VOSTRO_3500),
- SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xff00, 0x3600,
- "HP", STAC_92HD83XXX_HP),
SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1656,
"HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1657,
@@ -2875,7 +2837,8 @@
}
if (control) {
- strcpy(name, hda_get_input_pin_label(codec, nid, 1));
+ snd_hda_get_pin_label(codec, nid, &spec->autocfg,
+ name, sizeof(name), NULL);
return stac92xx_add_control(codec->spec, control,
strcat(name, " Jack Mode"), nid);
}
@@ -3553,7 +3516,7 @@
for (i = 0; i < spec->num_dmics; i++) {
hda_nid_t nid;
int index, type_idx;
- const char *label;
+ char label[32];
nid = spec->dmic_nids[i];
if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN)
@@ -3566,7 +3529,8 @@
if (index < 0)
continue;
- label = hda_get_input_pin_label(codec, nid, 1);
+ snd_hda_get_pin_label(codec, nid, &spec->autocfg,
+ label, sizeof(label), NULL);
snd_hda_add_imux_item(dimux, label, index, &type_idx);
if (snd_hda_get_bool_hint(codec, "separate_dmux") != 1)
snd_hda_add_imux_item(imux, label, index, &type_idx);
@@ -4164,65 +4128,18 @@
AC_VERB_SET_GPIO_DATA, gpiostate); /* sync */
}
-static int stac92xx_add_jack(struct hda_codec *codec,
- hda_nid_t nid, int type)
-{
-#ifdef CONFIG_SND_HDA_INPUT_JACK
- int def_conf = snd_hda_codec_get_pincfg(codec, nid);
- int connectivity = get_defcfg_connect(def_conf);
-
- if (connectivity && connectivity != AC_JACK_PORT_FIXED)
- return 0;
-
- return snd_hda_input_jack_add(codec, nid, type, NULL);
-#else
- return 0;
-#endif /* CONFIG_SND_HDA_INPUT_JACK */
-}
-
-static int stac_add_event(struct sigmatel_spec *spec, hda_nid_t nid,
+static int stac_add_event(struct hda_codec *codec, hda_nid_t nid,
unsigned char type, int data)
{
- struct sigmatel_event *event;
+ struct hda_jack_tbl *event;
- snd_array_init(&spec->events, sizeof(*event), 32);
- event = snd_array_new(&spec->events);
+ event = snd_hda_jack_tbl_new(codec, nid);
if (!event)
return -ENOMEM;
- event->nid = nid;
- event->type = type;
- event->tag = spec->events.used;
- event->data = data;
+ event->action = type;
+ event->private_data = data;
- return event->tag;
-}
-
-static struct sigmatel_event *stac_get_event(struct hda_codec *codec,
- hda_nid_t nid)
-{
- struct sigmatel_spec *spec = codec->spec;
- struct sigmatel_event *event = spec->events.list;
- int i;
-
- for (i = 0; i < spec->events.used; i++, event++) {
- if (event->nid == nid)
- return event;
- }
- return NULL;
-}
-
-static struct sigmatel_event *stac_get_event_from_tag(struct hda_codec *codec,
- unsigned char tag)
-{
- struct sigmatel_spec *spec = codec->spec;
- struct sigmatel_event *event = spec->events.list;
- int i;
-
- for (i = 0; i < spec->events.used; i++, event++) {
- if (event->tag == tag)
- return event;
- }
- return NULL;
+ return 0;
}
/* check if given nid is a valid pin and no other events are assigned
@@ -4232,24 +4149,17 @@
static int enable_pin_detect(struct hda_codec *codec, hda_nid_t nid,
unsigned int type)
{
- struct sigmatel_event *event;
- int tag;
+ struct hda_jack_tbl *event;
if (!is_jack_detectable(codec, nid))
return 0;
- event = stac_get_event(codec, nid);
- if (event) {
- if (event->type != type)
- return 0;
- tag = event->tag;
- } else {
- tag = stac_add_event(codec->spec, nid, type, 0);
- if (tag < 0)
- return 0;
- }
- snd_hda_codec_write_cache(codec, nid, 0,
- AC_VERB_SET_UNSOLICITED_ENABLE,
- AC_USRSP_EN | tag);
+ event = snd_hda_jack_tbl_new(codec, nid);
+ if (!event)
+ return -ENOMEM;
+ if (event->action && event->action != type)
+ return 0;
+ event->action = type;
+ snd_hda_jack_detect_enable(codec, nid, 0);
return 1;
}
@@ -4326,6 +4236,27 @@
}
}
+static void stac_issue_unsol_events(struct hda_codec *codec, int num_pins,
+ const hda_nid_t *pins)
+{
+ while (num_pins--)
+ stac_issue_unsol_event(codec, *pins++);
+}
+
+/* fake event to set up pins */
+static void stac_fake_hp_events(struct hda_codec *codec)
+{
+ struct sigmatel_spec *spec = codec->spec;
+
+ if (spec->autocfg.hp_outs)
+ stac_issue_unsol_events(codec, spec->autocfg.hp_outs,
+ spec->autocfg.hp_pins);
+ if (spec->autocfg.line_outs &&
+ spec->autocfg.line_out_pins[0] != spec->autocfg.hp_pins[0])
+ stac_issue_unsol_events(codec, spec->autocfg.line_outs,
+ spec->autocfg.line_out_pins);
+}
+
static int stac92xx_init(struct hda_codec *codec)
{
struct sigmatel_spec *spec = codec->spec;
@@ -4376,10 +4307,7 @@
stac92xx_auto_set_pinctl(codec, spec->autocfg.line_out_pins[0],
AC_PINCTL_OUT_EN);
/* fake event to set up pins */
- if (cfg->hp_pins[0])
- stac_issue_unsol_event(codec, cfg->hp_pins[0]);
- else if (cfg->line_out_pins[0])
- stac_issue_unsol_event(codec, cfg->line_out_pins[0]);
+ stac_fake_hp_events(codec);
} else {
stac92xx_auto_init_multi_out(codec);
stac92xx_auto_init_hp_out(codec);
@@ -4477,6 +4405,8 @@
stac_toggle_power_map(codec, nid, 0);
}
+ snd_hda_jack_report_sync(codec);
+
/* sync mute LED */
if (spec->gpio_led)
hda_call_check_power_status(codec, 0x01);
@@ -4533,8 +4463,6 @@
return;
stac92xx_shutup(codec);
- snd_hda_input_jack_free(codec);
- snd_array_free(&spec->events);
kfree(spec);
snd_hda_detach_beep_device(codec);
@@ -4798,26 +4726,13 @@
mic->mux_idx);
}
-static void stac_issue_unsol_event(struct hda_codec *codec, hda_nid_t nid)
-{
- struct sigmatel_event *event = stac_get_event(codec, nid);
- if (!event)
- return;
- codec->patch_ops.unsol_event(codec, (unsigned)event->tag << 26);
-}
-
-static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res)
+static void handle_unsol_event(struct hda_codec *codec,
+ struct hda_jack_tbl *event)
{
struct sigmatel_spec *spec = codec->spec;
- struct sigmatel_event *event;
- int tag, data;
+ int data;
- tag = (res >> 26) & 0x7f;
- event = stac_get_event_from_tag(codec, tag);
- if (!event)
- return;
-
- switch (event->type) {
+ switch (event->action) {
case STAC_HP_EVENT:
case STAC_LO_EVENT:
stac92xx_hp_detect(codec);
@@ -4827,7 +4742,7 @@
break;
}
- switch (event->type) {
+ switch (event->action) {
case STAC_HP_EVENT:
case STAC_LO_EVENT:
case STAC_MIC_EVENT:
@@ -4835,7 +4750,6 @@
case STAC_PWR_EVENT:
if (spec->num_pwrs > 0)
stac92xx_pin_sense(codec, event->nid);
- snd_hda_input_jack_report(codec, event->nid);
switch (codec->subsystem_id) {
case 0x103c308f:
@@ -4860,11 +4774,33 @@
AC_VERB_GET_GPIO_DATA, 0);
/* toggle VREF state based on GPIOx status */
snd_hda_codec_write(codec, codec->afg, 0, 0x7e0,
- !!(data & (1 << event->data)));
+ !!(data & (1 << event->private_data)));
break;
}
}
+static void stac_issue_unsol_event(struct hda_codec *codec, hda_nid_t nid)
+{
+ struct hda_jack_tbl *event = snd_hda_jack_tbl_get(codec, nid);
+ if (!event)
+ return;
+ handle_unsol_event(codec, event);
+}
+
+static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res)
+{
+ struct hda_jack_tbl *event;
+ int tag;
+
+ tag = (res >> 26) & 0x7f;
+ event = snd_hda_jack_tbl_get_from_tag(codec, tag);
+ if (!event)
+ return;
+ event->jack_dirty = 1;
+ handle_unsol_event(codec, event);
+ snd_hda_jack_report_sync(codec);
+}
+
static int hp_blike_system(u32 subsystem_id);
static void set_hp_led_gpio(struct hda_codec *codec)
@@ -4903,7 +4839,7 @@
* Need more information on whether it is true across the entire series.
* -- kunal
*/
-static int find_mute_led_gpio(struct hda_codec *codec, int default_polarity)
+static int find_mute_led_cfg(struct hda_codec *codec, int default_polarity)
{
struct sigmatel_spec *spec = codec->spec;
const struct dmi_device *dev = NULL;
@@ -4939,9 +4875,11 @@
/*
* Fallback case - if we don't find the DMI strings,
- * we statically set the GPIO - if not a B-series system.
+ * we statically set the GPIO - if not a B-series system
+ * and default polarity is provided
*/
- if (!hp_blike_system(codec->subsystem_id)) {
+ if (!hp_blike_system(codec->subsystem_id) &&
+ (default_polarity == 0 || default_polarity == 1)) {
set_hp_led_gpio(codec);
spec->gpio_led_polarity = default_polarity;
return 1;
@@ -5028,19 +4966,11 @@
#ifdef CONFIG_PM
static int stac92xx_resume(struct hda_codec *codec)
{
- struct sigmatel_spec *spec = codec->spec;
-
stac92xx_init(codec);
snd_hda_codec_resume_amp(codec);
snd_hda_codec_resume_cache(codec);
/* fake event to set up pins again to override cached values */
- if (spec->hp_detect) {
- if (spec->autocfg.hp_pins[0])
- stac_issue_unsol_event(codec, spec->autocfg.hp_pins[0]);
- else if (spec->autocfg.line_out_pins[0])
- stac_issue_unsol_event(codec,
- spec->autocfg.line_out_pins[0]);
- }
+ stac_fake_hp_events(codec);
return 0;
}
@@ -5651,7 +5581,7 @@
codec->patch_ops = stac92xx_patch_ops;
- if (find_mute_led_gpio(codec, 0))
+ if (find_mute_led_cfg(codec, -1/*no default cfg*/))
snd_printd("mute LED gpio %d polarity %d\n",
spec->gpio_led,
spec->gpio_led_polarity);
@@ -5839,15 +5769,13 @@
switch (spec->board_config) {
case STAC_HP_M4:
/* Enable VREF power saving on GPIO1 detect */
- err = stac_add_event(spec, codec->afg,
+ err = stac_add_event(codec, codec->afg,
STAC_VREF_EVENT, 0x02);
if (err < 0)
return err;
snd_hda_codec_write_cache(codec, codec->afg, 0,
AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, 0x02);
- snd_hda_codec_write_cache(codec, codec->afg, 0,
- AC_VERB_SET_UNSOLICITED_ENABLE,
- AC_USRSP_EN | err);
+ snd_hda_jack_detect_enable(codec, codec->afg, 0);
spec->gpio_mask |= 0x02;
break;
}
@@ -5964,7 +5892,7 @@
}
}
- if (find_mute_led_gpio(codec, 1))
+ if (find_mute_led_cfg(codec, 1))
snd_printd("mute LED gpio %d polarity %d\n",
spec->gpio_led,
spec->gpio_led_polarity);
@@ -6318,14 +6246,12 @@
snd_hda_codec_set_pincfg(codec, 0x20, 0x1c410030);
/* Enable unsol response for GPIO4/Dock HP connection */
- err = stac_add_event(spec, codec->afg, STAC_VREF_EVENT, 0x01);
+ err = stac_add_event(codec, codec->afg, STAC_VREF_EVENT, 0x01);
if (err < 0)
return err;
snd_hda_codec_write_cache(codec, codec->afg, 0,
AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, 0x10);
- snd_hda_codec_write_cache(codec, codec->afg, 0,
- AC_VERB_SET_UNSOLICITED_ENABLE,
- AC_USRSP_EN | err);
+ snd_hda_jack_detect_enable(codec, codec->afg, 0);
spec->gpio_dir = 0x0b;
spec->eapd_mask = 0x01;
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c
index b513762..03e63fe 100644
--- a/sound/pci/hda/patch_via.c
+++ b/sound/pci/hda/patch_via.c
@@ -54,6 +54,7 @@
#include <sound/asoundef.h>
#include "hda_codec.h"
#include "hda_local.h"
+#include "hda_jack.h"
/* Pin Widget NID */
#define VT1708_HP_PIN_NID 0x20
@@ -1503,6 +1504,11 @@
analog_low_current_mode(codec);
via_free_kctls(codec); /* no longer needed */
+
+ err = snd_hda_jack_add_kctls(codec, &spec->autocfg);
+ if (err < 0)
+ return err;
+
return 0;
}
@@ -1714,6 +1720,7 @@
unsigned int res)
{
res >>= 26;
+ res = snd_hda_jack_get_action(codec, res);
if (res & VIA_JACK_EVENT)
set_widgets_power_state(codec);
@@ -1724,6 +1731,7 @@
via_hp_automute(codec);
else if (res == VIA_GPIO_EVENT)
via_gpio_control(codec);
+ snd_hda_jack_report_sync(codec);
}
#ifdef CONFIG_PM
@@ -2200,7 +2208,10 @@
{
struct via_spec *spec = codec->spec;
- if (!spec->aa_mix_nid || !spec->out_mix_path.depth)
+ if (!spec->aa_mix_nid)
+ return 0; /* no loopback switching available */
+ if (!(spec->out_mix_path.depth || spec->hp_mix_path.depth ||
+ spec->speaker_path.depth))
return 0; /* no loopback switching available */
if (!via_clone_control(spec, &via_aamix_ctl_enum))
return -ENOMEM;
@@ -2736,9 +2747,8 @@
int i;
if (cfg->hp_pins[0] && is_jack_detectable(codec, cfg->hp_pins[0]))
- snd_hda_codec_write(codec, cfg->hp_pins[0], 0,
- AC_VERB_SET_UNSOLICITED_ENABLE,
- AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT);
+ snd_hda_jack_detect_enable(codec, cfg->hp_pins[0],
+ VIA_HP_EVENT | VIA_JACK_EVENT);
if (cfg->speaker_pins[0])
ev = VIA_LINE_EVENT;
@@ -2747,16 +2757,14 @@
for (i = 0; i < cfg->line_outs; i++) {
if (cfg->line_out_pins[i] &&
is_jack_detectable(codec, cfg->line_out_pins[i]))
- snd_hda_codec_write(codec, cfg->line_out_pins[i], 0,
- AC_VERB_SET_UNSOLICITED_ENABLE,
- AC_USRSP_EN | ev | VIA_JACK_EVENT);
+ snd_hda_jack_detect_enable(codec, cfg->line_out_pins[i],
+ ev | VIA_JACK_EVENT);
}
for (i = 0; i < cfg->num_inputs; i++) {
if (is_jack_detectable(codec, cfg->inputs[i].pin))
- snd_hda_codec_write(codec, cfg->inputs[i].pin, 0,
- AC_VERB_SET_UNSOLICITED_ENABLE,
- AC_USRSP_EN | VIA_JACK_EVENT);
+ snd_hda_jack_detect_enable(codec, cfg->inputs[i].pin,
+ VIA_JACK_EVENT);
}
}
@@ -2779,6 +2787,7 @@
via_hp_automute(codec);
vt1708_update_hp_work(spec);
+ snd_hda_jack_report_sync(codec);
return 0;
}
@@ -2789,6 +2798,7 @@
vt1708_hp_work.work);
if (spec->codec_type != VT1708)
return;
+ snd_hda_jack_set_dirty_all(spec->codec);
/* if jack state toggled */
if (spec->vt1708_hp_present
!= snd_hda_jack_detect(spec->codec, spec->autocfg.hp_pins[0])) {
diff --git a/sound/pci/ice1712/amp.c b/sound/pci/ice1712/amp.c
index e328cfb..e525da2 100644
--- a/sound/pci/ice1712/amp.c
+++ b/sound/pci/ice1712/amp.c
@@ -68,8 +68,11 @@
static int __devinit snd_vt1724_amp_add_controls(struct snd_ice1712 *ice)
{
- /* we use pins 39 and 41 of the VT1616 for left and right read outputs */
- snd_ac97_write_cache(ice->ac97, 0x5a, snd_ac97_read(ice->ac97, 0x5a) & ~0x8000);
+ if (ice->ac97)
+ /* we use pins 39 and 41 of the VT1616 for left and right
+ read outputs */
+ snd_ac97_write_cache(ice->ac97, 0x5a,
+ snd_ac97_read(ice->ac97, 0x5a) & ~0x8000);
return 0;
}
diff --git a/sound/pci/ice1712/envy24ht.h b/sound/pci/ice1712/envy24ht.h
index a0c5e00..4ca33a8 100644
--- a/sound/pci/ice1712/envy24ht.h
+++ b/sound/pci/ice1712/envy24ht.h
@@ -66,6 +66,7 @@
#define VT1724_CFG_CLOCK384 0x40 /* 16.9344Mhz, 44.1kHz*384 */
#define VT1724_CFG_MPU401 0x20 /* MPU401 UARTs */
#define VT1724_CFG_ADC_MASK 0x0c /* one, two or one and S/PDIF, stereo ADCs */
+#define VT1724_CFG_ADC_NONE 0x0c /* no ADCs */
#define VT1724_CFG_DAC_MASK 0x03 /* one, two, three, four stereo DACs */
#define VT1724_REG_AC97_CFG 0x05 /* byte */
diff --git a/sound/pci/ice1712/ice1712.c b/sound/pci/ice1712/ice1712.c
index 44446f2..132a86e 100644
--- a/sound/pci/ice1712/ice1712.c
+++ b/sound/pci/ice1712/ice1712.c
@@ -84,9 +84,9 @@
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;/* Enable this card */
+static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;/* Enable this card */
static char *model[SNDRV_CARDS];
-static int omni[SNDRV_CARDS]; /* Delta44 & 66 Omni I/O support */
+static bool omni[SNDRV_CARDS]; /* Delta44 & 66 Omni I/O support */
static int cs8427_timeout[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = 500}; /* CS8427 S/PDIF transceiver reset timeout value in msec */
static int dxr_enable[SNDRV_CARDS]; /* DXR enable for DMX6FIRE */
diff --git a/sound/pci/ice1712/ice1724.c b/sound/pci/ice1712/ice1724.c
index 4353e76..9236297 100644
--- a/sound/pci/ice1712/ice1724.c
+++ b/sound/pci/ice1712/ice1724.c
@@ -80,7 +80,7 @@
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
+static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
static char *model[SNDRV_CARDS];
module_param_array(index, int, NULL, 0444);
@@ -1117,14 +1117,21 @@
static int __devinit snd_vt1724_pcm_profi(struct snd_ice1712 *ice, int device)
{
struct snd_pcm *pcm;
- int err;
+ int capt, err;
- err = snd_pcm_new(ice->card, "ICE1724", device, 1, 1, &pcm);
+ if ((ice->eeprom.data[ICE_EEP2_SYSCONF] & VT1724_CFG_ADC_MASK) ==
+ VT1724_CFG_ADC_NONE)
+ capt = 0;
+ else
+ capt = 1;
+ err = snd_pcm_new(ice->card, "ICE1724", device, 1, capt, &pcm);
if (err < 0)
return err;
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_vt1724_playback_pro_ops);
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_vt1724_capture_pro_ops);
+ if (capt)
+ snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
+ &snd_vt1724_capture_pro_ops);
pcm->private_data = ice;
pcm->info_flags = 0;
@@ -1825,7 +1832,12 @@
uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
uinfo->count = 1;
- uinfo->value.enumerated.items = hw_rates_count + ice->ext_clock_count;
+ /* internal clocks */
+ uinfo->value.enumerated.items = hw_rates_count;
+ /* external clocks */
+ if (ice->force_rdma1 ||
+ (ice->eeprom.data[ICE_EEP2_SPDIF] & VT1724_CFG_SPDIF_IN))
+ uinfo->value.enumerated.items += ice->ext_clock_count;
/* upper limit - keep at top */
if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
@@ -2173,6 +2185,40 @@
static struct snd_ice1712_card_info no_matched __devinitdata;
+
+/*
+ ooAoo cards with no controls
+*/
+static unsigned char ooaoo_sq210_eeprom[] __devinitdata = {
+ [ICE_EEP2_SYSCONF] = 0x4c, /* 49MHz crystal, no mpu401, no ADC,
+ 1xDACs */
+ [ICE_EEP2_ACLINK] = 0x80, /* I2S */
+ [ICE_EEP2_I2S] = 0x78, /* no volume, 96k, 24bit, 192k */
+ [ICE_EEP2_SPDIF] = 0xc1, /* out-en, out-int, out-ext */
+ [ICE_EEP2_GPIO_DIR] = 0x00, /* no GPIOs are used */
+ [ICE_EEP2_GPIO_DIR1] = 0x00,
+ [ICE_EEP2_GPIO_DIR2] = 0x00,
+ [ICE_EEP2_GPIO_MASK] = 0xff,
+ [ICE_EEP2_GPIO_MASK1] = 0xff,
+ [ICE_EEP2_GPIO_MASK2] = 0xff,
+
+ [ICE_EEP2_GPIO_STATE] = 0x00, /* inputs */
+ [ICE_EEP2_GPIO_STATE1] = 0x00, /* all 1, but GPIO_CPLD_RW
+ and GPIO15 always zero */
+ [ICE_EEP2_GPIO_STATE2] = 0x00, /* inputs */
+};
+
+
+struct snd_ice1712_card_info snd_vt1724_ooaoo_cards[] __devinitdata = {
+ {
+ .name = "ooAoo SQ210a",
+ .model = "sq210a",
+ .eeprom_size = sizeof(ooaoo_sq210_eeprom),
+ .eeprom_data = ooaoo_sq210_eeprom,
+ },
+ { } /* terminator */
+};
+
static struct snd_ice1712_card_info *card_tables[] __devinitdata = {
snd_vt1724_revo_cards,
snd_vt1724_amp_cards,
@@ -2187,6 +2233,7 @@
snd_vt1724_wtm_cards,
snd_vt1724_se_cards,
snd_vt1724_qtet_cards,
+ snd_vt1724_ooaoo_cards,
NULL,
};
@@ -2270,7 +2317,7 @@
}
}
for (tbl = card_tables; *tbl; tbl++) {
- for (c = *tbl; c->subvendor; c++) {
+ for (c = *tbl; c->name; c++) {
if (modelname && c->model &&
!strcmp(modelname, c->model)) {
printk(KERN_INFO "ice1724: Using board model %s\n",
@@ -2579,8 +2626,10 @@
ice->ext_clock_count = 0;
for (tbl = card_tables; *tbl; tbl++) {
- for (c = *tbl; c->subvendor; c++) {
- if (c->subvendor == ice->eeprom.subvendor) {
+ for (c = *tbl; c->name; c++) {
+ if ((model[dev] && c->model &&
+ !strcmp(model[dev], c->model)) ||
+ (c->subvendor == ice->eeprom.subvendor)) {
strcpy(card->shortname, c->name);
if (c->driver) /* specific driver? */
strcpy(card->driver, c->driver);
diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c
index 11718b49..40b181b 100644
--- a/sound/pci/intel8x0.c
+++ b/sound/pci/intel8x0.c
@@ -79,9 +79,9 @@
static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */
static int ac97_clock;
static char *ac97_quirk;
-static int buggy_semaphore;
+static bool buggy_semaphore;
static int buggy_irq = -1; /* auto-check */
-static int xbox;
+static bool xbox;
static int spdif_aclink = -1;
static int inside_vm = -1;
@@ -105,7 +105,7 @@
MODULE_PARM_DESC(inside_vm, "KVM/Parallels optimization.");
/* just for backward compatibility */
-static int enable;
+static bool enable;
module_param(enable, bool, 0444);
static int joystick;
module_param(joystick, int, 0444);
diff --git a/sound/pci/intel8x0m.c b/sound/pci/intel8x0m.c
index 0f7041e..d689913 100644
--- a/sound/pci/intel8x0m.c
+++ b/sound/pci/intel8x0m.c
@@ -68,7 +68,7 @@
MODULE_PARM_DESC(ac97_clock, "AC'97 codec clock (0 = auto-detect).");
/* just for backward compatibility */
-static int enable;
+static bool enable;
module_param(enable, bool, 0444);
/*
diff --git a/sound/pci/korg1212/korg1212.c b/sound/pci/korg1212/korg1212.c
index 841864b..8fea45a 100644
--- a/sound/pci/korg1212/korg1212.c
+++ b/sound/pci/korg1212/korg1212.c
@@ -408,7 +408,7 @@
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */
+static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */
module_param_array(index, int, NULL, 0444);
MODULE_PARM_DESC(index, "Index value for Korg 1212 soundcard.");
diff --git a/sound/pci/lola/lola.c b/sound/pci/lola/lola.c
index 924168e..3759827 100644
--- a/sound/pci/lola/lola.c
+++ b/sound/pci/lola/lola.c
@@ -35,7 +35,7 @@
/* Standard options */
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 bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
module_param_array(index, int, NULL, 0444);
MODULE_PARM_DESC(index, "Index value for Digigram Lola driver.");
diff --git a/sound/pci/lx6464es/lx6464es.c b/sound/pci/lx6464es/lx6464es.c
index 04ae84b2..d94c0c2 100644
--- a/sound/pci/lx6464es/lx6464es.c
+++ b/sound/pci/lx6464es/lx6464es.c
@@ -42,7 +42,7 @@
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 bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
module_param_array(index, int, NULL, 0444);
MODULE_PARM_DESC(index, "Index value for Digigram LX6464ES interface.");
diff --git a/sound/pci/maestro3.c b/sound/pci/maestro3.c
index 863c8bd..78229b0 100644
--- a/sound/pci/maestro3.c
+++ b/sound/pci/maestro3.c
@@ -64,8 +64,8 @@
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* all enabled */
-static int external_amp[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1};
+static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* all enabled */
+static bool external_amp[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1};
static int amp_gpio[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = -1};
module_param_array(index, int, NULL, 0444);
diff --git a/sound/pci/mixart/mixart.c b/sound/pci/mixart/mixart.c
index a0bd1d9..487837c 100644
--- a/sound/pci/mixart/mixart.c
+++ b/sound/pci/mixart/mixart.c
@@ -49,7 +49,7 @@
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
+static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
module_param_array(index, int, NULL, 0444);
MODULE_PARM_DESC(index, "Index value for Digigram " CARD_NAME " soundcard.");
diff --git a/sound/pci/nm256/nm256.c b/sound/pci/nm256/nm256.c
index c6c45d9..ade2c64 100644
--- a/sound/pci/nm256/nm256.c
+++ b/sound/pci/nm256/nm256.c
@@ -57,12 +57,12 @@
static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */
static int playback_bufsize = 16;
static int capture_bufsize = 16;
-static int force_ac97; /* disabled as default */
+static bool force_ac97; /* disabled as default */
static int buffer_top; /* not specified */
-static int use_cache; /* disabled */
-static int vaio_hack; /* disabled */
-static int reset_workaround;
-static int reset_workaround_2;
+static bool use_cache; /* disabled */
+static bool vaio_hack; /* disabled */
+static bool reset_workaround;
+static bool reset_workaround_2;
module_param(index, int, 0444);
MODULE_PARM_DESC(index, "Index value for " CARD_NAME " soundcard.");
@@ -86,7 +86,7 @@
MODULE_PARM_DESC(reset_workaround_2, "Enable extended AC97 RESET workaround for some other laptops.");
/* just for backward compatibility */
-static int enable;
+static bool enable;
module_param(enable, bool, 0444);
diff --git a/sound/pci/oxygen/oxygen.c b/sound/pci/oxygen/oxygen.c
index 5f3a13d..eab663e 100644
--- a/sound/pci/oxygen/oxygen.c
+++ b/sound/pci/oxygen/oxygen.c
@@ -74,7 +74,7 @@
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 bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
module_param_array(index, int, NULL, 0444);
MODULE_PARM_DESC(index, "card index");
diff --git a/sound/pci/oxygen/virtuoso.c b/sound/pci/oxygen/virtuoso.c
index 4149a0c..3fdee49 100644
--- a/sound/pci/oxygen/virtuoso.c
+++ b/sound/pci/oxygen/virtuoso.c
@@ -32,7 +32,7 @@
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 bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
module_param_array(index, int, NULL, 0444);
MODULE_PARM_DESC(index, "card index");
diff --git a/sound/pci/oxygen/xonar_cs43xx.c b/sound/pci/oxygen/xonar_cs43xx.c
index 2527191..c8febf4 100644
--- a/sound/pci/oxygen/xonar_cs43xx.c
+++ b/sound/pci/oxygen/xonar_cs43xx.c
@@ -418,6 +418,7 @@
.device_config = PLAYBACK_0_TO_I2S |
PLAYBACK_1_TO_SPDIF |
CAPTURE_0_FROM_I2S_2 |
+ CAPTURE_1_FROM_SPDIF |
AC97_FMIC_SWITCH,
.dac_channels_pcm = 8,
.dac_channels_mixer = 8,
diff --git a/sound/pci/oxygen/xonar_dg.c b/sound/pci/oxygen/xonar_dg.c
index bc6eb58..793bdf0 100644
--- a/sound/pci/oxygen/xonar_dg.c
+++ b/sound/pci/oxygen/xonar_dg.c
@@ -597,7 +597,8 @@
.model_data_size = sizeof(struct dg),
.device_config = PLAYBACK_0_TO_I2S |
PLAYBACK_1_TO_SPDIF |
- CAPTURE_0_FROM_I2S_2,
+ CAPTURE_0_FROM_I2S_2 |
+ CAPTURE_1_FROM_SPDIF,
.dac_channels_pcm = 6,
.dac_channels_mixer = 0,
.function_flags = OXYGEN_FUNCTION_SPI,
diff --git a/sound/pci/oxygen/xonar_wm87x6.c b/sound/pci/oxygen/xonar_wm87x6.c
index 42d1ab1..478303e 100644
--- a/sound/pci/oxygen/xonar_wm87x6.c
+++ b/sound/pci/oxygen/xonar_wm87x6.c
@@ -1274,7 +1274,8 @@
.model_data_size = sizeof(struct xonar_wm87x6),
.device_config = PLAYBACK_0_TO_I2S |
PLAYBACK_1_TO_SPDIF |
- CAPTURE_0_FROM_I2S_1,
+ CAPTURE_0_FROM_I2S_1 |
+ CAPTURE_1_FROM_SPDIF,
.dac_channels_pcm = 8,
.dac_channels_mixer = 8,
.dac_volume_min = 255 - 2*60,
@@ -1306,7 +1307,8 @@
.model_data_size = sizeof(struct xonar_wm87x6),
.device_config = PLAYBACK_0_TO_I2S |
PLAYBACK_1_TO_SPDIF |
- CAPTURE_0_FROM_I2S_1,
+ CAPTURE_0_FROM_I2S_1 |
+ CAPTURE_1_FROM_SPDIF,
.dac_channels_pcm = 8,
.dac_channels_mixer = 2,
.dac_volume_min = 255 - 2*60,
diff --git a/sound/pci/pcxhr/pcxhr.c b/sound/pci/pcxhr/pcxhr.c
index 56a5265..fd1809a 100644
--- a/sound/pci/pcxhr/pcxhr.c
+++ b/sound/pci/pcxhr/pcxhr.c
@@ -52,8 +52,8 @@
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;/* Enable this card */
-static int mono[SNDRV_CARDS]; /* capture mono only */
+static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;/* Enable this card */
+static bool mono[SNDRV_CARDS]; /* capture mono only */
module_param_array(index, int, NULL, 0444);
MODULE_PARM_DESC(index, "Index value for Digigram " DRIVER_NAME " soundcard");
diff --git a/sound/pci/riptide/riptide.c b/sound/pci/riptide/riptide.c
index dcbedd3..0481d94 100644
--- a/sound/pci/riptide/riptide.c
+++ b/sound/pci/riptide/riptide.c
@@ -122,7 +122,7 @@
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE;
+static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE;
#ifdef SUPPORT_JOYSTICK
static int joystick_port[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS - 1)] = 0x200 };
diff --git a/sound/pci/rme32.c b/sound/pci/rme32.c
index 21bcb47..b4819d5 100644
--- a/sound/pci/rme32.c
+++ b/sound/pci/rme32.c
@@ -89,8 +89,8 @@
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
-static int fullduplex[SNDRV_CARDS]; // = {[0 ... (SNDRV_CARDS - 1)] = 1};
+static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
+static bool fullduplex[SNDRV_CARDS]; // = {[0 ... (SNDRV_CARDS - 1)] = 1};
module_param_array(index, int, NULL, 0444);
MODULE_PARM_DESC(index, "Index value for RME Digi32 soundcard.");
diff --git a/sound/pci/rme96.c b/sound/pci/rme96.c
index 4585c97..ba89415 100644
--- a/sound/pci/rme96.c
+++ b/sound/pci/rme96.c
@@ -53,7 +53,7 @@
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
+static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
module_param_array(index, int, NULL, 0444);
MODULE_PARM_DESC(index, "Index value for RME Digi96 soundcard.");
diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c
index f2a3758..b68cdec 100644
--- a/sound/pci/rme9652/hdsp.c
+++ b/sound/pci/rme9652/hdsp.c
@@ -45,7 +45,7 @@
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
+static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
module_param_array(index, int, NULL, 0444);
MODULE_PARM_DESC(index, "Index value for RME Hammerfall DSP interface.");
@@ -2640,8 +2640,7 @@
uinfo->value.enumerated.items = 3;
break;
default:
- uinfo->value.enumerated.items = 0;
- break;
+ return -EINVAL;
}
if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c
index 19ee220..cc9f6c8 100644
--- a/sound/pci/rme9652/hdspm.c
+++ b/sound/pci/rme9652/hdspm.c
@@ -61,7 +61,7 @@
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;/* Enable this card */
+static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;/* Enable this card */
module_param_array(index, int, NULL, 0444);
MODULE_PARM_DESC(index, "Index value for RME HDSPM interface.");
@@ -941,6 +941,8 @@
cycles_t last_interrupt;
+ unsigned int serial;
+
struct hdspm_peak_rms peak_rms;
};
@@ -4694,7 +4696,7 @@
snd_iprintf(buffer, "HW Serial: 0x%06x%06x\n",
(hdspm_read(hdspm, HDSPM_midiStatusIn1)>>8) & 0xFFFFFF,
- (hdspm_read(hdspm, HDSPM_midiStatusIn0)>>8) & 0xFFFFFF);
+ hdspm->serial);
snd_iprintf(buffer, "IRQ: %d Registers bus: 0x%lx VM: 0x%lx\n",
hdspm->irq, hdspm->port, (unsigned long)hdspm->iobase);
@@ -6266,8 +6268,7 @@
hdspm_version.card_type = hdspm->io_type;
strncpy(hdspm_version.cardname, hdspm->card_name,
sizeof(hdspm_version.cardname));
- hdspm_version.serial = (hdspm_read(hdspm,
- HDSPM_midiStatusIn0)>>8) & 0xFFFFFF;
+ hdspm_version.serial = hdspm->serial;
hdspm_version.firmware_rev = hdspm->firmware_rev;
hdspm_version.addons = 0;
if (hdspm->tco)
@@ -6782,6 +6783,25 @@
tasklet_init(&hdspm->midi_tasklet,
hdspm_midi_tasklet, (unsigned long) hdspm);
+
+ if (hdspm->io_type != MADIface) {
+ hdspm->serial = (hdspm_read(hdspm,
+ HDSPM_midiStatusIn0)>>8) & 0xFFFFFF;
+ /* id contains either a user-provided value or the default
+ * NULL. If it's the default, we're safe to
+ * fill card->id with the serial number.
+ *
+ * If the serial number is 0xFFFFFF, then we're dealing with
+ * an old PCI revision that comes without a sane number. In
+ * this case, we don't set card->id to avoid collisions
+ * when running with multiple cards.
+ */
+ if (NULL == id[hdspm->dev] && hdspm->serial != 0xFFFFFF) {
+ sprintf(card->id, "HDSPMx%06x", hdspm->serial);
+ snd_card_set_id(card, card->id);
+ }
+ }
+
snd_printdd("create alsa devices.\n");
err = snd_hdspm_create_alsa_devices(card, hdspm);
if (err < 0)
@@ -6868,10 +6888,10 @@
if (hdspm->io_type != MADIface) {
sprintf(card->shortname, "%s_%x",
hdspm->card_name,
- (hdspm_read(hdspm, HDSPM_midiStatusIn0)>>8) & 0xFFFFFF);
+ hdspm->serial);
sprintf(card->longname, "%s S/N 0x%x at 0x%lx, irq %d",
hdspm->card_name,
- (hdspm_read(hdspm, HDSPM_midiStatusIn0)>>8) & 0xFFFFFF,
+ hdspm->serial,
hdspm->port, hdspm->irq);
} else {
sprintf(card->shortname, "%s", hdspm->card_name);
diff --git a/sound/pci/rme9652/rme9652.c b/sound/pci/rme9652/rme9652.c
index 732c5e8..b737d16 100644
--- a/sound/pci/rme9652/rme9652.c
+++ b/sound/pci/rme9652/rme9652.c
@@ -38,8 +38,8 @@
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
-static int precise_ptr[SNDRV_CARDS]; /* Enable precise pointer */
+static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
+static bool precise_ptr[SNDRV_CARDS]; /* Enable precise pointer */
module_param_array(index, int, NULL, 0444);
MODULE_PARM_DESC(index, "Index value for RME Digi9652 (Hammerfall) soundcard.");
diff --git a/sound/pci/sis7019.c b/sound/pci/sis7019.c
index 28dfafb..ff500a8 100644
--- a/sound/pci/sis7019.c
+++ b/sound/pci/sis7019.c
@@ -40,7 +40,7 @@
static int index = SNDRV_DEFAULT_IDX1; /* Index 0-MAX */
static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */
-static int enable = 1;
+static bool enable = 1;
static int codecs = 1;
module_param(index, int, 0444);
@@ -983,7 +983,7 @@
mutex_unlock(&sis->ac97_mutex);
if (!count) {
- printk(KERN_ERR "sis7019: ac97 codec %d timeout cmd 0x%08x\n",
+ dev_err(&sis->pci->dev, "ac97 codec %d timeout cmd 0x%08x\n",
codec, cmd);
}
@@ -1142,13 +1142,13 @@
/* All done, check for errors.
*/
if (!sis->codecs_present) {
- printk(KERN_ERR "sis7019: could not find any codecs\n");
+ dev_err(&sis->pci->dev, "could not find any codecs\n");
return -EIO;
}
if (sis->codecs_present != codecs) {
- printk(KERN_WARNING "sis7019: missing codecs, found %0x, expected %0x\n",
- sis->codecs_present, codecs);
+ dev_warn(&sis->pci->dev, "missing codecs, found %0x, expected %0x\n",
+ sis->codecs_present, codecs);
}
/* Let the hardware know that the audio driver is alive,
@@ -1256,18 +1256,18 @@
pci_restore_state(pci);
if (pci_enable_device(pci) < 0) {
- printk(KERN_ERR "sis7019: unable to re-enable device\n");
+ dev_err(&pci->dev, "unable to re-enable device\n");
goto error;
}
if (sis_chip_init(sis)) {
- printk(KERN_ERR "sis7019: unable to re-init controller\n");
+ dev_err(&pci->dev, "unable to re-init controller\n");
goto error;
}
if (request_irq(pci->irq, sis_interrupt, IRQF_SHARED,
KBUILD_MODNAME, sis)) {
- printk(KERN_ERR "sis7019: unable to regain IRQ %d\n", pci->irq);
+ dev_err(&pci->dev, "unable to regain IRQ %d\n", pci->irq);
goto error;
}
@@ -1335,8 +1335,7 @@
goto error_out;
if (pci_set_dma_mask(pci, DMA_BIT_MASK(30)) < 0) {
- printk(KERN_ERR "sis7019: architecture does not support "
- "30-bit PCI busmaster DMA");
+ dev_err(&pci->dev, "architecture does not support 30-bit PCI busmaster DMA");
goto error_out_enabled;
}
@@ -1350,20 +1349,20 @@
rc = pci_request_regions(pci, "SiS7019");
if (rc) {
- printk(KERN_ERR "sis7019: unable request regions\n");
+ dev_err(&pci->dev, "unable request regions\n");
goto error_out_enabled;
}
rc = -EIO;
sis->ioaddr = ioremap_nocache(pci_resource_start(pci, 1), 0x4000);
if (!sis->ioaddr) {
- printk(KERN_ERR "sis7019: unable to remap MMIO, aborting\n");
+ dev_err(&pci->dev, "unable to remap MMIO, aborting\n");
goto error_out_cleanup;
}
rc = sis_alloc_suspend(sis);
if (rc < 0) {
- printk(KERN_ERR "sis7019: unable to allocate state storage\n");
+ dev_err(&pci->dev, "unable to allocate state storage\n");
goto error_out_cleanup;
}
@@ -1371,9 +1370,9 @@
if (rc)
goto error_out_cleanup;
- if (request_irq(pci->irq, sis_interrupt, IRQF_SHARED,
- KBUILD_MODNAME, sis)) {
- printk(KERN_ERR "unable to allocate irq %d\n", sis->irq);
+ if (request_irq(pci->irq, sis_interrupt, IRQF_SHARED, KBUILD_MODNAME,
+ sis)) {
+ dev_err(&pci->dev, "unable to allocate irq %d\n", sis->irq);
goto error_out_cleanup;
}
diff --git a/sound/pci/sonicvibes.c b/sound/pci/sonicvibes.c
index 31b6ad3..54cc802 100644
--- a/sound/pci/sonicvibes.c
+++ b/sound/pci/sonicvibes.c
@@ -52,9 +52,9 @@
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
-static int reverb[SNDRV_CARDS];
-static int mge[SNDRV_CARDS];
+static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
+static bool reverb[SNDRV_CARDS];
+static bool mge[SNDRV_CARDS];
static unsigned int dmaio = 0x7a00; /* DDMA i/o address */
module_param_array(index, int, NULL, 0444);
diff --git a/sound/pci/trident/trident.c b/sound/pci/trident/trident.c
index deb04b9..5f1def7 100644
--- a/sound/pci/trident/trident.c
+++ b/sound/pci/trident/trident.c
@@ -47,7 +47,7 @@
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
+static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
static int pcm_channels[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 32};
static int wavetable_size[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 8192};
diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c
index ae98d56..7563040 100644
--- a/sound/pci/via82xx.c
+++ b/sound/pci/via82xx.c
@@ -80,7 +80,7 @@
static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */
static long mpu_port;
#ifdef SUPPORT_JOYSTICK
-static int joystick;
+static bool joystick;
#endif
static int ac97_clock = 48000;
static char *ac97_quirk;
@@ -110,7 +110,7 @@
MODULE_PARM_DESC(nodelay, "Disable 500ms init delay");
/* just for backward compatibility */
-static int enable;
+static bool enable;
module_param(enable, bool, 0444);
diff --git a/sound/pci/via82xx_modem.c b/sound/pci/via82xx_modem.c
index 80a9c2b..5efcbca 100644
--- a/sound/pci/via82xx_modem.c
+++ b/sound/pci/via82xx_modem.c
@@ -66,7 +66,7 @@
MODULE_PARM_DESC(ac97_clock, "AC'97 codec clock (default 48000Hz).");
/* just for backward compatibility */
-static int enable;
+static bool enable;
module_param(enable, bool, 0444);
diff --git a/sound/pci/vx222/vx222.c b/sound/pci/vx222/vx222.c
index 6765822..6a534bf 100644
--- a/sound/pci/vx222/vx222.c
+++ b/sound/pci/vx222/vx222.c
@@ -37,8 +37,8 @@
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
-static int mic[SNDRV_CARDS]; /* microphone */
+static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
+static bool mic[SNDRV_CARDS]; /* microphone */
static int ibl[SNDRV_CARDS]; /* microphone */
module_param_array(index, int, NULL, 0444);
diff --git a/sound/pci/ymfpci/ymfpci.c b/sound/pci/ymfpci/ymfpci.c
index e97ddca..e57b89e8 100644
--- a/sound/pci/ymfpci/ymfpci.c
+++ b/sound/pci/ymfpci/ymfpci.c
@@ -41,13 +41,13 @@
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
+static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
static long fm_port[SNDRV_CARDS];
static long mpu_port[SNDRV_CARDS];
#ifdef SUPPORT_JOYSTICK
static long joystick_port[SNDRV_CARDS];
#endif
-static int rear_switch[SNDRV_CARDS];
+static bool rear_switch[SNDRV_CARDS];
module_param_array(index, int, NULL, 0444);
MODULE_PARM_DESC(index, "Index value for the Yamaha DS-1 PCI soundcard.");
diff --git a/sound/pcmcia/pdaudiocf/pdaudiocf.c b/sound/pcmcia/pdaudiocf/pdaudiocf.c
index 6af41d2..830839a 100644
--- a/sound/pcmcia/pdaudiocf/pdaudiocf.c
+++ b/sound/pcmcia/pdaudiocf/pdaudiocf.c
@@ -39,7 +39,7 @@
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable switches */
+static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable switches */
module_param_array(index, int, NULL, 0444);
MODULE_PARM_DESC(index, "Index value for " CARD_NAME " soundcard.");
diff --git a/sound/pcmcia/vx/vxpocket.c b/sound/pcmcia/vx/vxpocket.c
index 9e361c9..512f0b4 100644
--- a/sound/pcmcia/vx/vxpocket.c
+++ b/sound/pcmcia/vx/vxpocket.c
@@ -39,7 +39,7 @@
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable switches */
+static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable switches */
static int ibl[SNDRV_CARDS];
module_param_array(index, int, NULL, 0444);
diff --git a/sound/ppc/powermac.c b/sound/ppc/powermac.c
index 6564569..5a4e263 100644
--- a/sound/ppc/powermac.c
+++ b/sound/ppc/powermac.c
@@ -36,7 +36,7 @@
static int index = SNDRV_DEFAULT_IDX1; /* Index 0-MAX */
static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */
-static int enable_beep = 1;
+static bool enable_beep = 1;
module_param(index, int, 0444);
MODULE_PARM_DESC(index, "Index value for " CHIP_NAME " soundchip.");
diff --git a/sound/sh/aica.c b/sound/sh/aica.c
index 1120ca4..391a38c 100644
--- a/sound/sh/aica.c
+++ b/sound/sh/aica.c
@@ -55,7 +55,7 @@
#define CARD_NAME "AICA"
static int index = -1;
static char *id;
-static int enable = 1;
+static bool enable = 1;
module_param(index, int, 0444);
MODULE_PARM_DESC(index, "Index value for " CARD_NAME " soundcard.");
module_param(id, charp, 0444);
diff --git a/sound/sh/sh_dac_audio.c b/sound/sh/sh_dac_audio.c
index 56bcb46a..b11f82b 100644
--- a/sound/sh/sh_dac_audio.c
+++ b/sound/sh/sh_dac_audio.c
@@ -441,15 +441,4 @@
},
};
-static int __init sh_dac_init(void)
-{
- return platform_driver_register(&driver);
-}
-
-static void __exit sh_dac_exit(void)
-{
- platform_driver_unregister(&driver);
-}
-
-module_init(sh_dac_init);
-module_exit(sh_dac_exit);
+module_platform_driver(driver);
diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig
index 1381db8..35e662d 100644
--- a/sound/soc/Kconfig
+++ b/sound/soc/Kconfig
@@ -22,21 +22,6 @@
if SND_SOC
-config SND_SOC_CACHE_LZO
- bool "Support LZO compression for register caches"
- select LZO_COMPRESS
- select LZO_DECOMPRESS
- ---help---
- Select this to enable LZO compression for register caches.
- This will allow machine or CODEC drivers to compress register
- caches in memory, reducing the memory consumption at the
- expense of performance. If this is not present and is used
- the system will fall back to uncompressed caches.
-
- Usually it is safe to disable this option, where cache
- compression in used the rbtree option will typically perform
- better.
-
config SND_SOC_AC97_BUS
bool
diff --git a/sound/soc/atmel/Kconfig b/sound/soc/atmel/Kconfig
index d1fcc81..72b09cf 100644
--- a/sound/soc/atmel/Kconfig
+++ b/sound/soc/atmel/Kconfig
@@ -26,7 +26,7 @@
config SND_AT91_SOC_AFEB9260
tristate "SoC Audio support for AFEB9260 board"
- depends on ARCH_AT91 && MACH_AFEB9260 && SND_ATMEL_SOC
+ depends on ATMEL_SSC && ARCH_AT91 && MACH_AFEB9260 && SND_ATMEL_SOC
select SND_ATMEL_SOC_SSC
select SND_SOC_TLV320AIC23
help
diff --git a/sound/soc/atmel/atmel-pcm.c b/sound/soc/atmel/atmel-pcm.c
index f81d4c3..a21ff45 100644
--- a/sound/soc/atmel/atmel-pcm.c
+++ b/sound/soc/atmel/atmel-pcm.c
@@ -367,7 +367,6 @@
static int atmel_pcm_new(struct snd_soc_pcm_runtime *rtd)
{
struct snd_card *card = rtd->card->snd_card;
- struct snd_soc_dai *dai = rtd->cpu_dai;
struct snd_pcm *pcm = rtd->pcm;
int ret = 0;
@@ -376,14 +375,14 @@
if (!card->dev->coherent_dma_mask)
card->dev->coherent_dma_mask = 0xffffffff;
- if (dai->driver->playback.channels_min) {
+ if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
ret = atmel_pcm_preallocate_dma_buffer(pcm,
SNDRV_PCM_STREAM_PLAYBACK);
if (ret)
goto out;
}
- if (dai->driver->capture.channels_min) {
+ if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
pr_debug("atmel-pcm:"
"Allocating PCM capture DMA buffer\n");
ret = atmel_pcm_preallocate_dma_buffer(pcm,
@@ -495,17 +494,7 @@
.remove = __devexit_p(atmel_soc_platform_remove),
};
-static int __init snd_atmel_pcm_init(void)
-{
- return platform_driver_register(&atmel_pcm_driver);
-}
-module_init(snd_atmel_pcm_init);
-
-static void __exit snd_atmel_pcm_exit(void)
-{
- platform_driver_unregister(&atmel_pcm_driver);
-}
-module_exit(snd_atmel_pcm_exit);
+module_platform_driver(atmel_pcm_driver);
MODULE_AUTHOR("Sedji Gaouaou <sedji.gaouaou@atmel.com>");
MODULE_DESCRIPTION("Atmel PCM module");
diff --git a/sound/soc/atmel/atmel_ssc_dai.c b/sound/soc/atmel/atmel_ssc_dai.c
index 7122509..354341e 100644
--- a/sound/soc/atmel/atmel_ssc_dai.c
+++ b/sound/soc/atmel/atmel_ssc_dai.c
@@ -719,7 +719,7 @@
#define ATMEL_SSC_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE |\
SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
-static struct snd_soc_dai_ops atmel_ssc_dai_ops = {
+static const struct snd_soc_dai_ops atmel_ssc_dai_ops = {
.startup = atmel_ssc_startup,
.shutdown = atmel_ssc_shutdown,
.prepare = atmel_ssc_prepare,
@@ -859,17 +859,7 @@
}
EXPORT_SYMBOL_GPL(atmel_ssc_set_audio);
-static int __init snd_atmel_ssc_init(void)
-{
- return platform_driver_register(&asoc_ssc_driver);
-}
-module_init(snd_atmel_ssc_init);
-
-static void __exit snd_atmel_ssc_exit(void)
-{
- platform_driver_unregister(&asoc_ssc_driver);
-}
-module_exit(snd_atmel_ssc_exit);
+module_platform_driver(asoc_ssc_driver);
/* Module information */
MODULE_AUTHOR("Sedji Gaouaou, sedji.gaouaou@atmel.com, www.atmel.com");
diff --git a/sound/soc/atmel/sam9g20_wm8731.c b/sound/soc/atmel/sam9g20_wm8731.c
index 0377c54..c883514 100644
--- a/sound/soc/atmel/sam9g20_wm8731.c
+++ b/sound/soc/atmel/sam9g20_wm8731.c
@@ -189,6 +189,7 @@
static struct snd_soc_card snd_soc_at91sam9g20ek = {
.name = "AT91SAMG20-EK",
+ .owner = THIS_MODULE,
.dai_link = &at91sam9g20ek_dai,
.num_links = 1,
.set_bias_level = at91sam9g20ek_set_bias_level,
diff --git a/sound/soc/atmel/snd-soc-afeb9260.c b/sound/soc/atmel/snd-soc-afeb9260.c
index d427e92..4ca667d 100644
--- a/sound/soc/atmel/snd-soc-afeb9260.c
+++ b/sound/soc/atmel/snd-soc-afeb9260.c
@@ -135,6 +135,7 @@
/* Audio machine driver */
static struct snd_soc_card snd_soc_machine_afeb9260 = {
.name = "AFEB9260",
+ .owner = THIS_MODULE,
.dai_link = &afeb9260_dai,
.num_links = 1,
};
diff --git a/sound/soc/au1x/ac97c.c b/sound/soc/au1x/ac97c.c
index 726bd65..c5ac244 100644
--- a/sound/soc/au1x/ac97c.c
+++ b/sound/soc/au1x/ac97c.c
@@ -195,7 +195,7 @@
return 0;
}
-static struct snd_soc_dai_ops alchemy_ac97c_ops = {
+static const struct snd_soc_dai_ops alchemy_ac97c_ops = {
.startup = alchemy_ac97c_startup,
};
@@ -229,35 +229,34 @@
struct resource *iores, *dmares;
struct au1xpsc_audio_data *ctx;
- ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
+ ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
if (!ctx)
return -ENOMEM;
mutex_init(&ctx->lock);
iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!iores) {
- ret = -ENODEV;
- goto out0;
- }
+ if (!iores)
+ return -ENODEV;
- ret = -EBUSY;
- if (!request_mem_region(iores->start, resource_size(iores),
- pdev->name))
- goto out0;
+ if (!devm_request_mem_region(&pdev->dev, iores->start,
+ resource_size(iores),
+ pdev->name))
+ return -EBUSY;
- ctx->mmio = ioremap_nocache(iores->start, resource_size(iores));
+ ctx->mmio = devm_ioremap_nocache(&pdev->dev, iores->start,
+ resource_size(iores));
if (!ctx->mmio)
- goto out1;
+ return -EBUSY;
dmares = platform_get_resource(pdev, IORESOURCE_DMA, 0);
if (!dmares)
- goto out2;
+ return -EBUSY;
ctx->dmaids[SNDRV_PCM_STREAM_PLAYBACK] = dmares->start;
dmares = platform_get_resource(pdev, IORESOURCE_DMA, 1);
if (!dmares)
- goto out2;
+ return -EBUSY;
ctx->dmaids[SNDRV_PCM_STREAM_CAPTURE] = dmares->start;
/* switch it on */
@@ -271,33 +270,20 @@
ret = snd_soc_register_dai(&pdev->dev, &au1xac97c_dai_driver);
if (ret)
- goto out2;
+ return ret;
ac97c_workdata = ctx;
return 0;
-
-out2:
- iounmap(ctx->mmio);
-out1:
- release_mem_region(iores->start, resource_size(iores));
-out0:
- kfree(ctx);
- return ret;
}
static int __devexit au1xac97c_drvremove(struct platform_device *pdev)
{
struct au1xpsc_audio_data *ctx = platform_get_drvdata(pdev);
- struct resource *r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
snd_soc_unregister_dai(&pdev->dev);
WR(ctx, AC97_ENABLE, EN_D); /* clock off, disable */
- iounmap(ctx->mmio);
- release_mem_region(r->start, resource_size(r));
- kfree(ctx);
-
ac97c_workdata = NULL; /* MDEV */
return 0;
diff --git a/sound/soc/au1x/db1000.c b/sound/soc/au1x/db1000.c
index 127477a..511d83c 100644
--- a/sound/soc/au1x/db1000.c
+++ b/sound/soc/au1x/db1000.c
@@ -29,6 +29,7 @@
static struct snd_soc_card db1000_ac97 = {
.name = "DB1000_AC97",
+ .owner = THIS_MODULE,
.dai_link = &db1000_ac97_dai,
.num_links = 1,
};
@@ -57,18 +58,7 @@
.remove = __devexit_p(db1000_audio_remove),
};
-static int __init db1000_audio_load(void)
-{
- return platform_driver_register(&db1000_audio_driver);
-}
-
-static void __exit db1000_audio_unload(void)
-{
- platform_driver_unregister(&db1000_audio_driver);
-}
-
-module_init(db1000_audio_load);
-module_exit(db1000_audio_unload);
+module_platform_driver(db1000_audio_driver);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("DB1000/DB1500/DB1100 ASoC audio");
diff --git a/sound/soc/au1x/db1200.c b/sound/soc/au1x/db1200.c
index 289312c..1c62939 100644
--- a/sound/soc/au1x/db1200.c
+++ b/sound/soc/au1x/db1200.c
@@ -45,6 +45,7 @@
static struct snd_soc_card db1200_ac97_machine = {
.name = "DB1200_AC97",
+ .owner = THIS_MODULE,
.dai_link = &db1200_ac97_dai,
.num_links = 1,
};
@@ -94,6 +95,7 @@
static struct snd_soc_card db1200_i2s_machine = {
.name = "DB1200_I2S",
+ .owner = THIS_MODULE,
.dai_link = &db1200_i2s_dai,
.num_links = 1,
};
@@ -133,18 +135,7 @@
.remove = __devexit_p(db1200_audio_remove),
};
-static int __init db1200_audio_load(void)
-{
- return platform_driver_register(&db1200_audio_driver);
-}
-
-static void __exit db1200_audio_unload(void)
-{
- platform_driver_unregister(&db1200_audio_driver);
-}
-
-module_init(db1200_audio_load);
-module_exit(db1200_audio_unload);
+module_platform_driver(db1200_audio_driver);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("DB1200 ASoC audio support");
diff --git a/sound/soc/au1x/dbdma2.c b/sound/soc/au1x/dbdma2.c
index d7d04e2..8372cd3 100644
--- a/sound/soc/au1x/dbdma2.c
+++ b/sound/soc/au1x/dbdma2.c
@@ -341,7 +341,7 @@
}
/* au1xpsc audio platform */
-struct snd_soc_platform_driver au1xpsc_soc_platform = {
+static struct snd_soc_platform_driver au1xpsc_soc_platform = {
.ops = &au1xpsc_pcm_ops,
.pcm_new = au1xpsc_pcm_new,
.pcm_free = au1xpsc_pcm_free_dma_buffers,
@@ -350,27 +350,21 @@
static int __devinit au1xpsc_pcm_drvprobe(struct platform_device *pdev)
{
struct au1xpsc_audio_dmadata *dmadata;
- int ret;
- dmadata = kzalloc(2 * sizeof(struct au1xpsc_audio_dmadata), GFP_KERNEL);
+ dmadata = devm_kzalloc(&pdev->dev,
+ 2 * sizeof(struct au1xpsc_audio_dmadata),
+ GFP_KERNEL);
if (!dmadata)
return -ENOMEM;
platform_set_drvdata(pdev, dmadata);
- ret = snd_soc_register_platform(&pdev->dev, &au1xpsc_soc_platform);
- if (ret)
- kfree(dmadata);
-
- return ret;
+ return snd_soc_register_platform(&pdev->dev, &au1xpsc_soc_platform);
}
static int __devexit au1xpsc_pcm_drvremove(struct platform_device *pdev)
{
- struct au1xpsc_audio_dmadata *dmadata = platform_get_drvdata(pdev);
-
snd_soc_unregister_platform(&pdev->dev);
- kfree(dmadata);
return 0;
}
@@ -384,18 +378,7 @@
.remove = __devexit_p(au1xpsc_pcm_drvremove),
};
-static int __init au1xpsc_audio_dbdma_load(void)
-{
- return platform_driver_register(&au1xpsc_pcm_driver);
-}
-
-static void __exit au1xpsc_audio_dbdma_unload(void)
-{
- platform_driver_unregister(&au1xpsc_pcm_driver);
-}
-
-module_init(au1xpsc_audio_dbdma_load);
-module_exit(au1xpsc_audio_dbdma_unload);
+module_platform_driver(au1xpsc_pcm_driver);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Au12x0/Au1550 PSC Audio DMA driver");
diff --git a/sound/soc/au1x/dma.c b/sound/soc/au1x/dma.c
index 177f713..0a91b18 100644
--- a/sound/soc/au1x/dma.c
+++ b/sound/soc/au1x/dma.c
@@ -316,7 +316,7 @@
return 0;
}
-struct snd_soc_platform_driver alchemy_pcm_soc_platform = {
+static struct snd_soc_platform_driver alchemy_pcm_soc_platform = {
.ops = &alchemy_pcm_ops,
.pcm_new = alchemy_pcm_new,
.pcm_free = alchemy_pcm_free_dma_buffers,
@@ -325,27 +325,19 @@
static int __devinit alchemy_pcm_drvprobe(struct platform_device *pdev)
{
struct alchemy_pcm_ctx *ctx;
- int ret;
- ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
+ ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
if (!ctx)
return -ENOMEM;
platform_set_drvdata(pdev, ctx);
- ret = snd_soc_register_platform(&pdev->dev, &alchemy_pcm_soc_platform);
- if (ret)
- kfree(ctx);
-
- return ret;
+ return snd_soc_register_platform(&pdev->dev, &alchemy_pcm_soc_platform);
}
static int __devexit alchemy_pcm_drvremove(struct platform_device *pdev)
{
- struct alchemy_pcm_ctx *ctx = platform_get_drvdata(pdev);
-
snd_soc_unregister_platform(&pdev->dev);
- kfree(ctx);
return 0;
}
@@ -359,18 +351,7 @@
.remove = __devexit_p(alchemy_pcm_drvremove),
};
-static int __init alchemy_pcmdma_load(void)
-{
- return platform_driver_register(&alchemy_pcmdma_driver);
-}
-
-static void __exit alchemy_pcmdma_unload(void)
-{
- platform_driver_unregister(&alchemy_pcmdma_driver);
-}
-
-module_init(alchemy_pcmdma_load);
-module_exit(alchemy_pcmdma_unload);
+module_platform_driver(alchemy_pcmdma_driver);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Au1000/Au1500/Au1100 Audio DMA driver");
diff --git a/sound/soc/au1x/i2sc.c b/sound/soc/au1x/i2sc.c
index 6bcf48f..d4b9e36 100644
--- a/sound/soc/au1x/i2sc.c
+++ b/sound/soc/au1x/i2sc.c
@@ -227,69 +227,50 @@
static int __devinit au1xi2s_drvprobe(struct platform_device *pdev)
{
- int ret;
struct resource *iores, *dmares;
struct au1xpsc_audio_data *ctx;
- ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
+ ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
if (!ctx)
return -ENOMEM;
iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!iores) {
- ret = -ENODEV;
- goto out0;
- }
+ if (!iores)
+ return -ENODEV;
- ret = -EBUSY;
- if (!request_mem_region(iores->start, resource_size(iores),
- pdev->name))
- goto out0;
+ if (!devm_request_mem_region(&pdev->dev, iores->start,
+ resource_size(iores),
+ pdev->name))
+ return -EBUSY;
- ctx->mmio = ioremap_nocache(iores->start, resource_size(iores));
+ ctx->mmio = devm_ioremap_nocache(&pdev->dev, iores->start,
+ resource_size(iores));
if (!ctx->mmio)
- goto out1;
+ return -EBUSY;
dmares = platform_get_resource(pdev, IORESOURCE_DMA, 0);
if (!dmares)
- goto out2;
+ return -EBUSY;
ctx->dmaids[SNDRV_PCM_STREAM_PLAYBACK] = dmares->start;
dmares = platform_get_resource(pdev, IORESOURCE_DMA, 1);
if (!dmares)
- goto out2;
+ return -EBUSY;
ctx->dmaids[SNDRV_PCM_STREAM_CAPTURE] = dmares->start;
platform_set_drvdata(pdev, ctx);
- ret = snd_soc_register_dai(&pdev->dev, &au1xi2s_dai_driver);
- if (ret)
- goto out2;
-
- return 0;
-
-out2:
- iounmap(ctx->mmio);
-out1:
- release_mem_region(iores->start, resource_size(iores));
-out0:
- kfree(ctx);
- return ret;
+ return snd_soc_register_dai(&pdev->dev, &au1xi2s_dai_driver);
}
static int __devexit au1xi2s_drvremove(struct platform_device *pdev)
{
struct au1xpsc_audio_data *ctx = platform_get_drvdata(pdev);
- struct resource *r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
snd_soc_unregister_dai(&pdev->dev);
WR(ctx, I2S_ENABLE, EN_D); /* clock off, disable */
- iounmap(ctx->mmio);
- release_mem_region(r->start, resource_size(r));
- kfree(ctx);
-
return 0;
}
@@ -331,18 +312,7 @@
.remove = __devexit_p(au1xi2s_drvremove),
};
-static int __init au1xi2s_load(void)
-{
- return platform_driver_register(&au1xi2s_driver);
-}
-
-static void __exit au1xi2s_unload(void)
-{
- platform_driver_unregister(&au1xi2s_driver);
-}
-
-module_init(au1xi2s_load);
-module_exit(au1xi2s_unload);
+module_platform_driver(au1xi2s_driver);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Au1000/1500/1100 I2S ASoC driver");
diff --git a/sound/soc/au1x/psc-ac97.c b/sound/soc/au1x/psc-ac97.c
index 0c6acd5..476b79a 100644
--- a/sound/soc/au1x/psc-ac97.c
+++ b/sound/soc/au1x/psc-ac97.c
@@ -337,7 +337,7 @@
return au1xpsc_ac97_workdata ? 0 : -ENODEV;
}
-static struct snd_soc_dai_ops au1xpsc_ac97_dai_ops = {
+static const struct snd_soc_dai_ops au1xpsc_ac97_dai_ops = {
.startup = au1xpsc_ac97_startup,
.trigger = au1xpsc_ac97_trigger,
.hw_params = au1xpsc_ac97_hw_params,
@@ -368,35 +368,35 @@
unsigned long sel;
struct au1xpsc_audio_data *wd;
- wd = kzalloc(sizeof(struct au1xpsc_audio_data), GFP_KERNEL);
+ wd = devm_kzalloc(&pdev->dev, sizeof(struct au1xpsc_audio_data),
+ GFP_KERNEL);
if (!wd)
return -ENOMEM;
mutex_init(&wd->lock);
iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!iores) {
- ret = -ENODEV;
- goto out0;
- }
+ if (!iores)
+ return -ENODEV;
- ret = -EBUSY;
- if (!request_mem_region(iores->start, resource_size(iores),
- pdev->name))
- goto out0;
+ if (!devm_request_mem_region(&pdev->dev, iores->start,
+ resource_size(iores),
+ pdev->name))
+ return -EBUSY;
- wd->mmio = ioremap(iores->start, resource_size(iores));
+ wd->mmio = devm_ioremap(&pdev->dev, iores->start,
+ resource_size(iores));
if (!wd->mmio)
- goto out1;
+ return -EBUSY;
dmares = platform_get_resource(pdev, IORESOURCE_DMA, 0);
if (!dmares)
- goto out2;
+ return -EBUSY;
wd->dmaids[SNDRV_PCM_STREAM_PLAYBACK] = dmares->start;
dmares = platform_get_resource(pdev, IORESOURCE_DMA, 1);
if (!dmares)
- goto out2;
+ return -EBUSY;
wd->dmaids[SNDRV_PCM_STREAM_CAPTURE] = dmares->start;
/* configuration: max dma trigger threshold, enable ac97 */
@@ -421,24 +421,15 @@
ret = snd_soc_register_dai(&pdev->dev, &wd->dai_drv);
if (ret)
- goto out2;
+ return ret;
au1xpsc_ac97_workdata = wd;
return 0;
-
-out2:
- iounmap(wd->mmio);
-out1:
- release_mem_region(iores->start, resource_size(iores));
-out0:
- kfree(wd);
- return ret;
}
static int __devexit au1xpsc_ac97_drvremove(struct platform_device *pdev)
{
struct au1xpsc_audio_data *wd = platform_get_drvdata(pdev);
- struct resource *r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
snd_soc_unregister_dai(&pdev->dev);
@@ -448,10 +439,6 @@
au_writel(PSC_CTRL_DISABLE, PSC_CTRL(wd));
au_sync();
- iounmap(wd->mmio);
- release_mem_region(r->start, resource_size(r));
- kfree(wd);
-
au1xpsc_ac97_workdata = NULL; /* MDEV */
return 0;
diff --git a/sound/soc/au1x/psc-i2s.c b/sound/soc/au1x/psc-i2s.c
index e03c5ce..0607ba3 100644
--- a/sound/soc/au1x/psc-i2s.c
+++ b/sound/soc/au1x/psc-i2s.c
@@ -265,7 +265,7 @@
return 0;
}
-static struct snd_soc_dai_ops au1xpsc_i2s_dai_ops = {
+static const struct snd_soc_dai_ops au1xpsc_i2s_dai_ops = {
.startup = au1xpsc_i2s_startup,
.trigger = au1xpsc_i2s_trigger,
.hw_params = au1xpsc_i2s_hw_params,
@@ -295,33 +295,34 @@
int ret;
struct au1xpsc_audio_data *wd;
- wd = kzalloc(sizeof(struct au1xpsc_audio_data), GFP_KERNEL);
+ wd = devm_kzalloc(&pdev->dev, sizeof(struct au1xpsc_audio_data),
+ GFP_KERNEL);
if (!wd)
return -ENOMEM;
iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!iores) {
- ret = -ENODEV;
- goto out0;
- }
+ if (!iores)
+ return -ENODEV;
ret = -EBUSY;
- if (!request_mem_region(iores->start, resource_size(iores),
- pdev->name))
- goto out0;
+ if (!devm_request_mem_region(&pdev->dev, iores->start,
+ resource_size(iores),
+ pdev->name))
+ return -EBUSY;
- wd->mmio = ioremap(iores->start, resource_size(iores));
+ wd->mmio = devm_ioremap(&pdev->dev, iores->start,
+ resource_size(iores));
if (!wd->mmio)
- goto out1;
+ return -EBUSY;
dmares = platform_get_resource(pdev, IORESOURCE_DMA, 0);
if (!dmares)
- goto out2;
+ return -EBUSY;
wd->dmaids[SNDRV_PCM_STREAM_PLAYBACK] = dmares->start;
dmares = platform_get_resource(pdev, IORESOURCE_DMA, 1);
if (!dmares)
- goto out2;
+ return -EBUSY;
wd->dmaids[SNDRV_PCM_STREAM_CAPTURE] = dmares->start;
/* preserve PSC clock source set up by platform (dev.platform_data
@@ -349,23 +350,12 @@
platform_set_drvdata(pdev, wd);
- ret = snd_soc_register_dai(&pdev->dev, &wd->dai_drv);
- if (!ret)
- return 0;
-
-out2:
- iounmap(wd->mmio);
-out1:
- release_mem_region(iores->start, resource_size(iores));
-out0:
- kfree(wd);
- return ret;
+ return snd_soc_register_dai(&pdev->dev, &wd->dai_drv);
}
static int __devexit au1xpsc_i2s_drvremove(struct platform_device *pdev)
{
struct au1xpsc_audio_data *wd = platform_get_drvdata(pdev);
- struct resource *r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
snd_soc_unregister_dai(&pdev->dev);
@@ -374,10 +364,6 @@
au_writel(PSC_CTRL_DISABLE, PSC_CTRL(wd));
au_sync();
- iounmap(wd->mmio);
- release_mem_region(r->start, resource_size(r));
- kfree(wd);
-
return 0;
}
@@ -435,18 +421,7 @@
.remove = __devexit_p(au1xpsc_i2s_drvremove),
};
-static int __init au1xpsc_i2s_load(void)
-{
- return platform_driver_register(&au1xpsc_i2s_driver);
-}
-
-static void __exit au1xpsc_i2s_unload(void)
-{
- platform_driver_unregister(&au1xpsc_i2s_driver);
-}
-
-module_init(au1xpsc_i2s_load);
-module_exit(au1xpsc_i2s_unload);
+module_platform_driver(au1xpsc_i2s_driver);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Au12x0/Au1550 PSC I2S ALSA ASoC audio driver");
diff --git a/sound/soc/blackfin/bf5xx-ac97-pcm.c b/sound/soc/blackfin/bf5xx-ac97-pcm.c
index 56815c1..d7dc9bd 100644
--- a/sound/soc/blackfin/bf5xx-ac97-pcm.c
+++ b/sound/soc/blackfin/bf5xx-ac97-pcm.c
@@ -421,7 +421,6 @@
static int bf5xx_pcm_ac97_new(struct snd_soc_pcm_runtime *rtd)
{
struct snd_card *card = rtd->card->snd_card;
- struct snd_soc_dai *dai = rtd->cpu_dai;
struct snd_pcm *pcm = rtd->pcm;
int ret = 0;
@@ -431,14 +430,14 @@
if (!card->dev->coherent_dma_mask)
card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
- if (dai->driver->playback.channels_min) {
+ if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
ret = bf5xx_pcm_preallocate_dma_buffer(pcm,
SNDRV_PCM_STREAM_PLAYBACK);
if (ret)
goto out;
}
- if (dai->driver->capture.channels_min) {
+ if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
ret = bf5xx_pcm_preallocate_dma_buffer(pcm,
SNDRV_PCM_STREAM_CAPTURE);
if (ret)
@@ -475,17 +474,7 @@
.remove = __devexit_p(bf5xx_soc_platform_remove),
};
-static int __init snd_bf5xx_pcm_init(void)
-{
- return platform_driver_register(&bf5xx_pcm_driver);
-}
-module_init(snd_bf5xx_pcm_init);
-
-static void __exit snd_bf5xx_pcm_exit(void)
-{
- platform_driver_unregister(&bf5xx_pcm_driver);
-}
-module_exit(snd_bf5xx_pcm_exit);
+module_platform_driver(bf5xx_pcm_driver);
MODULE_AUTHOR("Cliff Cai");
MODULE_DESCRIPTION("ADI Blackfin AC97 PCM DMA module");
diff --git a/sound/soc/blackfin/bf5xx-ac97.c b/sound/soc/blackfin/bf5xx-ac97.c
index 6d21625..f4e9dc4 100644
--- a/sound/soc/blackfin/bf5xx-ac97.c
+++ b/sound/soc/blackfin/bf5xx-ac97.c
@@ -375,18 +375,7 @@
.remove = __devexit_p(asoc_bfin_ac97_remove),
};
-static int __init bfin_ac97_init(void)
-{
- return platform_driver_register(&asoc_bfin_ac97_driver);
-}
-module_init(bfin_ac97_init);
-
-static void __exit bfin_ac97_exit(void)
-{
- platform_driver_unregister(&asoc_bfin_ac97_driver);
-}
-module_exit(bfin_ac97_exit);
-
+module_platform_driver(asoc_bfin_ac97_driver);
MODULE_AUTHOR("Roy Huang");
MODULE_DESCRIPTION("AC97 driver for ADI Blackfin");
diff --git a/sound/soc/blackfin/bf5xx-ad1836.c b/sound/soc/blackfin/bf5xx-ad1836.c
index f79d165..60962ce 100644
--- a/sound/soc/blackfin/bf5xx-ad1836.c
+++ b/sound/soc/blackfin/bf5xx-ad1836.c
@@ -91,6 +91,7 @@
static struct snd_soc_card bf5xx_ad1836 = {
.name = "bfin-ad1836",
+ .owner = THIS_MODULE,
.dai_link = &bf5xx_ad1836_dai[CONFIG_SND_BF5XX_SPORT_NUM],
.num_links = 1,
};
diff --git a/sound/soc/blackfin/bf5xx-ad193x.c b/sound/soc/blackfin/bf5xx-ad193x.c
index 5956584..2d8d82d 100644
--- a/sound/soc/blackfin/bf5xx-ad193x.c
+++ b/sound/soc/blackfin/bf5xx-ad193x.c
@@ -119,6 +119,7 @@
static struct snd_soc_card bf5xx_ad193x = {
.name = "bfin-ad193x",
+ .owner = THIS_MODULE,
.dai_link = &bf5xx_ad193x_dai[CONFIG_SND_BF5XX_SPORT_NUM],
.num_links = 1,
};
diff --git a/sound/soc/blackfin/bf5xx-ad1980.c b/sound/soc/blackfin/bf5xx-ad1980.c
index 06a84b2..b30f88b 100644
--- a/sound/soc/blackfin/bf5xx-ad1980.c
+++ b/sound/soc/blackfin/bf5xx-ad1980.c
@@ -74,6 +74,7 @@
static struct snd_soc_card bf5xx_board = {
.name = "bfin-ad1980",
+ .owner = THIS_MODULE,
.dai_link = &bf5xx_board_dai[CONFIG_SND_BF5XX_SPORT_NUM],
.num_links = 1,
};
diff --git a/sound/soc/blackfin/bf5xx-ad73311.c b/sound/soc/blackfin/bf5xx-ad73311.c
index b94eb7e..8e49508 100644
--- a/sound/soc/blackfin/bf5xx-ad73311.c
+++ b/sound/soc/blackfin/bf5xx-ad73311.c
@@ -192,6 +192,7 @@
static struct snd_soc_card bf5xx_ad73311 = {
.name = "bfin-ad73311",
+ .owner = THIS_MODULE,
.probe = bf5xx_probe,
.dai_link = &bf5xx_ad73311_dai[CONFIG_SND_BF5XX_SPORT_NUM],
.num_links = 1,
diff --git a/sound/soc/blackfin/bf5xx-i2s-pcm.c b/sound/soc/blackfin/bf5xx-i2s-pcm.c
index 7565e15..63205d7 100644
--- a/sound/soc/blackfin/bf5xx-i2s-pcm.c
+++ b/sound/soc/blackfin/bf5xx-i2s-pcm.c
@@ -260,7 +260,6 @@
static int bf5xx_pcm_i2s_new(struct snd_soc_pcm_runtime *rtd)
{
struct snd_card *card = rtd->card->snd_card;
- struct snd_soc_dai *dai = rtd->cpu_dai;
struct snd_pcm *pcm = rtd->pcm;
int ret = 0;
@@ -270,14 +269,14 @@
if (!card->dev->coherent_dma_mask)
card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
- if (dai->driver->playback.channels_min) {
+ if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
ret = bf5xx_pcm_preallocate_dma_buffer(pcm,
SNDRV_PCM_STREAM_PLAYBACK);
if (ret)
goto out;
}
- if (dai->driver->capture.channels_min) {
+ if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
ret = bf5xx_pcm_preallocate_dma_buffer(pcm,
SNDRV_PCM_STREAM_CAPTURE);
if (ret)
@@ -314,17 +313,7 @@
.remove = __devexit_p(bfin_i2s_soc_platform_remove),
};
-static int __init snd_bfin_i2s_pcm_init(void)
-{
- return platform_driver_register(&bfin_i2s_pcm_driver);
-}
-module_init(snd_bfin_i2s_pcm_init);
-
-static void __exit snd_bfin_i2s_pcm_exit(void)
-{
- platform_driver_unregister(&bfin_i2s_pcm_driver);
-}
-module_exit(snd_bfin_i2s_pcm_exit);
+module_platform_driver(bfin_i2s_pcm_driver);
MODULE_AUTHOR("Cliff Cai");
MODULE_DESCRIPTION("ADI Blackfin I2S PCM DMA module");
diff --git a/sound/soc/blackfin/bf5xx-i2s.c b/sound/soc/blackfin/bf5xx-i2s.c
index 00cc3e0..4dccf03 100644
--- a/sound/soc/blackfin/bf5xx-i2s.c
+++ b/sound/soc/blackfin/bf5xx-i2s.c
@@ -223,7 +223,7 @@
SNDRV_PCM_FMTBIT_S24_LE | \
SNDRV_PCM_FMTBIT_S32_LE)
-static struct snd_soc_dai_ops bf5xx_i2s_dai_ops = {
+static const struct snd_soc_dai_ops bf5xx_i2s_dai_ops = {
.shutdown = bf5xx_i2s_shutdown,
.hw_params = bf5xx_i2s_hw_params,
.set_fmt = bf5xx_i2s_set_dai_fmt,
@@ -288,18 +288,7 @@
},
};
-static int __init bfin_i2s_init(void)
-{
- return platform_driver_register(&bfin_i2s_driver);
-}
-
-static void __exit bfin_i2s_exit(void)
-{
- platform_driver_unregister(&bfin_i2s_driver);
-}
-
-module_init(bfin_i2s_init);
-module_exit(bfin_i2s_exit);
+module_platform_driver(bfin_i2s_driver);
/* Module information */
MODULE_AUTHOR("Cliff Cai");
diff --git a/sound/soc/blackfin/bf5xx-ssm2602.c b/sound/soc/blackfin/bf5xx-ssm2602.c
index 767e772..0303032 100644
--- a/sound/soc/blackfin/bf5xx-ssm2602.c
+++ b/sound/soc/blackfin/bf5xx-ssm2602.c
@@ -125,6 +125,7 @@
static struct snd_soc_card bf5xx_ssm2602 = {
.name = "bfin-ssm2602",
+ .owner = THIS_MODULE,
.dai_link = &bf5xx_ssm2602_dai[CONFIG_SND_BF5XX_SPORT_NUM],
.num_links = 1,
};
diff --git a/sound/soc/blackfin/bf5xx-tdm-pcm.c b/sound/soc/blackfin/bf5xx-tdm-pcm.c
index c95cc03..254490c 100644
--- a/sound/soc/blackfin/bf5xx-tdm-pcm.c
+++ b/sound/soc/blackfin/bf5xx-tdm-pcm.c
@@ -286,7 +286,6 @@
static int bf5xx_pcm_tdm_new(struct snd_soc_pcm_runtime *rtd)
{
struct snd_card *card = rtd->card->snd_card;
- struct snd_soc_dai *dai = rtd->cpu_dai;
struct snd_pcm *pcm = rtd->pcm;
int ret = 0;
@@ -295,14 +294,14 @@
if (!card->dev->coherent_dma_mask)
card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
- if (dai->driver->playback.channels_min) {
+ if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
ret = bf5xx_pcm_preallocate_dma_buffer(pcm,
SNDRV_PCM_STREAM_PLAYBACK);
if (ret)
goto out;
}
- if (dai->driver->capture.channels_min) {
+ if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
ret = bf5xx_pcm_preallocate_dma_buffer(pcm,
SNDRV_PCM_STREAM_CAPTURE);
if (ret)
@@ -339,17 +338,7 @@
.remove = __devexit_p(bf5xx_soc_platform_remove),
};
-static int __init snd_bfin_tdm_init(void)
-{
- return platform_driver_register(&bfin_tdm_driver);
-}
-module_init(snd_bfin_tdm_init);
-
-static void __exit snd_bfin_tdm_exit(void)
-{
- platform_driver_unregister(&bfin_tdm_driver);
-}
-module_exit(snd_bfin_tdm_exit);
+module_platform_driver(bfin_tdm_driver);
MODULE_AUTHOR("Barry Song");
MODULE_DESCRIPTION("ADI Blackfin TDM PCM DMA module");
diff --git a/sound/soc/blackfin/bf5xx-tdm.c b/sound/soc/blackfin/bf5xx-tdm.c
index a822d1e..594f882 100644
--- a/sound/soc/blackfin/bf5xx-tdm.c
+++ b/sound/soc/blackfin/bf5xx-tdm.c
@@ -226,7 +226,7 @@
#define bf5xx_tdm_resume NULL
#endif
-static struct snd_soc_dai_ops bf5xx_tdm_dai_ops = {
+static const struct snd_soc_dai_ops bf5xx_tdm_dai_ops = {
.hw_params = bf5xx_tdm_hw_params,
.set_fmt = bf5xx_tdm_set_dai_fmt,
.shutdown = bf5xx_tdm_shutdown,
@@ -314,17 +314,7 @@
},
};
-static int __init bfin_tdm_init(void)
-{
- return platform_driver_register(&bfin_tdm_driver);
-}
-module_init(bfin_tdm_init);
-
-static void __exit bfin_tdm_exit(void)
-{
- platform_driver_unregister(&bfin_tdm_driver);
-}
-module_exit(bfin_tdm_exit);
+module_platform_driver(bfin_tdm_driver);
/* Module information */
MODULE_AUTHOR("Barry Song");
diff --git a/sound/soc/blackfin/bfin-eval-adau1373.c b/sound/soc/blackfin/bfin-eval-adau1373.c
index 8df2a3b..26b271c 100644
--- a/sound/soc/blackfin/bfin-eval-adau1373.c
+++ b/sound/soc/blackfin/bfin-eval-adau1373.c
@@ -147,6 +147,7 @@
static struct snd_soc_card bfin_eval_adau1373 = {
.name = "bfin-eval-adau1373",
+ .owner = THIS_MODULE,
.dai_link = &bfin_eval_adau1373_dai,
.num_links = 1,
@@ -184,17 +185,7 @@
.remove = __devexit_p(bfin_eval_adau1373_remove),
};
-static int __init bfin_eval_adau1373_init(void)
-{
- return platform_driver_register(&bfin_eval_adau1373_driver);
-}
-module_init(bfin_eval_adau1373_init);
-
-static void __exit bfin_eval_adau1373_exit(void)
-{
- platform_driver_unregister(&bfin_eval_adau1373_driver);
-}
-module_exit(bfin_eval_adau1373_exit);
+module_platform_driver(bfin_eval_adau1373_driver);
MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
MODULE_DESCRIPTION("ALSA SoC bfin adau1373 driver");
diff --git a/sound/soc/blackfin/bfin-eval-adau1701.c b/sound/soc/blackfin/bfin-eval-adau1701.c
index e5550ac..c0064fa 100644
--- a/sound/soc/blackfin/bfin-eval-adau1701.c
+++ b/sound/soc/blackfin/bfin-eval-adau1701.c
@@ -84,6 +84,7 @@
static struct snd_soc_card bfin_eval_adau1701 = {
.name = "bfin-eval-adau1701",
+ .owner = THIS_MODULE,
.dai_link = &bfin_eval_adau1701_dai[CONFIG_SND_BF5XX_SPORT_NUM],
.num_links = 1,
@@ -121,17 +122,7 @@
.remove = __devexit_p(bfin_eval_adau1701_remove),
};
-static int __init bfin_eval_adau1701_init(void)
-{
- return platform_driver_register(&bfin_eval_adau1701_driver);
-}
-module_init(bfin_eval_adau1701_init);
-
-static void __exit bfin_eval_adau1701_exit(void)
-{
- platform_driver_unregister(&bfin_eval_adau1701_driver);
-}
-module_exit(bfin_eval_adau1701_exit);
+module_platform_driver(bfin_eval_adau1701_driver);
MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
MODULE_DESCRIPTION("ALSA SoC bfin ADAU1701 driver");
diff --git a/sound/soc/blackfin/bfin-eval-adav80x.c b/sound/soc/blackfin/bfin-eval-adav80x.c
index 897cfa6..4ef079f 100644
--- a/sound/soc/blackfin/bfin-eval-adav80x.c
+++ b/sound/soc/blackfin/bfin-eval-adav80x.c
@@ -93,6 +93,7 @@
static struct snd_soc_card bfin_eval_adav80x = {
.name = "bfin-eval-adav80x",
+ .owner = THIS_MODULE,
.dai_link = bfin_eval_adav80x_dais,
.num_links = ARRAY_SIZE(bfin_eval_adav80x_dais),
@@ -157,17 +158,7 @@
.id_table = bfin_eval_adav80x_ids,
};
-static int __init bfin_eval_adav80x_init(void)
-{
- return platform_driver_register(&bfin_eval_adav80x_driver);
-}
-module_init(bfin_eval_adav80x_init);
-
-static void __exit bfin_eval_adav80x_exit(void)
-{
- platform_driver_unregister(&bfin_eval_adav80x_driver);
-}
-module_exit(bfin_eval_adav80x_exit);
+module_platform_driver(bfin_eval_adav80x_driver);
MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
MODULE_DESCRIPTION("ALSA SoC bfin adav80x driver");
diff --git a/sound/soc/codecs/88pm860x-codec.c b/sound/soc/codecs/88pm860x-codec.c
index 5ca122e..9fd3b68 100644
--- a/sound/soc/codecs/88pm860x-codec.c
+++ b/sound/soc/codecs/88pm860x-codec.c
@@ -861,7 +861,7 @@
PM860X_DAPM_OUTPUT("RSYNC", pm860x_rsync_event),
};
-static const struct snd_soc_dapm_route audio_map[] = {
+static const struct snd_soc_dapm_route pm860x_dapm_routes[] = {
/* supply */
{"Left DAC", NULL, "VCODEC"},
{"Right DAC", NULL, "VCODEC"},
@@ -1198,14 +1198,14 @@
return 0;
}
-static struct snd_soc_dai_ops pm860x_pcm_dai_ops = {
+static const struct snd_soc_dai_ops pm860x_pcm_dai_ops = {
.digital_mute = pm860x_digital_mute,
.hw_params = pm860x_pcm_hw_params,
.set_fmt = pm860x_pcm_set_dai_fmt,
.set_sysclk = pm860x_set_dai_sysclk,
};
-static struct snd_soc_dai_ops pm860x_i2s_dai_ops = {
+static const struct snd_soc_dai_ops pm860x_i2s_dai_ops = {
.digital_mute = pm860x_digital_mute,
.hw_params = pm860x_i2s_hw_params,
.set_fmt = pm860x_i2s_set_dai_fmt,
@@ -1361,7 +1361,6 @@
static int pm860x_probe(struct snd_soc_codec *codec)
{
struct pm860x_priv *pm860x = snd_soc_codec_get_drvdata(codec);
- struct snd_soc_dapm_context *dapm = &codec->dapm;
int i, ret;
pm860x->codec = codec;
@@ -1388,11 +1387,6 @@
goto out;
}
- snd_soc_add_controls(codec, pm860x_snd_controls,
- ARRAY_SIZE(pm860x_snd_controls));
- snd_soc_dapm_new_controls(dapm, pm860x_dapm_widgets,
- ARRAY_SIZE(pm860x_dapm_widgets));
- snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
return 0;
out:
@@ -1420,6 +1414,13 @@
.reg_cache_size = REG_CACHE_SIZE,
.reg_word_size = sizeof(u8),
.set_bias_level = pm860x_set_bias_level,
+
+ .controls = pm860x_snd_controls,
+ .num_controls = ARRAY_SIZE(pm860x_snd_controls),
+ .dapm_widgets = pm860x_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(pm860x_dapm_widgets),
+ .dapm_routes = pm860x_dapm_routes,
+ .num_dapm_routes = ARRAY_SIZE(pm860x_dapm_routes),
};
static int __devinit pm860x_codec_probe(struct platform_device *pdev)
@@ -1429,7 +1430,8 @@
struct resource *res;
int i, ret;
- pm860x = kzalloc(sizeof(struct pm860x_priv), GFP_KERNEL);
+ pm860x = devm_kzalloc(&pdev->dev, sizeof(struct pm860x_priv),
+ GFP_KERNEL);
if (pm860x == NULL)
return -ENOMEM;
@@ -1458,17 +1460,13 @@
out:
platform_set_drvdata(pdev, NULL);
- kfree(pm860x);
return -EINVAL;
}
static int __devexit pm860x_codec_remove(struct platform_device *pdev)
{
- struct pm860x_priv *pm860x = platform_get_drvdata(pdev);
-
snd_soc_unregister_codec(&pdev->dev);
platform_set_drvdata(pdev, NULL);
- kfree(pm860x);
return 0;
}
@@ -1481,17 +1479,7 @@
.remove = __devexit_p(pm860x_codec_remove),
};
-static __init int pm860x_init(void)
-{
- return platform_driver_register(&pm860x_codec_driver);
-}
-module_init(pm860x_init);
-
-static __exit void pm860x_exit(void)
-{
- platform_driver_unregister(&pm860x_codec_driver);
-}
-module_exit(pm860x_exit);
+module_platform_driver(pm860x_codec_driver);
MODULE_DESCRIPTION("ASoC 88PM860x driver");
MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index fa787d4..7c205e7 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -26,8 +26,10 @@
select SND_SOC_AK4642 if I2C
select SND_SOC_AK4671 if I2C
select SND_SOC_ALC5623 if I2C
+ select SND_SOC_ALC5632 if I2C
select SND_SOC_CQ0093VC if MFD_DAVINCI_VOICECODEC
select SND_SOC_CS42L51 if I2C
+ select SND_SOC_CS42L73 if I2C
select SND_SOC_CS4270 if I2C
select SND_SOC_CS4271 if SND_SOC_I2C_AND_SPI
select SND_SOC_CX20442
@@ -139,7 +141,7 @@
tristate
config SND_SOC_ADAU1701
- select SIGMA
+ select SND_SOC_SIGMADSP
tristate
config SND_SOC_ADAU1373
@@ -168,6 +170,8 @@
config SND_SOC_ALC5623
tristate
+config SND_SOC_ALC5632
+ tristate
config SND_SOC_CQ0093VC
tristate
@@ -175,6 +179,9 @@
config SND_SOC_CS42L51
tristate
+config SND_SOC_CS42L73
+ tristate
+
# Cirrus Logic CS4270 Codec
config SND_SOC_CS4270
tristate
@@ -227,6 +234,10 @@
config SND_SOC_SGTL5000
tristate
+config SND_SOC_SIGMADSP
+ tristate
+ select CRC32
+
config SND_SOC_SN95031
tristate
@@ -278,6 +289,9 @@
config SND_SOC_WM1250_EV1
tristate
+config SND_SOC_WM2000
+ tristate
+
config SND_SOC_WM5100
tristate
@@ -395,6 +409,9 @@
config SND_SOC_WM9081
tristate
+config SND_SOC_WM9090
+ tristate
+
config SND_SOC_WM9705
tristate
@@ -413,9 +430,3 @@
config SND_SOC_TPA6130A2
tristate
-
-config SND_SOC_WM2000
- tristate
-
-config SND_SOC_WM9090
- tristate
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index a2c7842..de80781 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -15,13 +15,16 @@
snd-soc-ak4671-objs := ak4671.o
snd-soc-cq93vc-objs := cq93vc.o
snd-soc-cs42l51-objs := cs42l51.o
+snd-soc-cs42l73-objs := cs42l73.o
snd-soc-cs4270-objs := cs4270.o
snd-soc-cs4271-objs := cs4271.o
snd-soc-cx20442-objs := cx20442.o
snd-soc-da7210-objs := da7210.o
snd-soc-dfbmcs320-objs := dfbmcs320.o
snd-soc-dmic-objs := dmic.o
+snd-soc-jz4740-codec-objs := jz4740.o
snd-soc-l3-objs := l3.o
+snd-soc-lm4857-objs := lm4857.o
snd-soc-max98088-objs := max98088.o
snd-soc-max98095-objs := max98095.o
snd-soc-max9850-objs := max9850.o
@@ -29,6 +32,8 @@
snd-soc-rt5631-objs := rt5631.o
snd-soc-sgtl5000-objs := sgtl5000.o
snd-soc-alc5623-objs := alc5623.o
+snd-soc-alc5632-objs := alc5632.o
+snd-soc-sigmadsp-objs := sigmadsp.o
snd-soc-sn95031-objs := sn95031.o
snd-soc-spdif-objs := spdif_transciever.o
snd-soc-ssm2602-objs := ssm2602.o
@@ -45,6 +50,7 @@
snd-soc-uda1380-objs := uda1380.o
snd-soc-wl1273-objs := wl1273.o
snd-soc-wm1250-ev1-objs := wm1250-ev1.o
+snd-soc-wm2000-objs := wm2000.o
snd-soc-wm5100-objs := wm5100.o wm5100-tables.o
snd-soc-wm8350-objs := wm8350.o
snd-soc-wm8400-objs := wm8400.o
@@ -81,21 +87,18 @@
snd-soc-wm8990-objs := wm8990.o
snd-soc-wm8991-objs := wm8991.o
snd-soc-wm8993-objs := wm8993.o
-snd-soc-wm8994-objs := wm8994.o wm8994-tables.o wm8958-dsp2.o
+snd-soc-wm8994-objs := wm8994.o wm8958-dsp2.o
snd-soc-wm8995-objs := wm8995.o
snd-soc-wm9081-objs := wm9081.o
+snd-soc-wm9090-objs := wm9090.o
snd-soc-wm9705-objs := wm9705.o
snd-soc-wm9712-objs := wm9712.o
snd-soc-wm9713-objs := wm9713.o
snd-soc-wm-hubs-objs := wm_hubs.o
-snd-soc-jz4740-codec-objs := jz4740.o
# Amp
-snd-soc-lm4857-objs := lm4857.o
snd-soc-max9877-objs := max9877.o
snd-soc-tpa6130a2-objs := tpa6130a2.o
-snd-soc-wm2000-objs := wm2000.o
-snd-soc-wm9090-objs := wm9090.o
obj-$(CONFIG_SND_SOC_88PM860X) += snd-soc-88pm860x.o
obj-$(CONFIG_SND_SOC_AC97_CODEC) += snd-soc-ac97.o
@@ -113,8 +116,10 @@
obj-$(CONFIG_SND_SOC_AK4642) += snd-soc-ak4642.o
obj-$(CONFIG_SND_SOC_AK4671) += snd-soc-ak4671.o
obj-$(CONFIG_SND_SOC_ALC5623) += snd-soc-alc5623.o
+obj-$(CONFIG_SND_SOC_ALC5632) += snd-soc-alc5632.o
obj-$(CONFIG_SND_SOC_CQ0093VC) += snd-soc-cq93vc.o
obj-$(CONFIG_SND_SOC_CS42L51) += snd-soc-cs42l51.o
+obj-$(CONFIG_SND_SOC_CS42L73) += snd-soc-cs42l73.o
obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o
obj-$(CONFIG_SND_SOC_CS4271) += snd-soc-cs4271.o
obj-$(CONFIG_SND_SOC_CX20442) += snd-soc-cx20442.o
@@ -122,6 +127,7 @@
obj-$(CONFIG_SND_SOC_DFBMCS320) += snd-soc-dfbmcs320.o
obj-$(CONFIG_SND_SOC_DMIC) += snd-soc-dmic.o
obj-$(CONFIG_SND_SOC_L3) += snd-soc-l3.o
+obj-$(CONFIG_SND_SOC_LM4857) += snd-soc-lm4857.o
obj-$(CONFIG_SND_SOC_JZ4740_CODEC) += snd-soc-jz4740-codec.o
obj-$(CONFIG_SND_SOC_MAX98088) += snd-soc-max98088.o
obj-$(CONFIG_SND_SOC_MAX98095) += snd-soc-max98095.o
@@ -129,6 +135,7 @@
obj-$(CONFIG_SND_SOC_PCM3008) += snd-soc-pcm3008.o
obj-$(CONFIG_SND_SOC_RT5631) += snd-soc-rt5631.o
obj-$(CONFIG_SND_SOC_SGTL5000) += snd-soc-sgtl5000.o
+obj-$(CONFIG_SND_SOC_SIGMADSP) += snd-soc-sigmadsp.o
obj-$(CONFIG_SND_SOC_SN95031) +=snd-soc-sn95031.o
obj-$(CONFIG_SND_SOC_SPDIF) += snd-soc-spdif.o
obj-$(CONFIG_SND_SOC_SSM2602) += snd-soc-ssm2602.o
@@ -145,6 +152,7 @@
obj-$(CONFIG_SND_SOC_UDA1380) += snd-soc-uda1380.o
obj-$(CONFIG_SND_SOC_WL1273) += snd-soc-wl1273.o
obj-$(CONFIG_SND_SOC_WM1250_EV1) += snd-soc-wm1250-ev1.o
+obj-$(CONFIG_SND_SOC_WM2000) += snd-soc-wm2000.o
obj-$(CONFIG_SND_SOC_WM5100) += snd-soc-wm5100.o
obj-$(CONFIG_SND_SOC_WM8350) += snd-soc-wm8350.o
obj-$(CONFIG_SND_SOC_WM8400) += snd-soc-wm8400.o
@@ -184,14 +192,12 @@
obj-$(CONFIG_SND_SOC_WM8994) += snd-soc-wm8994.o
obj-$(CONFIG_SND_SOC_WM8995) += snd-soc-wm8995.o
obj-$(CONFIG_SND_SOC_WM9081) += snd-soc-wm9081.o
+obj-$(CONFIG_SND_SOC_WM9090) += snd-soc-wm9090.o
obj-$(CONFIG_SND_SOC_WM9705) += snd-soc-wm9705.o
obj-$(CONFIG_SND_SOC_WM9712) += snd-soc-wm9712.o
obj-$(CONFIG_SND_SOC_WM9713) += snd-soc-wm9713.o
obj-$(CONFIG_SND_SOC_WM_HUBS) += snd-soc-wm-hubs.o
# Amp
-obj-$(CONFIG_SND_SOC_LM4857) += snd-soc-lm4857.o
obj-$(CONFIG_SND_SOC_MAX9877) += snd-soc-max9877.o
obj-$(CONFIG_SND_SOC_TPA6130A2) += snd-soc-tpa6130a2.o
-obj-$(CONFIG_SND_SOC_WM2000) += snd-soc-wm2000.o
-obj-$(CONFIG_SND_SOC_WM9090) += snd-soc-wm9090.o
diff --git a/sound/soc/codecs/ac97.c b/sound/soc/codecs/ac97.c
index e715186..1bbad4c 100644
--- a/sound/soc/codecs/ac97.c
+++ b/sound/soc/codecs/ac97.c
@@ -39,7 +39,7 @@
SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_44100 |\
SNDRV_PCM_RATE_48000)
-static struct snd_soc_dai_ops ac97_dai_ops = {
+static const struct snd_soc_dai_ops ac97_dai_ops = {
.prepare = ac97_prepare,
};
@@ -99,7 +99,7 @@
}
#ifdef CONFIG_PM
-static int ac97_soc_suspend(struct snd_soc_codec *codec, pm_message_t msg)
+static int ac97_soc_suspend(struct snd_soc_codec *codec)
{
snd_ac97_suspend(codec->ac97);
@@ -148,17 +148,7 @@
.remove = __devexit_p(ac97_remove),
};
-static int __init ac97_init(void)
-{
- return platform_driver_register(&ac97_codec_driver);
-}
-module_init(ac97_init);
-
-static void __exit ac97_exit(void)
-{
- platform_driver_unregister(&ac97_codec_driver);
-}
-module_exit(ac97_exit);
+module_platform_driver(ac97_codec_driver);
MODULE_DESCRIPTION("Soc Generic AC97 driver");
MODULE_AUTHOR("Liam Girdwood");
diff --git a/sound/soc/codecs/ad1836.c b/sound/soc/codecs/ad1836.c
index 4e5c572..982d201 100644
--- a/sound/soc/codecs/ad1836.c
+++ b/sound/soc/codecs/ad1836.c
@@ -189,7 +189,7 @@
return 0;
}
-static struct snd_soc_dai_ops ad1836_dai_ops = {
+static const struct snd_soc_dai_ops ad1836_dai_ops = {
.hw_params = ad1836_hw_params,
.set_fmt = ad1836_set_dai_fmt,
};
@@ -223,7 +223,7 @@
};
#ifdef CONFIG_PM
-static int ad1836_suspend(struct snd_soc_codec *codec, pm_message_t state)
+static int ad1836_suspend(struct snd_soc_codec *codec)
{
/* reset clock control mode */
return snd_soc_update_bits(codec, AD1836_ADC_CTRL2,
@@ -341,7 +341,8 @@
struct ad1836_priv *ad1836;
int ret;
- ad1836 = kzalloc(sizeof(struct ad1836_priv), GFP_KERNEL);
+ ad1836 = devm_kzalloc(&spi->dev, sizeof(struct ad1836_priv),
+ GFP_KERNEL);
if (ad1836 == NULL)
return -ENOMEM;
@@ -351,17 +352,15 @@
ret = snd_soc_register_codec(&spi->dev,
&soc_codec_dev_ad1836, &ad183x_dais[ad1836->type], 1);
- if (ret < 0)
- kfree(ad1836);
return ret;
}
static int __devexit ad1836_spi_remove(struct spi_device *spi)
{
snd_soc_unregister_codec(&spi->dev);
- kfree(spi_get_drvdata(spi));
return 0;
}
+
static const struct spi_device_id ad1836_ids[] = {
{ "ad1835", AD1835 },
{ "ad1836", AD1836 },
diff --git a/sound/soc/codecs/ad193x.c b/sound/soc/codecs/ad193x.c
index 1206021..a4a6bef 100644
--- a/sound/soc/codecs/ad193x.c
+++ b/sound/soc/codecs/ad193x.c
@@ -30,21 +30,23 @@
/*
* AD193X volume/mute/de-emphasis etc. controls
*/
-static const char *ad193x_deemp[] = {"None", "48kHz", "44.1kHz", "32kHz"};
+static const char * const ad193x_deemp[] = {"None", "48kHz", "44.1kHz", "32kHz"};
static const struct soc_enum ad193x_deemp_enum =
SOC_ENUM_SINGLE(AD193X_DAC_CTRL2, 1, 4, ad193x_deemp);
+static const DECLARE_TLV_DB_MINMAX(adau193x_tlv, -9563, 0);
+
static const struct snd_kcontrol_new ad193x_snd_controls[] = {
/* DAC volume control */
- SOC_DOUBLE_R("DAC1 Volume", AD193X_DAC_L1_VOL,
- AD193X_DAC_R1_VOL, 0, 0xFF, 1),
- SOC_DOUBLE_R("DAC2 Volume", AD193X_DAC_L2_VOL,
- AD193X_DAC_R2_VOL, 0, 0xFF, 1),
- SOC_DOUBLE_R("DAC3 Volume", AD193X_DAC_L3_VOL,
- AD193X_DAC_R3_VOL, 0, 0xFF, 1),
- SOC_DOUBLE_R("DAC4 Volume", AD193X_DAC_L4_VOL,
- AD193X_DAC_R4_VOL, 0, 0xFF, 1),
+ SOC_DOUBLE_R_TLV("DAC1 Volume", AD193X_DAC_L1_VOL,
+ AD193X_DAC_R1_VOL, 0, 0xFF, 1, adau193x_tlv),
+ SOC_DOUBLE_R_TLV("DAC2 Volume", AD193X_DAC_L2_VOL,
+ AD193X_DAC_R2_VOL, 0, 0xFF, 1, adau193x_tlv),
+ SOC_DOUBLE_R_TLV("DAC3 Volume", AD193X_DAC_L3_VOL,
+ AD193X_DAC_R3_VOL, 0, 0xFF, 1, adau193x_tlv),
+ SOC_DOUBLE_R_TLV("DAC4 Volume", AD193X_DAC_L4_VOL,
+ AD193X_DAC_R4_VOL, 0, 0xFF, 1, adau193x_tlv),
/* ADC switch control */
SOC_DOUBLE("ADC1 Switch", AD193X_ADC_CTRL0, AD193X_ADCL1_MUTE,
@@ -75,6 +77,7 @@
SND_SOC_DAPM_ADC("ADC", "Capture", SND_SOC_NOPM, 0, 0),
SND_SOC_DAPM_SUPPLY("PLL_PWR", AD193X_PLL_CLK_CTRL0, 0, 1, NULL, 0),
SND_SOC_DAPM_SUPPLY("ADC_PWR", AD193X_ADC_CTRL0, 0, 1, NULL, 0),
+ SND_SOC_DAPM_SUPPLY("SYSCLK", AD193X_PLL_CLK_CTRL0, 7, 0, NULL, 0),
SND_SOC_DAPM_OUTPUT("DAC1OUT"),
SND_SOC_DAPM_OUTPUT("DAC2OUT"),
SND_SOC_DAPM_OUTPUT("DAC3OUT"),
@@ -84,16 +87,17 @@
};
static const struct snd_soc_dapm_route audio_paths[] = {
- { "DAC", NULL, "PLL_PWR" },
- { "ADC", NULL, "PLL_PWR" },
+ { "DAC", NULL, "SYSCLK" },
+ { "ADC", NULL, "SYSCLK" },
{ "DAC", NULL, "ADC_PWR" },
{ "ADC", NULL, "ADC_PWR" },
- { "DAC1OUT", "DAC1 Switch", "DAC" },
- { "DAC2OUT", "DAC2 Switch", "DAC" },
- { "DAC3OUT", "DAC3 Switch", "DAC" },
- { "DAC4OUT", "DAC4 Switch", "DAC" },
- { "ADC", "ADC1 Switch", "ADC1IN" },
- { "ADC", "ADC2 Switch", "ADC2IN" },
+ { "DAC1OUT", NULL, "DAC" },
+ { "DAC2OUT", NULL, "DAC" },
+ { "DAC3OUT", NULL, "DAC" },
+ { "DAC4OUT", NULL, "DAC" },
+ { "ADC", NULL, "ADC1IN" },
+ { "ADC", NULL, "ADC2IN" },
+ { "SYSCLK", NULL, "PLL_PWR" },
};
/*
@@ -102,14 +106,14 @@
static int ad193x_mute(struct snd_soc_dai *dai, int mute)
{
- struct snd_soc_codec *codec = dai->codec;
+ struct ad193x_priv *ad193x = snd_soc_codec_get_drvdata(dai->codec);
if (mute)
- snd_soc_update_bits(codec, AD193X_DAC_CTRL2,
+ regmap_update_bits(ad193x->regmap, AD193X_DAC_CTRL2,
AD193X_DAC_MASTER_MUTE,
AD193X_DAC_MASTER_MUTE);
else
- snd_soc_update_bits(codec, AD193X_DAC_CTRL2,
+ regmap_update_bits(ad193x->regmap, AD193X_DAC_CTRL2,
AD193X_DAC_MASTER_MUTE, 0);
return 0;
@@ -118,36 +122,30 @@
static int ad193x_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
unsigned int rx_mask, int slots, int width)
{
- struct snd_soc_codec *codec = dai->codec;
- int dac_reg = snd_soc_read(codec, AD193X_DAC_CTRL1);
- int adc_reg = snd_soc_read(codec, AD193X_ADC_CTRL2);
-
- dac_reg &= ~AD193X_DAC_CHAN_MASK;
- adc_reg &= ~AD193X_ADC_CHAN_MASK;
+ struct ad193x_priv *ad193x = snd_soc_codec_get_drvdata(dai->codec);
+ unsigned int channels;
switch (slots) {
case 2:
- dac_reg |= AD193X_DAC_2_CHANNELS << AD193X_DAC_CHAN_SHFT;
- adc_reg |= AD193X_ADC_2_CHANNELS << AD193X_ADC_CHAN_SHFT;
+ channels = AD193X_2_CHANNELS;
break;
case 4:
- dac_reg |= AD193X_DAC_4_CHANNELS << AD193X_DAC_CHAN_SHFT;
- adc_reg |= AD193X_ADC_4_CHANNELS << AD193X_ADC_CHAN_SHFT;
+ channels = AD193X_4_CHANNELS;
break;
case 8:
- dac_reg |= AD193X_DAC_8_CHANNELS << AD193X_DAC_CHAN_SHFT;
- adc_reg |= AD193X_ADC_8_CHANNELS << AD193X_ADC_CHAN_SHFT;
+ channels = AD193X_8_CHANNELS;
break;
case 16:
- dac_reg |= AD193X_DAC_16_CHANNELS << AD193X_DAC_CHAN_SHFT;
- adc_reg |= AD193X_ADC_16_CHANNELS << AD193X_ADC_CHAN_SHFT;
+ channels = AD193X_16_CHANNELS;
break;
default:
return -EINVAL;
}
- snd_soc_write(codec, AD193X_DAC_CTRL1, dac_reg);
- snd_soc_write(codec, AD193X_ADC_CTRL2, adc_reg);
+ regmap_update_bits(ad193x->regmap, AD193X_DAC_CTRL1,
+ AD193X_DAC_CHAN_MASK, channels << AD193X_DAC_CHAN_SHFT);
+ regmap_update_bits(ad193x->regmap, AD193X_ADC_CTRL2,
+ AD193X_ADC_CHAN_MASK, channels << AD193X_ADC_CHAN_SHFT);
return 0;
}
@@ -155,24 +153,20 @@
static int ad193x_set_dai_fmt(struct snd_soc_dai *codec_dai,
unsigned int fmt)
{
- struct snd_soc_codec *codec = codec_dai->codec;
- int adc_reg1, adc_reg2, dac_reg;
-
- adc_reg1 = snd_soc_read(codec, AD193X_ADC_CTRL1);
- adc_reg2 = snd_soc_read(codec, AD193X_ADC_CTRL2);
- dac_reg = snd_soc_read(codec, AD193X_DAC_CTRL1);
+ struct ad193x_priv *ad193x = snd_soc_codec_get_drvdata(codec_dai->codec);
+ unsigned int adc_serfmt = 0;
+ unsigned int adc_fmt = 0;
+ unsigned int dac_fmt = 0;
/* At present, the driver only support AUX ADC mode(SND_SOC_DAIFMT_I2S
* with TDM) and ADC&DAC TDM mode(SND_SOC_DAIFMT_DSP_A)
*/
switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
case SND_SOC_DAIFMT_I2S:
- adc_reg1 &= ~AD193X_ADC_SERFMT_MASK;
- adc_reg1 |= AD193X_ADC_SERFMT_TDM;
+ adc_serfmt |= AD193X_ADC_SERFMT_TDM;
break;
case SND_SOC_DAIFMT_DSP_A:
- adc_reg1 &= ~AD193X_ADC_SERFMT_MASK;
- adc_reg1 |= AD193X_ADC_SERFMT_AUX;
+ adc_serfmt |= AD193X_ADC_SERFMT_AUX;
break;
default:
return -EINVAL;
@@ -180,29 +174,20 @@
switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
case SND_SOC_DAIFMT_NB_NF: /* normal bit clock + frame */
- adc_reg2 &= ~AD193X_ADC_LEFT_HIGH;
- adc_reg2 &= ~AD193X_ADC_BCLK_INV;
- dac_reg &= ~AD193X_DAC_LEFT_HIGH;
- dac_reg &= ~AD193X_DAC_BCLK_INV;
break;
case SND_SOC_DAIFMT_NB_IF: /* normal bclk + invert frm */
- adc_reg2 |= AD193X_ADC_LEFT_HIGH;
- adc_reg2 &= ~AD193X_ADC_BCLK_INV;
- dac_reg |= AD193X_DAC_LEFT_HIGH;
- dac_reg &= ~AD193X_DAC_BCLK_INV;
+ adc_fmt |= AD193X_ADC_LEFT_HIGH;
+ dac_fmt |= AD193X_DAC_LEFT_HIGH;
break;
case SND_SOC_DAIFMT_IB_NF: /* invert bclk + normal frm */
- adc_reg2 &= ~AD193X_ADC_LEFT_HIGH;
- adc_reg2 |= AD193X_ADC_BCLK_INV;
- dac_reg &= ~AD193X_DAC_LEFT_HIGH;
- dac_reg |= AD193X_DAC_BCLK_INV;
+ adc_fmt |= AD193X_ADC_BCLK_INV;
+ dac_fmt |= AD193X_DAC_BCLK_INV;
break;
-
case SND_SOC_DAIFMT_IB_IF: /* invert bclk + frm */
- adc_reg2 |= AD193X_ADC_LEFT_HIGH;
- adc_reg2 |= AD193X_ADC_BCLK_INV;
- dac_reg |= AD193X_DAC_LEFT_HIGH;
- dac_reg |= AD193X_DAC_BCLK_INV;
+ adc_fmt |= AD193X_ADC_LEFT_HIGH;
+ adc_fmt |= AD193X_ADC_BCLK_INV;
+ dac_fmt |= AD193X_DAC_LEFT_HIGH;
+ dac_fmt |= AD193X_DAC_BCLK_INV;
break;
default:
return -EINVAL;
@@ -210,36 +195,31 @@
switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
case SND_SOC_DAIFMT_CBM_CFM: /* codec clk & frm master */
- adc_reg2 |= AD193X_ADC_LCR_MASTER;
- adc_reg2 |= AD193X_ADC_BCLK_MASTER;
- dac_reg |= AD193X_DAC_LCR_MASTER;
- dac_reg |= AD193X_DAC_BCLK_MASTER;
+ adc_fmt |= AD193X_ADC_LCR_MASTER;
+ adc_fmt |= AD193X_ADC_BCLK_MASTER;
+ dac_fmt |= AD193X_DAC_LCR_MASTER;
+ dac_fmt |= AD193X_DAC_BCLK_MASTER;
break;
case SND_SOC_DAIFMT_CBS_CFM: /* codec clk slave & frm master */
- adc_reg2 |= AD193X_ADC_LCR_MASTER;
- adc_reg2 &= ~AD193X_ADC_BCLK_MASTER;
- dac_reg |= AD193X_DAC_LCR_MASTER;
- dac_reg &= ~AD193X_DAC_BCLK_MASTER;
+ adc_fmt |= AD193X_ADC_LCR_MASTER;
+ dac_fmt |= AD193X_DAC_LCR_MASTER;
break;
case SND_SOC_DAIFMT_CBM_CFS: /* codec clk master & frame slave */
- adc_reg2 &= ~AD193X_ADC_LCR_MASTER;
- adc_reg2 |= AD193X_ADC_BCLK_MASTER;
- dac_reg &= ~AD193X_DAC_LCR_MASTER;
- dac_reg |= AD193X_DAC_BCLK_MASTER;
+ adc_fmt |= AD193X_ADC_BCLK_MASTER;
+ dac_fmt |= AD193X_DAC_BCLK_MASTER;
break;
case SND_SOC_DAIFMT_CBS_CFS: /* codec clk & frm slave */
- adc_reg2 &= ~AD193X_ADC_LCR_MASTER;
- adc_reg2 &= ~AD193X_ADC_BCLK_MASTER;
- dac_reg &= ~AD193X_DAC_LCR_MASTER;
- dac_reg &= ~AD193X_DAC_BCLK_MASTER;
break;
default:
return -EINVAL;
}
- snd_soc_write(codec, AD193X_ADC_CTRL1, adc_reg1);
- snd_soc_write(codec, AD193X_ADC_CTRL2, adc_reg2);
- snd_soc_write(codec, AD193X_DAC_CTRL1, dac_reg);
+ regmap_update_bits(ad193x->regmap, AD193X_ADC_CTRL1,
+ AD193X_ADC_SERFMT_MASK, adc_serfmt);
+ regmap_update_bits(ad193x->regmap, AD193X_ADC_CTRL2,
+ AD193X_ADC_FMT_MASK, adc_fmt);
+ regmap_update_bits(ad193x->regmap, AD193X_DAC_CTRL1,
+ AD193X_DAC_FMT_MASK, dac_fmt);
return 0;
}
@@ -299,20 +279,20 @@
break;
}
- snd_soc_update_bits(codec, AD193X_PLL_CLK_CTRL0,
+ regmap_update_bits(ad193x->regmap, AD193X_PLL_CLK_CTRL0,
AD193X_PLL_INPUT_MASK, master_rate);
- snd_soc_update_bits(codec, AD193X_DAC_CTRL2,
+ regmap_update_bits(ad193x->regmap, AD193X_DAC_CTRL2,
AD193X_DAC_WORD_LEN_MASK,
word_len << AD193X_DAC_WORD_LEN_SHFT);
- snd_soc_update_bits(codec, AD193X_ADC_CTRL1,
+ regmap_update_bits(ad193x->regmap, AD193X_ADC_CTRL1,
AD193X_ADC_WORD_LEN_MASK, word_len);
return 0;
}
-static struct snd_soc_dai_ops ad193x_dai_ops = {
+static const struct snd_soc_dai_ops ad193x_dai_ops = {
.hw_params = ad193x_hw_params,
.digital_mute = ad193x_mute,
.set_tdm_slot = ad193x_set_tdm_slot,
@@ -345,7 +325,6 @@
static int ad193x_probe(struct snd_soc_codec *codec)
{
struct ad193x_priv *ad193x = snd_soc_codec_get_drvdata(codec);
- struct snd_soc_dapm_context *dapm = &codec->dapm;
int ret;
codec->control_data = ad193x->regmap;
@@ -358,32 +337,37 @@
/* default setting for ad193x */
/* unmute dac channels */
- snd_soc_write(codec, AD193X_DAC_CHNL_MUTE, 0x0);
+ regmap_write(ad193x->regmap, AD193X_DAC_CHNL_MUTE, 0x0);
/* de-emphasis: 48kHz, powedown dac */
- snd_soc_write(codec, AD193X_DAC_CTRL2, 0x1A);
+ regmap_write(ad193x->regmap, AD193X_DAC_CTRL2, 0x1A);
/* powerdown dac, dac in tdm mode */
- snd_soc_write(codec, AD193X_DAC_CTRL0, 0x41);
+ regmap_write(ad193x->regmap, AD193X_DAC_CTRL0, 0x41);
/* high-pass filter enable */
- snd_soc_write(codec, AD193X_ADC_CTRL0, 0x3);
+ regmap_write(ad193x->regmap, AD193X_ADC_CTRL0, 0x3);
/* sata delay=1, adc aux mode */
- snd_soc_write(codec, AD193X_ADC_CTRL1, 0x43);
+ regmap_write(ad193x->regmap, AD193X_ADC_CTRL1, 0x43);
/* pll input: mclki/xi */
- snd_soc_write(codec, AD193X_PLL_CLK_CTRL0, 0x99); /* mclk=24.576Mhz: 0x9D; mclk=12.288Mhz: 0x99 */
- snd_soc_write(codec, AD193X_PLL_CLK_CTRL1, 0x04);
-
- snd_soc_add_controls(codec, ad193x_snd_controls,
- ARRAY_SIZE(ad193x_snd_controls));
- snd_soc_dapm_new_controls(dapm, ad193x_dapm_widgets,
- ARRAY_SIZE(ad193x_dapm_widgets));
- snd_soc_dapm_add_routes(dapm, audio_paths, ARRAY_SIZE(audio_paths));
+ regmap_write(ad193x->regmap, AD193X_PLL_CLK_CTRL0, 0x99); /* mclk=24.576Mhz: 0x9D; mclk=12.288Mhz: 0x99 */
+ regmap_write(ad193x->regmap, AD193X_PLL_CLK_CTRL1, 0x04);
return ret;
}
static struct snd_soc_codec_driver soc_codec_dev_ad193x = {
.probe = ad193x_probe,
+ .controls = ad193x_snd_controls,
+ .num_controls = ARRAY_SIZE(ad193x_snd_controls),
+ .dapm_widgets = ad193x_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(ad193x_dapm_widgets),
+ .dapm_routes = audio_paths,
+ .num_dapm_routes = ARRAY_SIZE(audio_paths),
};
+static bool adau193x_reg_volatile(struct device *dev, unsigned int reg)
+{
+ return false;
+}
+
#if defined(CONFIG_SPI_MASTER)
static const struct regmap_config ad193x_spi_regmap_config = {
@@ -391,6 +375,9 @@
.reg_bits = 16,
.read_flag_mask = 0x09,
.write_flag_mask = 0x08,
+
+ .max_register = AD193X_NUM_REGS - 1,
+ .volatile_reg = adau193x_reg_volatile,
};
static int __devinit ad193x_spi_probe(struct spi_device *spi)
@@ -398,14 +385,15 @@
struct ad193x_priv *ad193x;
int ret;
- ad193x = kzalloc(sizeof(struct ad193x_priv), GFP_KERNEL);
+ ad193x = devm_kzalloc(&spi->dev, sizeof(struct ad193x_priv),
+ GFP_KERNEL);
if (ad193x == NULL)
return -ENOMEM;
ad193x->regmap = regmap_init_spi(spi, &ad193x_spi_regmap_config);
if (IS_ERR(ad193x->regmap)) {
ret = PTR_ERR(ad193x->regmap);
- goto err_free;
+ goto err_out;
}
spi_set_drvdata(spi, ad193x);
@@ -419,9 +407,7 @@
err_regmap_exit:
regmap_exit(ad193x->regmap);
-err_free:
- kfree(ad193x);
-
+err_out:
return ret;
}
@@ -431,7 +417,6 @@
snd_soc_unregister_codec(&spi->dev);
regmap_exit(ad193x->regmap);
- kfree(ad193x);
return 0;
}
@@ -450,6 +435,9 @@
static const struct regmap_config ad193x_i2c_regmap_config = {
.val_bits = 8,
.reg_bits = 8,
+
+ .max_register = AD193X_NUM_REGS - 1,
+ .volatile_reg = adau193x_reg_volatile,
};
static const struct i2c_device_id ad193x_id[] = {
@@ -465,14 +453,15 @@
struct ad193x_priv *ad193x;
int ret;
- ad193x = kzalloc(sizeof(struct ad193x_priv), GFP_KERNEL);
+ ad193x = devm_kzalloc(&client->dev, sizeof(struct ad193x_priv),
+ GFP_KERNEL);
if (ad193x == NULL)
return -ENOMEM;
ad193x->regmap = regmap_init_i2c(client, &ad193x_i2c_regmap_config);
if (IS_ERR(ad193x->regmap)) {
ret = PTR_ERR(ad193x->regmap);
- goto err_free;
+ goto err_out;
}
i2c_set_clientdata(client, ad193x);
@@ -486,8 +475,7 @@
err_regmap_exit:
regmap_exit(ad193x->regmap);
-err_free:
- kfree(ad193x);
+err_out:
return ret;
}
@@ -497,7 +485,6 @@
snd_soc_unregister_codec(&client->dev);
regmap_exit(ad193x->regmap);
- kfree(ad193x);
return 0;
}
diff --git a/sound/soc/codecs/ad193x.h b/sound/soc/codecs/ad193x.h
index 1507eaa..4733880 100644
--- a/sound/soc/codecs/ad193x.h
+++ b/sound/soc/codecs/ad193x.h
@@ -23,16 +23,14 @@
#define AD193X_DAC_SERFMT_STEREO (0 << 6)
#define AD193X_DAC_SERFMT_TDM (1 << 6)
#define AD193X_DAC_CTRL1 0x03
-#define AD193X_DAC_2_CHANNELS 0
-#define AD193X_DAC_4_CHANNELS 1
-#define AD193X_DAC_8_CHANNELS 2
-#define AD193X_DAC_16_CHANNELS 3
#define AD193X_DAC_CHAN_SHFT 1
#define AD193X_DAC_CHAN_MASK (3 << AD193X_DAC_CHAN_SHFT)
#define AD193X_DAC_LCR_MASTER (1 << 4)
#define AD193X_DAC_BCLK_MASTER (1 << 5)
#define AD193X_DAC_LEFT_HIGH (1 << 3)
#define AD193X_DAC_BCLK_INV (1 << 7)
+#define AD193X_DAC_FMT_MASK (AD193X_DAC_LCR_MASTER | \
+ AD193X_DAC_BCLK_MASTER | AD193X_DAC_LEFT_HIGH | AD193X_DAC_BCLK_INV)
#define AD193X_DAC_CTRL2 0x04
#define AD193X_DAC_WORD_LEN_SHFT 3
#define AD193X_DAC_WORD_LEN_MASK 0x18
@@ -68,16 +66,19 @@
#define AD193X_ADC_SERFMT_AUX (2 << 5)
#define AD193X_ADC_WORD_LEN_MASK 0x3
#define AD193X_ADC_CTRL2 0x10
-#define AD193X_ADC_2_CHANNELS 0
-#define AD193X_ADC_4_CHANNELS 1
-#define AD193X_ADC_8_CHANNELS 2
-#define AD193X_ADC_16_CHANNELS 3
#define AD193X_ADC_CHAN_SHFT 4
#define AD193X_ADC_CHAN_MASK (3 << AD193X_ADC_CHAN_SHFT)
#define AD193X_ADC_LCR_MASTER (1 << 3)
#define AD193X_ADC_BCLK_MASTER (1 << 6)
#define AD193X_ADC_LEFT_HIGH (1 << 2)
#define AD193X_ADC_BCLK_INV (1 << 1)
+#define AD193X_ADC_FMT_MASK (AD193X_ADC_LCR_MASTER | \
+ AD193X_ADC_BCLK_MASTER | AD193X_ADC_LEFT_HIGH | AD193X_ADC_BCLK_INV)
+
+#define AD193X_2_CHANNELS 0
+#define AD193X_4_CHANNELS 1
+#define AD193X_8_CHANNELS 2
+#define AD193X_16_CHANNELS 3
#define AD193X_NUM_REGS 17
diff --git a/sound/soc/codecs/ad1980.c b/sound/soc/codecs/ad1980.c
index e3931cc..9bba7f8 100644
--- a/sound/soc/codecs/ad1980.c
+++ b/sound/soc/codecs/ad1980.c
@@ -277,17 +277,7 @@
.remove = __devexit_p(ad1980_remove),
};
-static int __init ad1980_init(void)
-{
- return platform_driver_register(&ad1980_codec_driver);
-}
-module_init(ad1980_init);
-
-static void __exit ad1980_exit(void)
-{
- platform_driver_unregister(&ad1980_codec_driver);
-}
-module_exit(ad1980_exit);
+module_platform_driver(ad1980_codec_driver);
MODULE_DESCRIPTION("ASoC ad1980 driver (Obsolete)");
MODULE_AUTHOR("Roy Huang, Cliff Cai");
diff --git a/sound/soc/codecs/ad73311.c b/sound/soc/codecs/ad73311.c
index 8d793e9..ee7a68d 100644
--- a/sound/soc/codecs/ad73311.c
+++ b/sound/soc/codecs/ad73311.c
@@ -63,17 +63,7 @@
.remove = __devexit_p(ad73311_remove),
};
-static int __init ad73311_init(void)
-{
- return platform_driver_register(&ad73311_codec_driver);
-}
-module_init(ad73311_init);
-
-static void __exit ad73311_exit(void)
-{
- platform_driver_unregister(&ad73311_codec_driver);
-}
-module_exit(ad73311_exit);
+module_platform_driver(ad73311_codec_driver);
MODULE_DESCRIPTION("ASoC ad73311 driver");
MODULE_AUTHOR("Cliff Cai ");
diff --git a/sound/soc/codecs/adau1373.c b/sound/soc/codecs/adau1373.c
index 45c6302..971ba45 100644
--- a/sound/soc/codecs/adau1373.c
+++ b/sound/soc/codecs/adau1373.c
@@ -1321,7 +1321,7 @@
return 0;
}
-static int adau1373_suspend(struct snd_soc_codec *codec, pm_message_t state)
+static int adau1373_suspend(struct snd_soc_codec *codec)
{
return adau1373_set_bias_level(codec, SND_SOC_BIAS_OFF);
}
@@ -1360,7 +1360,7 @@
struct adau1373 *adau1373;
int ret;
- adau1373 = kzalloc(sizeof(*adau1373), GFP_KERNEL);
+ adau1373 = devm_kzalloc(&client->dev, sizeof(*adau1373), GFP_KERNEL);
if (!adau1373)
return -ENOMEM;
@@ -1368,16 +1368,12 @@
ret = snd_soc_register_codec(&client->dev, &adau1373_codec_driver,
adau1373_dai_driver, ARRAY_SIZE(adau1373_dai_driver));
- if (ret < 0)
- kfree(adau1373);
-
return ret;
}
static int __devexit adau1373_i2c_remove(struct i2c_client *client)
{
snd_soc_unregister_codec(&client->dev);
- kfree(dev_get_drvdata(&client->dev));
return 0;
}
diff --git a/sound/soc/codecs/adau1701.c b/sound/soc/codecs/adau1701.c
index 8b7e1c5..6b325ea 100644
--- a/sound/soc/codecs/adau1701.c
+++ b/sound/soc/codecs/adau1701.c
@@ -12,13 +12,13 @@
#include <linux/init.h>
#include <linux/i2c.h>
#include <linux/delay.h>
-#include <linux/sigma.h>
#include <linux/slab.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
+#include "sigmadsp.h"
#include "adau1701.h"
#define ADAU1701_DSPCTRL 0x1c
@@ -496,23 +496,19 @@
struct adau1701 *adau1701;
int ret;
- adau1701 = kzalloc(sizeof(*adau1701), GFP_KERNEL);
+ adau1701 = devm_kzalloc(&client->dev, sizeof(*adau1701), GFP_KERNEL);
if (!adau1701)
return -ENOMEM;
i2c_set_clientdata(client, adau1701);
ret = snd_soc_register_codec(&client->dev, &adau1701_codec_drv,
&adau1701_dai, 1);
- if (ret < 0)
- kfree(adau1701);
-
return ret;
}
static __devexit int adau1701_i2c_remove(struct i2c_client *client)
{
snd_soc_unregister_codec(&client->dev);
- kfree(i2c_get_clientdata(client));
return 0;
}
diff --git a/sound/soc/codecs/adav80x.c b/sound/soc/codecs/adav80x.c
index f9f0894..ebd7b37 100644
--- a/sound/soc/codecs/adav80x.c
+++ b/sound/soc/codecs/adav80x.c
@@ -798,7 +798,7 @@
return adav80x_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
}
-static int adav80x_suspend(struct snd_soc_codec *codec, pm_message_t state)
+static int adav80x_suspend(struct snd_soc_codec *codec)
{
return adav80x_set_bias_level(codec, SND_SOC_BIAS_OFF);
}
diff --git a/sound/soc/codecs/ads117x.c b/sound/soc/codecs/ads117x.c
index 9082e0f..8103b93 100644
--- a/sound/soc/codecs/ads117x.c
+++ b/sound/soc/codecs/ads117x.c
@@ -58,17 +58,7 @@
.remove = __devexit_p(ads117x_remove),
};
-static int __init ads117x_init(void)
-{
- return platform_driver_register(&ads117x_codec_driver);
-}
-module_init(ads117x_init);
-
-static void __exit ads117x_exit(void)
-{
- platform_driver_unregister(&ads117x_codec_driver);
-}
-module_exit(ads117x_exit);
+module_platform_driver(ads117x_codec_driver);
MODULE_DESCRIPTION("ASoC ads117x driver");
MODULE_AUTHOR("Graeme Gregory");
diff --git a/sound/soc/codecs/ak4104.c b/sound/soc/codecs/ak4104.c
index d3b29dc..d27b5e4 100644
--- a/sound/soc/codecs/ak4104.c
+++ b/sound/soc/codecs/ak4104.c
@@ -170,7 +170,7 @@
return ak4104_spi_write(codec, AK4104_REG_CHN_STATUS(3), val);
}
-static struct snd_soc_dai_ops ak4101_dai_ops = {
+static const struct snd_soc_dai_ops ak4101_dai_ops = {
.hw_params = ak4104_hw_params,
.set_fmt = ak4104_set_dai_fmt,
};
@@ -261,7 +261,8 @@
if (ret < 0)
return ret;
- ak4104 = kzalloc(sizeof(struct ak4104_private), GFP_KERNEL);
+ ak4104 = devm_kzalloc(&spi->dev, sizeof(struct ak4104_private),
+ GFP_KERNEL);
if (ak4104 == NULL)
return -ENOMEM;
@@ -271,15 +272,12 @@
ret = snd_soc_register_codec(&spi->dev,
&soc_codec_device_ak4104, &ak4104_dai, 1);
- if (ret < 0)
- kfree(ak4104);
return ret;
}
static int __devexit ak4104_spi_remove(struct spi_device *spi)
{
snd_soc_unregister_codec(&spi->dev);
- kfree(spi_get_drvdata(spi));
return 0;
}
diff --git a/sound/soc/codecs/ak4535.c b/sound/soc/codecs/ak4535.c
index 95d782d..9e809e0 100644
--- a/sound/soc/codecs/ak4535.c
+++ b/sound/soc/codecs/ak4535.c
@@ -18,7 +18,6 @@
#include <linux/delay.h>
#include <linux/pm.h>
#include <linux/i2c.h>
-#include <linux/platform_device.h>
#include <linux/slab.h>
#include <sound/core.h>
#include <sound/pcm.h>
@@ -331,7 +330,7 @@
SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\
SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000)
-static struct snd_soc_dai_ops ak4535_dai_ops = {
+static const struct snd_soc_dai_ops ak4535_dai_ops = {
.hw_params = ak4535_hw_params,
.set_fmt = ak4535_set_dai_fmt,
.digital_mute = ak4535_mute,
@@ -355,7 +354,7 @@
.ops = &ak4535_dai_ops,
};
-static int ak4535_suspend(struct snd_soc_codec *codec, pm_message_t state)
+static int ak4535_suspend(struct snd_soc_codec *codec)
{
ak4535_set_bias_level(codec, SND_SOC_BIAS_OFF);
return 0;
@@ -417,7 +416,8 @@
struct ak4535_priv *ak4535;
int ret;
- ak4535 = kzalloc(sizeof(struct ak4535_priv), GFP_KERNEL);
+ ak4535 = devm_kzalloc(&i2c->dev, sizeof(struct ak4535_priv),
+ GFP_KERNEL);
if (ak4535 == NULL)
return -ENOMEM;
@@ -426,15 +426,12 @@
ret = snd_soc_register_codec(&i2c->dev,
&soc_codec_dev_ak4535, &ak4535_dai, 1);
- if (ret < 0)
- kfree(ak4535);
return ret;
}
static __devexit int ak4535_i2c_remove(struct i2c_client *client)
{
snd_soc_unregister_codec(&client->dev);
- kfree(i2c_get_clientdata(client));
return 0;
}
diff --git a/sound/soc/codecs/ak4641.c b/sound/soc/codecs/ak4641.c
index 7783858..c4d165a 100644
--- a/sound/soc/codecs/ak4641.c
+++ b/sound/soc/codecs/ak4641.c
@@ -17,7 +17,6 @@
#include <linux/gpio.h>
#include <linux/pm.h>
#include <linux/i2c.h>
-#include <linux/platform_device.h>
#include <linux/slab.h>
#include <sound/core.h>
#include <sound/pcm.h>
@@ -340,6 +339,7 @@
{
struct snd_soc_codec *codec = codec_dai->codec;
u8 btif;
+ int ret;
/* interface format */
switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
@@ -359,7 +359,11 @@
return -EINVAL;
}
- return snd_soc_update_bits(codec, AK4641_BTIF, (0x3 << 5), btif);
+ ret = snd_soc_update_bits(codec, AK4641_BTIF, (0x3 << 5), btif);
+ if (ret < 0)
+ return ret;
+
+ return 0;
}
static int ak4641_i2s_set_dai_fmt(struct snd_soc_dai *codec_dai,
@@ -442,14 +446,14 @@
SNDRV_PCM_RATE_16000)
#define AK4641_FORMATS (SNDRV_PCM_FMTBIT_S16_LE)
-static struct snd_soc_dai_ops ak4641_i2s_dai_ops = {
+static const struct snd_soc_dai_ops ak4641_i2s_dai_ops = {
.hw_params = ak4641_i2s_hw_params,
.set_fmt = ak4641_i2s_set_dai_fmt,
.digital_mute = ak4641_mute,
.set_sysclk = ak4641_set_dai_sysclk,
};
-static struct snd_soc_dai_ops ak4641_pcm_dai_ops = {
+static const struct snd_soc_dai_ops ak4641_pcm_dai_ops = {
.hw_params = NULL, /* rates are controlled by BT chip */
.set_fmt = ak4641_pcm_set_dai_fmt,
.digital_mute = ak4641_mute,
@@ -499,7 +503,7 @@
},
};
-static int ak4641_suspend(struct snd_soc_codec *codec, pm_message_t state)
+static int ak4641_suspend(struct snd_soc_codec *codec)
{
ak4641_set_bias_level(codec, SND_SOC_BIAS_OFF);
return 0;
@@ -603,7 +607,8 @@
struct ak4641_priv *ak4641;
int ret;
- ak4641 = kzalloc(sizeof(struct ak4641_priv), GFP_KERNEL);
+ ak4641 = devm_kzalloc(&i2c->dev, sizeof(struct ak4641_priv),
+ GFP_KERNEL);
if (!ak4641)
return -ENOMEM;
@@ -611,16 +616,12 @@
ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_ak4641,
ak4641_dai, ARRAY_SIZE(ak4641_dai));
- if (ret < 0)
- kfree(ak4641);
-
return ret;
}
static int __devexit ak4641_i2c_remove(struct i2c_client *i2c)
{
snd_soc_unregister_codec(&i2c->dev);
- kfree(i2c_get_clientdata(i2c));
return 0;
}
diff --git a/sound/soc/codecs/ak4642.c b/sound/soc/codecs/ak4642.c
index 12c1bde..5ef70b5 100644
--- a/sound/soc/codecs/ak4642.c
+++ b/sound/soc/codecs/ak4642.c
@@ -18,21 +18,19 @@
* This is very simple driver.
* It can use headphone output / stereo input only
*
- * AK4642 is not tested.
+ * AK4642 is tested.
* AK4643 is tested.
+ * AK4648 is tested.
*/
#include <linux/delay.h>
#include <linux/i2c.h>
-#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <sound/soc.h>
#include <sound/initval.h>
#include <sound/tlv.h>
-#define AK4642_VERSION "0.0.1"
-
#define PW_MGMT1 0x00
#define PW_MGMT2 0x01
#define SG_SL1 0x02
@@ -71,8 +69,6 @@
#define HP_MS 0x23
#define SPK_MS 0x24
-#define AK4642_CACHEREGNUM 0x25
-
/* PW_MGMT1*/
#define PMVCM (1 << 6) /* VCOM Power Management */
#define PMMIN (1 << 5) /* MIN Input Power Management */
@@ -150,8 +146,52 @@
SOC_DOUBLE_R_TLV("Digital Playback Volume", L_DVC, R_DVC,
0, 0xFF, 1, out_tlv),
+
+ SOC_SINGLE("Headphone Switch", PW_MGMT2, 6, 1, 0),
};
+static const struct snd_kcontrol_new ak4642_hpout_mixer_controls[] = {
+ SOC_DAPM_SINGLE("DACH", MD_CTL4, 0, 1, 0),
+};
+
+static const struct snd_kcontrol_new ak4642_lout_mixer_controls[] = {
+ SOC_DAPM_SINGLE("DACL", SG_SL1, 4, 1, 0),
+};
+
+static const struct snd_soc_dapm_widget ak4642_dapm_widgets[] = {
+
+ /* Outputs */
+ SND_SOC_DAPM_OUTPUT("HPOUTL"),
+ SND_SOC_DAPM_OUTPUT("HPOUTR"),
+ SND_SOC_DAPM_OUTPUT("LINEOUT"),
+
+ SND_SOC_DAPM_MIXER("HPOUTL Mixer", PW_MGMT2, 5, 0,
+ &ak4642_hpout_mixer_controls[0],
+ ARRAY_SIZE(ak4642_hpout_mixer_controls)),
+
+ SND_SOC_DAPM_MIXER("HPOUTR Mixer", PW_MGMT2, 4, 0,
+ &ak4642_hpout_mixer_controls[0],
+ ARRAY_SIZE(ak4642_hpout_mixer_controls)),
+
+ SND_SOC_DAPM_MIXER("LINEOUT Mixer", PW_MGMT1, 3, 0,
+ &ak4642_lout_mixer_controls[0],
+ ARRAY_SIZE(ak4642_lout_mixer_controls)),
+
+ /* DAC */
+ SND_SOC_DAPM_DAC("DAC", "HiFi Playback", PW_MGMT1, 2, 0),
+};
+
+static const struct snd_soc_dapm_route ak4642_intercon[] = {
+
+ /* Outputs */
+ {"HPOUTL", NULL, "HPOUTL Mixer"},
+ {"HPOUTR", NULL, "HPOUTR Mixer"},
+ {"LINEOUT", NULL, "LINEOUT Mixer"},
+
+ {"HPOUTL Mixer", "DACH", "DAC"},
+ {"HPOUTR Mixer", "DACH", "DAC"},
+ {"LINEOUT Mixer", "DACL", "DAC"},
+};
/* codec private data */
struct ak4642_priv {
@@ -162,7 +202,7 @@
/*
* ak4642 register cache
*/
-static const u8 ak4642_reg[AK4642_CACHEREGNUM] = {
+static const u8 ak4642_reg[] = {
0x00, 0x00, 0x01, 0x00,
0x02, 0x00, 0x00, 0x00,
0xe1, 0xe1, 0x18, 0x00,
@@ -175,6 +215,19 @@
0x00,
};
+static const u8 ak4648_reg[] = {
+ 0x00, 0x00, 0x01, 0x00,
+ 0x02, 0x00, 0x00, 0x00,
+ 0xe1, 0xe1, 0x18, 0x00,
+ 0xe1, 0x18, 0x11, 0xb8,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x88, 0x88, 0x08,
+};
+
static int ak4642_dai_startup(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
@@ -192,14 +245,8 @@
* This operation came from example code of
* "ASAHI KASEI AK4642" (japanese) manual p97.
*/
- snd_soc_update_bits(codec, MD_CTL4, DACH, DACH);
- snd_soc_update_bits(codec, MD_CTL3, BST1, BST1);
snd_soc_write(codec, L_IVC, 0x91); /* volume */
snd_soc_write(codec, R_IVC, 0x91); /* volume */
- snd_soc_update_bits(codec, PW_MGMT1, PMVCM | PMMIN | PMDAC,
- PMVCM | PMMIN | PMDAC);
- snd_soc_update_bits(codec, PW_MGMT2, PMHP_MASK, PMHP);
- snd_soc_update_bits(codec, PW_MGMT2, HPMTN, HPMTN);
} else {
/*
* start stereo input
@@ -217,8 +264,7 @@
snd_soc_write(codec, SG_SL1, PMMP | MGAIN0);
snd_soc_write(codec, TIMER, ZTM(0x3) | WTM(0x3));
snd_soc_write(codec, ALC_CTL1, ALC | LMTH0);
- snd_soc_update_bits(codec, PW_MGMT1, PMVCM | PMADL,
- PMVCM | PMADL);
+ snd_soc_update_bits(codec, PW_MGMT1, PMADL, PMADL);
snd_soc_update_bits(codec, PW_MGMT3, PMADR, PMADR);
}
@@ -232,12 +278,6 @@
struct snd_soc_codec *codec = dai->codec;
if (is_play) {
- /* stop headphone output */
- snd_soc_update_bits(codec, PW_MGMT2, HPMTN, 0);
- snd_soc_update_bits(codec, PW_MGMT2, PMHP_MASK, 0);
- snd_soc_update_bits(codec, PW_MGMT1, PMMIN | PMDAC, 0);
- snd_soc_update_bits(codec, MD_CTL3, BST1, 0);
- snd_soc_update_bits(codec, MD_CTL4, DACH, 0);
} else {
/* stop stereo input */
snd_soc_update_bits(codec, PW_MGMT1, PMADL, 0);
@@ -376,7 +416,23 @@
return 0;
}
-static struct snd_soc_dai_ops ak4642_dai_ops = {
+static int ak4642_set_bias_level(struct snd_soc_codec *codec,
+ enum snd_soc_bias_level level)
+{
+ switch (level) {
+ case SND_SOC_BIAS_OFF:
+ snd_soc_write(codec, PW_MGMT1, 0x00);
+ break;
+ default:
+ snd_soc_update_bits(codec, PW_MGMT1, PMVCM, PMVCM);
+ break;
+ }
+ codec->dapm.bias_level = level;
+
+ return 0;
+}
+
+static const struct snd_soc_dai_ops ak4642_dai_ops = {
.startup = ak4642_dai_startup,
.shutdown = ak4642_dai_shutdown,
.set_sysclk = ak4642_dai_set_sysclk,
@@ -414,8 +470,6 @@
struct ak4642_priv *ak4642 = snd_soc_codec_get_drvdata(codec);
int ret;
- dev_info(codec->dev, "AK4642 Audio Codec %s", AK4642_VERSION);
-
ret = snd_soc_codec_set_cache_io(codec, 8, 8, ak4642->control_type);
if (ret < 0) {
dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
@@ -425,15 +479,43 @@
snd_soc_add_controls(codec, ak4642_snd_controls,
ARRAY_SIZE(ak4642_snd_controls));
+ ak4642_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+
+ return 0;
+}
+
+static int ak4642_remove(struct snd_soc_codec *codec)
+{
+ ak4642_set_bias_level(codec, SND_SOC_BIAS_OFF);
return 0;
}
static struct snd_soc_codec_driver soc_codec_dev_ak4642 = {
.probe = ak4642_probe,
+ .remove = ak4642_remove,
.resume = ak4642_resume,
- .reg_cache_size = ARRAY_SIZE(ak4642_reg),
+ .set_bias_level = ak4642_set_bias_level,
+ .reg_cache_default = ak4642_reg, /* ak4642 reg */
+ .reg_cache_size = ARRAY_SIZE(ak4642_reg), /* ak4642 reg */
.reg_word_size = sizeof(u8),
- .reg_cache_default = ak4642_reg,
+ .dapm_widgets = ak4642_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(ak4642_dapm_widgets),
+ .dapm_routes = ak4642_intercon,
+ .num_dapm_routes = ARRAY_SIZE(ak4642_intercon),
+};
+
+static struct snd_soc_codec_driver soc_codec_dev_ak4648 = {
+ .probe = ak4642_probe,
+ .remove = ak4642_remove,
+ .resume = ak4642_resume,
+ .set_bias_level = ak4642_set_bias_level,
+ .reg_cache_default = ak4648_reg, /* ak4648 reg */
+ .reg_cache_size = ARRAY_SIZE(ak4648_reg), /* ak4648 reg */
+ .reg_word_size = sizeof(u8),
+ .dapm_widgets = ak4642_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(ak4642_dapm_widgets),
+ .dapm_routes = ak4642_intercon,
+ .num_dapm_routes = ARRAY_SIZE(ak4642_intercon),
};
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
@@ -443,7 +525,8 @@
struct ak4642_priv *ak4642;
int ret;
- ak4642 = kzalloc(sizeof(struct ak4642_priv), GFP_KERNEL);
+ ak4642 = devm_kzalloc(&i2c->dev, sizeof(struct ak4642_priv),
+ GFP_KERNEL);
if (!ak4642)
return -ENOMEM;
@@ -451,22 +534,21 @@
ak4642->control_type = SND_SOC_I2C;
ret = snd_soc_register_codec(&i2c->dev,
- &soc_codec_dev_ak4642, &ak4642_dai, 1);
- if (ret < 0)
- kfree(ak4642);
+ (struct snd_soc_codec_driver *)id->driver_data,
+ &ak4642_dai, 1);
return ret;
}
static __devexit int ak4642_i2c_remove(struct i2c_client *client)
{
snd_soc_unregister_codec(&client->dev);
- kfree(i2c_get_clientdata(client));
return 0;
}
static const struct i2c_device_id ak4642_i2c_id[] = {
- { "ak4642", 0 },
- { "ak4643", 0 },
+ { "ak4642", (kernel_ulong_t)&soc_codec_dev_ak4642 },
+ { "ak4643", (kernel_ulong_t)&soc_codec_dev_ak4642 },
+ { "ak4648", (kernel_ulong_t)&soc_codec_dev_ak4648 },
{ }
};
MODULE_DEVICE_TABLE(i2c, ak4642_i2c_id);
diff --git a/sound/soc/codecs/ak4671.c b/sound/soc/codecs/ak4671.c
index de9ff66..a53b152 100644
--- a/sound/soc/codecs/ak4671.c
+++ b/sound/soc/codecs/ak4671.c
@@ -594,7 +594,7 @@
#define AK4671_FORMATS SNDRV_PCM_FMTBIT_S16_LE
-static struct snd_soc_dai_ops ak4671_dai_ops = {
+static const struct snd_soc_dai_ops ak4671_dai_ops = {
.hw_params = ak4671_hw_params,
.set_sysclk = ak4671_set_dai_sysclk,
.set_fmt = ak4671_set_dai_fmt,
@@ -661,7 +661,8 @@
struct ak4671_priv *ak4671;
int ret;
- ak4671 = kzalloc(sizeof(struct ak4671_priv), GFP_KERNEL);
+ ak4671 = devm_kzalloc(&client->dev, sizeof(struct ak4671_priv),
+ GFP_KERNEL);
if (ak4671 == NULL)
return -ENOMEM;
@@ -670,15 +671,12 @@
ret = snd_soc_register_codec(&client->dev,
&soc_codec_dev_ak4671, &ak4671_dai, 1);
- if (ret < 0)
- kfree(ak4671);
return ret;
}
static __devexit int ak4671_i2c_remove(struct i2c_client *client)
{
snd_soc_unregister_codec(&client->dev);
- kfree(i2c_get_clientdata(client));
return 0;
}
diff --git a/sound/soc/codecs/alc5623.c b/sound/soc/codecs/alc5623.c
index 984b14b..3feee56 100644
--- a/sound/soc/codecs/alc5623.c
+++ b/sound/soc/codecs/alc5623.c
@@ -22,7 +22,6 @@
#include <linux/pm.h>
#include <linux/i2c.h>
#include <linux/slab.h>
-#include <linux/platform_device.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
@@ -100,7 +99,7 @@
};
static const DECLARE_TLV_DB_SCALE(dig_tlv, 0, 600, 0);
-static const struct snd_kcontrol_new rt5621_vol_snd_controls[] = {
+static const struct snd_kcontrol_new alc5621_vol_snd_controls[] = {
SOC_DOUBLE_TLV("Speaker Playback Volume",
ALC5623_SPK_OUT_VOL, 8, 0, 31, 1, hp_tlv),
SOC_DOUBLE("Speaker Playback Switch",
@@ -111,7 +110,7 @@
ALC5623_HP_OUT_VOL, 15, 7, 1, 1),
};
-static const struct snd_kcontrol_new rt5622_vol_snd_controls[] = {
+static const struct snd_kcontrol_new alc5622_vol_snd_controls[] = {
SOC_DOUBLE_TLV("Speaker Playback Volume",
ALC5623_SPK_OUT_VOL, 8, 0, 31, 1, hp_tlv),
SOC_DOUBLE("Speaker Playback Switch",
@@ -839,7 +838,7 @@
| SNDRV_PCM_FMTBIT_S24_LE \
| SNDRV_PCM_FMTBIT_S32_LE)
-static struct snd_soc_dai_ops alc5623_dai_ops = {
+static const struct snd_soc_dai_ops alc5623_dai_ops = {
.hw_params = alc5623_pcm_hw_params,
.digital_mute = alc5623_mute,
.set_fmt = alc5623_set_dai_fmt,
@@ -869,7 +868,7 @@
.ops = &alc5623_dai_ops,
};
-static int alc5623_suspend(struct snd_soc_codec *codec, pm_message_t mesg)
+static int alc5623_suspend(struct snd_soc_codec *codec)
{
alc5623_set_bias_level(codec, SND_SOC_BIAS_OFF);
return 0;
@@ -926,12 +925,12 @@
switch (alc5623->id) {
case 0x21:
- snd_soc_add_controls(codec, rt5621_vol_snd_controls,
- ARRAY_SIZE(rt5621_vol_snd_controls));
+ snd_soc_add_controls(codec, alc5621_vol_snd_controls,
+ ARRAY_SIZE(alc5621_vol_snd_controls));
break;
case 0x22:
- snd_soc_add_controls(codec, rt5622_vol_snd_controls,
- ARRAY_SIZE(rt5622_vol_snd_controls));
+ snd_soc_add_controls(codec, alc5622_vol_snd_controls,
+ ARRAY_SIZE(alc5622_vol_snd_controls));
break;
case 0x23:
snd_soc_add_controls(codec, alc5623_vol_snd_controls,
@@ -1023,7 +1022,8 @@
dev_dbg(&client->dev, "Found codec id : alc56%02x\n", vid2);
- alc5623 = kzalloc(sizeof(struct alc5623_priv), GFP_KERNEL);
+ alc5623 = devm_kzalloc(&client->dev, sizeof(struct alc5623_priv),
+ GFP_KERNEL);
if (alc5623 == NULL)
return -ENOMEM;
@@ -1045,7 +1045,6 @@
alc5623_dai.name = "alc5623-hifi";
break;
default:
- kfree(alc5623);
return -EINVAL;
}
@@ -1054,20 +1053,15 @@
ret = snd_soc_register_codec(&client->dev,
&soc_codec_device_alc5623, &alc5623_dai, 1);
- if (ret != 0) {
+ if (ret != 0)
dev_err(&client->dev, "Failed to register codec: %d\n", ret);
- kfree(alc5623);
- }
return ret;
}
static int alc5623_i2c_remove(struct i2c_client *client)
{
- struct alc5623_priv *alc5623 = i2c_get_clientdata(client);
-
snd_soc_unregister_codec(&client->dev);
- kfree(alc5623);
return 0;
}
diff --git a/sound/soc/codecs/alc5632.c b/sound/soc/codecs/alc5632.c
new file mode 100644
index 0000000..390e437
--- /dev/null
+++ b/sound/soc/codecs/alc5632.c
@@ -0,0 +1,1159 @@
+/*
+* alc5632.c -- ALC5632 ALSA SoC Audio Codec
+*
+* Copyright (C) 2011 The AC100 Kernel Team <ac100@lists.lauchpad.net>
+*
+* Authors: Leon Romanovsky <leon@leon.nu>
+* Andrey Danin <danindrey@mail.ru>
+* Ilya Petrov <ilya.muromec@gmail.com>
+* Marc Dietrich <marvin24@gmx.de>
+*
+* Based on alc5623.c by Arnaud Patard
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License version 2 as
+* published by the Free Software Foundation.
+*/
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <linux/regmap.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/tlv.h>
+#include <sound/soc.h>
+#include <sound/initval.h>
+
+#include "alc5632.h"
+
+/*
+ * ALC5632 register cache
+ */
+static struct reg_default alc5632_reg_defaults[] = {
+ { 2, 0x8080 }, /* R2 - Speaker Output Volume */
+ { 4, 0x8080 }, /* R4 - Headphone Output Volume */
+ { 6, 0x8080 }, /* R6 - AUXOUT Volume */
+ { 8, 0xC800 }, /* R8 - Phone Input */
+ { 10, 0xE808 }, /* R10 - LINE_IN Volume */
+ { 12, 0x1010 }, /* R12 - STEREO DAC Input Volume */
+ { 14, 0x0808 }, /* R14 - MIC Input Volume */
+ { 16, 0xEE0F }, /* R16 - Stereo DAC and MIC Routing Control */
+ { 18, 0xCBCB }, /* R18 - ADC Record Gain */
+ { 20, 0x7F7F }, /* R20 - ADC Record Mixer Control */
+ { 24, 0xE010 }, /* R24 - Voice DAC Volume */
+ { 28, 0x8008 }, /* R28 - Output Mixer Control */
+ { 34, 0x0000 }, /* R34 - Microphone Control */
+ { 36, 0x00C0 }, /* R36 - Codec Digital MIC/Digital Boost
+ Control */
+ { 46, 0x0000 }, /* R46 - Stereo DAC/Voice DAC/Stereo ADC
+ Function Select */
+ { 52, 0x8000 }, /* R52 - Main Serial Data Port Control
+ (Stereo I2S) */
+ { 54, 0x0000 }, /* R54 - Extend Serial Data Port Control
+ (VoDAC_I2S/PCM) */
+ { 58, 0x0000 }, /* R58 - Power Management Addition 1 */
+ { 60, 0x0000 }, /* R60 - Power Management Addition 2 */
+ { 62, 0x8000 }, /* R62 - Power Management Addition 3 */
+ { 64, 0x0C0A }, /* R64 - General Purpose Control Register 1 */
+ { 66, 0x0000 }, /* R66 - General Purpose Control Register 2 */
+ { 68, 0x0000 }, /* R68 - PLL1 Control */
+ { 70, 0x0000 }, /* R70 - PLL2 Control */
+ { 76, 0xBE3E }, /* R76 - GPIO Pin Configuration */
+ { 78, 0xBE3E }, /* R78 - GPIO Pin Polarity */
+ { 80, 0x0000 }, /* R80 - GPIO Pin Sticky */
+ { 82, 0x0000 }, /* R82 - GPIO Pin Wake Up */
+ { 86, 0x0000 }, /* R86 - Pin Sharing */
+ { 90, 0x0009 }, /* R90 - Soft Volume Control Setting */
+ { 92, 0x0000 }, /* R92 - GPIO_Output Pin Control */
+ { 94, 0x3000 }, /* R94 - MISC Control */
+ { 96, 0x3075 }, /* R96 - Stereo DAC Clock Control_1 */
+ { 98, 0x1010 }, /* R98 - Stereo DAC Clock Control_2 */
+ { 100, 0x3110 }, /* R100 - VoDAC_PCM Clock Control_1 */
+ { 104, 0x0553 }, /* R104 - Pseudo Stereo and Spatial Effect
+ Block Control */
+ { 106, 0x0000 }, /* R106 - Private Register Address */
+};
+
+/* codec private data */
+struct alc5632_priv {
+ struct regmap *regmap;
+ u8 id;
+ unsigned int sysclk;
+};
+
+static bool alc5632_volatile_register(struct device *dev,
+ unsigned int reg)
+{
+ switch (reg) {
+ case ALC5632_RESET:
+ case ALC5632_PWR_DOWN_CTRL_STATUS:
+ case ALC5632_GPIO_PIN_STATUS:
+ case ALC5632_OVER_CURR_STATUS:
+ case ALC5632_HID_CTRL_DATA:
+ case ALC5632_EQ_CTRL:
+ case ALC5632_VENDOR_ID1:
+ case ALC5632_VENDOR_ID2:
+ return true;
+
+ default:
+ break;
+ }
+
+ return false;
+}
+
+static inline int alc5632_reset(struct regmap *map)
+{
+ return regmap_write(map, ALC5632_RESET, 0x59B4);
+}
+
+static int amp_mixer_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ /* to power-on/off class-d amp generators/speaker */
+ /* need to write to 'index-46h' register : */
+ /* so write index num (here 0x46) to reg 0x6a */
+ /* and then 0xffff/0 to reg 0x6c */
+ snd_soc_write(w->codec, ALC5632_HID_CTRL_INDEX, 0x46);
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ snd_soc_write(w->codec, ALC5632_HID_CTRL_DATA, 0xFFFF);
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ snd_soc_write(w->codec, ALC5632_HID_CTRL_DATA, 0);
+ break;
+ }
+
+ return 0;
+}
+
+/*
+ * ALC5632 Controls
+ */
+
+/* -34.5db min scale, 1.5db steps, no mute */
+static const DECLARE_TLV_DB_SCALE(vol_tlv, -3450, 150, 0);
+/* -46.5db min scale, 1.5db steps, no mute */
+static const DECLARE_TLV_DB_SCALE(hp_tlv, -4650, 150, 0);
+/* -16.5db min scale, 1.5db steps, no mute */
+static const DECLARE_TLV_DB_SCALE(adc_rec_tlv, -1650, 150, 0);
+static const unsigned int boost_tlv[] = {
+ TLV_DB_RANGE_HEAD(3),
+ 0, 0, TLV_DB_SCALE_ITEM(0, 0, 0),
+ 1, 1, TLV_DB_SCALE_ITEM(2000, 0, 0),
+ 2, 2, TLV_DB_SCALE_ITEM(3000, 0, 0),
+};
+/* 0db min scale, 6 db steps, no mute */
+static const DECLARE_TLV_DB_SCALE(dig_tlv, 0, 600, 0);
+/* 0db min scalem 0.75db steps, no mute */
+static const DECLARE_TLV_DB_SCALE(vdac_tlv, -3525, 075, 0);
+
+static const struct snd_kcontrol_new alc5632_vol_snd_controls[] = {
+ /* left starts at bit 8, right at bit 0 */
+ /* 31 steps (5 bit), -46.5db scale */
+ SOC_DOUBLE_TLV("Speaker Playback Volume",
+ ALC5632_SPK_OUT_VOL, 8, 0, 31, 1, hp_tlv),
+ /* bit 15 mutes left, bit 7 right */
+ SOC_DOUBLE("Speaker Playback Switch",
+ ALC5632_SPK_OUT_VOL, 15, 7, 1, 1),
+ SOC_DOUBLE_TLV("Headphone Playback Volume",
+ ALC5632_HP_OUT_VOL, 8, 0, 31, 1, hp_tlv),
+ SOC_DOUBLE("Headphone Playback Switch",
+ ALC5632_HP_OUT_VOL, 15, 7, 1, 1),
+};
+
+static const struct snd_kcontrol_new alc5632_snd_controls[] = {
+ SOC_DOUBLE_TLV("Auxout Playback Volume",
+ ALC5632_AUX_OUT_VOL, 8, 0, 31, 1, hp_tlv),
+ SOC_DOUBLE("Auxout Playback Switch",
+ ALC5632_AUX_OUT_VOL, 15, 7, 1, 1),
+ SOC_SINGLE_TLV("Voice DAC Playback Volume",
+ ALC5632_VOICE_DAC_VOL, 0, 63, 0, vdac_tlv),
+ SOC_SINGLE_TLV("Phone Capture Volume",
+ ALC5632_PHONE_IN_VOL, 8, 31, 1, vol_tlv),
+ SOC_DOUBLE_TLV("LineIn Capture Volume",
+ ALC5632_LINE_IN_VOL, 8, 0, 31, 1, vol_tlv),
+ SOC_DOUBLE_TLV("Master Playback Volume",
+ ALC5632_STEREO_DAC_IN_VOL, 8, 0, 63, 1, vdac_tlv),
+ SOC_DOUBLE("Master Playback Switch",
+ ALC5632_STEREO_DAC_IN_VOL, 15, 7, 1, 1),
+ SOC_SINGLE_TLV("Mic1 Capture Volume",
+ ALC5632_MIC_VOL, 8, 31, 1, vol_tlv),
+ SOC_SINGLE_TLV("Mic2 Capture Volume",
+ ALC5632_MIC_VOL, 0, 31, 1, vol_tlv),
+ SOC_DOUBLE_TLV("Rec Capture Volume",
+ ALC5632_ADC_REC_GAIN, 8, 0, 31, 0, adc_rec_tlv),
+ SOC_SINGLE_TLV("Mic 1 Boost Volume",
+ ALC5632_MIC_CTRL, 10, 2, 0, boost_tlv),
+ SOC_SINGLE_TLV("Mic 2 Boost Volume",
+ ALC5632_MIC_CTRL, 8, 2, 0, boost_tlv),
+ SOC_SINGLE_TLV("Digital Boost Volume",
+ ALC5632_DIGI_BOOST_CTRL, 0, 7, 0, dig_tlv),
+};
+
+/*
+ * DAPM Controls
+ */
+static const struct snd_kcontrol_new alc5632_hp_mixer_controls[] = {
+SOC_DAPM_SINGLE("LI2HP Playback Switch", ALC5632_LINE_IN_VOL, 15, 1, 1),
+SOC_DAPM_SINGLE("PHONE2HP Playback Switch", ALC5632_PHONE_IN_VOL, 15, 1, 1),
+SOC_DAPM_SINGLE("MIC12HP Playback Switch", ALC5632_MIC_ROUTING_CTRL, 15, 1, 1),
+SOC_DAPM_SINGLE("MIC22HP Playback Switch", ALC5632_MIC_ROUTING_CTRL, 11, 1, 1),
+SOC_DAPM_SINGLE("VOICE2HP Playback Switch", ALC5632_VOICE_DAC_VOL, 15, 1, 1),
+};
+
+static const struct snd_kcontrol_new alc5632_hpl_mixer_controls[] = {
+SOC_DAPM_SINGLE("ADC2HP_L Playback Switch", ALC5632_ADC_REC_GAIN, 15, 1, 1),
+SOC_DAPM_SINGLE("DACL2HP Playback Switch", ALC5632_MIC_ROUTING_CTRL, 3, 1, 1),
+};
+
+static const struct snd_kcontrol_new alc5632_hpr_mixer_controls[] = {
+SOC_DAPM_SINGLE("ADC2HP_R Playback Switch", ALC5632_ADC_REC_GAIN, 7, 1, 1),
+SOC_DAPM_SINGLE("DACR2HP Playback Switch", ALC5632_MIC_ROUTING_CTRL, 2, 1, 1),
+};
+
+static const struct snd_kcontrol_new alc5632_mono_mixer_controls[] = {
+SOC_DAPM_SINGLE("ADC2MONO_L Playback Switch", ALC5632_ADC_REC_GAIN, 14, 1, 1),
+SOC_DAPM_SINGLE("ADC2MONO_R Playback Switch", ALC5632_ADC_REC_GAIN, 6, 1, 1),
+SOC_DAPM_SINGLE("LI2MONO Playback Switch", ALC5632_LINE_IN_VOL, 13, 1, 1),
+SOC_DAPM_SINGLE("MIC12MONO Playback Switch",
+ ALC5632_MIC_ROUTING_CTRL, 13, 1, 1),
+SOC_DAPM_SINGLE("MIC22MONO Playback Switch",
+ ALC5632_MIC_ROUTING_CTRL, 9, 1, 1),
+SOC_DAPM_SINGLE("DAC2MONO Playback Switch", ALC5632_MIC_ROUTING_CTRL, 0, 1, 1),
+SOC_DAPM_SINGLE("VOICE2MONO Playback Switch", ALC5632_VOICE_DAC_VOL, 13, 1, 1),
+};
+
+static const struct snd_kcontrol_new alc5632_speaker_mixer_controls[] = {
+SOC_DAPM_SINGLE("LI2SPK Playback Switch", ALC5632_LINE_IN_VOL, 14, 1, 1),
+SOC_DAPM_SINGLE("PHONE2SPK Playback Switch", ALC5632_PHONE_IN_VOL, 14, 1, 1),
+SOC_DAPM_SINGLE("MIC12SPK Playback Switch",
+ ALC5632_MIC_ROUTING_CTRL, 14, 1, 1),
+SOC_DAPM_SINGLE("MIC22SPK Playback Switch",
+ ALC5632_MIC_ROUTING_CTRL, 10, 1, 1),
+SOC_DAPM_SINGLE("DAC2SPK Playback Switch", ALC5632_MIC_ROUTING_CTRL, 1, 1, 1),
+SOC_DAPM_SINGLE("VOICE2SPK Playback Switch", ALC5632_VOICE_DAC_VOL, 14, 1, 1),
+};
+
+/* Left Record Mixer */
+static const struct snd_kcontrol_new alc5632_captureL_mixer_controls[] = {
+SOC_DAPM_SINGLE("Mic1 Capture Switch", ALC5632_ADC_REC_MIXER, 14, 1, 1),
+SOC_DAPM_SINGLE("Mic2 Capture Switch", ALC5632_ADC_REC_MIXER, 13, 1, 1),
+SOC_DAPM_SINGLE("LineInL Capture Switch", ALC5632_ADC_REC_MIXER, 12, 1, 1),
+SOC_DAPM_SINGLE("Left Phone Capture Switch", ALC5632_ADC_REC_MIXER, 11, 1, 1),
+SOC_DAPM_SINGLE("HPMixerL Capture Switch", ALC5632_ADC_REC_MIXER, 10, 1, 1),
+SOC_DAPM_SINGLE("SPKMixer Capture Switch", ALC5632_ADC_REC_MIXER, 9, 1, 1),
+SOC_DAPM_SINGLE("MonoMixer Capture Switch", ALC5632_ADC_REC_MIXER, 8, 1, 1),
+};
+
+/* Right Record Mixer */
+static const struct snd_kcontrol_new alc5632_captureR_mixer_controls[] = {
+SOC_DAPM_SINGLE("Mic1 Capture Switch", ALC5632_ADC_REC_MIXER, 6, 1, 1),
+SOC_DAPM_SINGLE("Mic2 Capture Switch", ALC5632_ADC_REC_MIXER, 5, 1, 1),
+SOC_DAPM_SINGLE("LineInR Capture Switch", ALC5632_ADC_REC_MIXER, 4, 1, 1),
+SOC_DAPM_SINGLE("Right Phone Capture Switch", ALC5632_ADC_REC_MIXER, 3, 1, 1),
+SOC_DAPM_SINGLE("HPMixerR Capture Switch", ALC5632_ADC_REC_MIXER, 2, 1, 1),
+SOC_DAPM_SINGLE("SPKMixer Capture Switch", ALC5632_ADC_REC_MIXER, 1, 1, 1),
+SOC_DAPM_SINGLE("MonoMixer Capture Switch", ALC5632_ADC_REC_MIXER, 0, 1, 1),
+};
+
+static const char *alc5632_spk_n_sour_sel[] = {
+ "RN/-R", "RP/+R", "LN/-R", "Mute"};
+static const char *alc5632_hpl_out_input_sel[] = {
+ "Vmid", "HP Left Mix"};
+static const char *alc5632_hpr_out_input_sel[] = {
+ "Vmid", "HP Right Mix"};
+static const char *alc5632_spkout_input_sel[] = {
+ "Vmid", "HPOut Mix", "Speaker Mix", "Mono Mix"};
+static const char *alc5632_aux_out_input_sel[] = {
+ "Vmid", "HPOut Mix", "Speaker Mix", "Mono Mix"};
+
+/* auxout output mux */
+static const struct soc_enum alc5632_aux_out_input_enum =
+SOC_ENUM_SINGLE(ALC5632_OUTPUT_MIXER_CTRL, 6, 4, alc5632_aux_out_input_sel);
+static const struct snd_kcontrol_new alc5632_auxout_mux_controls =
+SOC_DAPM_ENUM("AuxOut Mux", alc5632_aux_out_input_enum);
+
+/* speaker output mux */
+static const struct soc_enum alc5632_spkout_input_enum =
+SOC_ENUM_SINGLE(ALC5632_OUTPUT_MIXER_CTRL, 10, 4, alc5632_spkout_input_sel);
+static const struct snd_kcontrol_new alc5632_spkout_mux_controls =
+SOC_DAPM_ENUM("SpeakerOut Mux", alc5632_spkout_input_enum);
+
+/* headphone left output mux */
+static const struct soc_enum alc5632_hpl_out_input_enum =
+SOC_ENUM_SINGLE(ALC5632_OUTPUT_MIXER_CTRL, 9, 2, alc5632_hpl_out_input_sel);
+static const struct snd_kcontrol_new alc5632_hpl_out_mux_controls =
+SOC_DAPM_ENUM("Left Headphone Mux", alc5632_hpl_out_input_enum);
+
+/* headphone right output mux */
+static const struct soc_enum alc5632_hpr_out_input_enum =
+SOC_ENUM_SINGLE(ALC5632_OUTPUT_MIXER_CTRL, 8, 2, alc5632_hpr_out_input_sel);
+static const struct snd_kcontrol_new alc5632_hpr_out_mux_controls =
+SOC_DAPM_ENUM("Right Headphone Mux", alc5632_hpr_out_input_enum);
+
+/* speaker output N select */
+static const struct soc_enum alc5632_spk_n_sour_enum =
+SOC_ENUM_SINGLE(ALC5632_OUTPUT_MIXER_CTRL, 14, 4, alc5632_spk_n_sour_sel);
+static const struct snd_kcontrol_new alc5632_spkoutn_mux_controls =
+SOC_DAPM_ENUM("SpeakerOut N Mux", alc5632_spk_n_sour_enum);
+
+/* speaker amplifier */
+static const char *alc5632_amp_names[] = {"AB Amp", "D Amp"};
+static const struct soc_enum alc5632_amp_enum =
+ SOC_ENUM_SINGLE(ALC5632_OUTPUT_MIXER_CTRL, 13, 2, alc5632_amp_names);
+static const struct snd_kcontrol_new alc5632_amp_mux_controls =
+ SOC_DAPM_ENUM("AB-D Amp Mux", alc5632_amp_enum);
+
+
+static const struct snd_soc_dapm_widget alc5632_dapm_widgets[] = {
+/* Muxes */
+SND_SOC_DAPM_MUX("AuxOut Mux", SND_SOC_NOPM, 0, 0,
+ &alc5632_auxout_mux_controls),
+SND_SOC_DAPM_MUX("SpeakerOut Mux", SND_SOC_NOPM, 0, 0,
+ &alc5632_spkout_mux_controls),
+SND_SOC_DAPM_MUX("Left Headphone Mux", SND_SOC_NOPM, 0, 0,
+ &alc5632_hpl_out_mux_controls),
+SND_SOC_DAPM_MUX("Right Headphone Mux", SND_SOC_NOPM, 0, 0,
+ &alc5632_hpr_out_mux_controls),
+SND_SOC_DAPM_MUX("SpeakerOut N Mux", SND_SOC_NOPM, 0, 0,
+ &alc5632_spkoutn_mux_controls),
+
+/* output mixers */
+SND_SOC_DAPM_MIXER("HP Mix", SND_SOC_NOPM, 0, 0,
+ &alc5632_hp_mixer_controls[0],
+ ARRAY_SIZE(alc5632_hp_mixer_controls)),
+SND_SOC_DAPM_MIXER("HPR Mix", ALC5632_PWR_MANAG_ADD2, 4, 0,
+ &alc5632_hpr_mixer_controls[0],
+ ARRAY_SIZE(alc5632_hpr_mixer_controls)),
+SND_SOC_DAPM_MIXER("HPL Mix", ALC5632_PWR_MANAG_ADD2, 5, 0,
+ &alc5632_hpl_mixer_controls[0],
+ ARRAY_SIZE(alc5632_hpl_mixer_controls)),
+SND_SOC_DAPM_MIXER("HPOut Mix", SND_SOC_NOPM, 0, 0, NULL, 0),
+SND_SOC_DAPM_MIXER("Mono Mix", ALC5632_PWR_MANAG_ADD2, 2, 0,
+ &alc5632_mono_mixer_controls[0],
+ ARRAY_SIZE(alc5632_mono_mixer_controls)),
+SND_SOC_DAPM_MIXER("Speaker Mix", ALC5632_PWR_MANAG_ADD2, 3, 0,
+ &alc5632_speaker_mixer_controls[0],
+ ARRAY_SIZE(alc5632_speaker_mixer_controls)),
+
+/* input mixers */
+SND_SOC_DAPM_MIXER("Left Capture Mix", ALC5632_PWR_MANAG_ADD2, 1, 0,
+ &alc5632_captureL_mixer_controls[0],
+ ARRAY_SIZE(alc5632_captureL_mixer_controls)),
+SND_SOC_DAPM_MIXER("Right Capture Mix", ALC5632_PWR_MANAG_ADD2, 0, 0,
+ &alc5632_captureR_mixer_controls[0],
+ ARRAY_SIZE(alc5632_captureR_mixer_controls)),
+
+SND_SOC_DAPM_DAC("Left DAC", "HiFi Playback",
+ ALC5632_PWR_MANAG_ADD2, 9, 0),
+SND_SOC_DAPM_DAC("Right DAC", "HiFi Playback",
+ ALC5632_PWR_MANAG_ADD2, 8, 0),
+SND_SOC_DAPM_MIXER("DAC Left Channel", ALC5632_PWR_MANAG_ADD1, 15, 0, NULL, 0),
+SND_SOC_DAPM_MIXER("DAC Right Channel",
+ ALC5632_PWR_MANAG_ADD1, 14, 0, NULL, 0),
+SND_SOC_DAPM_MIXER("I2S Mix", ALC5632_PWR_MANAG_ADD1, 11, 0, NULL, 0),
+SND_SOC_DAPM_MIXER("Phone Mix", SND_SOC_NOPM, 0, 0, NULL, 0),
+SND_SOC_DAPM_MIXER("Line Mix", SND_SOC_NOPM, 0, 0, NULL, 0),
+SND_SOC_DAPM_ADC("Left ADC", "HiFi Capture",
+ ALC5632_PWR_MANAG_ADD2, 7, 0),
+SND_SOC_DAPM_ADC("Right ADC", "HiFi Capture",
+ ALC5632_PWR_MANAG_ADD2, 6, 0),
+SND_SOC_DAPM_PGA("Left Headphone", ALC5632_PWR_MANAG_ADD3, 11, 0, NULL, 0),
+SND_SOC_DAPM_PGA("Right Headphone", ALC5632_PWR_MANAG_ADD3, 10, 0, NULL, 0),
+SND_SOC_DAPM_PGA("Left Speaker", ALC5632_PWR_MANAG_ADD3, 13, 0, NULL, 0),
+SND_SOC_DAPM_PGA("Right Speaker", ALC5632_PWR_MANAG_ADD3, 12, 0, NULL, 0),
+SND_SOC_DAPM_PGA("Aux Out", ALC5632_PWR_MANAG_ADD3, 14, 0, NULL, 0),
+SND_SOC_DAPM_PGA("Left LineIn", ALC5632_PWR_MANAG_ADD3, 7, 0, NULL, 0),
+SND_SOC_DAPM_PGA("Right LineIn", ALC5632_PWR_MANAG_ADD3, 6, 0, NULL, 0),
+SND_SOC_DAPM_PGA("Phone", ALC5632_PWR_MANAG_ADD3, 5, 0, NULL, 0),
+SND_SOC_DAPM_PGA("Phone ADMix", ALC5632_PWR_MANAG_ADD3, 4, 0, NULL, 0),
+SND_SOC_DAPM_PGA("MIC1 PGA", ALC5632_PWR_MANAG_ADD3, 3, 0, NULL, 0),
+SND_SOC_DAPM_PGA("MIC2 PGA", ALC5632_PWR_MANAG_ADD3, 2, 0, NULL, 0),
+SND_SOC_DAPM_PGA("MIC1 Pre Amp", ALC5632_PWR_MANAG_ADD3, 1, 0, NULL, 0),
+SND_SOC_DAPM_PGA("MIC2 Pre Amp", ALC5632_PWR_MANAG_ADD3, 0, 0, NULL, 0),
+SND_SOC_DAPM_SUPPLY("MICBIAS1", ALC5632_PWR_MANAG_ADD1, 3, 0, NULL, 0),
+SND_SOC_DAPM_SUPPLY("MICBIAS2", ALC5632_PWR_MANAG_ADD1, 2, 0, NULL, 0),
+
+SND_SOC_DAPM_PGA_E("D Amp", ALC5632_PWR_MANAG_ADD2, 14, 0, NULL, 0,
+ amp_mixer_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+SND_SOC_DAPM_PGA("AB Amp", ALC5632_PWR_MANAG_ADD2, 15, 0, NULL, 0),
+SND_SOC_DAPM_MUX("AB-D Amp Mux", ALC5632_PWR_MANAG_ADD1, 10, 0,
+ &alc5632_amp_mux_controls),
+
+SND_SOC_DAPM_OUTPUT("AUXOUT"),
+SND_SOC_DAPM_OUTPUT("HPL"),
+SND_SOC_DAPM_OUTPUT("HPR"),
+SND_SOC_DAPM_OUTPUT("SPKOUT"),
+SND_SOC_DAPM_OUTPUT("SPKOUTN"),
+SND_SOC_DAPM_INPUT("LINEINL"),
+SND_SOC_DAPM_INPUT("LINEINR"),
+SND_SOC_DAPM_INPUT("PHONEP"),
+SND_SOC_DAPM_INPUT("PHONEN"),
+SND_SOC_DAPM_INPUT("MIC1"),
+SND_SOC_DAPM_INPUT("MIC2"),
+SND_SOC_DAPM_VMID("Vmid"),
+};
+
+
+static const struct snd_soc_dapm_route alc5632_dapm_routes[] = {
+ /* virtual mixer - mixes left & right channels */
+ {"I2S Mix", NULL, "Left DAC"},
+ {"I2S Mix", NULL, "Right DAC"},
+ {"Line Mix", NULL, "Right LineIn"},
+ {"Line Mix", NULL, "Left LineIn"},
+ {"Phone Mix", NULL, "Phone"},
+ {"Phone Mix", NULL, "Phone ADMix"},
+ {"AUXOUT", NULL, "Aux Out"},
+
+ /* DAC */
+ {"DAC Right Channel", NULL, "I2S Mix"},
+ {"DAC Left Channel", NULL, "I2S Mix"},
+
+ /* HP mixer */
+ {"HPL Mix", "ADC2HP_L Playback Switch", "Left Capture Mix"},
+ {"HPL Mix", NULL, "HP Mix"},
+ {"HPR Mix", "ADC2HP_R Playback Switch", "Right Capture Mix"},
+ {"HPR Mix", NULL, "HP Mix"},
+ {"HP Mix", "LI2HP Playback Switch", "Line Mix"},
+ {"HP Mix", "PHONE2HP Playback Switch", "Phone Mix"},
+ {"HP Mix", "MIC12HP Playback Switch", "MIC1 PGA"},
+ {"HP Mix", "MIC22HP Playback Switch", "MIC2 PGA"},
+
+ {"HPR Mix", "DACR2HP Playback Switch", "DAC Right Channel"},
+ {"HPL Mix", "DACL2HP Playback Switch", "DAC Left Channel"},
+
+ /* speaker mixer */
+ {"Speaker Mix", "LI2SPK Playback Switch", "Line Mix"},
+ {"Speaker Mix", "PHONE2SPK Playback Switch", "Phone Mix"},
+ {"Speaker Mix", "MIC12SPK Playback Switch", "MIC1 PGA"},
+ {"Speaker Mix", "MIC22SPK Playback Switch", "MIC2 PGA"},
+ {"Speaker Mix", "DAC2SPK Playback Switch", "DAC Left Channel"},
+
+
+
+ /* mono mixer */
+ {"Mono Mix", "ADC2MONO_L Playback Switch", "Left Capture Mix"},
+ {"Mono Mix", "ADC2MONO_R Playback Switch", "Right Capture Mix"},
+ {"Mono Mix", "LI2MONO Playback Switch", "Line Mix"},
+ {"Mono Mix", "VOICE2MONO Playback Switch", "Phone Mix"},
+ {"Mono Mix", "MIC12MONO Playback Switch", "MIC1 PGA"},
+ {"Mono Mix", "MIC22MONO Playback Switch", "MIC2 PGA"},
+ {"Mono Mix", "DAC2MONO Playback Switch", "DAC Left Channel"},
+
+ /* Left record mixer */
+ {"Left Capture Mix", "LineInL Capture Switch", "LINEINL"},
+ {"Left Capture Mix", "Left Phone Capture Switch", "PHONEN"},
+ {"Left Capture Mix", "Mic1 Capture Switch", "MIC1 Pre Amp"},
+ {"Left Capture Mix", "Mic2 Capture Switch", "MIC2 Pre Amp"},
+ {"Left Capture Mix", "HPMixerL Capture Switch", "HPL Mix"},
+ {"Left Capture Mix", "SPKMixer Capture Switch", "Speaker Mix"},
+ {"Left Capture Mix", "MonoMixer Capture Switch", "Mono Mix"},
+
+ /*Right record mixer */
+ {"Right Capture Mix", "LineInR Capture Switch", "LINEINR"},
+ {"Right Capture Mix", "Right Phone Capture Switch", "PHONEP"},
+ {"Right Capture Mix", "Mic1 Capture Switch", "MIC1 Pre Amp"},
+ {"Right Capture Mix", "Mic2 Capture Switch", "MIC2 Pre Amp"},
+ {"Right Capture Mix", "HPMixerR Capture Switch", "HPR Mix"},
+ {"Right Capture Mix", "SPKMixer Capture Switch", "Speaker Mix"},
+ {"Right Capture Mix", "MonoMixer Capture Switch", "Mono Mix"},
+
+ /* headphone left mux */
+ {"Left Headphone Mux", "HP Left Mix", "HPL Mix"},
+ {"Left Headphone Mux", "Vmid", "Vmid"},
+
+ /* headphone right mux */
+ {"Right Headphone Mux", "HP Right Mix", "HPR Mix"},
+ {"Right Headphone Mux", "Vmid", "Vmid"},
+
+ /* speaker out mux */
+ {"SpeakerOut Mux", "Vmid", "Vmid"},
+ {"SpeakerOut Mux", "HPOut Mix", "HPOut Mix"},
+ {"SpeakerOut Mux", "Speaker Mix", "Speaker Mix"},
+ {"SpeakerOut Mux", "Mono Mix", "Mono Mix"},
+
+ /* Mono/Aux Out mux */
+ {"AuxOut Mux", "Vmid", "Vmid"},
+ {"AuxOut Mux", "HPOut Mix", "HPOut Mix"},
+ {"AuxOut Mux", "Speaker Mix", "Speaker Mix"},
+ {"AuxOut Mux", "Mono Mix", "Mono Mix"},
+
+ /* output pga */
+ {"HPL", NULL, "Left Headphone"},
+ {"Left Headphone", NULL, "Left Headphone Mux"},
+ {"HPR", NULL, "Right Headphone"},
+ {"Right Headphone", NULL, "Right Headphone Mux"},
+ {"Aux Out", NULL, "AuxOut Mux"},
+
+ /* input pga */
+ {"Left LineIn", NULL, "LINEINL"},
+ {"Right LineIn", NULL, "LINEINR"},
+ {"Phone", NULL, "PHONEP"},
+ {"MIC1 Pre Amp", NULL, "MIC1"},
+ {"MIC2 Pre Amp", NULL, "MIC2"},
+ {"MIC1 PGA", NULL, "MIC1 Pre Amp"},
+ {"MIC2 PGA", NULL, "MIC2 Pre Amp"},
+
+ /* left ADC */
+ {"Left ADC", NULL, "Left Capture Mix"},
+
+ /* right ADC */
+ {"Right ADC", NULL, "Right Capture Mix"},
+
+ {"SpeakerOut N Mux", "RN/-R", "Left Speaker"},
+ {"SpeakerOut N Mux", "RP/+R", "Left Speaker"},
+ {"SpeakerOut N Mux", "LN/-R", "Left Speaker"},
+ {"SpeakerOut N Mux", "Mute", "Vmid"},
+
+ {"SpeakerOut N Mux", "RN/-R", "Right Speaker"},
+ {"SpeakerOut N Mux", "RP/+R", "Right Speaker"},
+ {"SpeakerOut N Mux", "LN/-R", "Right Speaker"},
+ {"SpeakerOut N Mux", "Mute", "Vmid"},
+
+ {"AB Amp", NULL, "SpeakerOut Mux"},
+ {"D Amp", NULL, "SpeakerOut Mux"},
+ {"AB-D Amp Mux", "AB Amp", "AB Amp"},
+ {"AB-D Amp Mux", "D Amp", "D Amp"},
+ {"Left Speaker", NULL, "AB-D Amp Mux"},
+ {"Right Speaker", NULL, "AB-D Amp Mux"},
+
+ {"SPKOUT", NULL, "Left Speaker"},
+ {"SPKOUT", NULL, "Right Speaker"},
+
+ {"SPKOUTN", NULL, "SpeakerOut N Mux"},
+
+};
+
+/* PLL divisors */
+struct _pll_div {
+ u32 pll_in;
+ u32 pll_out;
+ u16 regvalue;
+};
+
+/* Note : pll code from original alc5632 driver. Not sure of how good it is */
+/* usefull only for master mode */
+static const struct _pll_div codec_master_pll_div[] = {
+
+ { 2048000, 8192000, 0x0ea0},
+ { 3686400, 8192000, 0x4e27},
+ { 12000000, 8192000, 0x456b},
+ { 13000000, 8192000, 0x495f},
+ { 13100000, 8192000, 0x0320},
+ { 2048000, 11289600, 0xf637},
+ { 3686400, 11289600, 0x2f22},
+ { 12000000, 11289600, 0x3e2f},
+ { 13000000, 11289600, 0x4d5b},
+ { 13100000, 11289600, 0x363b},
+ { 2048000, 16384000, 0x1ea0},
+ { 3686400, 16384000, 0x9e27},
+ { 12000000, 16384000, 0x452b},
+ { 13000000, 16384000, 0x542f},
+ { 13100000, 16384000, 0x03a0},
+ { 2048000, 16934400, 0xe625},
+ { 3686400, 16934400, 0x9126},
+ { 12000000, 16934400, 0x4d2c},
+ { 13000000, 16934400, 0x742f},
+ { 13100000, 16934400, 0x3c27},
+ { 2048000, 22579200, 0x2aa0},
+ { 3686400, 22579200, 0x2f20},
+ { 12000000, 22579200, 0x7e2f},
+ { 13000000, 22579200, 0x742f},
+ { 13100000, 22579200, 0x3c27},
+ { 2048000, 24576000, 0x2ea0},
+ { 3686400, 24576000, 0xee27},
+ { 12000000, 24576000, 0x2915},
+ { 13000000, 24576000, 0x772e},
+ { 13100000, 24576000, 0x0d20},
+};
+
+/* FOUT = MCLK*(N+2)/((M+2)*(K+2))
+ N: bit 15:8 (div 2 .. div 257)
+ K: bit 6:4 typical 2
+ M: bit 3:0 (div 2 .. div 17)
+
+ same as for 5623 - thanks!
+*/
+
+static const struct _pll_div codec_slave_pll_div[] = {
+
+ { 1024000, 16384000, 0x3ea0},
+ { 1411200, 22579200, 0x3ea0},
+ { 1536000, 24576000, 0x3ea0},
+ { 2048000, 16384000, 0x1ea0},
+ { 2822400, 22579200, 0x1ea0},
+ { 3072000, 24576000, 0x1ea0},
+
+};
+
+static int alc5632_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
+ int source, unsigned int freq_in, unsigned int freq_out)
+{
+ int i;
+ struct snd_soc_codec *codec = codec_dai->codec;
+ int gbl_clk = 0, pll_div = 0;
+ u16 reg;
+
+ if (pll_id < ALC5632_PLL_FR_MCLK || pll_id > ALC5632_PLL_FR_VBCLK)
+ return -EINVAL;
+
+ /* Disable PLL power */
+ snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD2,
+ ALC5632_PWR_ADD2_PLL1,
+ 0);
+ snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD2,
+ ALC5632_PWR_ADD2_PLL2,
+ 0);
+
+ /* pll is not used in slave mode */
+ reg = snd_soc_read(codec, ALC5632_DAI_CONTROL);
+ if (reg & ALC5632_DAI_SDP_SLAVE_MODE)
+ return 0;
+
+ if (!freq_in || !freq_out)
+ return 0;
+
+ switch (pll_id) {
+ case ALC5632_PLL_FR_MCLK:
+ for (i = 0; i < ARRAY_SIZE(codec_master_pll_div); i++) {
+ if (codec_master_pll_div[i].pll_in == freq_in
+ && codec_master_pll_div[i].pll_out == freq_out) {
+ /* PLL source from MCLK */
+ pll_div = codec_master_pll_div[i].regvalue;
+ break;
+ }
+ }
+ break;
+ case ALC5632_PLL_FR_BCLK:
+ for (i = 0; i < ARRAY_SIZE(codec_slave_pll_div); i++) {
+ if (codec_slave_pll_div[i].pll_in == freq_in
+ && codec_slave_pll_div[i].pll_out == freq_out) {
+ /* PLL source from Bitclk */
+ gbl_clk = ALC5632_PLL_FR_BCLK;
+ pll_div = codec_slave_pll_div[i].regvalue;
+ break;
+ }
+ }
+ break;
+ case ALC5632_PLL_FR_VBCLK:
+ for (i = 0; i < ARRAY_SIZE(codec_slave_pll_div); i++) {
+ if (codec_slave_pll_div[i].pll_in == freq_in
+ && codec_slave_pll_div[i].pll_out == freq_out) {
+ /* PLL source from voice clock */
+ gbl_clk = ALC5632_PLL_FR_VBCLK;
+ pll_div = codec_slave_pll_div[i].regvalue;
+ break;
+ }
+ }
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ if (!pll_div)
+ return -EINVAL;
+
+ /* choose MCLK/BCLK/VBCLK */
+ snd_soc_write(codec, ALC5632_GPCR2, gbl_clk);
+ /* choose PLL1 clock rate */
+ snd_soc_write(codec, ALC5632_PLL1_CTRL, pll_div);
+ /* enable PLL1 */
+ snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD2,
+ ALC5632_PWR_ADD2_PLL1,
+ ALC5632_PWR_ADD2_PLL1);
+ /* enable PLL2 */
+ snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD2,
+ ALC5632_PWR_ADD2_PLL2,
+ ALC5632_PWR_ADD2_PLL2);
+ /* use PLL1 as main SYSCLK */
+ snd_soc_update_bits(codec, ALC5632_GPCR1,
+ ALC5632_GPCR1_CLK_SYS_SRC_SEL_PLL1,
+ ALC5632_GPCR1_CLK_SYS_SRC_SEL_PLL1);
+
+ return 0;
+}
+
+struct _coeff_div {
+ u16 fs;
+ u16 regvalue;
+};
+
+/* codec hifi mclk (after PLL) clock divider coefficients */
+/* values inspired from column BCLK=32Fs of Appendix A table */
+static const struct _coeff_div coeff_div[] = {
+ {512*1, 0x3075},
+};
+
+static int get_coeff(struct snd_soc_codec *codec, int rate)
+{
+ struct alc5632_priv *alc5632 = snd_soc_codec_get_drvdata(codec);
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(coeff_div); i++) {
+ if (coeff_div[i].fs * rate == alc5632->sysclk)
+ return i;
+ }
+ return -EINVAL;
+}
+
+/*
+ * Clock after PLL and dividers
+ */
+static int alc5632_set_dai_sysclk(struct snd_soc_dai *codec_dai,
+ int clk_id, unsigned int freq, int dir)
+{
+ struct snd_soc_codec *codec = codec_dai->codec;
+ struct alc5632_priv *alc5632 = snd_soc_codec_get_drvdata(codec);
+
+ switch (freq) {
+ case 8192000:
+ case 11289600:
+ case 12288000:
+ case 16384000:
+ case 16934400:
+ case 18432000:
+ case 22579200:
+ case 24576000:
+ alc5632->sysclk = freq;
+ return 0;
+ }
+ return -EINVAL;
+}
+
+static int alc5632_set_dai_fmt(struct snd_soc_dai *codec_dai,
+ unsigned int fmt)
+{
+ struct snd_soc_codec *codec = codec_dai->codec;
+ u16 iface = 0;
+
+ /* set master/slave audio interface */
+ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+ case SND_SOC_DAIFMT_CBM_CFM:
+ iface = ALC5632_DAI_SDP_MASTER_MODE;
+ break;
+ case SND_SOC_DAIFMT_CBS_CFS:
+ iface = ALC5632_DAI_SDP_SLAVE_MODE;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /* interface format */
+ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+ case SND_SOC_DAIFMT_I2S:
+ iface |= ALC5632_DAI_I2S_DF_I2S;
+ break;
+ case SND_SOC_DAIFMT_LEFT_J:
+ iface |= ALC5632_DAI_I2S_DF_LEFT;
+ break;
+ case SND_SOC_DAIFMT_DSP_A:
+ iface |= ALC5632_DAI_I2S_DF_PCM_A;
+ break;
+ case SND_SOC_DAIFMT_DSP_B:
+ iface |= ALC5632_DAI_I2S_DF_PCM_B;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /* clock inversion */
+ switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+ case SND_SOC_DAIFMT_NB_NF:
+ break;
+ case SND_SOC_DAIFMT_IB_IF:
+ iface |= ALC5632_DAI_MAIN_I2S_BCLK_POL_CTRL;
+ break;
+ case SND_SOC_DAIFMT_IB_NF:
+ iface |= ALC5632_DAI_MAIN_I2S_BCLK_POL_CTRL;
+ break;
+ case SND_SOC_DAIFMT_NB_IF:
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return snd_soc_write(codec, ALC5632_DAI_CONTROL, iface);
+}
+
+static int alc5632_pcm_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_codec *codec = rtd->codec;
+ int coeff, rate;
+ u16 iface;
+
+ iface = snd_soc_read(codec, ALC5632_DAI_CONTROL);
+ iface &= ~ALC5632_DAI_I2S_DL_MASK;
+
+ /* bit size */
+ switch (params_format(params)) {
+ case SNDRV_PCM_FORMAT_S16_LE:
+ iface |= ALC5632_DAI_I2S_DL_16;
+ break;
+ case SNDRV_PCM_FORMAT_S20_3LE:
+ iface |= ALC5632_DAI_I2S_DL_20;
+ break;
+ case SNDRV_PCM_FORMAT_S24_LE:
+ iface |= ALC5632_DAI_I2S_DL_24;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /* set iface & srate */
+ snd_soc_write(codec, ALC5632_DAI_CONTROL, iface);
+ rate = params_rate(params);
+ coeff = get_coeff(codec, rate);
+ if (coeff < 0)
+ return -EINVAL;
+
+ coeff = coeff_div[coeff].regvalue;
+ snd_soc_write(codec, ALC5632_DAC_CLK_CTRL1, coeff);
+
+ return 0;
+}
+
+static int alc5632_mute(struct snd_soc_dai *dai, int mute)
+{
+ struct snd_soc_codec *codec = dai->codec;
+ u16 hp_mute = ALC5632_MISC_HP_DEPOP_MUTE_L
+ |ALC5632_MISC_HP_DEPOP_MUTE_R;
+ u16 mute_reg = snd_soc_read(codec, ALC5632_MISC_CTRL) & ~hp_mute;
+
+ if (mute)
+ mute_reg |= hp_mute;
+
+ return snd_soc_write(codec, ALC5632_MISC_CTRL, mute_reg);
+}
+
+#define ALC5632_ADD2_POWER_EN (ALC5632_PWR_ADD2_VREF)
+
+#define ALC5632_ADD3_POWER_EN (ALC5632_PWR_ADD3_MIC1_BOOST_AD)
+
+#define ALC5632_ADD1_POWER_EN \
+ (ALC5632_PWR_ADD1_DAC_REF \
+ | ALC5632_PWR_ADD1_SOFTGEN_EN \
+ | ALC5632_PWR_ADD1_HP_OUT_AMP \
+ | ALC5632_PWR_ADD1_HP_OUT_ENH_AMP \
+ | ALC5632_PWR_ADD1_MAIN_BIAS)
+
+static void enable_power_depop(struct snd_soc_codec *codec)
+{
+ snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD1,
+ ALC5632_PWR_ADD1_SOFTGEN_EN,
+ ALC5632_PWR_ADD1_SOFTGEN_EN);
+
+ snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD3,
+ ALC5632_ADD3_POWER_EN,
+ ALC5632_ADD3_POWER_EN);
+
+ snd_soc_update_bits(codec, ALC5632_MISC_CTRL,
+ ALC5632_MISC_HP_DEPOP_MODE2_EN,
+ ALC5632_MISC_HP_DEPOP_MODE2_EN);
+
+ /* "normal" mode: 0 @ 26 */
+ /* set all PR0-7 mixers to 0 */
+ snd_soc_update_bits(codec, ALC5632_PWR_DOWN_CTRL_STATUS,
+ ALC5632_PWR_DOWN_CTRL_STATUS_MASK,
+ 0);
+
+ msleep(500);
+
+ snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD2,
+ ALC5632_ADD2_POWER_EN,
+ ALC5632_ADD2_POWER_EN);
+
+ snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD1,
+ ALC5632_ADD1_POWER_EN,
+ ALC5632_ADD1_POWER_EN);
+
+ /* disable HP Depop2 */
+ snd_soc_update_bits(codec, ALC5632_MISC_CTRL,
+ ALC5632_MISC_HP_DEPOP_MODE2_EN,
+ 0);
+
+}
+
+static int alc5632_set_bias_level(struct snd_soc_codec *codec,
+ enum snd_soc_bias_level level)
+{
+ switch (level) {
+ case SND_SOC_BIAS_ON:
+ enable_power_depop(codec);
+ break;
+ case SND_SOC_BIAS_PREPARE:
+ break;
+ case SND_SOC_BIAS_STANDBY:
+ /* everything off except vref/vmid, */
+ snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD1,
+ ALC5632_PWR_MANAG_ADD1_MASK,
+ ALC5632_PWR_ADD1_MAIN_BIAS);
+ snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD2,
+ ALC5632_PWR_MANAG_ADD2_MASK,
+ ALC5632_PWR_ADD2_VREF);
+ /* "normal" mode: 0 @ 26 */
+ snd_soc_update_bits(codec, ALC5632_PWR_DOWN_CTRL_STATUS,
+ ALC5632_PWR_DOWN_CTRL_STATUS_MASK,
+ 0xffff ^ (ALC5632_PWR_VREF_PR3
+ | ALC5632_PWR_VREF_PR2));
+ break;
+ case SND_SOC_BIAS_OFF:
+ /* everything off, dac mute, inactive */
+ snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD2,
+ ALC5632_PWR_MANAG_ADD2_MASK, 0);
+ snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD3,
+ ALC5632_PWR_MANAG_ADD3_MASK, 0);
+ snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD1,
+ ALC5632_PWR_MANAG_ADD1_MASK, 0);
+ break;
+ }
+ codec->dapm.bias_level = level;
+ return 0;
+}
+
+#define ALC5632_FORMATS (SNDRV_PCM_FMTBIT_S16_LE \
+ | SNDRV_PCM_FMTBIT_S24_LE \
+ | SNDRV_PCM_FMTBIT_S32_LE)
+
+static const struct snd_soc_dai_ops alc5632_dai_ops = {
+ .hw_params = alc5632_pcm_hw_params,
+ .digital_mute = alc5632_mute,
+ .set_fmt = alc5632_set_dai_fmt,
+ .set_sysclk = alc5632_set_dai_sysclk,
+ .set_pll = alc5632_set_dai_pll,
+};
+
+static struct snd_soc_dai_driver alc5632_dai = {
+ .name = "alc5632-hifi",
+ .playback = {
+ .stream_name = "HiFi Playback",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rate_min = 8000,
+ .rate_max = 48000,
+ .rates = SNDRV_PCM_RATE_8000_48000,
+ .formats = ALC5632_FORMATS,},
+ .capture = {
+ .stream_name = "HiFi Capture",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rate_min = 8000,
+ .rate_max = 48000,
+ .rates = SNDRV_PCM_RATE_8000_48000,
+ .formats = ALC5632_FORMATS,},
+
+ .ops = &alc5632_dai_ops,
+ .symmetric_rates = 1,
+};
+
+#ifdef CONFIG_PM
+static int alc5632_suspend(struct snd_soc_codec *codec)
+{
+ alc5632_set_bias_level(codec, SND_SOC_BIAS_OFF);
+ return 0;
+}
+
+static int alc5632_resume(struct snd_soc_codec *codec)
+{
+ struct alc5632_priv *alc5632 = snd_soc_codec_get_drvdata(codec);
+
+ regcache_sync(alc5632->regmap);
+
+ alc5632_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+ return 0;
+}
+#else
+#define alc5632_suspend NULL
+#define alc5632_resume NULL
+#endif
+
+static int alc5632_probe(struct snd_soc_codec *codec)
+{
+ struct alc5632_priv *alc5632 = snd_soc_codec_get_drvdata(codec);
+ int ret;
+
+ codec->control_data = alc5632->regmap;
+
+ ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP);
+ if (ret != 0) {
+ dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
+ return ret;
+ }
+
+ /* power on device */
+ alc5632_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+
+ switch (alc5632->id) {
+ case 0x5c:
+ snd_soc_add_controls(codec, alc5632_vol_snd_controls,
+ ARRAY_SIZE(alc5632_vol_snd_controls));
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return ret;
+}
+
+/* power down chip */
+static int alc5632_remove(struct snd_soc_codec *codec)
+{
+ alc5632_set_bias_level(codec, SND_SOC_BIAS_OFF);
+ return 0;
+}
+
+static struct snd_soc_codec_driver soc_codec_device_alc5632 = {
+ .probe = alc5632_probe,
+ .remove = alc5632_remove,
+ .suspend = alc5632_suspend,
+ .resume = alc5632_resume,
+ .set_bias_level = alc5632_set_bias_level,
+ .controls = alc5632_snd_controls,
+ .num_controls = ARRAY_SIZE(alc5632_snd_controls),
+ .dapm_widgets = alc5632_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(alc5632_dapm_widgets),
+ .dapm_routes = alc5632_dapm_routes,
+ .num_dapm_routes = ARRAY_SIZE(alc5632_dapm_routes),
+};
+
+static struct regmap_config alc5632_regmap = {
+ .reg_bits = 8,
+ .val_bits = 16,
+
+ .max_register = ALC5632_MAX_REGISTER,
+ .reg_defaults = alc5632_reg_defaults,
+ .num_reg_defaults = ARRAY_SIZE(alc5632_reg_defaults),
+ .volatile_reg = alc5632_volatile_register,
+ .cache_type = REGCACHE_RBTREE,
+};
+
+/*
+ * alc5632 2 wire address is determined by A1 pin
+ * state during powerup.
+ * low = 0x1a
+ * high = 0x1b
+ */
+static __devinit int alc5632_i2c_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct alc5632_priv *alc5632;
+ int ret, ret1, ret2;
+ unsigned int vid1, vid2;
+
+ alc5632 = devm_kzalloc(&client->dev,
+ sizeof(struct alc5632_priv), GFP_KERNEL);
+ if (alc5632 == NULL)
+ return -ENOMEM;
+
+ i2c_set_clientdata(client, alc5632);
+
+ alc5632->regmap = regmap_init_i2c(client, &alc5632_regmap);
+ if (IS_ERR(alc5632->regmap)) {
+ ret = PTR_ERR(alc5632->regmap);
+ dev_err(&client->dev, "regmap_init() failed: %d\n", ret);
+ return ret;
+ }
+
+ ret1 = regmap_read(alc5632->regmap, ALC5632_VENDOR_ID1, &vid1);
+ ret2 = regmap_read(alc5632->regmap, ALC5632_VENDOR_ID2, &vid2);
+ if (ret1 != 0 || ret2 != 0) {
+ dev_err(&client->dev,
+ "Failed to read chip ID: ret1=%d, ret2=%d\n", ret1, ret2);
+ regmap_exit(alc5632->regmap);
+ return -EIO;
+ }
+
+ vid2 >>= 8;
+
+ if ((vid1 != 0x10EC) || (vid2 != id->driver_data)) {
+ dev_err(&client->dev,
+ "Device is not a ALC5632: VID1=0x%x, VID2=0x%x\n", vid1, vid2);
+ regmap_exit(alc5632->regmap);
+ return -EINVAL;
+ }
+
+ ret = alc5632_reset(alc5632->regmap);
+ if (ret < 0) {
+ dev_err(&client->dev, "Failed to issue reset\n");
+ regmap_exit(alc5632->regmap);
+ return ret;
+ }
+
+ alc5632->id = vid2;
+ switch (alc5632->id) {
+ case 0x5c:
+ alc5632_dai.name = "alc5632-hifi";
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ ret = snd_soc_register_codec(&client->dev,
+ &soc_codec_device_alc5632, &alc5632_dai, 1);
+
+ if (ret < 0) {
+ dev_err(&client->dev, "Failed to register codec: %d\n", ret);
+ regmap_exit(alc5632->regmap);
+ return ret;
+ }
+
+ return ret;
+}
+
+static int alc5632_i2c_remove(struct i2c_client *client)
+{
+ struct alc5632_priv *alc5632 = i2c_get_clientdata(client);
+ snd_soc_unregister_codec(&client->dev);
+ regmap_exit(alc5632->regmap);
+ return 0;
+}
+
+static const struct i2c_device_id alc5632_i2c_table[] = {
+ {"alc5632", 0x5c},
+ {}
+};
+MODULE_DEVICE_TABLE(i2c, alc5632_i2c_table);
+
+/* i2c codec control layer */
+static struct i2c_driver alc5632_i2c_driver = {
+ .driver = {
+ .name = "alc5632",
+ .owner = THIS_MODULE,
+ },
+ .probe = alc5632_i2c_probe,
+ .remove = __devexit_p(alc5632_i2c_remove),
+ .id_table = alc5632_i2c_table,
+};
+
+static int __init alc5632_modinit(void)
+{
+ int ret;
+
+ ret = i2c_add_driver(&alc5632_i2c_driver);
+ if (ret != 0) {
+ printk(KERN_ERR "%s: can't add i2c driver", __func__);
+ return ret;
+ }
+
+ return ret;
+}
+module_init(alc5632_modinit);
+
+static void __exit alc5632_modexit(void)
+{
+ i2c_del_driver(&alc5632_i2c_driver);
+}
+module_exit(alc5632_modexit);
+
+MODULE_DESCRIPTION("ASoC ALC5632 driver");
+MODULE_AUTHOR("Leon Romanovsky <leon@leon.nu>");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/alc5632.h b/sound/soc/codecs/alc5632.h
new file mode 100644
index 0000000..357651e
--- /dev/null
+++ b/sound/soc/codecs/alc5632.h
@@ -0,0 +1,251 @@
+/*
+* alc5632.h -- ALC5632 ALSA SoC Audio Codec
+*
+* Copyright (C) 2011 The AC100 Kernel Team <ac100@lists.lauchpad.net>
+*
+* Authors: Leon Romanovsky <leon@leon.nu>
+* Andrey Danin <danindrey@mail.ru>
+* Ilya Petrov <ilya.muromec@gmail.com>
+* Marc Dietrich <marvin24@gmx.de>
+*
+* Based on alc5623.h by Arnaud Patard
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License version 2 as
+* published by the Free Software Foundation.
+*/
+
+#ifndef _ALC5632_H
+#define _ALC5632_H
+
+#define ALC5632_RESET 0x00
+/* speaker output vol 2 2 */
+/* line output vol 4 2 */
+/* HP output vol 4 0 4 */
+#define ALC5632_SPK_OUT_VOL 0x02 /* spe out vol */
+#define ALC5632_SPK_OUT_VOL_STEP 1.5
+#define ALC5632_HP_OUT_VOL 0x04 /* hp out vol */
+#define ALC5632_AUX_OUT_VOL 0x06 /* aux out vol */
+#define ALC5632_PHONE_IN_VOL 0x08 /* phone in vol */
+#define ALC5632_LINE_IN_VOL 0x0A /* line in vol */
+#define ALC5632_STEREO_DAC_IN_VOL 0x0C /* stereo dac in vol */
+#define ALC5632_MIC_VOL 0x0E /* mic in vol */
+/* stero dac/mic routing */
+#define ALC5632_MIC_ROUTING_CTRL 0x10
+#define ALC5632_MIC_ROUTE_MONOMIX (1 << 0)
+#define ALC5632_MIC_ROUTE_SPK (1 << 1)
+#define ALC5632_MIC_ROUTE_HP (1 << 2)
+
+#define ALC5632_ADC_REC_GAIN 0x12 /* rec gain */
+#define ALC5632_ADC_REC_GAIN_RANGE 0x1F1F
+#define ALC5632_ADC_REC_GAIN_BASE (-16.5)
+#define ALC5632_ADC_REC_GAIN_STEP 1.5
+
+#define ALC5632_ADC_REC_MIXER 0x14 /* mixer control */
+#define ALC5632_ADC_REC_MIC1 (1 << 6)
+#define ALC5632_ADC_REC_MIC2 (1 << 5)
+#define ALC5632_ADC_REC_LINE_IN (1 << 4)
+#define ALC5632_ADC_REC_AUX (1 << 3)
+#define ALC5632_ADC_REC_HP (1 << 2)
+#define ALC5632_ADC_REC_SPK (1 << 1)
+#define ALC5632_ADC_REC_MONOMIX (1 << 0)
+
+#define ALC5632_VOICE_DAC_VOL 0x18 /* voice dac vol */
+/* ALC5632_OUTPUT_MIXER_CTRL : */
+/* same remark as for reg 2 line vs speaker */
+#define ALC5632_OUTPUT_MIXER_CTRL 0x1C /* out mix ctrl */
+#define ALC5632_OUTPUT_MIXER_RP (1 << 14)
+#define ALC5632_OUTPUT_MIXER_WEEK (1 << 12)
+#define ALC5632_OUTPUT_MIXER_HP (1 << 10)
+#define ALC5632_OUTPUT_MIXER_AUX_SPK (2 << 6)
+#define ALC5632_OUTPUT_MIXER_AUX_HP_LR (1 << 6)
+#define ALC5632_OUTPUT_MIXER_HP_R (1 << 8)
+#define ALC5632_OUTPUT_MIXER_HP_L (1 << 9)
+
+#define ALC5632_MIC_CTRL 0x22 /* mic phone ctrl */
+#define ALC5632_MIC_BOOST_BYPASS 0
+#define ALC5632_MIC_BOOST_20DB 1
+#define ALC5632_MIC_BOOST_30DB 2
+#define ALC5632_MIC_BOOST_40DB 3
+
+#define ALC5632_DIGI_BOOST_CTRL 0x24 /* digi mic / bost ctl */
+#define ALC5632_MIC_BOOST_RANGE 7
+#define ALC5632_MIC_BOOST_STEP 6
+#define ALC5632_PWR_DOWN_CTRL_STATUS 0x26
+#define ALC5632_PWR_DOWN_CTRL_STATUS_MASK 0xEF00
+#define ALC5632_PWR_VREF_PR3 (1 << 11)
+#define ALC5632_PWR_VREF_PR2 (1 << 10)
+#define ALC5632_PWR_VREF_STATUS (1 << 3)
+#define ALC5632_PWR_AMIX_STATUS (1 << 2)
+#define ALC5632_PWR_DAC_STATUS (1 << 1)
+#define ALC5632_PWR_ADC_STATUS (1 << 0)
+/* stereo/voice DAC / stereo adc func ctrl */
+#define ALC5632_DAC_FUNC_SELECT 0x2E
+
+/* Main serial data port ctrl (i2s) */
+#define ALC5632_DAI_CONTROL 0x34
+
+#define ALC5632_DAI_SDP_MASTER_MODE (0 << 15)
+#define ALC5632_DAI_SDP_SLAVE_MODE (1 << 15)
+#define ALC5632_DAI_SADLRCK_MODE (1 << 14)
+/* 0:voice, 1:main */
+#define ALC5632_DAI_MAIN_I2S_SYSCLK_SEL (1 << 8)
+#define ALC5632_DAI_MAIN_I2S_BCLK_POL_CTRL (1 << 7)
+/* 0:normal, 1:invert */
+#define ALC5632_DAI_MAIN_I2S_LRCK_INV (1 << 6)
+#define ALC5632_DAI_I2S_DL_MASK (3 << 2)
+#define ALC5632_DAI_I2S_DL_8 (3 << 2)
+#define ALC5632_DAI_I2S_DL_24 (2 << 2)
+#define ALC5632_DAI_I2S_DL_20 (1 << 2)
+#define ALC5632_DAI_I2S_DL_16 (0 << 2)
+#define ALC5632_DAI_I2S_DF_MASK (3 << 0)
+#define ALC5632_DAI_I2S_DF_PCM_B (3 << 0)
+#define ALC5632_DAI_I2S_DF_PCM_A (2 << 0)
+#define ALC5632_DAI_I2S_DF_LEFT (1 << 0)
+#define ALC5632_DAI_I2S_DF_I2S (0 << 0)
+/* extend serial data port control (VoDAC_i2c/pcm) */
+#define ALC5632_DAI_CONTROL2 0x36
+/* 0:gpio func, 1:voice pcm */
+#define ALC5632_DAI_VOICE_PCM_ENABLE (1 << 15)
+/* 0:master, 1:slave */
+#define ALC5632_DAI_VOICE_MODE_SEL (1 << 14)
+/* 0:disable, 1:enable */
+#define ALC5632_DAI_HPF_CLK_CTRL (1 << 13)
+/* 0:main, 1:voice */
+#define ALC5632_DAI_VOICE_I2S_SYSCLK_SEL (1 << 8)
+/* 0:normal, 1:invert */
+#define ALC5632_DAI_VOICE_VBCLK_SYSCLK_SEL (1 << 7)
+/* 0:normal, 1:invert */
+#define ALC5632_DAI_VOICE_I2S_LR_INV (1 << 6)
+#define ALC5632_DAI_VOICE_DL_MASK (3 << 2)
+#define ALC5632_DAI_VOICE_DL_16 (0 << 2)
+#define ALC5632_DAI_VOICE_DL_20 (1 << 2)
+#define ALC5632_DAI_VOICE_DL_24 (2 << 2)
+#define ALC5632_DAI_VOICE_DL_8 (3 << 2)
+#define ALC5632_DAI_VOICE_DF_MASK (3 << 0)
+#define ALC5632_DAI_VOICE_DF_I2S (0 << 0)
+#define ALC5632_DAI_VOICE_DF_LEFT (1 << 0)
+#define ALC5632_DAI_VOICE_DF_PCM_A (2 << 0)
+#define ALC5632_DAI_VOICE_DF_PCM_B (3 << 0)
+
+#define ALC5632_PWR_MANAG_ADD1 0x3A
+#define ALC5632_PWR_MANAG_ADD1_MASK 0xEFFF
+#define ALC5632_PWR_ADD1_DAC_L_EN (1 << 15)
+#define ALC5632_PWR_ADD1_DAC_R_EN (1 << 14)
+#define ALC5632_PWR_ADD1_ZERO_CROSS (1 << 13)
+#define ALC5632_PWR_ADD1_MAIN_I2S_EN (1 << 11)
+#define ALC5632_PWR_ADD1_SPK_AMP_EN (1 << 10)
+#define ALC5632_PWR_ADD1_HP_OUT_AMP (1 << 9)
+#define ALC5632_PWR_ADD1_HP_OUT_ENH_AMP (1 << 8)
+#define ALC5632_PWR_ADD1_VOICE_DAC_MIX (1 << 7)
+#define ALC5632_PWR_ADD1_SOFTGEN_EN (1 << 6)
+#define ALC5632_PWR_ADD1_MIC1_SHORT_CURR (1 << 5)
+#define ALC5632_PWR_ADD1_MIC2_SHORT_CURR (1 << 4)
+#define ALC5632_PWR_ADD1_MIC1_EN (1 << 3)
+#define ALC5632_PWR_ADD1_MIC2_EN (1 << 2)
+#define ALC5632_PWR_ADD1_MAIN_BIAS (1 << 1)
+#define ALC5632_PWR_ADD1_DAC_REF (1 << 0)
+
+#define ALC5632_PWR_MANAG_ADD2 0x3C
+#define ALC5632_PWR_MANAG_ADD2_MASK 0x7FFF
+#define ALC5632_PWR_ADD2_PLL1 (1 << 15)
+#define ALC5632_PWR_ADD2_PLL2 (1 << 14)
+#define ALC5632_PWR_ADD2_VREF (1 << 13)
+#define ALC5632_PWR_ADD2_OVT_DET (1 << 12)
+#define ALC5632_PWR_ADD2_VOICE_DAC (1 << 10)
+#define ALC5632_PWR_ADD2_L_DAC_CLK (1 << 9)
+#define ALC5632_PWR_ADD2_R_DAC_CLK (1 << 8)
+#define ALC5632_PWR_ADD2_L_ADC_CLK_GAIN (1 << 7)
+#define ALC5632_PWR_ADD2_R_ADC_CLK_GAIN (1 << 6)
+#define ALC5632_PWR_ADD2_L_HP_MIXER (1 << 5)
+#define ALC5632_PWR_ADD2_R_HP_MIXER (1 << 4)
+#define ALC5632_PWR_ADD2_SPK_MIXER (1 << 3)
+#define ALC5632_PWR_ADD2_MONO_MIXER (1 << 2)
+#define ALC5632_PWR_ADD2_L_ADC_REC_MIXER (1 << 1)
+#define ALC5632_PWR_ADD2_R_ADC_REC_MIXER (1 << 0)
+
+#define ALC5632_PWR_MANAG_ADD3 0x3E
+#define ALC5632_PWR_MANAG_ADD3_MASK 0x7CFF
+#define ALC5632_PWR_ADD3_AUXOUT_VOL (1 << 14)
+#define ALC5632_PWR_ADD3_SPK_L_OUT (1 << 13)
+#define ALC5632_PWR_ADD3_SPK_R_OUT (1 << 12)
+#define ALC5632_PWR_ADD3_HP_L_OUT_VOL (1 << 11)
+#define ALC5632_PWR_ADD3_HP_R_OUT_VOL (1 << 10)
+#define ALC5632_PWR_ADD3_LINEIN_L_VOL (1 << 7)
+#define ALC5632_PWR_ADD3_LINEIN_R_VOL (1 << 6)
+#define ALC5632_PWR_ADD3_AUXIN_VOL (1 << 5)
+#define ALC5632_PWR_ADD3_AUXIN_MIX (1 << 4)
+#define ALC5632_PWR_ADD3_MIC1_VOL (1 << 3)
+#define ALC5632_PWR_ADD3_MIC2_VOL (1 << 2)
+#define ALC5632_PWR_ADD3_MIC1_BOOST_AD (1 << 1)
+#define ALC5632_PWR_ADD3_MIC2_BOOST_AD (1 << 0)
+
+#define ALC5632_GPCR1 0x40
+#define ALC5632_GPCR1_CLK_SYS_SRC_SEL_PLL1 (1 << 15)
+#define ALC5632_GPCR1_CLK_SYS_SRC_SEL_MCLK (0 << 15)
+#define ALC5632_GPCR1_DAC_HI_FLT_EN (1 << 10)
+#define ALC5632_GPCR1_SPK_AMP_CTRL (7 << 1)
+#define ALC5632_GPCR1_VDD_100 (5 << 1)
+#define ALC5632_GPCR1_VDD_125 (4 << 1)
+#define ALC5632_GPCR1_VDD_150 (3 << 1)
+#define ALC5632_GPCR1_VDD_175 (2 << 1)
+#define ALC5632_GPCR1_VDD_200 (1 << 1)
+#define ALC5632_GPCR1_VDD_225 (0 << 1)
+
+#define ALC5632_GPCR2 0x42
+#define ALC5632_GPCR2_PLL1_SOUR_SEL (3 << 12)
+#define ALC5632_PLL_FR_MCLK (0 << 12)
+#define ALC5632_PLL_FR_BCLK (2 << 12)
+#define ALC5632_PLL_FR_VBCLK (3 << 12)
+#define ALC5632_GPCR2_CLK_PLL_PRE_DIV1 (0 << 0)
+
+#define ALC5632_PLL1_CTRL 0x44
+#define ALC5632_PLL1_CTRL_N_VAL(n) (((n) & 0x0f) << 8)
+#define ALC5632_PLL1_M_BYPASS (1 << 7)
+#define ALC5632_PLL1_CTRL_K_VAL(k) (((k) & 0x07) << 4)
+#define ALC5632_PLL1_CTRL_M_VAL(m) (((m) & 0x0f) << 0)
+
+#define ALC5632_PLL2_CTRL 0x46
+#define ALC5632_PLL2_EN (1 << 15)
+#define ALC5632_PLL2_RATIO (0 << 15)
+
+#define ALC5632_GPIO_PIN_CONFIG 0x4C
+#define ALC5632_GPIO_PIN_POLARITY 0x4E
+#define ALC5632_GPIO_PIN_STICKY 0x50
+#define ALC5632_GPIO_PIN_WAKEUP 0x52
+#define ALC5632_GPIO_PIN_STATUS 0x54
+#define ALC5632_GPIO_PIN_SHARING 0x56
+#define ALC5632_OVER_CURR_STATUS 0x58
+#define ALC5632_SOFTVOL_CTRL 0x5A
+#define ALC5632_GPIO_OUPUT_PIN_CTRL 0x5C
+
+#define ALC5632_MISC_CTRL 0x5E
+#define ALC5632_MISC_DISABLE_FAST_VREG (1 << 15)
+#define ALC5632_MISC_AVC_TRGT_SEL (3 << 12)
+#define ALC5632_MISC_AVC_TRGT_RIGHT (1 << 12)
+#define ALC5632_MISC_AVC_TRGT_LEFT (2 << 12)
+#define ALC5632_MISC_AVC_TRGT_BOTH (3 << 12)
+#define ALC5632_MISC_HP_DEPOP_MODE1_EN (1 << 9)
+#define ALC5632_MISC_HP_DEPOP_MODE2_EN (1 << 8)
+#define ALC5632_MISC_HP_DEPOP_MUTE_L (1 << 7)
+#define ALC5632_MISC_HP_DEPOP_MUTE_R (1 << 6)
+#define ALC5632_MISC_HP_DEPOP_MUTE (1 << 5)
+#define ALC5632_MISC_GPIO_WAKEUP_CTRL (1 << 1)
+#define ALC5632_MISC_IRQOUT_INV_CTRL (1 << 0)
+
+#define ALC5632_DAC_CLK_CTRL1 0x60
+#define ALC5632_DAC_CLK_CTRL2 0x62
+#define ALC5632_DAC_CLK_CTRL2_DIV1_2 (1 << 0)
+#define ALC5632_VOICE_DAC_PCM_CLK_CTRL1 0x64
+#define ALC5632_PSEUDO_SPATIAL_CTRL 0x68
+#define ALC5632_HID_CTRL_INDEX 0x6A
+#define ALC5632_HID_CTRL_DATA 0x6C
+#define ALC5632_EQ_CTRL 0x6E
+
+/* undocumented */
+#define ALC5632_VENDOR_ID1 0x7C
+#define ALC5632_VENDOR_ID2 0x7E
+
+#define ALC5632_MAX_REGISTER 0x7E
+
+#endif
diff --git a/sound/soc/codecs/cq93vc.c b/sound/soc/codecs/cq93vc.c
index 46dbfd0..4854b47 100644
--- a/sound/soc/codecs/cq93vc.c
+++ b/sound/soc/codecs/cq93vc.c
@@ -122,7 +122,7 @@
#define CQ93VC_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000)
#define CQ93VC_FORMATS (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE)
-static struct snd_soc_dai_ops cq93vc_dai_ops = {
+static const struct snd_soc_dai_ops cq93vc_dai_ops = {
.digital_mute = cq93vc_mute,
.set_sysclk = cq93vc_set_dai_sysclk,
};
@@ -206,17 +206,7 @@
.remove = __devexit_p(cq93vc_platform_remove),
};
-static int __init cq93vc_init(void)
-{
- return platform_driver_register(&cq93vc_codec_driver);
-}
-module_init(cq93vc_init);
-
-static void __exit cq93vc_exit(void)
-{
- platform_driver_unregister(&cq93vc_codec_driver);
-}
-module_exit(cq93vc_exit);
+module_platform_driver(cq93vc_codec_driver);
MODULE_DESCRIPTION("Texas Instruments DaVinci ASoC CQ0093 Voice Codec Driver");
MODULE_AUTHOR("Miguel Aguilar");
diff --git a/sound/soc/codecs/cs4270.c b/sound/soc/codecs/cs4270.c
index 73f46eb..0555366 100644
--- a/sound/soc/codecs/cs4270.c
+++ b/sound/soc/codecs/cs4270.c
@@ -22,7 +22,6 @@
*/
#include <linux/module.h>
-#include <linux/platform_device.h>
#include <linux/slab.h>
#include <sound/core.h>
#include <sound/soc.h>
@@ -447,7 +446,7 @@
snd_soc_get_volsw, cs4270_soc_put_mute),
};
-static struct snd_soc_dai_ops cs4270_dai_ops = {
+static const struct snd_soc_dai_ops cs4270_dai_ops = {
.hw_params = cs4270_hw_params,
.set_sysclk = cs4270_set_dai_sysclk,
.set_fmt = cs4270_set_dai_fmt,
@@ -579,7 +578,7 @@
* and all registers are written back to the hardware when resuming.
*/
-static int cs4270_soc_suspend(struct snd_soc_codec *codec, pm_message_t mesg)
+static int cs4270_soc_suspend(struct snd_soc_codec *codec)
{
struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
int reg, ret;
@@ -672,7 +671,8 @@
i2c_client->addr);
dev_info(&i2c_client->dev, "hardware revision %X\n", ret & 0xF);
- cs4270 = kzalloc(sizeof(struct cs4270_private), GFP_KERNEL);
+ cs4270 = devm_kzalloc(&i2c_client->dev, sizeof(struct cs4270_private),
+ GFP_KERNEL);
if (!cs4270) {
dev_err(&i2c_client->dev, "could not allocate codec\n");
return -ENOMEM;
@@ -683,8 +683,6 @@
ret = snd_soc_register_codec(&i2c_client->dev,
&soc_codec_device_cs4270, &cs4270_dai, 1);
- if (ret < 0)
- kfree(cs4270);
return ret;
}
@@ -697,7 +695,6 @@
static int cs4270_i2c_remove(struct i2c_client *i2c_client)
{
snd_soc_unregister_codec(&i2c_client->dev);
- kfree(i2c_get_clientdata(i2c_client));
return 0;
}
diff --git a/sound/soc/codecs/cs4271.c b/sound/soc/codecs/cs4271.c
index 69fde15..f6fe846 100644
--- a/sound/soc/codecs/cs4271.c
+++ b/sound/soc/codecs/cs4271.c
@@ -402,7 +402,7 @@
7, 1, 1),
};
-static struct snd_soc_dai_ops cs4271_dai_ops = {
+static const struct snd_soc_dai_ops cs4271_dai_ops = {
.hw_params = cs4271_hw_params,
.set_sysclk = cs4271_set_dai_sysclk,
.set_fmt = cs4271_set_dai_fmt,
@@ -430,7 +430,7 @@
};
#ifdef CONFIG_PM
-static int cs4271_soc_suspend(struct snd_soc_codec *codec, pm_message_t mesg)
+static int cs4271_soc_suspend(struct snd_soc_codec *codec)
{
int ret;
/* Set power-down bit */
diff --git a/sound/soc/codecs/cs42l51.c b/sound/soc/codecs/cs42l51.c
index 1ee66361..a8bf588 100644
--- a/sound/soc/codecs/cs42l51.c
+++ b/sound/soc/codecs/cs42l51.c
@@ -22,7 +22,6 @@
*/
#include <linux/module.h>
-#include <linux/platform_device.h>
#include <linux/slab.h>
#include <sound/core.h>
#include <sound/soc.h>
@@ -175,21 +174,18 @@
static int cs42l51_pdn_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
- unsigned long value;
-
- value = snd_soc_read(w->codec, CS42L51_POWER_CTL1);
- value &= ~CS42L51_POWER_CTL1_PDN;
-
switch (event) {
case SND_SOC_DAPM_PRE_PMD:
- value |= CS42L51_POWER_CTL1_PDN;
+ snd_soc_update_bits(w->codec, CS42L51_POWER_CTL1,
+ CS42L51_POWER_CTL1_PDN,
+ CS42L51_POWER_CTL1_PDN);
break;
default:
case SND_SOC_DAPM_POST_PMD:
+ snd_soc_update_bits(w->codec, CS42L51_POWER_CTL1,
+ CS42L51_POWER_CTL1_PDN, 0);
break;
}
- snd_soc_update_bits(w->codec, CS42L51_POWER_CTL1,
- CS42L51_POWER_CTL1_PDN, value);
return 0;
}
@@ -486,7 +482,7 @@
return snd_soc_write(codec, CS42L51_DAC_OUT_CTL, reg);
}
-static struct snd_soc_dai_ops cs42l51_dai_ops = {
+static const struct snd_soc_dai_ops cs42l51_dai_ops = {
.hw_params = cs42l51_hw_params,
.set_sysclk = cs42l51_set_dai_sysclk,
.set_fmt = cs42l51_set_dai_fmt,
@@ -515,7 +511,6 @@
static int cs42l51_probe(struct snd_soc_codec *codec)
{
struct cs42l51_private *cs42l51 = snd_soc_codec_get_drvdata(codec);
- struct snd_soc_dapm_context *dapm = &codec->dapm;
int ret, reg;
ret = cs42l51_fill_cache(codec);
@@ -543,20 +538,20 @@
if (ret < 0)
return ret;
- snd_soc_add_controls(codec, cs42l51_snd_controls,
- ARRAY_SIZE(cs42l51_snd_controls));
- snd_soc_dapm_new_controls(dapm, cs42l51_dapm_widgets,
- ARRAY_SIZE(cs42l51_dapm_widgets));
- snd_soc_dapm_add_routes(dapm, cs42l51_routes,
- ARRAY_SIZE(cs42l51_routes));
-
return 0;
}
static struct snd_soc_codec_driver soc_codec_device_cs42l51 = {
- .probe = cs42l51_probe,
+ .probe = cs42l51_probe,
.reg_cache_size = CS42L51_NUMREGS + 1,
.reg_word_size = sizeof(u8),
+
+ .controls = cs42l51_snd_controls,
+ .num_controls = ARRAY_SIZE(cs42l51_snd_controls),
+ .dapm_widgets = cs42l51_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(cs42l51_dapm_widgets),
+ .dapm_routes = cs42l51_routes,
+ .num_dapm_routes = ARRAY_SIZE(cs42l51_routes),
};
static int cs42l51_i2c_probe(struct i2c_client *i2c_client,
@@ -582,7 +577,8 @@
dev_info(&i2c_client->dev, "found device cs42l51 rev %d\n",
ret & 7);
- cs42l51 = kzalloc(sizeof(struct cs42l51_private), GFP_KERNEL);
+ cs42l51 = devm_kzalloc(&i2c_client->dev, sizeof(struct cs42l51_private),
+ GFP_KERNEL);
if (!cs42l51) {
dev_err(&i2c_client->dev, "could not allocate codec\n");
return -ENOMEM;
@@ -593,18 +589,13 @@
ret = snd_soc_register_codec(&i2c_client->dev,
&soc_codec_device_cs42l51, &cs42l51_dai, 1);
- if (ret < 0)
- kfree(cs42l51);
error:
return ret;
}
static int cs42l51_i2c_remove(struct i2c_client *client)
{
- struct cs42l51_private *cs42l51 = i2c_get_clientdata(client);
-
snd_soc_unregister_codec(&client->dev);
- kfree(cs42l51);
return 0;
}
diff --git a/sound/soc/codecs/cs42l73.c b/sound/soc/codecs/cs42l73.c
new file mode 100644
index 0000000..9d38db8
--- /dev/null
+++ b/sound/soc/codecs/cs42l73.c
@@ -0,0 +1,1453 @@
+/*
+ * cs42l73.c -- CS42L73 ALSA Soc Audio driver
+ *
+ * Copyright 2011 Cirrus Logic, Inc.
+ *
+ * Authors: Georgi Vlaev, Nucleus Systems Ltd, <joe@nucleusys.com>
+ * Brian Austin, Cirrus Logic Inc, <brian.austin@cirrus.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <linux/i2c.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <sound/initval.h>
+#include <sound/tlv.h>
+#include "cs42l73.h"
+
+struct sp_config {
+ u8 spc, mmcc, spfs;
+ u32 srate;
+};
+struct cs42l73_private {
+ struct sp_config config[3];
+ struct regmap *regmap;
+ u32 sysclk;
+ u8 mclksel;
+ u32 mclk;
+};
+
+static const struct reg_default cs42l73_reg_defaults[] = {
+ { 1, 0x42 }, /* r01 - Device ID A&B */
+ { 2, 0xA7 }, /* r02 - Device ID C&D */
+ { 3, 0x30 }, /* r03 - Device ID E */
+ { 6, 0xF1 }, /* r06 - Power Ctl 1 */
+ { 7, 0xDF }, /* r07 - Power Ctl 2 */
+ { 8, 0x3F }, /* r08 - Power Ctl 3 */
+ { 9, 0x50 }, /* r09 - Charge Pump Freq */
+ { 10, 0x53 }, /* r0A - Output Load MicBias Short Detect */
+ { 11, 0x00 }, /* r0B - DMIC Master Clock Ctl */
+ { 12, 0x00 }, /* r0C - Aux PCM Ctl */
+ { 13, 0x15 }, /* r0D - Aux PCM Master Clock Ctl */
+ { 14, 0x00 }, /* r0E - Audio PCM Ctl */
+ { 15, 0x15 }, /* r0F - Audio PCM Master Clock Ctl */
+ { 16, 0x00 }, /* r10 - Voice PCM Ctl */
+ { 17, 0x15 }, /* r11 - Voice PCM Master Clock Ctl */
+ { 18, 0x00 }, /* r12 - Voice/Aux Sample Rate */
+ { 19, 0x06 }, /* r13 - Misc I/O Path Ctl */
+ { 20, 0x00 }, /* r14 - ADC Input Path Ctl */
+ { 21, 0x00 }, /* r15 - MICA Preamp, PGA Volume */
+ { 22, 0x00 }, /* r16 - MICB Preamp, PGA Volume */
+ { 23, 0x00 }, /* r17 - Input Path A Digital Volume */
+ { 24, 0x00 }, /* r18 - Input Path B Digital Volume */
+ { 25, 0x00 }, /* r19 - Playback Digital Ctl */
+ { 26, 0x00 }, /* r1A - HP/LO Left Digital Volume */
+ { 27, 0x00 }, /* r1B - HP/LO Right Digital Volume */
+ { 28, 0x00 }, /* r1C - Speakerphone Digital Volume */
+ { 29, 0x00 }, /* r1D - Ear/SPKLO Digital Volume */
+ { 30, 0x00 }, /* r1E - HP Left Analog Volume */
+ { 31, 0x00 }, /* r1F - HP Right Analog Volume */
+ { 32, 0x00 }, /* r20 - LO Left Analog Volume */
+ { 33, 0x00 }, /* r21 - LO Right Analog Volume */
+ { 34, 0x00 }, /* r22 - Stereo Input Path Advisory Volume */
+ { 35, 0x00 }, /* r23 - Aux PCM Input Advisory Volume */
+ { 36, 0x00 }, /* r24 - Audio PCM Input Advisory Volume */
+ { 37, 0x00 }, /* r25 - Voice PCM Input Advisory Volume */
+ { 38, 0x00 }, /* r26 - Limiter Attack Rate HP/LO */
+ { 39, 0x7F }, /* r27 - Limter Ctl, Release Rate HP/LO */
+ { 40, 0x00 }, /* r28 - Limter Threshold HP/LO */
+ { 41, 0x00 }, /* r29 - Limiter Attack Rate Speakerphone */
+ { 42, 0x3F }, /* r2A - Limter Ctl, Release Rate Speakerphone */
+ { 43, 0x00 }, /* r2B - Limter Threshold Speakerphone */
+ { 44, 0x00 }, /* r2C - Limiter Attack Rate Ear/SPKLO */
+ { 45, 0x3F }, /* r2D - Limter Ctl, Release Rate Ear/SPKLO */
+ { 46, 0x00 }, /* r2E - Limter Threshold Ear/SPKLO */
+ { 47, 0x00 }, /* r2F - ALC Enable, Attack Rate Left/Right */
+ { 48, 0x3F }, /* r30 - ALC Release Rate Left/Right */
+ { 49, 0x00 }, /* r31 - ALC Threshold Left/Right */
+ { 50, 0x00 }, /* r32 - Noise Gate Ctl Left/Right */
+ { 51, 0x00 }, /* r33 - ALC/NG Misc Ctl */
+ { 52, 0x18 }, /* r34 - Mixer Ctl */
+ { 53, 0x3F }, /* r35 - HP/LO Left Mixer Input Path Volume */
+ { 54, 0x3F }, /* r36 - HP/LO Right Mixer Input Path Volume */
+ { 55, 0x3F }, /* r37 - HP/LO Left Mixer Aux PCM Volume */
+ { 56, 0x3F }, /* r38 - HP/LO Right Mixer Aux PCM Volume */
+ { 57, 0x3F }, /* r39 - HP/LO Left Mixer Audio PCM Volume */
+ { 58, 0x3F }, /* r3A - HP/LO Right Mixer Audio PCM Volume */
+ { 59, 0x3F }, /* r3B - HP/LO Left Mixer Voice PCM Mono Volume */
+ { 60, 0x3F }, /* r3C - HP/LO Right Mixer Voice PCM Mono Volume */
+ { 61, 0x3F }, /* r3D - Aux PCM Left Mixer Input Path Volume */
+ { 62, 0x3F }, /* r3E - Aux PCM Right Mixer Input Path Volume */
+ { 63, 0x3F }, /* r3F - Aux PCM Left Mixer Volume */
+ { 64, 0x3F }, /* r40 - Aux PCM Left Mixer Volume */
+ { 65, 0x3F }, /* r41 - Aux PCM Left Mixer Audio PCM L Volume */
+ { 66, 0x3F }, /* r42 - Aux PCM Right Mixer Audio PCM R Volume */
+ { 67, 0x3F }, /* r43 - Aux PCM Left Mixer Voice PCM Volume */
+ { 68, 0x3F }, /* r44 - Aux PCM Right Mixer Voice PCM Volume */
+ { 69, 0x3F }, /* r45 - Audio PCM Left Input Path Volume */
+ { 70, 0x3F }, /* r46 - Audio PCM Right Input Path Volume */
+ { 71, 0x3F }, /* r47 - Audio PCM Left Mixer Aux PCM L Volume */
+ { 72, 0x3F }, /* r48 - Audio PCM Right Mixer Aux PCM R Volume */
+ { 73, 0x3F }, /* r49 - Audio PCM Left Mixer Volume */
+ { 74, 0x3F }, /* r4A - Audio PCM Right Mixer Volume */
+ { 75, 0x3F }, /* r4B - Audio PCM Left Mixer Voice PCM Volume */
+ { 76, 0x3F }, /* r4C - Audio PCM Right Mixer Voice PCM Volume */
+ { 77, 0x3F }, /* r4D - Voice PCM Left Input Path Volume */
+ { 78, 0x3F }, /* r4E - Voice PCM Right Input Path Volume */
+ { 79, 0x3F }, /* r4F - Voice PCM Left Mixer Aux PCM L Volume */
+ { 80, 0x3F }, /* r50 - Voice PCM Right Mixer Aux PCM R Volume */
+ { 81, 0x3F }, /* r51 - Voice PCM Left Mixer Audio PCM L Volume */
+ { 82, 0x3F }, /* r52 - Voice PCM Right Mixer Audio PCM R Volume */
+ { 83, 0x3F }, /* r53 - Voice PCM Left Mixer Voice PCM Volume */
+ { 84, 0x3F }, /* r54 - Voice PCM Right Mixer Voice PCM Volume */
+ { 85, 0xAA }, /* r55 - Mono Mixer Ctl */
+ { 86, 0x3F }, /* r56 - SPK Mono Mixer Input Path Volume */
+ { 87, 0x3F }, /* r57 - SPK Mono Mixer Aux PCM Mono/L/R Volume */
+ { 88, 0x3F }, /* r58 - SPK Mono Mixer Audio PCM Mono/L/R Volume */
+ { 89, 0x3F }, /* r59 - SPK Mono Mixer Voice PCM Mono Volume */
+ { 90, 0x3F }, /* r5A - SPKLO Mono Mixer Input Path Mono Volume */
+ { 91, 0x3F }, /* r5B - SPKLO Mono Mixer Aux Mono/L/R Volume */
+ { 92, 0x3F }, /* r5C - SPKLO Mono Mixer Audio Mono/L/R Volume */
+ { 93, 0x3F }, /* r5D - SPKLO Mono Mixer Voice Mono Volume */
+ { 94, 0x00 }, /* r5E - Interrupt Mask 1 */
+ { 95, 0x00 }, /* r5F - Interrupt Mask 2 */
+};
+
+static bool cs42l73_volatile_register(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case CS42L73_IS1:
+ case CS42L73_IS2:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static bool cs42l73_readable_register(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case CS42L73_DEVID_AB:
+ case CS42L73_DEVID_CD:
+ case CS42L73_DEVID_E:
+ case CS42L73_REVID:
+ case CS42L73_PWRCTL1:
+ case CS42L73_PWRCTL2:
+ case CS42L73_PWRCTL3:
+ case CS42L73_CPFCHC:
+ case CS42L73_OLMBMSDC:
+ case CS42L73_DMMCC:
+ case CS42L73_XSPC:
+ case CS42L73_XSPMMCC:
+ case CS42L73_ASPC:
+ case CS42L73_ASPMMCC:
+ case CS42L73_VSPC:
+ case CS42L73_VSPMMCC:
+ case CS42L73_VXSPFS:
+ case CS42L73_MIOPC:
+ case CS42L73_ADCIPC:
+ case CS42L73_MICAPREPGAAVOL:
+ case CS42L73_MICBPREPGABVOL:
+ case CS42L73_IPADVOL:
+ case CS42L73_IPBDVOL:
+ case CS42L73_PBDC:
+ case CS42L73_HLADVOL:
+ case CS42L73_HLBDVOL:
+ case CS42L73_SPKDVOL:
+ case CS42L73_ESLDVOL:
+ case CS42L73_HPAAVOL:
+ case CS42L73_HPBAVOL:
+ case CS42L73_LOAAVOL:
+ case CS42L73_LOBAVOL:
+ case CS42L73_STRINV:
+ case CS42L73_XSPINV:
+ case CS42L73_ASPINV:
+ case CS42L73_VSPINV:
+ case CS42L73_LIMARATEHL:
+ case CS42L73_LIMRRATEHL:
+ case CS42L73_LMAXHL:
+ case CS42L73_LIMARATESPK:
+ case CS42L73_LIMRRATESPK:
+ case CS42L73_LMAXSPK:
+ case CS42L73_LIMARATEESL:
+ case CS42L73_LIMRRATEESL:
+ case CS42L73_LMAXESL:
+ case CS42L73_ALCARATE:
+ case CS42L73_ALCRRATE:
+ case CS42L73_ALCMINMAX:
+ case CS42L73_NGCAB:
+ case CS42L73_ALCNGMC:
+ case CS42L73_MIXERCTL:
+ case CS42L73_HLAIPAA:
+ case CS42L73_HLBIPBA:
+ case CS42L73_HLAXSPAA:
+ case CS42L73_HLBXSPBA:
+ case CS42L73_HLAASPAA:
+ case CS42L73_HLBASPBA:
+ case CS42L73_HLAVSPMA:
+ case CS42L73_HLBVSPMA:
+ case CS42L73_XSPAIPAA:
+ case CS42L73_XSPBIPBA:
+ case CS42L73_XSPAXSPAA:
+ case CS42L73_XSPBXSPBA:
+ case CS42L73_XSPAASPAA:
+ case CS42L73_XSPAASPBA:
+ case CS42L73_XSPAVSPMA:
+ case CS42L73_XSPBVSPMA:
+ case CS42L73_ASPAIPAA:
+ case CS42L73_ASPBIPBA:
+ case CS42L73_ASPAXSPAA:
+ case CS42L73_ASPBXSPBA:
+ case CS42L73_ASPAASPAA:
+ case CS42L73_ASPBASPBA:
+ case CS42L73_ASPAVSPMA:
+ case CS42L73_ASPBVSPMA:
+ case CS42L73_VSPAIPAA:
+ case CS42L73_VSPBIPBA:
+ case CS42L73_VSPAXSPAA:
+ case CS42L73_VSPBXSPBA:
+ case CS42L73_VSPAASPAA:
+ case CS42L73_VSPBASPBA:
+ case CS42L73_VSPAVSPMA:
+ case CS42L73_VSPBVSPMA:
+ case CS42L73_MMIXCTL:
+ case CS42L73_SPKMIPMA:
+ case CS42L73_SPKMXSPA:
+ case CS42L73_SPKMASPA:
+ case CS42L73_SPKMVSPMA:
+ case CS42L73_ESLMIPMA:
+ case CS42L73_ESLMXSPA:
+ case CS42L73_ESLMASPA:
+ case CS42L73_ESLMVSPMA:
+ case CS42L73_IM1:
+ case CS42L73_IM2:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static const unsigned int hpaloa_tlv[] = {
+ TLV_DB_RANGE_HEAD(2),
+ 0, 13, TLV_DB_SCALE_ITEM(-7600, 200, 0),
+ 14, 75, TLV_DB_SCALE_ITEM(-4900, 100, 0),
+};
+
+static DECLARE_TLV_DB_SCALE(adc_boost_tlv, 0, 2500, 0);
+
+static DECLARE_TLV_DB_SCALE(hl_tlv, -10200, 50, 0);
+
+static DECLARE_TLV_DB_SCALE(ipd_tlv, -9600, 100, 0);
+
+static DECLARE_TLV_DB_SCALE(micpga_tlv, -600, 50, 0);
+
+static const unsigned int limiter_tlv[] = {
+ TLV_DB_RANGE_HEAD(2),
+ 0, 2, TLV_DB_SCALE_ITEM(-3000, 600, 0),
+ 3, 7, TLV_DB_SCALE_ITEM(-1200, 300, 0),
+};
+
+static const DECLARE_TLV_DB_SCALE(attn_tlv, -6300, 100, 1);
+
+static const char * const cs42l73_pgaa_text[] = { "Line A", "Mic 1" };
+static const char * const cs42l73_pgab_text[] = { "Line B", "Mic 2" };
+
+static const struct soc_enum pgaa_enum =
+ SOC_ENUM_SINGLE(CS42L73_ADCIPC, 3,
+ ARRAY_SIZE(cs42l73_pgaa_text), cs42l73_pgaa_text);
+
+static const struct soc_enum pgab_enum =
+ SOC_ENUM_SINGLE(CS42L73_ADCIPC, 7,
+ ARRAY_SIZE(cs42l73_pgab_text), cs42l73_pgab_text);
+
+static const struct snd_kcontrol_new pgaa_mux =
+ SOC_DAPM_ENUM("Left Analog Input Capture Mux", pgaa_enum);
+
+static const struct snd_kcontrol_new pgab_mux =
+ SOC_DAPM_ENUM("Right Analog Input Capture Mux", pgab_enum);
+
+static const struct snd_kcontrol_new input_left_mixer[] = {
+ SOC_DAPM_SINGLE("ADC Left Input", CS42L73_PWRCTL1,
+ 5, 1, 1),
+ SOC_DAPM_SINGLE("DMIC Left Input", CS42L73_PWRCTL1,
+ 4, 1, 1),
+};
+
+static const struct snd_kcontrol_new input_right_mixer[] = {
+ SOC_DAPM_SINGLE("ADC Right Input", CS42L73_PWRCTL1,
+ 7, 1, 1),
+ SOC_DAPM_SINGLE("DMIC Right Input", CS42L73_PWRCTL1,
+ 6, 1, 1),
+};
+
+static const char * const cs42l73_ng_delay_text[] = {
+ "50ms", "100ms", "150ms", "200ms" };
+
+static const struct soc_enum ng_delay_enum =
+ SOC_ENUM_SINGLE(CS42L73_NGCAB, 0,
+ ARRAY_SIZE(cs42l73_ng_delay_text), cs42l73_ng_delay_text);
+
+static const char * const charge_pump_freq_text[] = {
+ "0", "1", "2", "3", "4",
+ "5", "6", "7", "8", "9",
+ "10", "11", "12", "13", "14", "15" };
+
+static const struct soc_enum charge_pump_enum =
+ SOC_ENUM_SINGLE(CS42L73_CPFCHC, 4,
+ ARRAY_SIZE(charge_pump_freq_text), charge_pump_freq_text);
+
+static const char * const cs42l73_mono_mix_texts[] = {
+ "Left", "Right", "Mono Mix"};
+
+static const unsigned int cs42l73_mono_mix_values[] = { 0, 1, 2 };
+
+static const struct soc_enum spk_asp_enum =
+ SOC_VALUE_ENUM_SINGLE(CS42L73_MMIXCTL, 6, 1,
+ ARRAY_SIZE(cs42l73_mono_mix_texts),
+ cs42l73_mono_mix_texts,
+ cs42l73_mono_mix_values);
+
+static const struct snd_kcontrol_new spk_asp_mixer =
+ SOC_DAPM_ENUM("Route", spk_asp_enum);
+
+static const struct soc_enum spk_xsp_enum =
+ SOC_VALUE_ENUM_SINGLE(CS42L73_MMIXCTL, 4, 3,
+ ARRAY_SIZE(cs42l73_mono_mix_texts),
+ cs42l73_mono_mix_texts,
+ cs42l73_mono_mix_values);
+
+static const struct snd_kcontrol_new spk_xsp_mixer =
+ SOC_DAPM_ENUM("Route", spk_xsp_enum);
+
+static const struct soc_enum esl_asp_enum =
+ SOC_VALUE_ENUM_SINGLE(CS42L73_MMIXCTL, 2, 5,
+ ARRAY_SIZE(cs42l73_mono_mix_texts),
+ cs42l73_mono_mix_texts,
+ cs42l73_mono_mix_values);
+
+static const struct snd_kcontrol_new esl_asp_mixer =
+ SOC_DAPM_ENUM("Route", esl_asp_enum);
+
+static const struct soc_enum esl_xsp_enum =
+ SOC_VALUE_ENUM_SINGLE(CS42L73_MMIXCTL, 0, 7,
+ ARRAY_SIZE(cs42l73_mono_mix_texts),
+ cs42l73_mono_mix_texts,
+ cs42l73_mono_mix_values);
+
+static const struct snd_kcontrol_new esl_xsp_mixer =
+ SOC_DAPM_ENUM("Route", esl_xsp_enum);
+
+static const char * const cs42l73_ip_swap_text[] = {
+ "Stereo", "Mono A", "Mono B", "Swap A-B"};
+
+static const struct soc_enum ip_swap_enum =
+ SOC_ENUM_SINGLE(CS42L73_MIOPC, 6,
+ ARRAY_SIZE(cs42l73_ip_swap_text), cs42l73_ip_swap_text);
+
+static const char * const cs42l73_spo_mixer_text[] = {"Mono", "Stereo"};
+
+static const struct soc_enum vsp_output_mux_enum =
+ SOC_ENUM_SINGLE(CS42L73_MIXERCTL, 5,
+ ARRAY_SIZE(cs42l73_spo_mixer_text), cs42l73_spo_mixer_text);
+
+static const struct soc_enum xsp_output_mux_enum =
+ SOC_ENUM_SINGLE(CS42L73_MIXERCTL, 4,
+ ARRAY_SIZE(cs42l73_spo_mixer_text), cs42l73_spo_mixer_text);
+
+static const struct snd_kcontrol_new vsp_output_mux =
+ SOC_DAPM_ENUM("Route", vsp_output_mux_enum);
+
+static const struct snd_kcontrol_new xsp_output_mux =
+ SOC_DAPM_ENUM("Route", xsp_output_mux_enum);
+
+static const struct snd_kcontrol_new hp_amp_ctl =
+ SOC_DAPM_SINGLE("Switch", CS42L73_PWRCTL3, 0, 1, 1);
+
+static const struct snd_kcontrol_new lo_amp_ctl =
+ SOC_DAPM_SINGLE("Switch", CS42L73_PWRCTL3, 1, 1, 1);
+
+static const struct snd_kcontrol_new spk_amp_ctl =
+ SOC_DAPM_SINGLE("Switch", CS42L73_PWRCTL3, 2, 1, 1);
+
+static const struct snd_kcontrol_new spklo_amp_ctl =
+ SOC_DAPM_SINGLE("Switch", CS42L73_PWRCTL3, 4, 1, 1);
+
+static const struct snd_kcontrol_new ear_amp_ctl =
+ SOC_DAPM_SINGLE("Switch", CS42L73_PWRCTL3, 3, 1, 1);
+
+static const struct snd_kcontrol_new cs42l73_snd_controls[] = {
+ SOC_DOUBLE_R_SX_TLV("Headphone Analog Playback Volume",
+ CS42L73_HPAAVOL, CS42L73_HPBAVOL, 7,
+ 0xffffffC1, 0x0C, hpaloa_tlv),
+
+ SOC_DOUBLE_R_SX_TLV("LineOut Analog Playback Volume", CS42L73_LOAAVOL,
+ CS42L73_LOBAVOL, 7, 0xffffffC1, 0x0C, hpaloa_tlv),
+
+ SOC_DOUBLE_R_SX_TLV("Input PGA Analog Volume", CS42L73_MICAPREPGAAVOL,
+ CS42L73_MICBPREPGABVOL, 5, 0xffffff35,
+ 0x34, micpga_tlv),
+
+ SOC_DOUBLE_R("MIC Preamp Switch", CS42L73_MICAPREPGAAVOL,
+ CS42L73_MICBPREPGABVOL, 6, 1, 1),
+
+ SOC_DOUBLE_R_SX_TLV("Input Path Digital Volume", CS42L73_IPADVOL,
+ CS42L73_IPBDVOL, 7, 0xffffffA0, 0xA0, ipd_tlv),
+
+ SOC_DOUBLE_R_SX_TLV("HL Digital Playback Volume",
+ CS42L73_HLADVOL, CS42L73_HLBDVOL, 7, 0xffffffE5,
+ 0xE4, hl_tlv),
+
+ SOC_SINGLE_TLV("ADC A Boost Volume",
+ CS42L73_ADCIPC, 2, 0x01, 1, adc_boost_tlv),
+
+ SOC_SINGLE_TLV("ADC B Boost Volume",
+ CS42L73_ADCIPC, 6, 0x01, 1, adc_boost_tlv),
+
+ SOC_SINGLE_TLV("Speakerphone Digital Playback Volume",
+ CS42L73_SPKDVOL, 0, 0xE4, 1, hl_tlv),
+
+ SOC_SINGLE_TLV("Ear Speaker Digital Playback Volume",
+ CS42L73_ESLDVOL, 0, 0xE4, 1, hl_tlv),
+
+ SOC_DOUBLE_R("Headphone Analog Playback Switch", CS42L73_HPAAVOL,
+ CS42L73_HPBAVOL, 7, 1, 1),
+
+ SOC_DOUBLE_R("LineOut Analog Playback Switch", CS42L73_LOAAVOL,
+ CS42L73_LOBAVOL, 7, 1, 1),
+ SOC_DOUBLE("Input Path Digital Switch", CS42L73_ADCIPC, 0, 4, 1, 1),
+ SOC_DOUBLE("HL Digital Playback Switch", CS42L73_PBDC, 0,
+ 1, 1, 1),
+ SOC_SINGLE("Speakerphone Digital Playback Switch", CS42L73_PBDC, 2, 1,
+ 1),
+ SOC_SINGLE("Ear Speaker Digital Playback Switch", CS42L73_PBDC, 3, 1,
+ 1),
+
+ SOC_SINGLE("PGA Soft-Ramp Switch", CS42L73_MIOPC, 3, 1, 0),
+ SOC_SINGLE("Analog Zero Cross Switch", CS42L73_MIOPC, 2, 1, 0),
+ SOC_SINGLE("Digital Soft-Ramp Switch", CS42L73_MIOPC, 1, 1, 0),
+ SOC_SINGLE("Analog Output Soft-Ramp Switch", CS42L73_MIOPC, 0, 1, 0),
+
+ SOC_DOUBLE("ADC Signal Polarity Switch", CS42L73_ADCIPC, 1, 5, 1,
+ 0),
+
+ SOC_SINGLE("HL Limiter Attack Rate", CS42L73_LIMARATEHL, 0, 0x3F,
+ 0),
+ SOC_SINGLE("HL Limiter Release Rate", CS42L73_LIMRRATEHL, 0,
+ 0x3F, 0),
+
+
+ SOC_SINGLE("HL Limiter Switch", CS42L73_LIMRRATEHL, 7, 1, 0),
+ SOC_SINGLE("HL Limiter All Channels Switch", CS42L73_LIMRRATEHL, 6, 1,
+ 0),
+
+ SOC_SINGLE_TLV("HL Limiter Max Threshold Volume", CS42L73_LMAXHL, 5, 7,
+ 1, limiter_tlv),
+
+ SOC_SINGLE_TLV("HL Limiter Cushion Volume", CS42L73_LMAXHL, 2, 7, 1,
+ limiter_tlv),
+
+ SOC_SINGLE("SPK Limiter Attack Rate Volume", CS42L73_LIMARATESPK, 0,
+ 0x3F, 0),
+ SOC_SINGLE("SPK Limiter Release Rate Volume", CS42L73_LIMRRATESPK, 0,
+ 0x3F, 0),
+ SOC_SINGLE("SPK Limiter Switch", CS42L73_LIMRRATESPK, 7, 1, 0),
+ SOC_SINGLE("SPK Limiter All Channels Switch", CS42L73_LIMRRATESPK,
+ 6, 1, 0),
+ SOC_SINGLE_TLV("SPK Limiter Max Threshold Volume", CS42L73_LMAXSPK, 5,
+ 7, 1, limiter_tlv),
+
+ SOC_SINGLE_TLV("SPK Limiter Cushion Volume", CS42L73_LMAXSPK, 2, 7, 1,
+ limiter_tlv),
+
+ SOC_SINGLE("ESL Limiter Attack Rate Volume", CS42L73_LIMARATEESL, 0,
+ 0x3F, 0),
+ SOC_SINGLE("ESL Limiter Release Rate Volume", CS42L73_LIMRRATEESL, 0,
+ 0x3F, 0),
+ SOC_SINGLE("ESL Limiter Switch", CS42L73_LIMRRATEESL, 7, 1, 0),
+ SOC_SINGLE_TLV("ESL Limiter Max Threshold Volume", CS42L73_LMAXESL, 5,
+ 7, 1, limiter_tlv),
+
+ SOC_SINGLE_TLV("ESL Limiter Cushion Volume", CS42L73_LMAXESL, 2, 7, 1,
+ limiter_tlv),
+
+ SOC_SINGLE("ALC Attack Rate Volume", CS42L73_ALCARATE, 0, 0x3F, 0),
+ SOC_SINGLE("ALC Release Rate Volume", CS42L73_ALCRRATE, 0, 0x3F, 0),
+ SOC_DOUBLE("ALC Switch", CS42L73_ALCARATE, 6, 7, 1, 0),
+ SOC_SINGLE_TLV("ALC Max Threshold Volume", CS42L73_ALCMINMAX, 5, 7, 0,
+ limiter_tlv),
+ SOC_SINGLE_TLV("ALC Min Threshold Volume", CS42L73_ALCMINMAX, 2, 7, 0,
+ limiter_tlv),
+
+ SOC_DOUBLE("NG Enable Switch", CS42L73_NGCAB, 6, 7, 1, 0),
+ SOC_SINGLE("NG Boost Switch", CS42L73_NGCAB, 5, 1, 0),
+ /*
+ NG Threshold depends on NG_BOOTSAB, which selects
+ between two threshold scales in decibels.
+ Set linear values for now ..
+ */
+ SOC_SINGLE("NG Threshold", CS42L73_NGCAB, 2, 7, 0),
+ SOC_ENUM("NG Delay", ng_delay_enum),
+
+ SOC_ENUM("Charge Pump Frequency", charge_pump_enum),
+
+ SOC_DOUBLE_R_TLV("XSP-IP Volume",
+ CS42L73_XSPAIPAA, CS42L73_XSPBIPBA, 0, 0x3F, 1,
+ attn_tlv),
+ SOC_DOUBLE_R_TLV("XSP-XSP Volume",
+ CS42L73_XSPAXSPAA, CS42L73_XSPBXSPBA, 0, 0x3F, 1,
+ attn_tlv),
+ SOC_DOUBLE_R_TLV("XSP-ASP Volume",
+ CS42L73_XSPAASPAA, CS42L73_XSPAASPBA, 0, 0x3F, 1,
+ attn_tlv),
+ SOC_DOUBLE_R_TLV("XSP-VSP Volume",
+ CS42L73_XSPAVSPMA, CS42L73_XSPBVSPMA, 0, 0x3F, 1,
+ attn_tlv),
+
+ SOC_DOUBLE_R_TLV("ASP-IP Volume",
+ CS42L73_ASPAIPAA, CS42L73_ASPBIPBA, 0, 0x3F, 1,
+ attn_tlv),
+ SOC_DOUBLE_R_TLV("ASP-XSP Volume",
+ CS42L73_ASPAXSPAA, CS42L73_ASPBXSPBA, 0, 0x3F, 1,
+ attn_tlv),
+ SOC_DOUBLE_R_TLV("ASP-ASP Volume",
+ CS42L73_ASPAASPAA, CS42L73_ASPBASPBA, 0, 0x3F, 1,
+ attn_tlv),
+ SOC_DOUBLE_R_TLV("ASP-VSP Volume",
+ CS42L73_ASPAVSPMA, CS42L73_ASPBVSPMA, 0, 0x3F, 1,
+ attn_tlv),
+
+ SOC_DOUBLE_R_TLV("VSP-IP Volume",
+ CS42L73_VSPAIPAA, CS42L73_VSPBIPBA, 0, 0x3F, 1,
+ attn_tlv),
+ SOC_DOUBLE_R_TLV("VSP-XSP Volume",
+ CS42L73_VSPAXSPAA, CS42L73_VSPBXSPBA, 0, 0x3F, 1,
+ attn_tlv),
+ SOC_DOUBLE_R_TLV("VSP-ASP Volume",
+ CS42L73_VSPAASPAA, CS42L73_VSPBASPBA, 0, 0x3F, 1,
+ attn_tlv),
+ SOC_DOUBLE_R_TLV("VSP-VSP Volume",
+ CS42L73_VSPAVSPMA, CS42L73_VSPBVSPMA, 0, 0x3F, 1,
+ attn_tlv),
+
+ SOC_DOUBLE_R_TLV("HL-IP Volume",
+ CS42L73_HLAIPAA, CS42L73_HLBIPBA, 0, 0x3F, 1,
+ attn_tlv),
+ SOC_DOUBLE_R_TLV("HL-XSP Volume",
+ CS42L73_HLAXSPAA, CS42L73_HLBXSPBA, 0, 0x3F, 1,
+ attn_tlv),
+ SOC_DOUBLE_R_TLV("HL-ASP Volume",
+ CS42L73_HLAASPAA, CS42L73_HLBASPBA, 0, 0x3F, 1,
+ attn_tlv),
+ SOC_DOUBLE_R_TLV("HL-VSP Volume",
+ CS42L73_HLAVSPMA, CS42L73_HLBVSPMA, 0, 0x3F, 1,
+ attn_tlv),
+
+ SOC_SINGLE_TLV("SPK-IP Mono Volume",
+ CS42L73_SPKMIPMA, 0, 0x3E, 1, attn_tlv),
+ SOC_SINGLE_TLV("SPK-XSP Mono Volume",
+ CS42L73_SPKMXSPA, 0, 0x3E, 1, attn_tlv),
+ SOC_SINGLE_TLV("SPK-ASP Mono Volume",
+ CS42L73_SPKMASPA, 0, 0x3E, 1, attn_tlv),
+ SOC_SINGLE_TLV("SPK-VSP Mono Volume",
+ CS42L73_SPKMVSPMA, 0, 0x3E, 1, attn_tlv),
+
+ SOC_SINGLE_TLV("ESL-IP Mono Volume",
+ CS42L73_ESLMIPMA, 0, 0x3E, 1, attn_tlv),
+ SOC_SINGLE_TLV("ESL-XSP Mono Volume",
+ CS42L73_ESLMXSPA, 0, 0x3E, 1, attn_tlv),
+ SOC_SINGLE_TLV("ESL-ASP Mono Volume",
+ CS42L73_ESLMASPA, 0, 0x3E, 1, attn_tlv),
+ SOC_SINGLE_TLV("ESL-VSP Mono Volume",
+ CS42L73_ESLMVSPMA, 0, 0x3E, 1, attn_tlv),
+
+ SOC_ENUM("IP Digital Swap/Mono Select", ip_swap_enum),
+
+ SOC_ENUM("VSPOUT Mono/Stereo Select", vsp_output_mux_enum),
+ SOC_ENUM("XSPOUT Mono/Stereo Select", xsp_output_mux_enum),
+};
+
+static const struct snd_soc_dapm_widget cs42l73_dapm_widgets[] = {
+ SND_SOC_DAPM_INPUT("LINEINA"),
+ SND_SOC_DAPM_INPUT("LINEINB"),
+ SND_SOC_DAPM_INPUT("MIC1"),
+ SND_SOC_DAPM_SUPPLY("MIC1 Bias", CS42L73_PWRCTL2, 6, 1, NULL, 0),
+ SND_SOC_DAPM_INPUT("MIC2"),
+ SND_SOC_DAPM_SUPPLY("MIC2 Bias", CS42L73_PWRCTL2, 7, 1, NULL, 0),
+
+ SND_SOC_DAPM_AIF_OUT("XSPOUTL", "XSP Capture", 0,
+ CS42L73_PWRCTL2, 1, 1),
+ SND_SOC_DAPM_AIF_OUT("XSPOUTR", "XSP Capture", 0,
+ CS42L73_PWRCTL2, 1, 1),
+ SND_SOC_DAPM_AIF_OUT("ASPOUTL", "ASP Capture", 0,
+ CS42L73_PWRCTL2, 3, 1),
+ SND_SOC_DAPM_AIF_OUT("ASPOUTR", "ASP Capture", 0,
+ CS42L73_PWRCTL2, 3, 1),
+ SND_SOC_DAPM_AIF_OUT("VSPOUTL", "VSP Capture", 0,
+ CS42L73_PWRCTL2, 4, 1),
+ SND_SOC_DAPM_AIF_OUT("VSPOUTR", "VSP Capture", 0,
+ CS42L73_PWRCTL2, 4, 1),
+
+ SND_SOC_DAPM_PGA("PGA Left", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("PGA Right", SND_SOC_NOPM, 0, 0, NULL, 0),
+
+ SND_SOC_DAPM_MUX("PGA Left Mux", SND_SOC_NOPM, 0, 0, &pgaa_mux),
+ SND_SOC_DAPM_MUX("PGA Right Mux", SND_SOC_NOPM, 0, 0, &pgab_mux),
+
+ SND_SOC_DAPM_ADC("ADC Left", NULL, CS42L73_PWRCTL1, 7, 1),
+ SND_SOC_DAPM_ADC("ADC Right", NULL, CS42L73_PWRCTL1, 5, 1),
+ SND_SOC_DAPM_ADC("DMIC Left", NULL, CS42L73_PWRCTL1, 6, 1),
+ SND_SOC_DAPM_ADC("DMIC Right", NULL, CS42L73_PWRCTL1, 4, 1),
+
+ SND_SOC_DAPM_MIXER_NAMED_CTL("Input Left Capture", SND_SOC_NOPM,
+ 0, 0, input_left_mixer,
+ ARRAY_SIZE(input_left_mixer)),
+
+ SND_SOC_DAPM_MIXER_NAMED_CTL("Input Right Capture", SND_SOC_NOPM,
+ 0, 0, input_right_mixer,
+ ARRAY_SIZE(input_right_mixer)),
+
+ SND_SOC_DAPM_MIXER("ASPL Output Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("ASPR Output Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("XSPL Output Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("XSPR Output Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("VSPL Output Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("VSPR Output Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
+
+ SND_SOC_DAPM_AIF_IN("XSPINL", "XSP Playback", 0,
+ CS42L73_PWRCTL2, 0, 1),
+ SND_SOC_DAPM_AIF_IN("XSPINR", "XSP Playback", 0,
+ CS42L73_PWRCTL2, 0, 1),
+ SND_SOC_DAPM_AIF_IN("XSPINM", "XSP Playback", 0,
+ CS42L73_PWRCTL2, 0, 1),
+
+ SND_SOC_DAPM_AIF_IN("ASPINL", "ASP Playback", 0,
+ CS42L73_PWRCTL2, 2, 1),
+ SND_SOC_DAPM_AIF_IN("ASPINR", "ASP Playback", 0,
+ CS42L73_PWRCTL2, 2, 1),
+ SND_SOC_DAPM_AIF_IN("ASPINM", "ASP Playback", 0,
+ CS42L73_PWRCTL2, 2, 1),
+
+ SND_SOC_DAPM_AIF_IN("VSPIN", "VSP Playback", 0,
+ CS42L73_PWRCTL2, 4, 1),
+
+ SND_SOC_DAPM_MIXER("HL Left Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("HL Right Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("SPK Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("ESL Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
+
+ SND_SOC_DAPM_MUX("ESL-XSP Mux", SND_SOC_NOPM,
+ 0, 0, &esl_xsp_mixer),
+
+ SND_SOC_DAPM_MUX("ESL-ASP Mux", SND_SOC_NOPM,
+ 0, 0, &esl_asp_mixer),
+
+ SND_SOC_DAPM_MUX("SPK-ASP Mux", SND_SOC_NOPM,
+ 0, 0, &spk_asp_mixer),
+
+ SND_SOC_DAPM_MUX("SPK-XSP Mux", SND_SOC_NOPM,
+ 0, 0, &spk_xsp_mixer),
+
+ SND_SOC_DAPM_PGA("HL Left DAC", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("HL Right DAC", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("SPK DAC", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("ESL DAC", SND_SOC_NOPM, 0, 0, NULL, 0),
+
+ SND_SOC_DAPM_SWITCH("HP Amp", CS42L73_PWRCTL3, 0, 1,
+ &hp_amp_ctl),
+ SND_SOC_DAPM_SWITCH("LO Amp", CS42L73_PWRCTL3, 1, 1,
+ &lo_amp_ctl),
+ SND_SOC_DAPM_SWITCH("SPK Amp", CS42L73_PWRCTL3, 2, 1,
+ &spk_amp_ctl),
+ SND_SOC_DAPM_SWITCH("EAR Amp", CS42L73_PWRCTL3, 3, 1,
+ &ear_amp_ctl),
+ SND_SOC_DAPM_SWITCH("SPKLO Amp", CS42L73_PWRCTL3, 4, 1,
+ &spklo_amp_ctl),
+
+ SND_SOC_DAPM_OUTPUT("HPOUTA"),
+ SND_SOC_DAPM_OUTPUT("HPOUTB"),
+ SND_SOC_DAPM_OUTPUT("LINEOUTA"),
+ SND_SOC_DAPM_OUTPUT("LINEOUTB"),
+ SND_SOC_DAPM_OUTPUT("EAROUT"),
+ SND_SOC_DAPM_OUTPUT("SPKOUT"),
+ SND_SOC_DAPM_OUTPUT("SPKLINEOUT"),
+};
+
+static const struct snd_soc_dapm_route cs42l73_audio_map[] = {
+
+ /* SPKLO EARSPK Paths */
+ {"EAROUT", NULL, "EAR Amp"},
+ {"SPKLINEOUT", NULL, "SPKLO Amp"},
+
+ {"EAR Amp", "Switch", "ESL DAC"},
+ {"SPKLO Amp", "Switch", "ESL DAC"},
+
+ {"ESL DAC", "ESL-ASP Mono Volume", "ESL Mixer"},
+ {"ESL DAC", "ESL-XSP Mono Volume", "ESL Mixer"},
+ {"ESL DAC", "ESL-VSP Mono Volume", "VSPIN"},
+ /* Loopback */
+ {"ESL DAC", "ESL-IP Mono Volume", "Input Left Capture"},
+ {"ESL DAC", "ESL-IP Mono Volume", "Input Right Capture"},
+
+ {"ESL Mixer", NULL, "ESL-ASP Mux"},
+ {"ESL Mixer", NULL, "ESL-XSP Mux"},
+
+ {"ESL-ASP Mux", "Left", "ASPINL"},
+ {"ESL-ASP Mux", "Right", "ASPINR"},
+ {"ESL-ASP Mux", "Mono Mix", "ASPINM"},
+
+ {"ESL-XSP Mux", "Left", "XSPINL"},
+ {"ESL-XSP Mux", "Right", "XSPINR"},
+ {"ESL-XSP Mux", "Mono Mix", "XSPINM"},
+
+ /* Speakerphone Paths */
+ {"SPKOUT", NULL, "SPK Amp"},
+ {"SPK Amp", "Switch", "SPK DAC"},
+
+ {"SPK DAC", "SPK-ASP Mono Volume", "SPK Mixer"},
+ {"SPK DAC", "SPK-XSP Mono Volume", "SPK Mixer"},
+ {"SPK DAC", "SPK-VSP Mono Volume", "VSPIN"},
+ /* Loopback */
+ {"SPK DAC", "SPK-IP Mono Volume", "Input Left Capture"},
+ {"SPK DAC", "SPK-IP Mono Volume", "Input Right Capture"},
+
+ {"SPK Mixer", NULL, "SPK-ASP Mux"},
+ {"SPK Mixer", NULL, "SPK-XSP Mux"},
+
+ {"SPK-ASP Mux", "Left", "ASPINL"},
+ {"SPK-ASP Mux", "Mono Mix", "ASPINM"},
+ {"SPK-ASP Mux", "Right", "ASPINR"},
+
+ {"SPK-XSP Mux", "Left", "XSPINL"},
+ {"SPK-XSP Mux", "Mono Mix", "XSPINM"},
+ {"SPK-XSP Mux", "Right", "XSPINR"},
+
+ /* HP LineOUT Paths */
+ {"HPOUTA", NULL, "HP Amp"},
+ {"HPOUTB", NULL, "HP Amp"},
+ {"LINEOUTA", NULL, "LO Amp"},
+ {"LINEOUTB", NULL, "LO Amp"},
+
+ {"HP Amp", "Switch", "HL Left DAC"},
+ {"HP Amp", "Switch", "HL Right DAC"},
+ {"LO Amp", "Switch", "HL Left DAC"},
+ {"LO Amp", "Switch", "HL Right DAC"},
+
+ {"HL Left DAC", "HL-XSP Volume", "HL Left Mixer"},
+ {"HL Right DAC", "HL-XSP Volume", "HL Right Mixer"},
+ {"HL Left DAC", "HL-ASP Volume", "HL Left Mixer"},
+ {"HL Right DAC", "HL-ASP Volume", "HL Right Mixer"},
+ {"HL Left DAC", "HL-VSP Volume", "HL Left Mixer"},
+ {"HL Right DAC", "HL-VSP Volume", "HL Right Mixer"},
+ /* Loopback */
+ {"HL Left DAC", "HL-IP Volume", "HL Left Mixer"},
+ {"HL Right DAC", "HL-IP Volume", "HL Right Mixer"},
+ {"HL Left Mixer", NULL, "Input Left Capture"},
+ {"HL Right Mixer", NULL, "Input Right Capture"},
+
+ {"HL Left Mixer", NULL, "ASPINL"},
+ {"HL Right Mixer", NULL, "ASPINR"},
+ {"HL Left Mixer", NULL, "XSPINL"},
+ {"HL Right Mixer", NULL, "XSPINR"},
+ {"HL Left Mixer", NULL, "VSPIN"},
+ {"HL Right Mixer", NULL, "VSPIN"},
+
+ /* Capture Paths */
+ {"MIC1", NULL, "MIC1 Bias"},
+ {"PGA Left Mux", "Mic 1", "MIC1"},
+ {"MIC2", NULL, "MIC2 Bias"},
+ {"PGA Right Mux", "Mic 2", "MIC2"},
+
+ {"PGA Left Mux", "Line A", "LINEINA"},
+ {"PGA Right Mux", "Line B", "LINEINB"},
+
+ {"PGA Left", NULL, "PGA Left Mux"},
+ {"PGA Right", NULL, "PGA Right Mux"},
+
+ {"ADC Left", NULL, "PGA Left"},
+ {"ADC Right", NULL, "PGA Right"},
+
+ {"Input Left Capture", "ADC Left Input", "ADC Left"},
+ {"Input Right Capture", "ADC Right Input", "ADC Right"},
+ {"Input Left Capture", "DMIC Left Input", "DMIC Left"},
+ {"Input Right Capture", "DMIC Right Input", "DMIC Right"},
+
+ /* Audio Capture */
+ {"ASPL Output Mixer", NULL, "Input Left Capture"},
+ {"ASPR Output Mixer", NULL, "Input Right Capture"},
+
+ {"ASPOUTL", "ASP-IP Volume", "ASPL Output Mixer"},
+ {"ASPOUTR", "ASP-IP Volume", "ASPR Output Mixer"},
+
+ /* Auxillary Capture */
+ {"XSPL Output Mixer", NULL, "Input Left Capture"},
+ {"XSPR Output Mixer", NULL, "Input Right Capture"},
+
+ {"XSPOUTL", "XSP-IP Volume", "XSPL Output Mixer"},
+ {"XSPOUTR", "XSP-IP Volume", "XSPR Output Mixer"},
+
+ {"XSPOUTL", NULL, "XSPL Output Mixer"},
+ {"XSPOUTR", NULL, "XSPR Output Mixer"},
+
+ /* Voice Capture */
+ {"VSPL Output Mixer", NULL, "Input Left Capture"},
+ {"VSPR Output Mixer", NULL, "Input Left Capture"},
+
+ {"VSPOUTL", "VSP-IP Volume", "VSPL Output Mixer"},
+ {"VSPOUTR", "VSP-IP Volume", "VSPR Output Mixer"},
+
+ {"VSPOUTL", NULL, "VSPL Output Mixer"},
+ {"VSPOUTR", NULL, "VSPR Output Mixer"},
+};
+
+struct cs42l73_mclk_div {
+ u32 mclk;
+ u32 srate;
+ u8 mmcc;
+};
+
+static struct cs42l73_mclk_div cs42l73_mclk_coeffs[] = {
+ /* MCLK, Sample Rate, xMMCC[5:0] */
+ {5644800, 11025, 0x30},
+ {5644800, 22050, 0x20},
+ {5644800, 44100, 0x10},
+
+ {6000000, 8000, 0x39},
+ {6000000, 11025, 0x33},
+ {6000000, 12000, 0x31},
+ {6000000, 16000, 0x29},
+ {6000000, 22050, 0x23},
+ {6000000, 24000, 0x21},
+ {6000000, 32000, 0x19},
+ {6000000, 44100, 0x13},
+ {6000000, 48000, 0x11},
+
+ {6144000, 8000, 0x38},
+ {6144000, 12000, 0x30},
+ {6144000, 16000, 0x28},
+ {6144000, 24000, 0x20},
+ {6144000, 32000, 0x18},
+ {6144000, 48000, 0x10},
+
+ {6500000, 8000, 0x3C},
+ {6500000, 11025, 0x35},
+ {6500000, 12000, 0x34},
+ {6500000, 16000, 0x2C},
+ {6500000, 22050, 0x25},
+ {6500000, 24000, 0x24},
+ {6500000, 32000, 0x1C},
+ {6500000, 44100, 0x15},
+ {6500000, 48000, 0x14},
+
+ {6400000, 8000, 0x3E},
+ {6400000, 11025, 0x37},
+ {6400000, 12000, 0x36},
+ {6400000, 16000, 0x2E},
+ {6400000, 22050, 0x27},
+ {6400000, 24000, 0x26},
+ {6400000, 32000, 0x1E},
+ {6400000, 44100, 0x17},
+ {6400000, 48000, 0x16},
+};
+
+struct cs42l73_mclkx_div {
+ u32 mclkx;
+ u8 ratio;
+ u8 mclkdiv;
+};
+
+static struct cs42l73_mclkx_div cs42l73_mclkx_coeffs[] = {
+ {5644800, 1, 0}, /* 5644800 */
+ {6000000, 1, 0}, /* 6000000 */
+ {6144000, 1, 0}, /* 6144000 */
+ {11289600, 2, 2}, /* 5644800 */
+ {12288000, 2, 2}, /* 6144000 */
+ {12000000, 2, 2}, /* 6000000 */
+ {13000000, 2, 2}, /* 6500000 */
+ {19200000, 3, 3}, /* 6400000 */
+ {24000000, 4, 4}, /* 6000000 */
+ {26000000, 4, 4}, /* 6500000 */
+ {38400000, 6, 5} /* 6400000 */
+};
+
+static int cs42l73_get_mclkx_coeff(int mclkx)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(cs42l73_mclkx_coeffs); i++) {
+ if (cs42l73_mclkx_coeffs[i].mclkx == mclkx)
+ return i;
+ }
+ return -EINVAL;
+}
+
+static int cs42l73_get_mclk_coeff(int mclk, int srate)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(cs42l73_mclk_coeffs); i++) {
+ if (cs42l73_mclk_coeffs[i].mclk == mclk &&
+ cs42l73_mclk_coeffs[i].srate == srate)
+ return i;
+ }
+ return -EINVAL;
+
+}
+
+static int cs42l73_set_mclk(struct snd_soc_dai *dai, unsigned int freq)
+{
+ struct snd_soc_codec *codec = dai->codec;
+ struct cs42l73_private *priv = snd_soc_codec_get_drvdata(codec);
+
+ int mclkx_coeff;
+ u32 mclk = 0;
+ u8 dmmcc = 0;
+
+ /* MCLKX -> MCLK */
+ mclkx_coeff = cs42l73_get_mclkx_coeff(freq);
+
+ mclk = cs42l73_mclkx_coeffs[mclkx_coeff].mclkx /
+ cs42l73_mclkx_coeffs[mclkx_coeff].ratio;
+
+ dev_dbg(codec->dev, "MCLK%u %u <-> internal MCLK %u\n",
+ priv->mclksel + 1, cs42l73_mclkx_coeffs[mclkx_coeff].mclkx,
+ mclk);
+
+ dmmcc = (priv->mclksel << 4) |
+ (cs42l73_mclkx_coeffs[mclkx_coeff].mclkdiv << 1);
+
+ snd_soc_write(codec, CS42L73_DMMCC, dmmcc);
+
+ priv->sysclk = mclkx_coeff;
+ priv->mclk = mclk;
+
+ return 0;
+}
+
+static int cs42l73_set_sysclk(struct snd_soc_dai *dai,
+ int clk_id, unsigned int freq, int dir)
+{
+ struct snd_soc_codec *codec = dai->codec;
+ struct cs42l73_private *priv = snd_soc_codec_get_drvdata(codec);
+
+ switch (clk_id) {
+ case CS42L73_CLKID_MCLK1:
+ break;
+ case CS42L73_CLKID_MCLK2:
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ if ((cs42l73_set_mclk(dai, freq)) < 0) {
+ dev_err(codec->dev, "Unable to set MCLK for dai %s\n",
+ dai->name);
+ return -EINVAL;
+ }
+
+ priv->mclksel = clk_id;
+
+ return 0;
+}
+
+static int cs42l73_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
+{
+ struct snd_soc_codec *codec = codec_dai->codec;
+ struct cs42l73_private *priv = snd_soc_codec_get_drvdata(codec);
+ u8 id = codec_dai->id;
+ unsigned int inv, format;
+ u8 spc, mmcc;
+
+ spc = snd_soc_read(codec, CS42L73_SPC(id));
+ mmcc = snd_soc_read(codec, CS42L73_MMCC(id));
+
+ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+ case SND_SOC_DAIFMT_CBM_CFM:
+ mmcc |= MS_MASTER;
+ break;
+
+ case SND_SOC_DAIFMT_CBS_CFS:
+ mmcc &= ~MS_MASTER;
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ format = (fmt & SND_SOC_DAIFMT_FORMAT_MASK);
+ inv = (fmt & SND_SOC_DAIFMT_INV_MASK);
+
+ switch (format) {
+ case SND_SOC_DAIFMT_I2S:
+ spc &= ~SPDIF_PCM;
+ break;
+ case SND_SOC_DAIFMT_DSP_A:
+ case SND_SOC_DAIFMT_DSP_B:
+ if (mmcc & MS_MASTER) {
+ dev_err(codec->dev,
+ "PCM format in slave mode only\n");
+ return -EINVAL;
+ }
+ if (id == CS42L73_ASP) {
+ dev_err(codec->dev,
+ "PCM format is not supported on ASP port\n");
+ return -EINVAL;
+ }
+ spc |= SPDIF_PCM;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ if (spc & SPDIF_PCM) {
+ /* Clear PCM mode, clear PCM_BIT_ORDER bit for MSB->LSB */
+ spc &= ~(PCM_MODE_MASK | PCM_BIT_ORDER);
+ switch (format) {
+ case SND_SOC_DAIFMT_DSP_B:
+ if (inv == SND_SOC_DAIFMT_IB_IF)
+ spc |= PCM_MODE0;
+ if (inv == SND_SOC_DAIFMT_IB_NF)
+ spc |= PCM_MODE1;
+ break;
+ case SND_SOC_DAIFMT_DSP_A:
+ if (inv == SND_SOC_DAIFMT_IB_IF)
+ spc |= PCM_MODE1;
+ break;
+ default:
+ return -EINVAL;
+ }
+ }
+
+ priv->config[id].spc = spc;
+ priv->config[id].mmcc = mmcc;
+
+ return 0;
+}
+
+static u32 cs42l73_asrc_rates[] = {
+ 8000, 11025, 12000, 16000, 22050,
+ 24000, 32000, 44100, 48000
+};
+
+static unsigned int cs42l73_get_xspfs_coeff(u32 rate)
+{
+ int i;
+ for (i = 0; i < ARRAY_SIZE(cs42l73_asrc_rates); i++) {
+ if (cs42l73_asrc_rates[i] == rate)
+ return i + 1;
+ }
+ return 0; /* 0 = Don't know */
+}
+
+static void cs42l73_update_asrc(struct snd_soc_codec *codec, int id, int srate)
+{
+ u8 spfs = 0;
+
+ if (srate > 0)
+ spfs = cs42l73_get_xspfs_coeff(srate);
+
+ switch (id) {
+ case CS42L73_XSP:
+ snd_soc_update_bits(codec, CS42L73_VXSPFS, 0x0f, spfs);
+ break;
+ case CS42L73_ASP:
+ snd_soc_update_bits(codec, CS42L73_ASPC, 0x3c, spfs << 2);
+ break;
+ case CS42L73_VSP:
+ snd_soc_update_bits(codec, CS42L73_VXSPFS, 0xf0, spfs << 4);
+ break;
+ default:
+ break;
+ }
+}
+
+static int cs42l73_pcm_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params,
+ struct snd_soc_dai *dai)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_codec *codec = rtd->codec;
+ struct cs42l73_private *priv = snd_soc_codec_get_drvdata(codec);
+ int id = dai->id;
+ int mclk_coeff;
+ int srate = params_rate(params);
+
+ if (priv->config[id].mmcc & MS_MASTER) {
+ /* CS42L73 Master */
+ /* MCLK -> srate */
+ mclk_coeff =
+ cs42l73_get_mclk_coeff(priv->mclk, srate);
+
+ if (mclk_coeff < 0)
+ return -EINVAL;
+
+ dev_dbg(codec->dev,
+ "DAI[%d]: MCLK %u, srate %u, MMCC[5:0] = %x\n",
+ id, priv->mclk, srate,
+ cs42l73_mclk_coeffs[mclk_coeff].mmcc);
+
+ priv->config[id].mmcc &= 0xC0;
+ priv->config[id].mmcc |= cs42l73_mclk_coeffs[mclk_coeff].mmcc;
+ priv->config[id].spc &= 0xFC;
+ priv->config[id].spc &= MCK_SCLK_64FS;
+ } else {
+ /* CS42L73 Slave */
+ priv->config[id].spc &= 0xFC;
+ priv->config[id].spc |= MCK_SCLK_64FS;
+ }
+ /* Update ASRCs */
+ priv->config[id].srate = srate;
+
+ snd_soc_write(codec, CS42L73_SPC(id), priv->config[id].spc);
+ snd_soc_write(codec, CS42L73_MMCC(id), priv->config[id].mmcc);
+
+ cs42l73_update_asrc(codec, id, srate);
+
+ return 0;
+}
+
+static int cs42l73_set_bias_level(struct snd_soc_codec *codec,
+ enum snd_soc_bias_level level)
+{
+ struct cs42l73_private *cs42l73 = snd_soc_codec_get_drvdata(codec);
+
+ switch (level) {
+ case SND_SOC_BIAS_ON:
+ snd_soc_update_bits(codec, CS42L73_DMMCC, MCLKDIS, 0);
+ snd_soc_update_bits(codec, CS42L73_PWRCTL1, PDN, 0);
+ break;
+
+ case SND_SOC_BIAS_PREPARE:
+ break;
+
+ case SND_SOC_BIAS_STANDBY:
+ if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
+ regcache_cache_only(cs42l73->regmap, false);
+ regcache_sync(cs42l73->regmap);
+ }
+ snd_soc_update_bits(codec, CS42L73_PWRCTL1, PDN, 1);
+ break;
+
+ case SND_SOC_BIAS_OFF:
+ snd_soc_update_bits(codec, CS42L73_PWRCTL1, PDN, 1);
+ snd_soc_update_bits(codec, CS42L73_DMMCC, MCLKDIS, 1);
+ break;
+ }
+ codec->dapm.bias_level = level;
+ return 0;
+}
+
+static int cs42l73_set_tristate(struct snd_soc_dai *dai, int tristate)
+{
+ struct snd_soc_codec *codec = dai->codec;
+ int id = dai->id;
+
+ return snd_soc_update_bits(codec, CS42L73_SPC(id),
+ 0x7F, tristate << 7);
+}
+
+static struct snd_pcm_hw_constraint_list constraints_12_24 = {
+ .count = ARRAY_SIZE(cs42l73_asrc_rates),
+ .list = cs42l73_asrc_rates,
+};
+
+static int cs42l73_pcm_startup(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ snd_pcm_hw_constraint_list(substream->runtime, 0,
+ SNDRV_PCM_HW_PARAM_RATE,
+ &constraints_12_24);
+ return 0;
+}
+
+/* SNDRV_PCM_RATE_KNOT -> 12000, 24000 Hz, limit with constraint list */
+#define CS42L73_RATES (SNDRV_PCM_RATE_8000_48000 | SNDRV_PCM_RATE_KNOT)
+
+
+#define CS42L73_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
+ SNDRV_PCM_FMTBIT_S24_LE)
+
+static const struct snd_soc_dai_ops cs42l73_ops = {
+ .startup = cs42l73_pcm_startup,
+ .hw_params = cs42l73_pcm_hw_params,
+ .set_fmt = cs42l73_set_dai_fmt,
+ .set_sysclk = cs42l73_set_sysclk,
+ .set_tristate = cs42l73_set_tristate,
+};
+
+static struct snd_soc_dai_driver cs42l73_dai[] = {
+ {
+ .name = "cs42l73-xsp",
+ .id = CS42L73_XSP,
+ .playback = {
+ .stream_name = "XSP Playback",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = CS42L73_RATES,
+ .formats = CS42L73_FORMATS,
+ },
+ .capture = {
+ .stream_name = "XSP Capture",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = CS42L73_RATES,
+ .formats = CS42L73_FORMATS,
+ },
+ .ops = &cs42l73_ops,
+ .symmetric_rates = 1,
+ },
+ {
+ .name = "cs42l73-asp",
+ .id = CS42L73_ASP,
+ .playback = {
+ .stream_name = "ASP Playback",
+ .channels_min = 2,
+ .channels_max = 2,
+ .rates = CS42L73_RATES,
+ .formats = CS42L73_FORMATS,
+ },
+ .capture = {
+ .stream_name = "ASP Capture",
+ .channels_min = 2,
+ .channels_max = 2,
+ .rates = CS42L73_RATES,
+ .formats = CS42L73_FORMATS,
+ },
+ .ops = &cs42l73_ops,
+ .symmetric_rates = 1,
+ },
+ {
+ .name = "cs42l73-vsp",
+ .id = CS42L73_VSP,
+ .playback = {
+ .stream_name = "VSP Playback",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = CS42L73_RATES,
+ .formats = CS42L73_FORMATS,
+ },
+ .capture = {
+ .stream_name = "VSP Capture",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = CS42L73_RATES,
+ .formats = CS42L73_FORMATS,
+ },
+ .ops = &cs42l73_ops,
+ .symmetric_rates = 1,
+ }
+};
+
+static int cs42l73_suspend(struct snd_soc_codec *codec)
+{
+ cs42l73_set_bias_level(codec, SND_SOC_BIAS_OFF);
+
+ return 0;
+}
+
+static int cs42l73_resume(struct snd_soc_codec *codec)
+{
+ cs42l73_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+ return 0;
+}
+
+static int cs42l73_probe(struct snd_soc_codec *codec)
+{
+ int ret;
+ struct cs42l73_private *cs42l73 = snd_soc_codec_get_drvdata(codec);
+
+ codec->control_data = cs42l73->regmap;
+
+ ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
+ if (ret < 0) {
+ dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
+ return ret;
+ }
+
+ regcache_cache_only(cs42l73->regmap, true);
+
+ cs42l73_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+
+ cs42l73->mclksel = CS42L73_CLKID_MCLK1; /* MCLK1 as master clk */
+ cs42l73->mclk = 0;
+
+ return ret;
+}
+
+static int cs42l73_remove(struct snd_soc_codec *codec)
+{
+ cs42l73_set_bias_level(codec, SND_SOC_BIAS_OFF);
+ return 0;
+}
+
+static struct snd_soc_codec_driver soc_codec_dev_cs42l73 = {
+ .probe = cs42l73_probe,
+ .remove = cs42l73_remove,
+ .suspend = cs42l73_suspend,
+ .resume = cs42l73_resume,
+ .set_bias_level = cs42l73_set_bias_level,
+
+ .dapm_widgets = cs42l73_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(cs42l73_dapm_widgets),
+ .dapm_routes = cs42l73_audio_map,
+ .num_dapm_routes = ARRAY_SIZE(cs42l73_audio_map),
+
+ .controls = cs42l73_snd_controls,
+ .num_controls = ARRAY_SIZE(cs42l73_snd_controls),
+};
+
+static struct regmap_config cs42l73_regmap = {
+ .reg_bits = 8,
+ .val_bits = 8,
+
+ .max_register = CS42L73_MAX_REGISTER,
+ .reg_defaults = cs42l73_reg_defaults,
+ .num_reg_defaults = ARRAY_SIZE(cs42l73_reg_defaults),
+ .volatile_reg = cs42l73_volatile_register,
+ .readable_reg = cs42l73_readable_register,
+ .cache_type = REGCACHE_RBTREE,
+};
+
+static __devinit int cs42l73_i2c_probe(struct i2c_client *i2c_client,
+ const struct i2c_device_id *id)
+{
+ struct cs42l73_private *cs42l73;
+ int ret;
+ unsigned int devid = 0;
+ unsigned int reg;
+
+ cs42l73 = devm_kzalloc(&i2c_client->dev, sizeof(struct cs42l73_private),
+ GFP_KERNEL);
+ if (!cs42l73) {
+ dev_err(&i2c_client->dev, "could not allocate codec\n");
+ return -ENOMEM;
+ }
+
+ i2c_set_clientdata(i2c_client, cs42l73);
+
+ cs42l73->regmap = regmap_init_i2c(i2c_client, &cs42l73_regmap);
+ if (IS_ERR(cs42l73->regmap)) {
+ ret = PTR_ERR(cs42l73->regmap);
+ dev_err(&i2c_client->dev, "regmap_init() failed: %d\n", ret);
+ goto err;
+ }
+ /* initialize codec */
+ ret = regmap_read(cs42l73->regmap, CS42L73_DEVID_AB, ®);
+ devid = (reg & 0xFF) << 12;
+
+ ret = regmap_read(cs42l73->regmap, CS42L73_DEVID_CD, ®);
+ devid |= (reg & 0xFF) << 4;
+
+ ret = regmap_read(cs42l73->regmap, CS42L73_DEVID_E, ®);
+ devid |= (reg & 0xF0) >> 4;
+
+
+ if (devid != CS42L73_DEVID) {
+ ret = -ENODEV;
+ dev_err(&i2c_client->dev,
+ "CS42L73 Device ID (%X). Expected %X\n",
+ devid, CS42L73_DEVID);
+ goto err_regmap;
+ }
+
+ ret = regmap_read(cs42l73->regmap, CS42L73_REVID, ®);
+ if (ret < 0) {
+ dev_err(&i2c_client->dev, "Get Revision ID failed\n");
+ goto err_regmap;
+ }
+
+ dev_info(&i2c_client->dev,
+ "Cirrus Logic CS42L73, Revision: %02X\n", reg & 0xFF);
+
+ regcache_cache_only(cs42l73->regmap, true);
+
+ ret = snd_soc_register_codec(&i2c_client->dev,
+ &soc_codec_dev_cs42l73, cs42l73_dai,
+ ARRAY_SIZE(cs42l73_dai));
+ if (ret < 0)
+ goto err_regmap;
+ return 0;
+
+err_regmap:
+ regmap_exit(cs42l73->regmap);
+
+err:
+ return ret;
+}
+
+static __devexit int cs42l73_i2c_remove(struct i2c_client *client)
+{
+ struct cs42l73_private *cs42l73 = i2c_get_clientdata(client);
+
+ snd_soc_unregister_codec(&client->dev);
+ regmap_exit(cs42l73->regmap);
+
+ return 0;
+}
+
+static const struct i2c_device_id cs42l73_id[] = {
+ {"cs42l73", 0},
+ {}
+};
+
+MODULE_DEVICE_TABLE(i2c, cs42l73_id);
+
+static struct i2c_driver cs42l73_i2c_driver = {
+ .driver = {
+ .name = "cs42l73",
+ .owner = THIS_MODULE,
+ },
+ .id_table = cs42l73_id,
+ .probe = cs42l73_i2c_probe,
+ .remove = __devexit_p(cs42l73_i2c_remove),
+
+};
+
+static int __init cs42l73_modinit(void)
+{
+ int ret;
+ ret = i2c_add_driver(&cs42l73_i2c_driver);
+ if (ret != 0) {
+ pr_err("Failed to register CS42L73 I2C driver: %d\n", ret);
+ return ret;
+ }
+ return 0;
+}
+
+module_init(cs42l73_modinit);
+
+static void __exit cs42l73_exit(void)
+{
+ i2c_del_driver(&cs42l73_i2c_driver);
+}
+
+module_exit(cs42l73_exit);
+
+MODULE_DESCRIPTION("ASoC CS42L73 driver");
+MODULE_AUTHOR("Georgi Vlaev, Nucleus Systems Ltd, <joe@nucleusys.com>");
+MODULE_AUTHOR("Brian Austin, Cirrus Logic Inc, <brian.austin@cirrus.com>");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/cs42l73.h b/sound/soc/codecs/cs42l73.h
new file mode 100644
index 0000000..f30a4c4
--- /dev/null
+++ b/sound/soc/codecs/cs42l73.h
@@ -0,0 +1,227 @@
+/*
+ * ALSA SoC CS42L73 codec driver
+ *
+ * Copyright 2011 Cirrus Logic, Inc.
+ *
+ * Author: Georgi Vlaev <joe@nucleusys.com>
+ * Brian Austin <brian.austin@cirrus.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * 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
+ *
+ */
+
+#ifndef __CS42L73_H__
+#define __CS42L73_H__
+
+/* I2C Registers */
+/* I2C Address: 1001010[R/W] - 10010100 = 0x94(Write); 10010101 = 0x95(Read) */
+#define CS42L73_CHIP_ID 0x4a
+#define CS42L73_DEVID_AB 0x01 /* Device ID A & B [RO]. */
+#define CS42L73_DEVID_CD 0x02 /* Device ID C & D [RO]. */
+#define CS42L73_DEVID_E 0x03 /* Device ID E [RO]. */
+#define CS42L73_REVID 0x05 /* Revision ID [RO]. */
+#define CS42L73_PWRCTL1 0x06 /* Power Control 1. */
+#define CS42L73_PWRCTL2 0x07 /* Power Control 2. */
+#define CS42L73_PWRCTL3 0x08 /* Power Control 3. */
+#define CS42L73_CPFCHC 0x09 /* Charge Pump Freq. Class H Ctl. */
+#define CS42L73_OLMBMSDC 0x0A /* Output Load, MIC Bias, MIC2 SDT */
+#define CS42L73_DMMCC 0x0B /* Digital MIC & Master Clock Ctl. */
+#define CS42L73_XSPC 0x0C /* Auxiliary Serial Port (XSP) Ctl. */
+#define CS42L73_XSPMMCC 0x0D /* XSP Master Mode Clocking Control. */
+#define CS42L73_ASPC 0x0E /* Audio Serial Port (ASP) Control. */
+#define CS42L73_ASPMMCC 0x0F /* ASP Master Mode Clocking Control. */
+#define CS42L73_VSPC 0x10 /* Voice Serial Port (VSP) Control. */
+#define CS42L73_VSPMMCC 0x11 /* VSP Master Mode Clocking Control. */
+#define CS42L73_VXSPFS 0x12 /* VSP & XSP Sample Rate. */
+#define CS42L73_MIOPC 0x13 /* Misc. Input & Output Path Control. */
+#define CS42L73_ADCIPC 0x14 /* ADC/IP Control. */
+#define CS42L73_MICAPREPGAAVOL 0x15 /* MIC 1 [A] PreAmp, PGAA Vol. */
+#define CS42L73_MICBPREPGABVOL 0x16 /* MIC 2 [B] PreAmp, PGAB Vol. */
+#define CS42L73_IPADVOL 0x17 /* Input Pat7h A Digital Volume. */
+#define CS42L73_IPBDVOL 0x18 /* Input Path B Digital Volume. */
+#define CS42L73_PBDC 0x19 /* Playback Digital Control. */
+#define CS42L73_HLADVOL 0x1A /* HP/Line A Out Digital Vol. */
+#define CS42L73_HLBDVOL 0x1B /* HP/Line B Out Digital Vol. */
+#define CS42L73_SPKDVOL 0x1C /* Spkphone Out [A] Digital Vol. */
+#define CS42L73_ESLDVOL 0x1D /* Ear/Spkphone LO [B] Digital */
+#define CS42L73_HPAAVOL 0x1E /* HP A Analog Volume. */
+#define CS42L73_HPBAVOL 0x1F /* HP B Analog Volume. */
+#define CS42L73_LOAAVOL 0x20 /* Line Out A Analog Volume. */
+#define CS42L73_LOBAVOL 0x21 /* Line Out B Analog Volume. */
+#define CS42L73_STRINV 0x22 /* Stereo Input Path Adv. Vol. */
+#define CS42L73_XSPINV 0x23 /* Auxiliary Port Input Advisory Vol. */
+#define CS42L73_ASPINV 0x24 /* Audio Port Input Advisory Vol. */
+#define CS42L73_VSPINV 0x25 /* Voice Port Input Advisory Vol. */
+#define CS42L73_LIMARATEHL 0x26 /* Lmtr Attack Rate HP/Line. */
+#define CS42L73_LIMRRATEHL 0x27 /* Lmtr Ctl, Rel.Rate HP/Line. */
+#define CS42L73_LMAXHL 0x28 /* Lmtr Thresholds HP/Line. */
+#define CS42L73_LIMARATESPK 0x29 /* Lmtr Attack Rate Spkphone [A]. */
+#define CS42L73_LIMRRATESPK 0x2A /* Lmtr Ctl,Release Rate Spk. [A]. */
+#define CS42L73_LMAXSPK 0x2B /* Lmtr Thresholds Spkphone [A]. */
+#define CS42L73_LIMARATEESL 0x2C /* Lmtr Attack Rate */
+#define CS42L73_LIMRRATEESL 0x2D /* Lmtr Ctl,Release Rate */
+#define CS42L73_LMAXESL 0x2E /* Lmtr Thresholds */
+#define CS42L73_ALCARATE 0x2F /* ALC Enable, Attack Rate AB. */
+#define CS42L73_ALCRRATE 0x30 /* ALC Release Rate AB. */
+#define CS42L73_ALCMINMAX 0x31 /* ALC Thresholds AB. */
+#define CS42L73_NGCAB 0x32 /* Noise Gate Ctl AB. */
+#define CS42L73_ALCNGMC 0x33 /* ALC & Noise Gate Misc Ctl. */
+#define CS42L73_MIXERCTL 0x34 /* Mixer Control. */
+#define CS42L73_HLAIPAA 0x35 /* HP/LO Left Mixer: L. */
+#define CS42L73_HLBIPBA 0x36 /* HP/LO Right Mixer: R. */
+#define CS42L73_HLAXSPAA 0x37 /* HP/LO Left Mixer: XSP L */
+#define CS42L73_HLBXSPBA 0x38 /* HP/LO Right Mixer: XSP R */
+#define CS42L73_HLAASPAA 0x39 /* HP/LO Left Mixer: ASP L */
+#define CS42L73_HLBASPBA 0x3A /* HP/LO Right Mixer: ASP R */
+#define CS42L73_HLAVSPMA 0x3B /* HP/LO Left Mixer: VSP. */
+#define CS42L73_HLBVSPMA 0x3C /* HP/LO Right Mixer: VSP */
+#define CS42L73_XSPAIPAA 0x3D /* XSP Left Mixer: Left */
+#define CS42L73_XSPBIPBA 0x3E /* XSP Rt. Mixer: Right */
+#define CS42L73_XSPAXSPAA 0x3F /* XSP Left Mixer: XSP L */
+#define CS42L73_XSPBXSPBA 0x40 /* XSP Rt. Mixer: XSP R */
+#define CS42L73_XSPAASPAA 0x41 /* XSP Left Mixer: ASP L */
+#define CS42L73_XSPAASPBA 0x42 /* XSP Rt. Mixer: ASP R */
+#define CS42L73_XSPAVSPMA 0x43 /* XSP Left Mixer: VSP */
+#define CS42L73_XSPBVSPMA 0x44 /* XSP Rt. Mixer: VSP */
+#define CS42L73_ASPAIPAA 0x45 /* ASP Left Mixer: Left */
+#define CS42L73_ASPBIPBA 0x46 /* ASP Rt. Mixer: Right */
+#define CS42L73_ASPAXSPAA 0x47 /* ASP Left Mixer: XSP L */
+#define CS42L73_ASPBXSPBA 0x48 /* ASP Rt. Mixer: XSP R */
+#define CS42L73_ASPAASPAA 0x49 /* ASP Left Mixer: ASP L */
+#define CS42L73_ASPBASPBA 0x4A /* ASP Rt. Mixer: ASP R */
+#define CS42L73_ASPAVSPMA 0x4B /* ASP Left Mixer: VSP */
+#define CS42L73_ASPBVSPMA 0x4C /* ASP Rt. Mixer: VSP */
+#define CS42L73_VSPAIPAA 0x4D /* VSP Left Mixer: Left */
+#define CS42L73_VSPBIPBA 0x4E /* VSP Rt. Mixer: Right */
+#define CS42L73_VSPAXSPAA 0x4F /* VSP Left Mixer: XSP L */
+#define CS42L73_VSPBXSPBA 0x50 /* VSP Rt. Mixer: XSP R */
+#define CS42L73_VSPAASPAA 0x51 /* VSP Left Mixer: ASP Left */
+#define CS42L73_VSPBASPBA 0x52 /* VSP Rt. Mixer: ASP Right */
+#define CS42L73_VSPAVSPMA 0x53 /* VSP Left Mixer: VSP */
+#define CS42L73_VSPBVSPMA 0x54 /* VSP Rt. Mixer: VSP */
+#define CS42L73_MMIXCTL 0x55 /* Mono Mixer Controls. */
+#define CS42L73_SPKMIPMA 0x56 /* SPK Mono Mixer: In. Path */
+#define CS42L73_SPKMXSPA 0x57 /* SPK Mono Mixer: XSP Mono/L/R Att. */
+#define CS42L73_SPKMASPA 0x58 /* SPK Mono Mixer: ASP Mono/L/R Att. */
+#define CS42L73_SPKMVSPMA 0x59 /* SPK Mono Mixer: VSP Mono Atten. */
+#define CS42L73_ESLMIPMA 0x5A /* Ear/SpLO Mono Mixer: */
+#define CS42L73_ESLMXSPA 0x5B /* Ear/SpLO Mono Mixer: XSP */
+#define CS42L73_ESLMASPA 0x5C /* Ear/SpLO Mono Mixer: ASP */
+#define CS42L73_ESLMVSPMA 0x5D /* Ear/SpLO Mono Mixer: VSP */
+#define CS42L73_IM1 0x5E /* Interrupt Mask 1. */
+#define CS42L73_IM2 0x5F /* Interrupt Mask 2. */
+#define CS42L73_IS1 0x60 /* Interrupt Status 1 [RO]. */
+#define CS42L73_IS2 0x61 /* Interrupt Status 2 [RO]. */
+#define CS42L73_MAX_REGISTER 0x61 /* Total Registers */
+/* Bitfield Definitions */
+
+/* CS42L73_PWRCTL1 */
+#define PDN_ADCB (1 << 7)
+#define PDN_DMICB (1 << 6)
+#define PDN_ADCA (1 << 5)
+#define PDN_DMICA (1 << 4)
+#define PDN_LDO (1 << 2)
+#define DISCHG_FILT (1 << 1)
+#define PDN (1 << 0)
+
+/* CS42L73_PWRCTL2 */
+#define PDN_MIC2_BIAS (1 << 7)
+#define PDN_MIC1_BIAS (1 << 6)
+#define PDN_VSP (1 << 4)
+#define PDN_ASP_SDOUT (1 << 3)
+#define PDN_ASP_SDIN (1 << 2)
+#define PDN_XSP_SDOUT (1 << 1)
+#define PDN_XSP_SDIN (1 << 0)
+
+/* CS42L73_PWRCTL3 */
+#define PDN_THMS (1 << 5)
+#define PDN_SPKLO (1 << 4)
+#define PDN_EAR (1 << 3)
+#define PDN_SPK (1 << 2)
+#define PDN_LO (1 << 1)
+#define PDN_HP (1 << 0)
+
+/* Thermal Overload Detect. Requires interrupt ... */
+#define THMOVLD_150C 0
+#define THMOVLD_132C 1
+#define THMOVLD_115C 2
+#define THMOVLD_098C 3
+
+
+/* CS42L73_ASPC, CS42L73_XSPC, CS42L73_VSPC */
+#define SP_3ST (1 << 7)
+#define SPDIF_I2S (0 << 6)
+#define SPDIF_PCM (1 << 6)
+#define PCM_MODE0 (0 << 4)
+#define PCM_MODE1 (1 << 4)
+#define PCM_MODE2 (2 << 4)
+#define PCM_MODE_MASK (3 << 4)
+#define PCM_BIT_ORDER (1 << 3)
+#define MCK_SCLK_64FS (0 << 0)
+#define MCK_SCLK_MCLK (2 << 0)
+#define MCK_SCLK_PREMCLK (3 << 0)
+
+/* CS42L73_xSPMMCC */
+#define MS_MASTER (1 << 7)
+
+
+/* CS42L73_DMMCC */
+#define MCLKDIS (1 << 0)
+#define MCLKSEL_MCLK2 (1 << 4)
+#define MCLKSEL_MCLK1 (0 << 4)
+
+/* CS42L73 MCLK derived from MCLK1 or MCLK2 */
+#define CS42L73_CLKID_MCLK1 0
+#define CS42L73_CLKID_MCLK2 1
+
+#define CS42L73_MCLKXDIV 0
+#define CS42L73_MMCCDIV 1
+
+#define CS42L73_XSP 0
+#define CS42L73_ASP 1
+#define CS42L73_VSP 2
+
+/* IS1, IM1 */
+#define MIC2_SDET (1 << 6)
+#define THMOVLD (1 << 4)
+#define DIGMIXOVFL (1 << 3)
+#define IPBOVFL (1 << 1)
+#define IPAOVFL (1 << 0)
+
+/* Analog Softramp */
+#define ANLGOSFT (1 << 0)
+
+/* HP A/B Analog Mute */
+#define HPA_MUTE (1 << 7)
+/* LO A/B Analog Mute */
+#define LOA_MUTE (1 << 7)
+/* Digital Mute */
+#define HLAD_MUTE (1 << 0)
+#define HLBD_MUTE (1 << 1)
+#define SPKD_MUTE (1 << 2)
+#define ESLD_MUTE (1 << 3)
+
+/* Misc defines for codec */
+#define CS42L73_RESET_GPIO 143
+
+#define CS42L73_DEVID 0x00042A73
+#define CS42L73_MCLKX_MIN 5644800
+#define CS42L73_MCLKX_MAX 38400000
+
+#define CS42L73_SPC(id) (CS42L73_XSPC + (id << 1))
+#define CS42L73_MMCC(id) (CS42L73_XSPMMCC + (id << 1))
+#define CS42L73_SPFS(id) ((id == CS42L73_ASP) ? CS42L73_ASPC : CS42L73_VXSPFS)
+
+#endif /* __CS42L73_H__ */
diff --git a/sound/soc/codecs/cx20442.c b/sound/soc/codecs/cx20442.c
index bc7067d..d5fd00a 100644
--- a/sound/soc/codecs/cx20442.c
+++ b/sound/soc/codecs/cx20442.c
@@ -16,6 +16,7 @@
#include <linux/tty.h>
#include <linux/slab.h>
#include <linux/module.h>
+#include <linux/regulator/consumer.h>
#include <sound/core.h>
#include <sound/initval.h>
@@ -25,8 +26,8 @@
struct cx20442_priv {
- enum snd_soc_control_type control_type;
void *control_data;
+ struct regulator *por;
};
#define CX20442_PM 0x0
@@ -324,6 +325,38 @@
},
};
+static int cx20442_set_bias_level(struct snd_soc_codec *codec,
+ enum snd_soc_bias_level level)
+{
+ struct cx20442_priv *cx20442 = snd_soc_codec_get_drvdata(codec);
+ int err = 0;
+
+ switch (level) {
+ case SND_SOC_BIAS_PREPARE:
+ if (codec->dapm.bias_level != SND_SOC_BIAS_STANDBY)
+ break;
+ if (IS_ERR(cx20442->por))
+ err = PTR_ERR(cx20442->por);
+ else
+ err = regulator_enable(cx20442->por);
+ break;
+ case SND_SOC_BIAS_STANDBY:
+ if (codec->dapm.bias_level != SND_SOC_BIAS_PREPARE)
+ break;
+ if (IS_ERR(cx20442->por))
+ err = PTR_ERR(cx20442->por);
+ else
+ err = regulator_disable(cx20442->por);
+ break;
+ default:
+ break;
+ }
+ if (!err)
+ codec->dapm.bias_level = level;
+
+ return err;
+}
+
static int cx20442_codec_probe(struct snd_soc_codec *codec)
{
struct cx20442_priv *cx20442;
@@ -331,9 +364,13 @@
cx20442 = kzalloc(sizeof(struct cx20442_priv), GFP_KERNEL);
if (cx20442 == NULL)
return -ENOMEM;
- snd_soc_codec_set_drvdata(codec, cx20442);
+ cx20442->por = regulator_get(codec->dev, "POR");
+ if (IS_ERR(cx20442->por))
+ dev_warn(codec->dev, "failed to get the regulator");
cx20442->control_data = NULL;
+
+ snd_soc_codec_set_drvdata(codec, cx20442);
codec->hw_write = NULL;
codec->card->pop_time = 0;
@@ -350,6 +387,12 @@
tty_hangup(tty);
}
+ if (!IS_ERR(cx20442->por)) {
+ /* should be already in STANDBY, hence disabled */
+ regulator_put(cx20442->por);
+ }
+
+ snd_soc_codec_set_drvdata(codec, NULL);
kfree(cx20442);
return 0;
}
@@ -359,6 +402,7 @@
static struct snd_soc_codec_driver cx20442_codec_dev = {
.probe = cx20442_codec_probe,
.remove = cx20442_codec_remove,
+ .set_bias_level = cx20442_set_bias_level,
.reg_cache_default = &cx20442_reg,
.reg_cache_size = 1,
.reg_word_size = sizeof(u8),
@@ -391,17 +435,7 @@
.remove = __exit_p(cx20442_platform_remove),
};
-static int __init cx20442_init(void)
-{
- return platform_driver_register(&cx20442_platform_driver);
-}
-module_init(cx20442_init);
-
-static void __exit cx20442_exit(void)
-{
- platform_driver_unregister(&cx20442_platform_driver);
-}
-module_exit(cx20442_exit);
+module_platform_driver(cx20442_platform_driver);
MODULE_DESCRIPTION("ASoC CX20442-11 voice modem codec driver");
MODULE_AUTHOR("Janusz Krzysztofik");
diff --git a/sound/soc/codecs/da7210.c b/sound/soc/codecs/da7210.c
index b545b7d..ab38e93 100644
--- a/sound/soc/codecs/da7210.c
+++ b/sound/soc/codecs/da7210.c
@@ -17,7 +17,6 @@
#include <linux/delay.h>
#include <linux/i2c.h>
-#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <sound/pcm.h>
@@ -182,9 +181,14 @@
/* AUX1_L bit fields */
#define DA7210_AUX1_L_VOL (0x3F << 0)
+#define DA7210_AUX1_L_EN (1 << 7)
/* AUX1_R bit fields */
#define DA7210_AUX1_R_VOL (0x3F << 0)
+#define DA7210_AUX1_R_EN (1 << 7)
+
+/* AUX2 bit fields */
+#define DA7210_AUX2_EN (1 << 3)
/* Minimum INPGA and AUX1 volume to enable noise suppression */
#define DA7210_INPGA_MIN_VOL_NS 0x0A /* 10.5dB */
@@ -235,12 +239,22 @@
0x3, 0x7, TLV_DB_SCALE_ITEM(-1800, 600, 0)
};
+static const unsigned int aux1_vol_tlv[] = {
+ TLV_DB_RANGE_HEAD(2),
+ 0x0, 0x10, TLV_DB_SCALE_ITEM(TLV_DB_GAIN_MUTE, 0, 1),
+ /* -48dB to 21dB */
+ 0x11, 0x3f, TLV_DB_SCALE_ITEM(-4800, 150, 0)
+};
+
static const DECLARE_TLV_DB_SCALE(eq_gain_tlv, -1050, 150, 0);
static const DECLARE_TLV_DB_SCALE(adc_eq_master_gain_tlv, -1800, 600, 1);
static const DECLARE_TLV_DB_SCALE(dac_gain_tlv, -7725, 75, 0);
+static const DECLARE_TLV_DB_SCALE(mic_vol_tlv, -600, 600, 0);
+static const DECLARE_TLV_DB_SCALE(aux2_vol_tlv, -600, 600, 0);
+static const DECLARE_TLV_DB_SCALE(inpga_gain_tlv, -450, 150, 0);
/* ADC and DAC high pass filter f0 value */
-static const char const *da7210_hpf_cutoff_txt[] = {
+static const char * const da7210_hpf_cutoff_txt[] = {
"Fs/8192*pi", "Fs/4096*pi", "Fs/2048*pi", "Fs/1024*pi"
};
@@ -251,7 +265,7 @@
SOC_ENUM_SINGLE(DA7210_ADC_HPF, 0, 4, da7210_hpf_cutoff_txt);
/* ADC and DAC voice (8kHz) high pass cutoff value */
-static const char const *da7210_vf_cutoff_txt[] = {
+static const char * const da7210_vf_cutoff_txt[] = {
"2.5Hz", "25Hz", "50Hz", "100Hz", "150Hz", "200Hz", "300Hz", "400Hz"
};
@@ -345,6 +359,17 @@
SOC_SINGLE_TLV("Mono Playback Volume", DA7210_OUT2, 0, 0x7, 0,
mono_vol_tlv),
+ SOC_DOUBLE_R_TLV("Mic Capture Volume",
+ DA7210_MIC_L, DA7210_MIC_R,
+ 0, 0x5, 0, mic_vol_tlv),
+ SOC_DOUBLE_R_TLV("Aux1 Capture Volume",
+ DA7210_AUX1_L, DA7210_AUX1_R,
+ 0, 0x3f, 0, aux1_vol_tlv),
+ SOC_SINGLE_TLV("Aux2 Capture Volume", DA7210_AUX2, 0, 0x3, 0,
+ aux2_vol_tlv),
+ SOC_DOUBLE_TLV("In PGA Capture Volume", DA7210_IN_GAIN, 0, 4, 0xF, 0,
+ inpga_gain_tlv),
+
/* DAC Equalizer controls */
SOC_SINGLE("DAC EQ Switch", DA7210_DAC_EQ5, 7, 1, 0),
SOC_SINGLE_TLV("DAC EQ1 Volume", DA7210_DAC_EQ1_2, 0, 0xf, 1,
@@ -422,26 +447,42 @@
static const struct snd_kcontrol_new da7210_dapm_inmixl_controls[] = {
SOC_DAPM_SINGLE("Mic Left Switch", DA7210_INMIX_L, 0, 1, 0),
SOC_DAPM_SINGLE("Mic Right Switch", DA7210_INMIX_L, 1, 1, 0),
+ SOC_DAPM_SINGLE("Aux1 Left Switch", DA7210_INMIX_L, 2, 1, 0),
+ SOC_DAPM_SINGLE("Aux2 Switch", DA7210_INMIX_L, 3, 1, 0),
+ SOC_DAPM_SINGLE("Outmix Left Switch", DA7210_INMIX_L, 4, 1, 0),
};
/* In Mixer Right */
static const struct snd_kcontrol_new da7210_dapm_inmixr_controls[] = {
SOC_DAPM_SINGLE("Mic Right Switch", DA7210_INMIX_R, 0, 1, 0),
SOC_DAPM_SINGLE("Mic Left Switch", DA7210_INMIX_R, 1, 1, 0),
+ SOC_DAPM_SINGLE("Aux1 Right Switch", DA7210_INMIX_R, 2, 1, 0),
+ SOC_DAPM_SINGLE("Aux2 Switch", DA7210_INMIX_R, 3, 1, 0),
+ SOC_DAPM_SINGLE("Outmix Right Switch", DA7210_INMIX_R, 4, 1, 0),
};
/* Out Mixer Left */
static const struct snd_kcontrol_new da7210_dapm_outmixl_controls[] = {
+ SOC_DAPM_SINGLE("Aux1 Left Switch", DA7210_OUTMIX_L, 0, 1, 0),
+ SOC_DAPM_SINGLE("Aux2 Switch", DA7210_OUTMIX_L, 1, 1, 0),
+ SOC_DAPM_SINGLE("INPGA Left Switch", DA7210_OUTMIX_L, 2, 1, 0),
+ SOC_DAPM_SINGLE("INPGA Right Switch", DA7210_OUTMIX_L, 3, 1, 0),
SOC_DAPM_SINGLE("DAC Left Switch", DA7210_OUTMIX_L, 4, 1, 0),
};
/* Out Mixer Right */
static const struct snd_kcontrol_new da7210_dapm_outmixr_controls[] = {
+ SOC_DAPM_SINGLE("Aux1 Right Switch", DA7210_OUTMIX_R, 0, 1, 0),
+ SOC_DAPM_SINGLE("Aux2 Switch", DA7210_OUTMIX_R, 1, 1, 0),
+ SOC_DAPM_SINGLE("INPGA Left Switch", DA7210_OUTMIX_R, 2, 1, 0),
+ SOC_DAPM_SINGLE("INPGA Right Switch", DA7210_OUTMIX_R, 3, 1, 0),
SOC_DAPM_SINGLE("DAC Right Switch", DA7210_OUTMIX_R, 4, 1, 0),
};
/* Mono Mixer */
static const struct snd_kcontrol_new da7210_dapm_monomix_controls[] = {
+ SOC_DAPM_SINGLE("INPGA Right Switch", DA7210_OUT2, 3, 1, 0),
+ SOC_DAPM_SINGLE("INPGA Left Switch", DA7210_OUT2, 4, 1, 0),
SOC_DAPM_SINGLE("Outmix Right Switch", DA7210_OUT2, 5, 1, 0),
SOC_DAPM_SINGLE("Outmix Left Switch", DA7210_OUT2, 6, 1, 0),
};
@@ -452,14 +493,23 @@
/* Input Lines */
SND_SOC_DAPM_INPUT("MICL"),
SND_SOC_DAPM_INPUT("MICR"),
+ SND_SOC_DAPM_INPUT("AUX1L"),
+ SND_SOC_DAPM_INPUT("AUX1R"),
+ SND_SOC_DAPM_INPUT("AUX2"),
/* Input PGAs */
SND_SOC_DAPM_PGA("Mic Left", DA7210_STARTUP3, 0, 1, NULL, 0),
SND_SOC_DAPM_PGA("Mic Right", DA7210_STARTUP3, 1, 1, NULL, 0),
+ SND_SOC_DAPM_PGA("Aux1 Left", DA7210_STARTUP3, 2, 1, NULL, 0),
+ SND_SOC_DAPM_PGA("Aux1 Right", DA7210_STARTUP3, 3, 1, NULL, 0),
+ SND_SOC_DAPM_PGA("Aux2 Mono", DA7210_STARTUP3, 4, 1, NULL, 0),
SND_SOC_DAPM_PGA("INPGA Left", DA7210_INMIX_L, 7, 0, NULL, 0),
SND_SOC_DAPM_PGA("INPGA Right", DA7210_INMIX_R, 7, 0, NULL, 0),
+ /* MICBIAS */
+ SND_SOC_DAPM_SUPPLY("Mic Bias", DA7210_MIC_L, 6, 0, NULL, 0),
+
/* Input Mixers */
SND_SOC_DAPM_MIXER("In Mixer Left", SND_SOC_NOPM, 0, 0,
&da7210_dapm_inmixl_controls[0],
@@ -515,12 +565,21 @@
/* Input path */
{"Mic Left", NULL, "MICL"},
{"Mic Right", NULL, "MICR"},
+ {"Aux1 Left", NULL, "AUX1L"},
+ {"Aux1 Right", NULL, "AUX1R"},
+ {"Aux2 Mono", NULL, "AUX2"},
{"In Mixer Left", "Mic Left Switch", "Mic Left"},
{"In Mixer Left", "Mic Right Switch", "Mic Right"},
+ {"In Mixer Left", "Aux1 Left Switch", "Aux1 Left"},
+ {"In Mixer Left", "Aux2 Switch", "Aux2 Mono"},
+ {"In Mixer Left", "Outmix Left Switch", "Out Mixer Left"},
{"In Mixer Right", "Mic Right Switch", "Mic Right"},
{"In Mixer Right", "Mic Left Switch", "Mic Left"},
+ {"In Mixer Right", "Aux1 Right Switch", "Aux1 Right"},
+ {"In Mixer Right", "Aux2 Switch", "Aux2 Mono"},
+ {"In Mixer Right", "Outmix Right Switch", "Out Mixer Right"},
{"INPGA Left", NULL, "In Mixer Left"},
{"ADC Left", NULL, "INPGA Left"},
@@ -529,9 +588,20 @@
{"ADC Right", NULL, "INPGA Right"},
/* Output path */
+ {"Out Mixer Left", "Aux1 Left Switch", "Aux1 Left"},
+ {"Out Mixer Left", "Aux2 Switch", "Aux2 Mono"},
+ {"Out Mixer Left", "INPGA Left Switch", "INPGA Left"},
+ {"Out Mixer Left", "INPGA Right Switch", "INPGA Right"},
{"Out Mixer Left", "DAC Left Switch", "DAC Left"},
+
+ {"Out Mixer Right", "Aux1 Right Switch", "Aux1 Right"},
+ {"Out Mixer Right", "Aux2 Switch", "Aux2 Mono"},
+ {"Out Mixer Right", "INPGA Right Switch", "INPGA Right"},
+ {"Out Mixer Right", "INPGA Left Switch", "INPGA Left"},
{"Out Mixer Right", "DAC Right Switch", "DAC Right"},
+ {"Mono Mixer", "INPGA Right Switch", "INPGA Right"},
+ {"Mono Mixer", "INPGA Left Switch", "INPGA Left"},
{"Mono Mixer", "Outmix Right Switch", "Out Mixer Right"},
{"Mono Mixer", "Outmix Left Switch", "Out Mixer Left"},
@@ -761,7 +831,7 @@
SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
/* DAI operations */
-static struct snd_soc_dai_ops da7210_dai_ops = {
+static const struct snd_soc_dai_ops da7210_dai_ops = {
.hw_params = da7210_hw_params,
.set_fmt = da7210_set_dai_fmt,
.digital_mute = da7210_mute,
@@ -888,6 +958,12 @@
snd_soc_write(codec, DA7210_OUT2, DA7210_OUT2_EN |
DA7210_OUT2_OUTMIX_L | DA7210_OUT2_OUTMIX_R);
+ /* Enable Aux1 */
+ snd_soc_write(codec, DA7210_AUX1_L, DA7210_AUX1_L_EN);
+ snd_soc_write(codec, DA7210_AUX1_R, DA7210_AUX1_R_EN);
+ /* Enable Aux2 */
+ snd_soc_write(codec, DA7210_AUX2, DA7210_AUX2_EN);
+
/* Diable PLL and bypass it */
snd_soc_write(codec, DA7210_PLL, DA7210_PLL_FS_48000);
@@ -945,7 +1021,8 @@
struct da7210_priv *da7210;
int ret;
- da7210 = kzalloc(sizeof(struct da7210_priv), GFP_KERNEL);
+ da7210 = devm_kzalloc(&i2c->dev, sizeof(struct da7210_priv),
+ GFP_KERNEL);
if (!da7210)
return -ENOMEM;
@@ -954,16 +1031,12 @@
ret = snd_soc_register_codec(&i2c->dev,
&soc_codec_dev_da7210, &da7210_dai, 1);
- if (ret < 0)
- kfree(da7210);
-
return ret;
}
static int __devexit da7210_i2c_remove(struct i2c_client *client)
{
snd_soc_unregister_codec(&client->dev);
- kfree(i2c_get_clientdata(client));
return 0;
}
diff --git a/sound/soc/codecs/dfbmcs320.c b/sound/soc/codecs/dfbmcs320.c
index 704bbde..bfe46aa 100644
--- a/sound/soc/codecs/dfbmcs320.c
+++ b/sound/soc/codecs/dfbmcs320.c
@@ -55,17 +55,7 @@
.remove = __devexit_p(dfbmcs320_remove),
};
-static int __init dfbmcs320_init(void)
-{
- return platform_driver_register(&dfmcs320_driver);
-}
-module_init(dfbmcs320_init);
-
-static void __exit dfbmcs320_exit(void)
-{
- platform_driver_unregister(&dfmcs320_driver);
-}
-module_exit(dfbmcs320_exit);
+module_platform_driver(dfmcs320_driver);
MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
MODULE_DESCRIPTION("ASoC DFBM-CS320 bluethooth module driver");
diff --git a/sound/soc/codecs/dmic.c b/sound/soc/codecs/dmic.c
index 6fae765..3e929f0 100644
--- a/sound/soc/codecs/dmic.c
+++ b/sound/soc/codecs/dmic.c
@@ -89,17 +89,7 @@
.remove = __devexit_p(dmic_dev_remove),
};
-static int __init dmic_init(void)
-{
- return platform_driver_register(&dmic_driver);
-}
-module_init(dmic_init);
-
-static void __exit dmic_exit(void)
-{
- platform_driver_unregister(&dmic_driver);
-}
-module_exit(dmic_exit);
+module_platform_driver(dmic_driver);
MODULE_DESCRIPTION("Generic DMIC driver");
MODULE_AUTHOR("Liam Girdwood <lrg@slimlogic.co.uk>");
diff --git a/sound/soc/codecs/jz4740.c b/sound/soc/codecs/jz4740.c
index 3e1f4e1..4624e75 100644
--- a/sound/soc/codecs/jz4740.c
+++ b/sound/soc/codecs/jz4740.c
@@ -207,7 +207,7 @@
return 0;
}
-static struct snd_soc_dai_ops jz4740_codec_dai_ops = {
+static const struct snd_soc_dai_ops jz4740_codec_dai_ops = {
.hw_params = jz4740_codec_hw_params,
};
@@ -312,7 +312,7 @@
#ifdef CONFIG_PM_SLEEP
-static int jz4740_codec_suspend(struct snd_soc_codec *codec, pm_message_t state)
+static int jz4740_codec_suspend(struct snd_soc_codec *codec)
{
return jz4740_codec_set_bias_level(codec, SND_SOC_BIAS_OFF);
}
@@ -353,7 +353,8 @@
struct jz4740_codec *jz4740_codec;
struct resource *mem;
- jz4740_codec = kzalloc(sizeof(*jz4740_codec), GFP_KERNEL);
+ jz4740_codec = devm_kzalloc(&pdev->dev, sizeof(*jz4740_codec),
+ GFP_KERNEL);
if (!jz4740_codec)
return -ENOMEM;
@@ -361,14 +362,14 @@
if (!mem) {
dev_err(&pdev->dev, "Failed to get mmio memory resource\n");
ret = -ENOENT;
- goto err_free_codec;
+ goto err_out;
}
mem = request_mem_region(mem->start, resource_size(mem), pdev->name);
if (!mem) {
dev_err(&pdev->dev, "Failed to request mmio memory region\n");
ret = -EBUSY;
- goto err_free_codec;
+ goto err_out;
}
jz4740_codec->base = ioremap(mem->start, resource_size(mem));
@@ -394,9 +395,7 @@
iounmap(jz4740_codec->base);
err_release_mem_region:
release_mem_region(mem->start, resource_size(mem));
-err_free_codec:
- kfree(jz4740_codec);
-
+err_out:
return ret;
}
@@ -411,7 +410,6 @@
release_mem_region(mem->start, resource_size(mem));
platform_set_drvdata(pdev, NULL);
- kfree(jz4740_codec);
return 0;
}
@@ -425,17 +423,7 @@
},
};
-static int __init jz4740_codec_init(void)
-{
- return platform_driver_register(&jz4740_codec_driver);
-}
-module_init(jz4740_codec_init);
-
-static void __exit jz4740_codec_exit(void)
-{
- platform_driver_unregister(&jz4740_codec_driver);
-}
-module_exit(jz4740_codec_exit);
+module_platform_driver(jz4740_codec_driver);
MODULE_DESCRIPTION("JZ4740 SoC internal codec driver");
MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
diff --git a/sound/soc/codecs/lm4857.c b/sound/soc/codecs/lm4857.c
index c387daf..3190392 100644
--- a/sound/soc/codecs/lm4857.c
+++ b/sound/soc/codecs/lm4857.c
@@ -215,7 +215,7 @@
struct lm4857 *lm4857;
int ret;
- lm4857 = kzalloc(sizeof(*lm4857), GFP_KERNEL);
+ lm4857 = devm_kzalloc(&i2c->dev, sizeof(*lm4857), GFP_KERNEL);
if (!lm4857)
return -ENOMEM;
@@ -225,21 +225,12 @@
ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_lm4857, NULL, 0);
- if (ret) {
- kfree(lm4857);
- return ret;
- }
-
- return 0;
+ return ret;
}
static int __devexit lm4857_i2c_remove(struct i2c_client *i2c)
{
- struct lm4857 *lm4857 = i2c_get_clientdata(i2c);
-
snd_soc_unregister_codec(&i2c->dev);
- kfree(lm4857);
-
return 0;
}
diff --git a/sound/soc/codecs/max98088.c b/sound/soc/codecs/max98088.c
index ebbf63c..006efcf 100644
--- a/sound/soc/codecs/max98088.c
+++ b/sound/soc/codecs/max98088.c
@@ -15,7 +15,6 @@
#include <linux/delay.h>
#include <linux/pm.h>
#include <linux/i2c.h>
-#include <linux/platform_device.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
@@ -1650,14 +1649,14 @@
#define MAX98088_RATES SNDRV_PCM_RATE_8000_96000
#define MAX98088_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE)
-static struct snd_soc_dai_ops max98088_dai1_ops = {
+static const struct snd_soc_dai_ops max98088_dai1_ops = {
.set_sysclk = max98088_dai_set_sysclk,
.set_fmt = max98088_dai1_set_fmt,
.hw_params = max98088_dai1_hw_params,
.digital_mute = max98088_dai1_digital_mute,
};
-static struct snd_soc_dai_ops max98088_dai2_ops = {
+static const struct snd_soc_dai_ops max98088_dai2_ops = {
.set_sysclk = max98088_dai_set_sysclk,
.set_fmt = max98088_dai2_set_fmt,
.hw_params = max98088_dai2_hw_params,
@@ -1947,7 +1946,7 @@
}
#ifdef CONFIG_PM
-static int max98088_suspend(struct snd_soc_codec *codec, pm_message_t state)
+static int max98088_suspend(struct snd_soc_codec *codec)
{
max98088_set_bias_level(codec, SND_SOC_BIAS_OFF);
@@ -2070,7 +2069,8 @@
struct max98088_priv *max98088;
int ret;
- max98088 = kzalloc(sizeof(struct max98088_priv), GFP_KERNEL);
+ max98088 = devm_kzalloc(&i2c->dev, sizeof(struct max98088_priv),
+ GFP_KERNEL);
if (max98088 == NULL)
return -ENOMEM;
@@ -2081,15 +2081,12 @@
ret = snd_soc_register_codec(&i2c->dev,
&soc_codec_dev_max98088, &max98088_dai[0], 2);
- if (ret < 0)
- kfree(max98088);
return ret;
}
static int __devexit max98088_i2c_remove(struct i2c_client *client)
{
snd_soc_unregister_codec(&client->dev);
- kfree(i2c_get_clientdata(client));
return 0;
}
diff --git a/sound/soc/codecs/max98095.c b/sound/soc/codecs/max98095.c
index 26d7b08..fcfa749 100644
--- a/sound/soc/codecs/max98095.c
+++ b/sound/soc/codecs/max98095.c
@@ -15,7 +15,6 @@
#include <linux/delay.h>
#include <linux/pm.h>
#include <linux/i2c.h>
-#include <linux/platform_device.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
@@ -1782,19 +1781,19 @@
#define MAX98095_RATES SNDRV_PCM_RATE_8000_96000
#define MAX98095_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE)
-static struct snd_soc_dai_ops max98095_dai1_ops = {
+static const struct snd_soc_dai_ops max98095_dai1_ops = {
.set_sysclk = max98095_dai_set_sysclk,
.set_fmt = max98095_dai1_set_fmt,
.hw_params = max98095_dai1_hw_params,
};
-static struct snd_soc_dai_ops max98095_dai2_ops = {
+static const struct snd_soc_dai_ops max98095_dai2_ops = {
.set_sysclk = max98095_dai_set_sysclk,
.set_fmt = max98095_dai2_set_fmt,
.hw_params = max98095_dai2_hw_params,
};
-static struct snd_soc_dai_ops max98095_dai3_ops = {
+static const struct snd_soc_dai_ops max98095_dai3_ops = {
.set_sysclk = max98095_dai_set_sysclk,
.set_fmt = max98095_dai3_set_fmt,
.hw_params = max98095_dai3_hw_params,
@@ -2175,7 +2174,7 @@
}
#ifdef CONFIG_PM
-static int max98095_suspend(struct snd_soc_codec *codec, pm_message_t state)
+static int max98095_suspend(struct snd_soc_codec *codec)
{
max98095_set_bias_level(codec, SND_SOC_BIAS_OFF);
@@ -2341,7 +2340,8 @@
struct max98095_priv *max98095;
int ret;
- max98095 = kzalloc(sizeof(struct max98095_priv), GFP_KERNEL);
+ max98095 = devm_kzalloc(&i2c->dev, sizeof(struct max98095_priv),
+ GFP_KERNEL);
if (max98095 == NULL)
return -ENOMEM;
@@ -2351,16 +2351,12 @@
ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_max98095,
max98095_dai, ARRAY_SIZE(max98095_dai));
- if (ret < 0)
- kfree(max98095);
return ret;
}
static int __devexit max98095_i2c_remove(struct i2c_client *client)
{
snd_soc_unregister_codec(&client->dev);
- kfree(i2c_get_clientdata(client));
-
return 0;
}
diff --git a/sound/soc/codecs/max9850.c b/sound/soc/codecs/max9850.c
index 208d2ee..a191309 100644
--- a/sound/soc/codecs/max9850.c
+++ b/sound/soc/codecs/max9850.c
@@ -86,7 +86,7 @@
SND_SOC_DAPM_INPUT("INR"),
};
-static const struct snd_soc_dapm_route intercon[] = {
+static const struct snd_soc_dapm_route max9850_dapm_routes[] = {
/* output mixer */
{"Output Mixer", NULL, "DAC"},
{"Output Mixer", "Line In Switch", "Line Input"},
@@ -254,7 +254,7 @@
#define MAX9850_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
SNDRV_PCM_FMTBIT_S24_LE)
-static struct snd_soc_dai_ops max9850_dai_ops = {
+static const struct snd_soc_dai_ops max9850_dai_ops = {
.hw_params = max9850_hw_params,
.set_sysclk = max9850_set_dai_sysclk,
.set_fmt = max9850_set_dai_fmt,
@@ -273,7 +273,7 @@
};
#ifdef CONFIG_PM
-static int max9850_suspend(struct snd_soc_codec *codec, pm_message_t state)
+static int max9850_suspend(struct snd_soc_codec *codec)
{
max9850_set_bias_level(codec, SND_SOC_BIAS_OFF);
@@ -293,7 +293,6 @@
static int max9850_probe(struct snd_soc_codec *codec)
{
- struct snd_soc_dapm_context *dapm = &codec->dapm;
int ret;
ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_I2C);
@@ -309,13 +308,6 @@
/* set slew-rate 125ms */
snd_soc_update_bits(codec, MAX9850_CHARGE_PUMP, 0xff, 0xc0);
- snd_soc_dapm_new_controls(dapm, max9850_dapm_widgets,
- ARRAY_SIZE(max9850_dapm_widgets));
- snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
-
- snd_soc_add_controls(codec, max9850_controls,
- ARRAY_SIZE(max9850_controls));
-
return 0;
}
@@ -328,6 +320,13 @@
.reg_word_size = sizeof(u8),
.reg_cache_default = max9850_reg,
.volatile_register = max9850_volatile_register,
+
+ .controls = max9850_controls,
+ .num_controls = ARRAY_SIZE(max9850_controls),
+ .dapm_widgets = max9850_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(max9850_dapm_widgets),
+ .dapm_routes = max9850_dapm_routes,
+ .num_dapm_routes = ARRAY_SIZE(max9850_dapm_routes),
};
static int __devinit max9850_i2c_probe(struct i2c_client *i2c,
@@ -336,7 +335,8 @@
struct max9850_priv *max9850;
int ret;
- max9850 = kzalloc(sizeof(struct max9850_priv), GFP_KERNEL);
+ max9850 = devm_kzalloc(&i2c->dev, sizeof(struct max9850_priv),
+ GFP_KERNEL);
if (max9850 == NULL)
return -ENOMEM;
@@ -344,15 +344,12 @@
ret = snd_soc_register_codec(&i2c->dev,
&soc_codec_dev_max9850, &max9850_dai, 1);
- if (ret < 0)
- kfree(max9850);
return ret;
}
static __devexit int max9850_i2c_remove(struct i2c_client *client)
{
snd_soc_unregister_codec(&client->dev);
- kfree(i2c_get_clientdata(client));
return 0;
}
diff --git a/sound/soc/codecs/pcm3008.c b/sound/soc/codecs/pcm3008.c
index f731651..edcaa7e 100644
--- a/sound/soc/codecs/pcm3008.c
+++ b/sound/soc/codecs/pcm3008.c
@@ -118,7 +118,7 @@
}
#ifdef CONFIG_PM
-static int pcm3008_soc_suspend(struct snd_soc_codec *codec, pm_message_t msg)
+static int pcm3008_soc_suspend(struct snd_soc_codec *codec)
{
struct pcm3008_setup_data *setup = codec->dev->platform_data;
@@ -172,17 +172,7 @@
},
};
-static int __init pcm3008_modinit(void)
-{
- return platform_driver_register(&pcm3008_codec_driver);
-}
-module_init(pcm3008_modinit);
-
-static void __exit pcm3008_exit(void)
-{
- platform_driver_unregister(&pcm3008_codec_driver);
-}
-module_exit(pcm3008_exit);
+module_platform_driver(pcm3008_codec_driver);
MODULE_DESCRIPTION("Soc PCM3008 driver");
MODULE_AUTHOR("Hugo Villeneuve");
diff --git a/sound/soc/codecs/rt5631.c b/sound/soc/codecs/rt5631.c
index 4646e80..20c324c 100644
--- a/sound/soc/codecs/rt5631.c
+++ b/sound/soc/codecs/rt5631.c
@@ -18,7 +18,6 @@
#include <linux/delay.h>
#include <linux/pm.h>
#include <linux/i2c.h>
-#include <linux/platform_device.h>
#include <linux/spi/spi.h>
#include <sound/core.h>
#include <sound/pcm.h>
@@ -1642,7 +1641,7 @@
}
#ifdef CONFIG_PM
-static int rt5631_suspend(struct snd_soc_codec *codec, pm_message_t state)
+static int rt5631_suspend(struct snd_soc_codec *codec)
{
rt5631_set_bias_level(codec, SND_SOC_BIAS_OFF);
return 0;
@@ -1664,7 +1663,7 @@
SNDRV_PCM_FMTBIT_S24_LE | \
SNDRV_PCM_FMTBIT_S8)
-static struct snd_soc_dai_ops rt5631_ops = {
+static const struct snd_soc_dai_ops rt5631_ops = {
.hw_params = rt5631_hifi_pcm_params,
.set_fmt = rt5631_hifi_codec_set_dai_fmt,
.set_sysclk = rt5631_hifi_codec_set_dai_sysclk,
@@ -1725,7 +1724,8 @@
struct rt5631_priv *rt5631;
int ret;
- rt5631 = kzalloc(sizeof(struct rt5631_priv), GFP_KERNEL);
+ rt5631 = devm_kzalloc(&i2c->dev, sizeof(struct rt5631_priv),
+ GFP_KERNEL);
if (NULL == rt5631)
return -ENOMEM;
@@ -1733,16 +1733,12 @@
ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5631,
rt5631_dai, ARRAY_SIZE(rt5631_dai));
- if (ret < 0)
- kfree(rt5631);
-
return ret;
}
static __devexit int rt5631_i2c_remove(struct i2c_client *client)
{
snd_soc_unregister_codec(&client->dev);
- kfree(i2c_get_clientdata(client));
return 0;
}
diff --git a/sound/soc/codecs/sgtl5000.c b/sound/soc/codecs/sgtl5000.c
index f6b6551..d7bd918 100644
--- a/sound/soc/codecs/sgtl5000.c
+++ b/sound/soc/codecs/sgtl5000.c
@@ -16,7 +16,6 @@
#include <linux/pm.h>
#include <linux/i2c.h>
#include <linux/clk.h>
-#include <linux/platform_device.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>
#include <linux/regulator/consumer.h>
@@ -923,7 +922,7 @@
SNDRV_PCM_FMTBIT_S24_LE |\
SNDRV_PCM_FMTBIT_S32_LE)
-static struct snd_soc_dai_ops sgtl5000_ops = {
+static const struct snd_soc_dai_ops sgtl5000_ops = {
.hw_params = sgtl5000_pcm_hw_params,
.digital_mute = sgtl5000_digital_mute,
.set_fmt = sgtl5000_set_dai_fmt,
@@ -968,7 +967,7 @@
}
#ifdef CONFIG_SUSPEND
-static int sgtl5000_suspend(struct snd_soc_codec *codec, pm_message_t state)
+static int sgtl5000_suspend(struct snd_soc_codec *codec)
{
sgtl5000_set_bias_level(codec, SND_SOC_BIAS_OFF);
@@ -1077,7 +1076,7 @@
/* according to datasheet, maximum voltage of supplies */
if (vdda > 3600 || vddio > 3600 || vddd > 1980) {
dev_err(codec->dev,
- "exceed max voltage vdda %dmv vddio %dma vddd %dma\n",
+ "exceed max voltage vdda %dmV vddio %dmV vddd %dmV\n",
vdda, vddio, vddd);
return -EINVAL;
@@ -1402,7 +1401,8 @@
struct sgtl5000_priv *sgtl5000;
int ret;
- sgtl5000 = kzalloc(sizeof(struct sgtl5000_priv), GFP_KERNEL);
+ sgtl5000 = devm_kzalloc(&client->dev, sizeof(struct sgtl5000_priv),
+ GFP_KERNEL);
if (!sgtl5000)
return -ENOMEM;
@@ -1410,22 +1410,13 @@
ret = snd_soc_register_codec(&client->dev,
&sgtl5000_driver, &sgtl5000_dai, 1);
- if (ret) {
- dev_err(&client->dev, "Failed to register codec: %d\n", ret);
- kfree(sgtl5000);
- return ret;
- }
-
- return 0;
+ return ret;
}
static __devexit int sgtl5000_i2c_remove(struct i2c_client *client)
{
- struct sgtl5000_priv *sgtl5000 = i2c_get_clientdata(client);
-
snd_soc_unregister_codec(&client->dev);
- kfree(sgtl5000);
return 0;
}
diff --git a/sound/soc/codecs/sigmadsp.c b/sound/soc/codecs/sigmadsp.c
new file mode 100644
index 0000000..5be42bf
--- /dev/null
+++ b/sound/soc/codecs/sigmadsp.c
@@ -0,0 +1,246 @@
+/*
+ * Load Analog Devices SigmaStudio firmware files
+ *
+ * Copyright 2009-2011 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <linux/crc32.h>
+#include <linux/delay.h>
+#include <linux/firmware.h>
+#include <linux/kernel.h>
+#include <linux/i2c.h>
+#include <linux/regmap.h>
+#include <linux/module.h>
+
+#include "sigmadsp.h"
+
+#define SIGMA_MAGIC "ADISIGM"
+
+struct sigma_firmware_header {
+ unsigned char magic[7];
+ u8 version;
+ __le32 crc;
+} __packed;
+
+enum {
+ SIGMA_ACTION_WRITEXBYTES = 0,
+ SIGMA_ACTION_WRITESINGLE,
+ SIGMA_ACTION_WRITESAFELOAD,
+ SIGMA_ACTION_DELAY,
+ SIGMA_ACTION_PLLWAIT,
+ SIGMA_ACTION_NOOP,
+ SIGMA_ACTION_END,
+};
+
+struct sigma_action {
+ u8 instr;
+ u8 len_hi;
+ __le16 len;
+ __be16 addr;
+ unsigned char payload[];
+} __packed;
+
+struct sigma_firmware {
+ const struct firmware *fw;
+ size_t pos;
+
+ void *control_data;
+ int (*write)(void *control_data, const struct sigma_action *sa,
+ size_t len);
+};
+
+static inline u32 sigma_action_len(struct sigma_action *sa)
+{
+ return (sa->len_hi << 16) | le16_to_cpu(sa->len);
+}
+
+static size_t sigma_action_size(struct sigma_action *sa)
+{
+ size_t payload = 0;
+
+ switch (sa->instr) {
+ case SIGMA_ACTION_WRITEXBYTES:
+ case SIGMA_ACTION_WRITESINGLE:
+ case SIGMA_ACTION_WRITESAFELOAD:
+ payload = sigma_action_len(sa);
+ break;
+ default:
+ break;
+ }
+
+ payload = ALIGN(payload, 2);
+
+ return payload + sizeof(struct sigma_action);
+}
+
+/*
+ * Returns a negative error value in case of an error, 0 if processing of
+ * the firmware should be stopped after this action, 1 otherwise.
+ */
+static int
+process_sigma_action(struct sigma_firmware *ssfw, struct sigma_action *sa)
+{
+ size_t len = sigma_action_len(sa);
+ int ret;
+
+ pr_debug("%s: instr:%i addr:%#x len:%zu\n", __func__,
+ sa->instr, sa->addr, len);
+
+ switch (sa->instr) {
+ case SIGMA_ACTION_WRITEXBYTES:
+ case SIGMA_ACTION_WRITESINGLE:
+ case SIGMA_ACTION_WRITESAFELOAD:
+ ret = ssfw->write(ssfw->control_data, sa, len);
+ if (ret < 0)
+ return -EINVAL;
+ break;
+ case SIGMA_ACTION_DELAY:
+ udelay(len);
+ len = 0;
+ break;
+ case SIGMA_ACTION_END:
+ return 0;
+ default:
+ return -EINVAL;
+ }
+
+ return 1;
+}
+
+static int
+process_sigma_actions(struct sigma_firmware *ssfw)
+{
+ struct sigma_action *sa;
+ size_t size;
+ int ret;
+
+ while (ssfw->pos + sizeof(*sa) <= ssfw->fw->size) {
+ sa = (struct sigma_action *)(ssfw->fw->data + ssfw->pos);
+
+ size = sigma_action_size(sa);
+ ssfw->pos += size;
+ if (ssfw->pos > ssfw->fw->size || size == 0)
+ break;
+
+ ret = process_sigma_action(ssfw, sa);
+
+ pr_debug("%s: action returned %i\n", __func__, ret);
+
+ if (ret <= 0)
+ return ret;
+ }
+
+ if (ssfw->pos != ssfw->fw->size)
+ return -EINVAL;
+
+ return 0;
+}
+
+static int _process_sigma_firmware(struct device *dev,
+ struct sigma_firmware *ssfw, const char *name)
+{
+ int ret;
+ struct sigma_firmware_header *ssfw_head;
+ const struct firmware *fw;
+ u32 crc;
+
+ pr_debug("%s: loading firmware %s\n", __func__, name);
+
+ /* first load the blob */
+ ret = request_firmware(&fw, name, dev);
+ if (ret) {
+ pr_debug("%s: request_firmware() failed with %i\n", __func__, ret);
+ return ret;
+ }
+ ssfw->fw = fw;
+
+ /* then verify the header */
+ ret = -EINVAL;
+
+ /*
+ * Reject too small or unreasonable large files. The upper limit has been
+ * chosen a bit arbitrarily, but it should be enough for all practical
+ * purposes and having the limit makes it easier to avoid integer
+ * overflows later in the loading process.
+ */
+ if (fw->size < sizeof(*ssfw_head) || fw->size >= 0x4000000) {
+ dev_err(dev, "Failed to load firmware: Invalid size\n");
+ goto done;
+ }
+
+ ssfw_head = (void *)fw->data;
+ if (memcmp(ssfw_head->magic, SIGMA_MAGIC, ARRAY_SIZE(ssfw_head->magic))) {
+ dev_err(dev, "Failed to load firmware: Invalid magic\n");
+ goto done;
+ }
+
+ crc = crc32(0, fw->data + sizeof(*ssfw_head),
+ fw->size - sizeof(*ssfw_head));
+ pr_debug("%s: crc=%x\n", __func__, crc);
+ if (crc != le32_to_cpu(ssfw_head->crc)) {
+ dev_err(dev, "Failed to load firmware: Wrong crc checksum: expected %x got %x\n",
+ le32_to_cpu(ssfw_head->crc), crc);
+ goto done;
+ }
+
+ ssfw->pos = sizeof(*ssfw_head);
+
+ /* finally process all of the actions */
+ ret = process_sigma_actions(ssfw);
+
+ done:
+ release_firmware(fw);
+
+ pr_debug("%s: loaded %s\n", __func__, name);
+
+ return ret;
+}
+
+#if IS_ENABLED(CONFIG_I2C)
+
+static int sigma_action_write_i2c(void *control_data,
+ const struct sigma_action *sa, size_t len)
+{
+ return i2c_master_send(control_data, (const unsigned char *)&sa->addr,
+ len);
+}
+
+int process_sigma_firmware(struct i2c_client *client, const char *name)
+{
+ struct sigma_firmware ssfw;
+
+ ssfw.control_data = client;
+ ssfw.write = sigma_action_write_i2c;
+
+ return _process_sigma_firmware(&client->dev, &ssfw, name);
+}
+EXPORT_SYMBOL(process_sigma_firmware);
+
+#endif
+
+#if IS_ENABLED(CONFIG_REGMAP)
+
+static int sigma_action_write_regmap(void *control_data,
+ const struct sigma_action *sa, size_t len)
+{
+ return regmap_raw_write(control_data, le16_to_cpu(sa->addr),
+ sa->payload, len - 2);
+}
+
+int process_sigma_firmware_regmap(struct device *dev, struct regmap *regmap,
+ const char *name)
+{
+ struct sigma_firmware ssfw;
+
+ ssfw.control_data = regmap;
+ ssfw.write = sigma_action_write_regmap;
+
+ return _process_sigma_firmware(dev, &ssfw, name);
+}
+EXPORT_SYMBOL(process_sigma_firmware_regmap);
+
+#endif
+
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/sigmadsp.h b/sound/soc/codecs/sigmadsp.h
new file mode 100644
index 0000000..e439cbd
--- /dev/null
+++ b/sound/soc/codecs/sigmadsp.h
@@ -0,0 +1,21 @@
+/*
+ * Load firmware files from Analog Devices SigmaStudio
+ *
+ * Copyright 2009-2011 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#ifndef __SIGMA_FIRMWARE_H__
+#define __SIGMA_FIRMWARE_H__
+
+#include <linux/device.h>
+#include <linux/regmap.h>
+
+struct i2c_client;
+
+extern int process_sigma_firmware(struct i2c_client *client, const char *name);
+extern int process_sigma_firmware_regmap(struct device *dev,
+ struct regmap *regmap, const char *name);
+
+#endif
diff --git a/sound/soc/codecs/sn95031.c b/sound/soc/codecs/sn95031.c
index 887d618..f99baa0 100644
--- a/sound/soc/codecs/sn95031.c
+++ b/sound/soc/codecs/sn95031.c
@@ -698,21 +698,21 @@
}
/* Codec DAI section */
-static struct snd_soc_dai_ops sn95031_headset_dai_ops = {
+static const struct snd_soc_dai_ops sn95031_headset_dai_ops = {
.digital_mute = sn95031_pcm_hs_mute,
.hw_params = sn95031_pcm_hw_params,
};
-static struct snd_soc_dai_ops sn95031_speaker_dai_ops = {
+static const struct snd_soc_dai_ops sn95031_speaker_dai_ops = {
.digital_mute = sn95031_pcm_spkr_mute,
.hw_params = sn95031_pcm_hw_params,
};
-static struct snd_soc_dai_ops sn95031_vib1_dai_ops = {
+static const struct snd_soc_dai_ops sn95031_vib1_dai_ops = {
.hw_params = sn95031_pcm_hw_params,
};
-static struct snd_soc_dai_ops sn95031_vib2_dai_ops = {
+static const struct snd_soc_dai_ops sn95031_vib2_dai_ops = {
.hw_params = sn95031_pcm_hw_params,
};
@@ -920,19 +920,7 @@
.remove = __devexit_p(sn95031_device_remove),
};
-static int __init sn95031_init(void)
-{
- pr_debug("driver init called\n");
- return platform_driver_register(&sn95031_codec_driver);
-}
-module_init(sn95031_init);
-
-static void __exit sn95031_exit(void)
-{
- pr_debug("driver exit called\n");
- platform_driver_unregister(&sn95031_codec_driver);
-}
-module_exit(sn95031_exit);
+module_platform_driver(sn95031_codec_driver);
MODULE_DESCRIPTION("ASoC TI SN95031 codec driver");
MODULE_AUTHOR("Vinod Koul <vinod.koul@intel.com>");
diff --git a/sound/soc/codecs/spdif_transciever.c b/sound/soc/codecs/spdif_transciever.c
index 6a1a7e7..112a49d 100644
--- a/sound/soc/codecs/spdif_transciever.c
+++ b/sound/soc/codecs/spdif_transciever.c
@@ -61,18 +61,7 @@
},
};
-static int __init dit_modinit(void)
-{
- return platform_driver_register(&spdif_dit_driver);
-}
-
-static void __exit dit_exit(void)
-{
- platform_driver_unregister(&spdif_dit_driver);
-}
-
-module_init(dit_modinit);
-module_exit(dit_exit);
+module_platform_driver(spdif_dit_driver);
MODULE_AUTHOR("Steve Chen <schen@mvista.com>");
MODULE_DESCRIPTION("SPDIF dummy codec driver");
diff --git a/sound/soc/codecs/ssm2602.c b/sound/soc/codecs/ssm2602.c
index 3cb3271..333dd98 100644
--- a/sound/soc/codecs/ssm2602.c
+++ b/sound/soc/codecs/ssm2602.c
@@ -33,7 +33,6 @@
#include <linux/pm.h>
#include <linux/i2c.h>
#include <linux/spi/spi.h>
-#include <linux/platform_device.h>
#include <linux/slab.h>
#include <sound/core.h>
#include <sound/pcm.h>
@@ -498,7 +497,7 @@
#define SSM2602_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
-static struct snd_soc_dai_ops ssm2602_dai_ops = {
+static const struct snd_soc_dai_ops ssm2602_dai_ops = {
.startup = ssm2602_startup,
.hw_params = ssm2602_hw_params,
.shutdown = ssm2602_shutdown,
@@ -524,7 +523,7 @@
.ops = &ssm2602_dai_ops,
};
-static int ssm2602_suspend(struct snd_soc_codec *codec, pm_message_t state)
+static int ssm2602_suspend(struct snd_soc_codec *codec)
{
ssm2602_set_bias_level(codec, SND_SOC_BIAS_OFF);
return 0;
@@ -653,7 +652,8 @@
struct ssm2602_priv *ssm2602;
int ret;
- ssm2602 = kzalloc(sizeof(struct ssm2602_priv), GFP_KERNEL);
+ ssm2602 = devm_kzalloc(&spi->dev, sizeof(struct ssm2602_priv),
+ GFP_KERNEL);
if (ssm2602 == NULL)
return -ENOMEM;
@@ -663,15 +663,12 @@
ret = snd_soc_register_codec(&spi->dev,
&soc_codec_dev_ssm2602, &ssm2602_dai, 1);
- if (ret < 0)
- kfree(ssm2602);
return ret;
}
static int __devexit ssm2602_spi_remove(struct spi_device *spi)
{
snd_soc_unregister_codec(&spi->dev);
- kfree(spi_get_drvdata(spi));
return 0;
}
@@ -698,7 +695,8 @@
struct ssm2602_priv *ssm2602;
int ret;
- ssm2602 = kzalloc(sizeof(struct ssm2602_priv), GFP_KERNEL);
+ ssm2602 = devm_kzalloc(&i2c->dev, sizeof(struct ssm2602_priv),
+ GFP_KERNEL);
if (ssm2602 == NULL)
return -ENOMEM;
@@ -708,15 +706,12 @@
ret = snd_soc_register_codec(&i2c->dev,
&soc_codec_dev_ssm2602, &ssm2602_dai, 1);
- if (ret < 0)
- kfree(ssm2602);
return ret;
}
static int __devexit ssm2602_i2c_remove(struct i2c_client *client)
{
snd_soc_unregister_codec(&client->dev);
- kfree(i2c_get_clientdata(client));
return 0;
}
diff --git a/sound/soc/codecs/sta32x.c b/sound/soc/codecs/sta32x.c
index d2f3715..7db6fa5 100644
--- a/sound/soc/codecs/sta32x.c
+++ b/sound/soc/codecs/sta32x.c
@@ -24,9 +24,9 @@
#include <linux/delay.h>
#include <linux/pm.h>
#include <linux/i2c.h>
-#include <linux/platform_device.h>
#include <linux/regulator/consumer.h>
#include <linux/slab.h>
+#include <linux/workqueue.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
@@ -35,6 +35,7 @@
#include <sound/initval.h>
#include <sound/tlv.h>
+#include <sound/sta32x.h>
#include "sta32x.h"
#define STA32X_RATES (SNDRV_PCM_RATE_32000 | \
@@ -73,11 +74,14 @@
struct sta32x_priv {
struct regulator_bulk_data supplies[ARRAY_SIZE(sta32x_supply_names)];
struct snd_soc_codec *codec;
+ struct sta32x_platform_data *pdata;
unsigned int mclk;
unsigned int format;
u32 coef_shadow[STA32X_COEF_COUNT];
+ struct delayed_work watchdog_work;
+ int shutdown;
};
static const DECLARE_TLV_DB_SCALE(mvol_tlv, -12700, 50, 1);
@@ -260,7 +264,7 @@
return 0;
}
-int sta32x_sync_coef_shadow(struct snd_soc_codec *codec)
+static int sta32x_sync_coef_shadow(struct snd_soc_codec *codec)
{
struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec);
unsigned int cfud;
@@ -285,7 +289,7 @@
return 0;
}
-int sta32x_cache_sync(struct snd_soc_codec *codec)
+static int sta32x_cache_sync(struct snd_soc_codec *codec)
{
unsigned int mute;
int rc;
@@ -302,6 +306,46 @@
return rc;
}
+/* work around ESD issue where sta32x resets and loses all configuration */
+static void sta32x_watchdog(struct work_struct *work)
+{
+ struct sta32x_priv *sta32x = container_of(work, struct sta32x_priv,
+ watchdog_work.work);
+ struct snd_soc_codec *codec = sta32x->codec;
+ unsigned int confa, confa_cached;
+
+ /* check if sta32x has reset itself */
+ confa_cached = snd_soc_read(codec, STA32X_CONFA);
+ codec->cache_bypass = 1;
+ confa = snd_soc_read(codec, STA32X_CONFA);
+ codec->cache_bypass = 0;
+ if (confa != confa_cached) {
+ codec->cache_sync = 1;
+ sta32x_cache_sync(codec);
+ }
+
+ if (!sta32x->shutdown)
+ schedule_delayed_work(&sta32x->watchdog_work,
+ round_jiffies_relative(HZ));
+}
+
+static void sta32x_watchdog_start(struct sta32x_priv *sta32x)
+{
+ if (sta32x->pdata->needs_esd_watchdog) {
+ sta32x->shutdown = 0;
+ schedule_delayed_work(&sta32x->watchdog_work,
+ round_jiffies_relative(HZ));
+ }
+}
+
+static void sta32x_watchdog_stop(struct sta32x_priv *sta32x)
+{
+ if (sta32x->pdata->needs_esd_watchdog) {
+ sta32x->shutdown = 1;
+ cancel_delayed_work_sync(&sta32x->watchdog_work);
+ }
+}
+
#define SINGLE_COEF(xname, index) \
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
.info = sta32x_coefficient_info, \
@@ -478,6 +522,7 @@
rate_min = fs;
if (fs > rate_max)
rate_max = fs;
+ break;
}
}
}
@@ -712,6 +757,7 @@
}
sta32x_cache_sync(codec);
+ sta32x_watchdog_start(sta32x);
}
/* Power up to mute */
@@ -728,7 +774,7 @@
STA32X_CONFF_PWDN | STA32X_CONFF_EAPD,
STA32X_CONFF_PWDN);
msleep(300);
-
+ sta32x_watchdog_stop(sta32x);
regulator_bulk_disable(ARRAY_SIZE(sta32x->supplies),
sta32x->supplies);
break;
@@ -737,7 +783,7 @@
return 0;
}
-static struct snd_soc_dai_ops sta32x_dai_ops = {
+static const struct snd_soc_dai_ops sta32x_dai_ops = {
.hw_params = sta32x_hw_params,
.set_sysclk = sta32x_set_dai_sysclk,
.set_fmt = sta32x_set_dai_fmt,
@@ -756,7 +802,7 @@
};
#ifdef CONFIG_PM
-static int sta32x_suspend(struct snd_soc_codec *codec, pm_message_t state)
+static int sta32x_suspend(struct snd_soc_codec *codec)
{
sta32x_set_bias_level(codec, SND_SOC_BIAS_OFF);
return 0;
@@ -775,9 +821,10 @@
static int sta32x_probe(struct snd_soc_codec *codec)
{
struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec);
- int i, ret = 0;
+ int i, ret = 0, thermal = 0;
sta32x->codec = codec;
+ sta32x->pdata = dev_get_platdata(codec->dev);
/* regulators */
for (i = 0; i < ARRAY_SIZE(sta32x->supplies); i++)
@@ -820,25 +867,34 @@
snd_soc_cache_write(codec, STA32X_AUTO3, 0x00);
snd_soc_cache_write(codec, STA32X_C3CFG, 0x40);
- /* FIXME enable thermal warning adjustment and recovery */
+ /* set thermal warning adjustment and recovery */
+ if (!(sta32x->pdata->thermal_conf & STA32X_THERMAL_ADJUSTMENT_ENABLE))
+ thermal |= STA32X_CONFA_TWAB;
+ if (!(sta32x->pdata->thermal_conf & STA32X_THERMAL_RECOVERY_ENABLE))
+ thermal |= STA32X_CONFA_TWRB;
snd_soc_update_bits(codec, STA32X_CONFA,
- STA32X_CONFA_TWAB | STA32X_CONFA_TWRB, 0);
+ STA32X_CONFA_TWAB | STA32X_CONFA_TWRB,
+ thermal);
- /* FIXME select 2.1 mode */
+ /* select output configuration */
snd_soc_update_bits(codec, STA32X_CONFF,
STA32X_CONFF_OCFG_MASK,
- 1 << STA32X_CONFF_OCFG_SHIFT);
+ sta32x->pdata->output_conf
+ << STA32X_CONFF_OCFG_SHIFT);
- /* FIXME channel to output mapping */
+ /* channel to output mapping */
snd_soc_update_bits(codec, STA32X_C1CFG,
STA32X_CxCFG_OM_MASK,
- 0 << STA32X_CxCFG_OM_SHIFT);
+ sta32x->pdata->ch1_output_mapping
+ << STA32X_CxCFG_OM_SHIFT);
snd_soc_update_bits(codec, STA32X_C2CFG,
STA32X_CxCFG_OM_MASK,
- 1 << STA32X_CxCFG_OM_SHIFT);
+ sta32x->pdata->ch2_output_mapping
+ << STA32X_CxCFG_OM_SHIFT);
snd_soc_update_bits(codec, STA32X_C3CFG,
STA32X_CxCFG_OM_MASK,
- 2 << STA32X_CxCFG_OM_SHIFT);
+ sta32x->pdata->ch3_output_mapping
+ << STA32X_CxCFG_OM_SHIFT);
/* initialize coefficient shadow RAM with reset values */
for (i = 4; i <= 49; i += 5)
@@ -851,6 +907,9 @@
sta32x->coef_shadow[60] = 0x400000;
sta32x->coef_shadow[61] = 0x400000;
+ if (sta32x->pdata->needs_esd_watchdog)
+ INIT_DELAYED_WORK(&sta32x->watchdog_work, sta32x_watchdog);
+
sta32x_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
/* Bias level configuration will have done an extra enable */
regulator_bulk_disable(ARRAY_SIZE(sta32x->supplies), sta32x->supplies);
@@ -867,6 +926,7 @@
{
struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec);
+ sta32x_watchdog_stop(sta32x);
sta32x_set_bias_level(codec, SND_SOC_BIAS_OFF);
regulator_bulk_disable(ARRAY_SIZE(sta32x->supplies), sta32x->supplies);
regulator_bulk_free(ARRAY_SIZE(sta32x->supplies), sta32x->supplies);
@@ -909,28 +969,23 @@
struct sta32x_priv *sta32x;
int ret;
- sta32x = kzalloc(sizeof(struct sta32x_priv), GFP_KERNEL);
+ sta32x = devm_kzalloc(&i2c->dev, sizeof(struct sta32x_priv),
+ GFP_KERNEL);
if (!sta32x)
return -ENOMEM;
i2c_set_clientdata(i2c, sta32x);
ret = snd_soc_register_codec(&i2c->dev, &sta32x_codec, &sta32x_dai, 1);
- if (ret != 0) {
+ if (ret != 0)
dev_err(&i2c->dev, "Failed to register codec (%d)\n", ret);
- kfree(sta32x);
- return ret;
- }
- return 0;
+ return ret;
}
static __devexit int sta32x_i2c_remove(struct i2c_client *client)
{
- struct sta32x_priv *sta32x = i2c_get_clientdata(client);
-
snd_soc_unregister_codec(&client->dev);
- kfree(sta32x);
return 0;
}
diff --git a/sound/soc/codecs/stac9766.c b/sound/soc/codecs/stac9766.c
index 78b2b50..cc0566c 100644
--- a/sound/soc/codecs/stac9766.c
+++ b/sound/soc/codecs/stac9766.c
@@ -256,8 +256,7 @@
return 0;
}
-static int stac9766_codec_suspend(struct snd_soc_codec *codec,
- pm_message_t state)
+static int stac9766_codec_suspend(struct snd_soc_codec *codec)
{
stac9766_set_bias_level(codec, SND_SOC_BIAS_OFF);
return 0;
@@ -286,11 +285,11 @@
return 0;
}
-static struct snd_soc_dai_ops stac9766_dai_ops_analog = {
+static const struct snd_soc_dai_ops stac9766_dai_ops_analog = {
.prepare = ac97_analog_prepare,
};
-static struct snd_soc_dai_ops stac9766_dai_ops_digital = {
+static const struct snd_soc_dai_ops stac9766_dai_ops_digital = {
.prepare = ac97_digital_prepare,
};
@@ -380,7 +379,7 @@
.remove = stac9766_codec_remove,
.suspend = stac9766_codec_suspend,
.resume = stac9766_codec_resume,
- .reg_cache_size = sizeof(stac9766_reg),
+ .reg_cache_size = ARRAY_SIZE(stac9766_reg),
.reg_word_size = sizeof(u16),
.reg_cache_step = 2,
.reg_cache_default = stac9766_reg,
@@ -408,17 +407,7 @@
.remove = __devexit_p(stac9766_remove),
};
-static int __init stac9766_init(void)
-{
- return platform_driver_register(&stac9766_codec_driver);
-}
-module_init(stac9766_init);
-
-static void __exit stac9766_exit(void)
-{
- platform_driver_unregister(&stac9766_codec_driver);
-}
-module_exit(stac9766_exit);
+module_platform_driver(stac9766_codec_driver);
MODULE_DESCRIPTION("ASoC stac9766 driver");
MODULE_AUTHOR("Jon Smirl <jonsmirl@gmail.com>");
diff --git a/sound/soc/codecs/tlv320aic23.c b/sound/soc/codecs/tlv320aic23.c
index 336de8f..dfa41a9 100644
--- a/sound/soc/codecs/tlv320aic23.c
+++ b/sound/soc/codecs/tlv320aic23.c
@@ -24,7 +24,6 @@
#include <linux/delay.h>
#include <linux/pm.h>
#include <linux/i2c.h>
-#include <linux/platform_device.h>
#include <linux/slab.h>
#include <sound/core.h>
#include <sound/pcm.h>
@@ -503,7 +502,7 @@
#define AIC23_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE)
-static struct snd_soc_dai_ops tlv320aic23_dai_ops = {
+static const struct snd_soc_dai_ops tlv320aic23_dai_ops = {
.prepare = tlv320aic23_pcm_prepare,
.hw_params = tlv320aic23_hw_params,
.shutdown = tlv320aic23_shutdown,
@@ -529,8 +528,7 @@
.ops = &tlv320aic23_dai_ops,
};
-static int tlv320aic23_suspend(struct snd_soc_codec *codec,
- pm_message_t state)
+static int tlv320aic23_suspend(struct snd_soc_codec *codec)
{
tlv320aic23_set_bias_level(codec, SND_SOC_BIAS_OFF);
@@ -636,7 +634,7 @@
if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
return -EINVAL;
- aic23 = kzalloc(sizeof(struct aic23), GFP_KERNEL);
+ aic23 = devm_kzalloc(&i2c->dev, sizeof(struct aic23), GFP_KERNEL);
if (aic23 == NULL)
return -ENOMEM;
@@ -645,14 +643,11 @@
ret = snd_soc_register_codec(&i2c->dev,
&soc_codec_dev_tlv320aic23, &tlv320aic23_dai, 1);
- if (ret < 0)
- kfree(aic23);
return ret;
}
static int __exit tlv320aic23_i2c_remove(struct i2c_client *i2c)
{
snd_soc_unregister_codec(&i2c->dev);
- kfree(i2c_get_clientdata(i2c));
return 0;
}
diff --git a/sound/soc/codecs/tlv320aic26.c b/sound/soc/codecs/tlv320aic26.c
index 7859bdc..a038dae 100644
--- a/sound/soc/codecs/tlv320aic26.c
+++ b/sound/soc/codecs/tlv320aic26.c
@@ -275,7 +275,7 @@
#define AIC26_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_BE |\
SNDRV_PCM_FMTBIT_S24_BE | SNDRV_PCM_FMTBIT_S32_BE)
-static struct snd_soc_dai_ops aic26_dai_ops = {
+static const struct snd_soc_dai_ops aic26_dai_ops = {
.hw_params = aic26_hw_params,
.digital_mute = aic26_mute,
.set_sysclk = aic26_set_sysclk,
@@ -416,7 +416,7 @@
dev_dbg(&spi->dev, "probing tlv320aic26 spi device\n");
/* Allocate driver data */
- aic26 = kzalloc(sizeof *aic26, GFP_KERNEL);
+ aic26 = devm_kzalloc(&spi->dev, sizeof *aic26, GFP_KERNEL);
if (!aic26)
return -ENOMEM;
@@ -427,18 +427,12 @@
ret = snd_soc_register_codec(&spi->dev,
&aic26_soc_codec_dev, &aic26_dai, 1);
- if (ret < 0)
- kfree(aic26);
return ret;
-
- dev_dbg(&spi->dev, "SPI device initialized\n");
- return 0;
}
static int aic26_spi_remove(struct spi_device *spi)
{
snd_soc_unregister_codec(&spi->dev);
- kfree(spi_get_drvdata(spi));
return 0;
}
diff --git a/sound/soc/codecs/tlv320aic32x4.c b/sound/soc/codecs/tlv320aic32x4.c
index b21c610..eb401ef 100644
--- a/sound/soc/codecs/tlv320aic32x4.c
+++ b/sound/soc/codecs/tlv320aic32x4.c
@@ -29,7 +29,6 @@
#include <linux/delay.h>
#include <linux/pm.h>
#include <linux/i2c.h>
-#include <linux/platform_device.h>
#include <linux/cdev.h>
#include <linux/slab.h>
@@ -597,7 +596,7 @@
#define AIC32X4_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE \
| SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE)
-static struct snd_soc_dai_ops aic32x4_ops = {
+static const struct snd_soc_dai_ops aic32x4_ops = {
.hw_params = aic32x4_hw_params,
.digital_mute = aic32x4_mute,
.set_fmt = aic32x4_set_dai_fmt,
@@ -622,7 +621,7 @@
.symmetric_rates = 1,
};
-static int aic32x4_suspend(struct snd_soc_codec *codec, pm_message_t state)
+static int aic32x4_suspend(struct snd_soc_codec *codec)
{
aic32x4_set_bias_level(codec, SND_SOC_BIAS_OFF);
return 0;
@@ -710,7 +709,8 @@
struct aic32x4_priv *aic32x4;
int ret;
- aic32x4 = kzalloc(sizeof(struct aic32x4_priv), GFP_KERNEL);
+ aic32x4 = devm_kzalloc(&i2c->dev, sizeof(struct aic32x4_priv),
+ GFP_KERNEL);
if (aic32x4 == NULL)
return -ENOMEM;
@@ -729,15 +729,12 @@
ret = snd_soc_register_codec(&i2c->dev,
&soc_codec_dev_aic32x4, &aic32x4_dai, 1);
- if (ret < 0)
- kfree(aic32x4);
return ret;
}
static __devexit int aic32x4_i2c_remove(struct i2c_client *client)
{
snd_soc_unregister_codec(&client->dev);
- kfree(i2c_get_clientdata(client));
return 0;
}
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c
index 87d5ef1..492f22f 100644
--- a/sound/soc/codecs/tlv320aic3x.c
+++ b/sound/soc/codecs/tlv320aic3x.c
@@ -40,7 +40,6 @@
#include <linux/i2c.h>
#include <linux/gpio.h>
#include <linux/regulator/consumer.h>
-#include <linux/platform_device.h>
#include <linux/slab.h>
#include <sound/core.h>
#include <sound/pcm.h>
@@ -833,7 +832,6 @@
int codec_clk = 0, bypass_pll = 0, fsref, last_clk = 0;
u8 data, j, r, p, pll_q, pll_p = 1, pll_r = 1, pll_j = 1;
u16 d, pll_d = 1;
- u8 reg;
int clk;
/* select data word length */
@@ -869,14 +867,13 @@
snd_soc_write(codec, AIC3X_PLL_PROGA_REG, pll_q << PLLQ_SHIFT);
snd_soc_write(codec, AIC3X_GPIOB_REG, CODEC_CLKIN_CLKDIV);
/* disable PLL if it is bypassed */
- reg = snd_soc_read(codec, AIC3X_PLL_PROGA_REG);
- snd_soc_write(codec, AIC3X_PLL_PROGA_REG, reg & ~PLL_ENABLE);
+ snd_soc_update_bits(codec, AIC3X_PLL_PROGA_REG, PLL_ENABLE, 0);
} else {
snd_soc_write(codec, AIC3X_GPIOB_REG, CODEC_CLKIN_PLLDIV);
/* enable PLL when it is used */
- reg = snd_soc_read(codec, AIC3X_PLL_PROGA_REG);
- snd_soc_write(codec, AIC3X_PLL_PROGA_REG, reg | PLL_ENABLE);
+ snd_soc_update_bits(codec, AIC3X_PLL_PROGA_REG,
+ PLL_ENABLE, PLL_ENABLE);
}
/* Route Left DAC to left channel input and
@@ -1156,7 +1153,6 @@
enum snd_soc_bias_level level)
{
struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
- u8 reg;
switch (level) {
case SND_SOC_BIAS_ON:
@@ -1165,9 +1161,8 @@
if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY &&
aic3x->master) {
/* enable pll */
- reg = snd_soc_read(codec, AIC3X_PLL_PROGA_REG);
- snd_soc_write(codec, AIC3X_PLL_PROGA_REG,
- reg | PLL_ENABLE);
+ snd_soc_update_bits(codec, AIC3X_PLL_PROGA_REG,
+ PLL_ENABLE, PLL_ENABLE);
}
break;
case SND_SOC_BIAS_STANDBY:
@@ -1176,9 +1171,8 @@
if (codec->dapm.bias_level == SND_SOC_BIAS_PREPARE &&
aic3x->master) {
/* disable pll */
- reg = snd_soc_read(codec, AIC3X_PLL_PROGA_REG);
- snd_soc_write(codec, AIC3X_PLL_PROGA_REG,
- reg & ~PLL_ENABLE);
+ snd_soc_update_bits(codec, AIC3X_PLL_PROGA_REG,
+ PLL_ENABLE, 0);
}
break;
case SND_SOC_BIAS_OFF:
@@ -1249,7 +1243,7 @@
#define AIC3X_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE)
-static struct snd_soc_dai_ops aic3x_dai_ops = {
+static const struct snd_soc_dai_ops aic3x_dai_ops = {
.hw_params = aic3x_hw_params,
.digital_mute = aic3x_mute,
.set_sysclk = aic3x_set_dai_sysclk,
@@ -1274,7 +1268,7 @@
.symmetric_rates = 1,
};
-static int aic3x_suspend(struct snd_soc_codec *codec, pm_message_t state)
+static int aic3x_suspend(struct snd_soc_codec *codec)
{
aic3x_set_bias_level(codec, SND_SOC_BIAS_OFF);
@@ -1295,7 +1289,6 @@
static int aic3x_init(struct snd_soc_codec *codec)
{
struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
- int reg;
snd_soc_write(codec, AIC3X_PAGE_SELECT, PAGE0_SELECT);
snd_soc_write(codec, AIC3X_RESET, SOFT_RESET);
@@ -1317,20 +1310,13 @@
snd_soc_write(codec, DACR1_2_MONOLOPM_VOL, DEFAULT_VOL | ROUTE_ON);
/* unmute all outputs */
- reg = snd_soc_read(codec, LLOPM_CTRL);
- snd_soc_write(codec, LLOPM_CTRL, reg | UNMUTE);
- reg = snd_soc_read(codec, RLOPM_CTRL);
- snd_soc_write(codec, RLOPM_CTRL, reg | UNMUTE);
- reg = snd_soc_read(codec, MONOLOPM_CTRL);
- snd_soc_write(codec, MONOLOPM_CTRL, reg | UNMUTE);
- reg = snd_soc_read(codec, HPLOUT_CTRL);
- snd_soc_write(codec, HPLOUT_CTRL, reg | UNMUTE);
- reg = snd_soc_read(codec, HPROUT_CTRL);
- snd_soc_write(codec, HPROUT_CTRL, reg | UNMUTE);
- reg = snd_soc_read(codec, HPLCOM_CTRL);
- snd_soc_write(codec, HPLCOM_CTRL, reg | UNMUTE);
- reg = snd_soc_read(codec, HPRCOM_CTRL);
- snd_soc_write(codec, HPRCOM_CTRL, reg | UNMUTE);
+ snd_soc_update_bits(codec, LLOPM_CTRL, UNMUTE, UNMUTE);
+ snd_soc_update_bits(codec, RLOPM_CTRL, UNMUTE, UNMUTE);
+ snd_soc_update_bits(codec, MONOLOPM_CTRL, UNMUTE, UNMUTE);
+ snd_soc_update_bits(codec, HPLOUT_CTRL, UNMUTE, UNMUTE);
+ snd_soc_update_bits(codec, HPROUT_CTRL, UNMUTE, UNMUTE);
+ snd_soc_update_bits(codec, HPLCOM_CTRL, UNMUTE, UNMUTE);
+ snd_soc_update_bits(codec, HPRCOM_CTRL, UNMUTE, UNMUTE);
/* ADC default volume and unmute */
snd_soc_write(codec, LADC_VOL, DEFAULT_GAIN);
@@ -1494,7 +1480,6 @@
.resume = aic3x_resume,
};
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
/*
* AIC3X 2 wire address can be up to 4 devices with device addresses
* 0x18, 0x19, 0x1A, 0x1B
@@ -1519,7 +1504,7 @@
struct aic3x_priv *aic3x;
int ret;
- aic3x = kzalloc(sizeof(struct aic3x_priv), GFP_KERNEL);
+ aic3x = devm_kzalloc(&i2c->dev, sizeof(struct aic3x_priv), GFP_KERNEL);
if (aic3x == NULL) {
dev_err(&i2c->dev, "failed to create private data\n");
return -ENOMEM;
@@ -1539,15 +1524,12 @@
ret = snd_soc_register_codec(&i2c->dev,
&soc_codec_dev_aic3x, &aic3x_dai, 1);
- if (ret < 0)
- kfree(aic3x);
return ret;
}
static int aic3x_i2c_remove(struct i2c_client *client)
{
snd_soc_unregister_codec(&client->dev);
- kfree(i2c_get_clientdata(client));
return 0;
}
@@ -1561,27 +1543,22 @@
.remove = aic3x_i2c_remove,
.id_table = aic3x_i2c_id,
};
-#endif
static int __init aic3x_modinit(void)
{
int ret = 0;
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
ret = i2c_add_driver(&aic3x_i2c_driver);
if (ret != 0) {
printk(KERN_ERR "Failed to register TLV320AIC3x I2C driver: %d\n",
ret);
}
-#endif
return ret;
}
module_init(aic3x_modinit);
static void __exit aic3x_exit(void)
{
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
i2c_del_driver(&aic3x_i2c_driver);
-#endif
}
module_exit(aic3x_exit);
diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c
index dc8a2b2..f0aad26 100644
--- a/sound/soc/codecs/tlv320dac33.c
+++ b/sound/soc/codecs/tlv320dac33.c
@@ -27,7 +27,6 @@
#include <linux/delay.h>
#include <linux/pm.h>
#include <linux/i2c.h>
-#include <linux/platform_device.h>
#include <linux/interrupt.h>
#include <linux/gpio.h>
#include <linux/regulator/consumer.h>
@@ -1461,7 +1460,7 @@
return 0;
}
-static int dac33_soc_suspend(struct snd_soc_codec *codec, pm_message_t state)
+static int dac33_soc_suspend(struct snd_soc_codec *codec)
{
dac33_set_bias_level(codec, SND_SOC_BIAS_OFF);
@@ -1499,7 +1498,7 @@
SNDRV_PCM_RATE_48000)
#define DAC33_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE)
-static struct snd_soc_dai_ops dac33_dai_ops = {
+static const struct snd_soc_dai_ops dac33_dai_ops = {
.startup = dac33_startup,
.shutdown = dac33_shutdown,
.hw_params = dac33_hw_params,
@@ -1533,7 +1532,8 @@
}
pdata = client->dev.platform_data;
- dac33 = kzalloc(sizeof(struct tlv320dac33_priv), GFP_KERNEL);
+ dac33 = devm_kzalloc(&client->dev, sizeof(struct tlv320dac33_priv),
+ GFP_KERNEL);
if (dac33 == NULL)
return -ENOMEM;
@@ -1588,7 +1588,6 @@
if (dac33->power_gpio >= 0)
gpio_free(dac33->power_gpio);
err_gpio:
- kfree(dac33);
return ret;
}
@@ -1605,8 +1604,6 @@
regulator_bulk_free(ARRAY_SIZE(dac33->supplies), dac33->supplies);
snd_soc_unregister_codec(&client->dev);
- kfree(dac33);
-
return 0;
}
diff --git a/sound/soc/codecs/tpa6130a2.c b/sound/soc/codecs/tpa6130a2.c
index 7eeca79..363b99d 100644
--- a/sound/soc/codecs/tpa6130a2.c
+++ b/sound/soc/codecs/tpa6130a2.c
@@ -376,7 +376,7 @@
return -ENODEV;
}
- data = kzalloc(sizeof(*data), GFP_KERNEL);
+ data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL);
if (data == NULL) {
dev_err(dev, "Can not allocate memory\n");
return -ENOMEM;
@@ -450,7 +450,6 @@
if (data->power_gpio >= 0)
gpio_free(data->power_gpio);
err_gpio:
- kfree(data);
tpa6130a2_client = NULL;
return ret;
@@ -466,8 +465,6 @@
gpio_free(data->power_gpio);
regulator_put(data->supply);
-
- kfree(data);
tpa6130a2_client = NULL;
return 0;
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c
index f798247..18e7101 100644
--- a/sound/soc/codecs/twl4030.c
+++ b/sound/soc/codecs/twl4030.c
@@ -2149,7 +2149,7 @@
#define TWL4030_RATES (SNDRV_PCM_RATE_8000_48000)
#define TWL4030_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE)
-static struct snd_soc_dai_ops twl4030_dai_hifi_ops = {
+static const struct snd_soc_dai_ops twl4030_dai_hifi_ops = {
.startup = twl4030_startup,
.shutdown = twl4030_shutdown,
.hw_params = twl4030_hw_params,
@@ -2158,7 +2158,7 @@
.set_tristate = twl4030_set_tristate,
};
-static struct snd_soc_dai_ops twl4030_dai_voice_ops = {
+static const struct snd_soc_dai_ops twl4030_dai_voice_ops = {
.startup = twl4030_voice_startup,
.shutdown = twl4030_voice_shutdown,
.hw_params = twl4030_voice_hw_params,
@@ -2202,7 +2202,7 @@
},
};
-static int twl4030_soc_suspend(struct snd_soc_codec *codec, pm_message_t state)
+static int twl4030_soc_suspend(struct snd_soc_codec *codec)
{
twl4030_set_bias_level(codec, SND_SOC_BIAS_OFF);
return 0;
@@ -2294,17 +2294,7 @@
},
};
-static int __init twl4030_modinit(void)
-{
- return platform_driver_register(&twl4030_codec_driver);
-}
-module_init(twl4030_modinit);
-
-static void __exit twl4030_exit(void)
-{
- platform_driver_unregister(&twl4030_codec_driver);
-}
-module_exit(twl4030_exit);
+module_platform_driver(twl4030_codec_driver);
MODULE_DESCRIPTION("ASoC TWL4030 codec driver");
MODULE_AUTHOR("Steve Sakoman");
diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c
index 73e11f0..5b9c79b 100644
--- a/sound/soc/codecs/twl6040.c
+++ b/sound/soc/codecs/twl6040.c
@@ -33,6 +33,7 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
+#include <sound/soc-dapm.h>
#include <sound/initval.h>
#include <sound/tlv.h>
@@ -1012,6 +1013,28 @@
return 0;
}
+int twl6040_get_dl1_gain(struct snd_soc_codec *codec)
+{
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
+
+ if (snd_soc_dapm_get_pin_status(dapm, "EP"))
+ return -1; /* -1dB */
+
+ if (snd_soc_dapm_get_pin_status(dapm, "HSOR") ||
+ snd_soc_dapm_get_pin_status(dapm, "HSOL")) {
+
+ u8 val = snd_soc_read(codec, TWL6040_REG_HSLCTL);
+ if (val & TWL6040_HSDACMODE)
+ /* HSDACL in LP mode */
+ return -8; /* -8dB */
+ else
+ /* HSDACL in HP mode */
+ return -1; /* -1dB */
+ }
+ return 0; /* 0dB */
+}
+EXPORT_SYMBOL_GPL(twl6040_get_dl1_gain);
+
int twl6040_get_clk_id(struct snd_soc_codec *codec)
{
struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
@@ -1397,7 +1420,7 @@
return 0;
}
-static struct snd_soc_dai_ops twl6040_dai_ops = {
+static const struct snd_soc_dai_ops twl6040_dai_ops = {
.startup = twl6040_startup,
.hw_params = twl6040_hw_params,
.prepare = twl6040_prepare,
@@ -1470,7 +1493,7 @@
};
#ifdef CONFIG_PM
-static int twl6040_suspend(struct snd_soc_codec *codec, pm_message_t state)
+static int twl6040_suspend(struct snd_soc_codec *codec)
{
twl6040_set_bias_level(codec, SND_SOC_BIAS_OFF);
@@ -1620,17 +1643,7 @@
.remove = __devexit_p(twl6040_codec_remove),
};
-static int __init twl6040_codec_init(void)
-{
- return platform_driver_register(&twl6040_codec_driver);
-}
-module_init(twl6040_codec_init);
-
-static void __exit twl6040_codec_exit(void)
-{
- platform_driver_unregister(&twl6040_codec_driver);
-}
-module_exit(twl6040_codec_exit);
+module_platform_driver(twl6040_codec_driver);
MODULE_DESCRIPTION("ASoC TWL6040 codec driver");
MODULE_AUTHOR("Misael Lopez Cruz");
diff --git a/sound/soc/codecs/twl6040.h b/sound/soc/codecs/twl6040.h
index a83277b..ef273f1 100644
--- a/sound/soc/codecs/twl6040.h
+++ b/sound/soc/codecs/twl6040.h
@@ -34,6 +34,7 @@
#define TWL6040_HSF_TRIM_LEFT(x) (x & 0x0f)
#define TWL6040_HSF_TRIM_RIGHT(x) ((x >> 4) & 0x0f)
+int twl6040_get_dl1_gain(struct snd_soc_codec *codec);
void twl6040_hs_jack_detect(struct snd_soc_codec *codec,
struct snd_soc_jack *jack, int report);
int twl6040_get_clk_id(struct snd_soc_codec *codec);
diff --git a/sound/soc/codecs/uda134x.c b/sound/soc/codecs/uda134x.c
index a7b8f30..8f4f469 100644
--- a/sound/soc/codecs/uda134x.c
+++ b/sound/soc/codecs/uda134x.c
@@ -452,7 +452,7 @@
SOC_SINGLE("DC Filter Enable Switch", UDA134X_STATUS0, 0, 1, 0),
};
-static struct snd_soc_dai_ops uda134x_dai_ops = {
+static const struct snd_soc_dai_ops uda134x_dai_ops = {
.startup = uda134x_startup,
.shutdown = uda134x_shutdown,
.hw_params = uda134x_hw_params,
@@ -571,8 +571,7 @@
}
#if defined(CONFIG_PM)
-static int uda134x_soc_suspend(struct snd_soc_codec *codec,
- pm_message_t state)
+static int uda134x_soc_suspend(struct snd_soc_codec *codec)
{
uda134x_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
uda134x_set_bias_level(codec, SND_SOC_BIAS_OFF);
@@ -625,17 +624,7 @@
.remove = __devexit_p(uda134x_codec_remove),
};
-static int __init uda134x_codec_init(void)
-{
- return platform_driver_register(&uda134x_codec_driver);
-}
-module_init(uda134x_codec_init);
-
-static void __exit uda134x_codec_exit(void)
-{
- platform_driver_unregister(&uda134x_codec_driver);
-}
-module_exit(uda134x_codec_exit);
+module_platform_driver(uda134x_codec_driver);
MODULE_DESCRIPTION("UDA134X ALSA soc codec driver");
MODULE_AUTHOR("Zoltan Devai, Christian Pellegrin <chripell@evolware.org>");
diff --git a/sound/soc/codecs/uda1380.c b/sound/soc/codecs/uda1380.c
index 0441893..4f1b23d 100644
--- a/sound/soc/codecs/uda1380.c
+++ b/sound/soc/codecs/uda1380.c
@@ -373,7 +373,7 @@
SND_SOC_DAPM_PGA("HeadPhone Driver", UDA1380_PM, 13, 0, NULL, 0),
};
-static const struct snd_soc_dapm_route audio_map[] = {
+static const struct snd_soc_dapm_route uda1380_dapm_routes[] = {
/* output mux */
{"HeadPhone Driver", NULL, "Output Mux"},
@@ -410,17 +410,6 @@
{"Right PGA", NULL, "VINR"},
};
-static int uda1380_add_widgets(struct snd_soc_codec *codec)
-{
- struct snd_soc_dapm_context *dapm = &codec->dapm;
-
- snd_soc_dapm_new_controls(dapm, uda1380_dapm_widgets,
- ARRAY_SIZE(uda1380_dapm_widgets));
- snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
-
- return 0;
-}
-
static int uda1380_set_dai_fmt_both(struct snd_soc_dai *codec_dai,
unsigned int fmt)
{
@@ -643,21 +632,21 @@
SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\
SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000)
-static struct snd_soc_dai_ops uda1380_dai_ops = {
+static const struct snd_soc_dai_ops uda1380_dai_ops = {
.hw_params = uda1380_pcm_hw_params,
.shutdown = uda1380_pcm_shutdown,
.trigger = uda1380_trigger,
.set_fmt = uda1380_set_dai_fmt_both,
};
-static struct snd_soc_dai_ops uda1380_dai_ops_playback = {
+static const struct snd_soc_dai_ops uda1380_dai_ops_playback = {
.hw_params = uda1380_pcm_hw_params,
.shutdown = uda1380_pcm_shutdown,
.trigger = uda1380_trigger,
.set_fmt = uda1380_set_dai_fmt_playback,
};
-static struct snd_soc_dai_ops uda1380_dai_ops_capture = {
+static const struct snd_soc_dai_ops uda1380_dai_ops_capture = {
.hw_params = uda1380_pcm_hw_params,
.shutdown = uda1380_pcm_shutdown,
.trigger = uda1380_trigger,
@@ -705,7 +694,7 @@
},
};
-static int uda1380_suspend(struct snd_soc_codec *codec, pm_message_t state)
+static int uda1380_suspend(struct snd_soc_codec *codec)
{
uda1380_set_bias_level(codec, SND_SOC_BIAS_OFF);
return 0;
@@ -732,27 +721,21 @@
return -EINVAL;
if (gpio_is_valid(pdata->gpio_reset)) {
- ret = gpio_request(pdata->gpio_reset, "uda1380 reset");
+ ret = gpio_request_one(pdata->gpio_reset, GPIOF_OUT_INIT_LOW,
+ "uda1380 reset");
if (ret)
goto err_out;
- ret = gpio_direction_output(pdata->gpio_reset, 0);
- if (ret)
- goto err_gpio_reset_conf;
}
if (gpio_is_valid(pdata->gpio_power)) {
- ret = gpio_request(pdata->gpio_power, "uda1380 power");
+ ret = gpio_request_one(pdata->gpio_power, GPIOF_OUT_INIT_LOW,
+ "uda1380 power");
if (ret)
- goto err_gpio;
- ret = gpio_direction_output(pdata->gpio_power, 0);
- if (ret)
- goto err_gpio_power_conf;
+ goto err_free_gpio;
} else {
ret = uda1380_reset(codec);
- if (ret) {
- dev_err(codec->dev, "Failed to issue reset\n");
- goto err_reset;
- }
+ if (ret)
+ goto err_free_gpio;
}
INIT_WORK(&uda1380->work, uda1380_flush_work);
@@ -770,19 +753,9 @@
break;
}
- snd_soc_add_controls(codec, uda1380_snd_controls,
- ARRAY_SIZE(uda1380_snd_controls));
- uda1380_add_widgets(codec);
-
return 0;
-err_reset:
-err_gpio_power_conf:
- if (gpio_is_valid(pdata->gpio_power))
- gpio_free(pdata->gpio_power);
-
-err_gpio_reset_conf:
-err_gpio:
+err_free_gpio:
if (gpio_is_valid(pdata->gpio_reset))
gpio_free(pdata->gpio_reset);
err_out:
@@ -814,6 +787,13 @@
.reg_word_size = sizeof(u16),
.reg_cache_default = uda1380_reg,
.reg_cache_step = 1,
+
+ .controls = uda1380_snd_controls,
+ .num_controls = ARRAY_SIZE(uda1380_snd_controls),
+ .dapm_widgets = uda1380_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(uda1380_dapm_widgets),
+ .dapm_routes = uda1380_dapm_routes,
+ .num_dapm_routes = ARRAY_SIZE(uda1380_dapm_routes),
};
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
@@ -823,7 +803,8 @@
struct uda1380_priv *uda1380;
int ret;
- uda1380 = kzalloc(sizeof(struct uda1380_priv), GFP_KERNEL);
+ uda1380 = devm_kzalloc(&i2c->dev, sizeof(struct uda1380_priv),
+ GFP_KERNEL);
if (uda1380 == NULL)
return -ENOMEM;
@@ -832,15 +813,12 @@
ret = snd_soc_register_codec(&i2c->dev,
&soc_codec_dev_uda1380, uda1380_dai, ARRAY_SIZE(uda1380_dai));
- if (ret < 0)
- kfree(uda1380);
return ret;
}
static int __devexit uda1380_i2c_remove(struct i2c_client *i2c)
{
snd_soc_unregister_codec(&i2c->dev);
- kfree(i2c_get_clientdata(i2c));
return 0;
}
diff --git a/sound/soc/codecs/wl1273.c b/sound/soc/codecs/wl1273.c
index a854989..44aacf9 100644
--- a/sound/soc/codecs/wl1273.c
+++ b/sound/soc/codecs/wl1273.c
@@ -386,7 +386,7 @@
return 0;
}
-static struct snd_soc_dai_ops wl1273_dai_ops = {
+static const struct snd_soc_dai_ops wl1273_dai_ops = {
.startup = wl1273_startup,
.hw_params = wl1273_hw_params,
};
@@ -510,17 +510,7 @@
.remove = __devexit_p(wl1273_platform_remove),
};
-static int __init wl1273_init(void)
-{
- return platform_driver_register(&wl1273_platform_driver);
-}
-module_init(wl1273_init);
-
-static void __exit wl1273_exit(void)
-{
- platform_driver_unregister(&wl1273_platform_driver);
-}
-module_exit(wl1273_exit);
+module_platform_driver(wl1273_platform_driver);
MODULE_AUTHOR("Matti Aaltonen <matti.j.aaltonen@nokia.com>");
MODULE_DESCRIPTION("ASoC WL1273 codec driver");
diff --git a/sound/soc/codecs/wm1250-ev1.c b/sound/soc/codecs/wm1250-ev1.c
index cd0ec0f..aefb4f8 100644
--- a/sound/soc/codecs/wm1250-ev1.c
+++ b/sound/soc/codecs/wm1250-ev1.c
@@ -116,7 +116,7 @@
if (!pdata)
return 0;
- wm1250 = kzalloc(sizeof(*wm1250), GFP_KERNEL);
+ wm1250 = devm_kzalloc(&i2c->dev, sizeof(*wm1250), GFP_KERNEL);
if (!wm1250) {
dev_err(&i2c->dev, "Unable to allocate private data\n");
ret = -ENOMEM;
@@ -134,15 +134,13 @@
ret = gpio_request_array(wm1250->gpios, ARRAY_SIZE(wm1250->gpios));
if (ret != 0) {
dev_err(&i2c->dev, "Failed to get GPIOs: %d\n", ret);
- goto err_alloc;
+ goto err;
}
dev_set_drvdata(&i2c->dev, wm1250);
return ret;
-err_alloc:
- kfree(wm1250);
err:
return ret;
}
@@ -151,10 +149,8 @@
{
struct wm1250_priv *wm1250 = dev_get_drvdata(&i2c->dev);
- if (wm1250) {
+ if (wm1250)
gpio_free_array(wm1250->gpios, ARRAY_SIZE(wm1250->gpios));
- kfree(wm1250);
- }
}
static int __devinit wm1250_ev1_probe(struct i2c_client *i2c,
diff --git a/sound/soc/codecs/wm2000.c b/sound/soc/codecs/wm2000.c
index a3b9cbb..c288090 100644
--- a/sound/soc/codecs/wm2000.c
+++ b/sound/soc/codecs/wm2000.c
@@ -29,7 +29,7 @@
#include <linux/delay.h>
#include <linux/pm.h>
#include <linux/i2c.h>
-#include <linux/platform_device.h>
+#include <linux/regmap.h>
#include <linux/debugfs.h>
#include <linux/slab.h>
#include <sound/core.h>
@@ -52,6 +52,7 @@
struct wm2000_priv {
struct i2c_client *i2c;
+ struct regmap *regmap;
enum wm2000_anc_mode anc_mode;
@@ -66,59 +67,24 @@
char *anc_download;
};
-static struct i2c_client *wm2000_i2c;
-
static int wm2000_write(struct i2c_client *i2c, unsigned int reg,
unsigned int value)
{
- u8 data[3];
- int ret;
-
- data[0] = (reg >> 8) & 0xff;
- data[1] = reg & 0xff;
- data[2] = value & 0xff;
-
- dev_vdbg(&i2c->dev, "write %x = %x\n", reg, value);
-
- ret = i2c_master_send(i2c, data, 3);
- if (ret == 3)
- return 0;
- if (ret < 0)
- return ret;
- else
- return -EIO;
+ struct wm2000_priv *wm2000 = i2c_get_clientdata(i2c);
+ return regmap_write(wm2000->regmap, reg, value);
}
static unsigned int wm2000_read(struct i2c_client *i2c, unsigned int r)
{
- struct i2c_msg xfer[2];
- u8 reg[2];
- u8 data;
+ struct wm2000_priv *wm2000 = i2c_get_clientdata(i2c);
+ unsigned int val;
int ret;
- /* Write register */
- reg[0] = (r >> 8) & 0xff;
- reg[1] = r & 0xff;
- xfer[0].addr = i2c->addr;
- xfer[0].flags = 0;
- xfer[0].len = sizeof(reg);
- xfer[0].buf = ®[0];
+ ret = regmap_read(wm2000->regmap, r, &val);
+ if (ret < 0)
+ return -1;
- /* Read data */
- xfer[1].addr = i2c->addr;
- xfer[1].flags = I2C_M_RD;
- xfer[1].len = 1;
- xfer[1].buf = &data;
-
- ret = i2c_transfer(i2c->adapter, xfer, 2);
- if (ret != 2) {
- dev_err(&i2c->dev, "i2c_transfer() returned %d\n", ret);
- return 0;
- }
-
- dev_vdbg(&i2c->dev, "read %x from %x\n", data, r);
-
- return data;
+ return val;
}
static void wm2000_reset(struct wm2000_priv *wm2000)
@@ -612,7 +578,8 @@
static int wm2000_anc_mode_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
- struct wm2000_priv *wm2000 = dev_get_drvdata(&wm2000_i2c->dev);
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev);
ucontrol->value.enumerated.item[0] = wm2000->anc_active;
@@ -622,7 +589,8 @@
static int wm2000_anc_mode_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
- struct wm2000_priv *wm2000 = dev_get_drvdata(&wm2000_i2c->dev);
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev);
int anc_active = ucontrol->value.enumerated.item[0];
if (anc_active > 1)
@@ -636,7 +604,8 @@
static int wm2000_speaker_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
- struct wm2000_priv *wm2000 = dev_get_drvdata(&wm2000_i2c->dev);
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev);
ucontrol->value.enumerated.item[0] = wm2000->spk_ena;
@@ -646,7 +615,8 @@
static int wm2000_speaker_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
- struct wm2000_priv *wm2000 = dev_get_drvdata(&wm2000_i2c->dev);
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev);
int val = ucontrol->value.enumerated.item[0];
if (val > 1)
@@ -669,7 +639,8 @@
static int wm2000_anc_power_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
- struct wm2000_priv *wm2000 = dev_get_drvdata(&wm2000_i2c->dev);
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev);
if (SND_SOC_DAPM_EVENT_ON(event))
wm2000->anc_eng_ena = 1;
@@ -682,11 +653,11 @@
static const struct snd_soc_dapm_widget wm2000_dapm_widgets[] = {
/* Externally visible pins */
-SND_SOC_DAPM_OUTPUT("WM2000 SPKN"),
-SND_SOC_DAPM_OUTPUT("WM2000 SPKP"),
+SND_SOC_DAPM_OUTPUT("SPKN"),
+SND_SOC_DAPM_OUTPUT("SPKP"),
-SND_SOC_DAPM_INPUT("WM2000 LINN"),
-SND_SOC_DAPM_INPUT("WM2000 LINP"),
+SND_SOC_DAPM_INPUT("LINN"),
+SND_SOC_DAPM_INPUT("LINP"),
SND_SOC_DAPM_PGA_E("ANC Engine", SND_SOC_NOPM, 0, 0, NULL, 0,
wm2000_anc_power_event,
@@ -694,37 +665,67 @@
};
/* Target, Path, Source */
-static const struct snd_soc_dapm_route audio_map[] = {
- { "WM2000 SPKN", NULL, "ANC Engine" },
- { "WM2000 SPKP", NULL, "ANC Engine" },
- { "ANC Engine", NULL, "WM2000 LINN" },
- { "ANC Engine", NULL, "WM2000 LINP" },
+static const struct snd_soc_dapm_route wm2000_audio_map[] = {
+ { "SPKN", NULL, "ANC Engine" },
+ { "SPKP", NULL, "ANC Engine" },
+ { "ANC Engine", NULL, "LINN" },
+ { "ANC Engine", NULL, "LINP" },
};
-/* Called from the machine driver */
-int wm2000_add_controls(struct snd_soc_codec *codec)
+#ifdef CONFIG_PM
+static int wm2000_suspend(struct snd_soc_codec *codec)
{
- struct snd_soc_dapm_context *dapm = &codec->dapm;
- int ret;
+ struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev);
- if (!wm2000_i2c) {
- pr_err("WM2000 not yet probed\n");
- return -ENODEV;
- }
-
- ret = snd_soc_dapm_new_controls(dapm, wm2000_dapm_widgets,
- ARRAY_SIZE(wm2000_dapm_widgets));
- if (ret < 0)
- return ret;
-
- ret = snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
- if (ret < 0)
- return ret;
-
- return snd_soc_add_controls(codec, wm2000_controls,
- ARRAY_SIZE(wm2000_controls));
+ return wm2000_anc_transition(wm2000, ANC_OFF);
}
-EXPORT_SYMBOL_GPL(wm2000_add_controls);
+
+static int wm2000_resume(struct snd_soc_codec *codec)
+{
+ struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev);
+
+ return wm2000_anc_set_mode(wm2000);
+}
+#else
+#define wm2000_suspend NULL
+#define wm2000_resume NULL
+#endif
+
+static const struct regmap_config wm2000_regmap = {
+ .reg_bits = 8,
+ .val_bits = 8,
+};
+
+static int wm2000_probe(struct snd_soc_codec *codec)
+{
+ struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev);
+
+ /* This will trigger a transition to standby mode by default */
+ wm2000_anc_set_mode(wm2000);
+
+ return 0;
+}
+
+static int wm2000_remove(struct snd_soc_codec *codec)
+{
+ struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev);
+
+ return wm2000_anc_transition(wm2000, ANC_OFF);
+}
+
+static struct snd_soc_codec_driver soc_codec_dev_wm2000 = {
+ .probe = wm2000_probe,
+ .remove = wm2000_remove,
+ .suspend = wm2000_suspend,
+ .resume = wm2000_resume,
+
+ .dapm_widgets = wm2000_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(wm2000_dapm_widgets),
+ .dapm_routes = wm2000_audio_map,
+ .num_dapm_routes = ARRAY_SIZE(wm2000_audio_map),
+ .controls = wm2000_controls,
+ .num_controls = ARRAY_SIZE(wm2000_controls),
+};
static int __devinit wm2000_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *i2c_id)
@@ -736,17 +737,23 @@
int reg, ret;
u16 id;
- if (wm2000_i2c) {
- dev_err(&i2c->dev, "Another WM2000 is already registered\n");
- return -EINVAL;
- }
-
- wm2000 = kzalloc(sizeof(struct wm2000_priv), GFP_KERNEL);
+ wm2000 = devm_kzalloc(&i2c->dev, sizeof(struct wm2000_priv),
+ GFP_KERNEL);
if (wm2000 == NULL) {
dev_err(&i2c->dev, "Unable to allocate private data\n");
return -ENOMEM;
}
+ dev_set_drvdata(&i2c->dev, wm2000);
+
+ wm2000->regmap = regmap_init_i2c(i2c, &wm2000_regmap);
+ if (IS_ERR(wm2000->regmap)) {
+ ret = PTR_ERR(wm2000->regmap);
+ dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
+ ret);
+ goto err;
+ }
+
/* Verify that this is a WM2000 */
reg = wm2000_read(i2c, WM2000_REG_ID1);
id = reg << 8;
@@ -756,7 +763,7 @@
if (id != 0x2000) {
dev_err(&i2c->dev, "Device is not a WM2000 - ID %x\n", id);
ret = -ENODEV;
- goto err;
+ goto err_regmap;
}
reg = wm2000_read(i2c, WM2000_REG_REVISON);
@@ -775,12 +782,14 @@
ret = request_firmware(&fw, filename, &i2c->dev);
if (ret != 0) {
dev_err(&i2c->dev, "Failed to acquire ANC data: %d\n", ret);
- goto err;
+ goto err_regmap;
}
/* Pre-cook the concatenation of the register address onto the image */
wm2000->anc_download_size = fw->size + 2;
- wm2000->anc_download = kmalloc(wm2000->anc_download_size, GFP_KERNEL);
+ wm2000->anc_download = devm_kzalloc(&i2c->dev,
+ wm2000->anc_download_size,
+ GFP_KERNEL);
if (wm2000->anc_download == NULL) {
dev_err(&i2c->dev, "Out of memory\n");
ret = -ENOMEM;
@@ -793,7 +802,6 @@
release_firmware(fw);
- dev_set_drvdata(&i2c->dev, wm2000);
wm2000->anc_eng_ena = 1;
wm2000->anc_active = 1;
wm2000->spk_ena = 1;
@@ -801,17 +809,18 @@
wm2000_reset(wm2000);
- /* This will trigger a transition to standby mode by default */
- wm2000_anc_set_mode(wm2000);
-
- wm2000_i2c = i2c;
+ ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm2000,
+ NULL, 0);
+ if (ret != 0)
+ goto err_fw;
return 0;
err_fw:
release_firmware(fw);
+err_regmap:
+ regmap_exit(wm2000->regmap);
err:
- kfree(wm2000);
return ret;
}
@@ -819,42 +828,12 @@
{
struct wm2000_priv *wm2000 = dev_get_drvdata(&i2c->dev);
- wm2000_anc_transition(wm2000, ANC_OFF);
-
- wm2000_i2c = NULL;
- kfree(wm2000->anc_download);
- kfree(wm2000);
+ snd_soc_unregister_codec(&i2c->dev);
+ regmap_exit(wm2000->regmap);
return 0;
}
-static void wm2000_i2c_shutdown(struct i2c_client *i2c)
-{
- struct wm2000_priv *wm2000 = dev_get_drvdata(&i2c->dev);
-
- wm2000_anc_transition(wm2000, ANC_OFF);
-}
-
-#ifdef CONFIG_PM
-static int wm2000_i2c_suspend(struct device *dev)
-{
- struct i2c_client *i2c = to_i2c_client(dev);
- struct wm2000_priv *wm2000 = dev_get_drvdata(&i2c->dev);
-
- return wm2000_anc_transition(wm2000, ANC_OFF);
-}
-
-static int wm2000_i2c_resume(struct device *dev)
-{
- struct i2c_client *i2c = to_i2c_client(dev);
- struct wm2000_priv *wm2000 = dev_get_drvdata(&i2c->dev);
-
- return wm2000_anc_set_mode(wm2000);
-}
-#endif
-
-static SIMPLE_DEV_PM_OPS(wm2000_pm, wm2000_i2c_suspend, wm2000_i2c_resume);
-
static const struct i2c_device_id wm2000_i2c_id[] = {
{ "wm2000", 0 },
{ }
@@ -865,11 +844,9 @@
.driver = {
.name = "wm2000",
.owner = THIS_MODULE,
- .pm = &wm2000_pm,
},
.probe = wm2000_i2c_probe,
.remove = __devexit_p(wm2000_i2c_remove),
- .shutdown = wm2000_i2c_shutdown,
.id_table = wm2000_i2c_id,
};
diff --git a/sound/soc/codecs/wm2000.h b/sound/soc/codecs/wm2000.h
index 0b6f056..abcd82a 100644
--- a/sound/soc/codecs/wm2000.h
+++ b/sound/soc/codecs/wm2000.h
@@ -9,13 +9,6 @@
#ifndef _WM2000_H
#define _WM2000_H
-struct wm2000_setup_data {
- unsigned short i2c_address;
- int mclk_div; /* Set to a non-zero value if MCLK_DIV_2 required */
-};
-
-extern int wm2000_add_controls(struct snd_soc_codec *codec);
-
#define WM2000_REG_SYS_START 0x8000
#define WM2000_REG_SPEECH_CLARITY 0x8fef
#define WM2000_REG_SYS_WATCHDOG 0x8ff6
diff --git a/sound/soc/codecs/wm5100-tables.c b/sound/soc/codecs/wm5100-tables.c
index e9ce81a..9a18fae 100644
--- a/sound/soc/codecs/wm5100-tables.c
+++ b/sound/soc/codecs/wm5100-tables.c
@@ -13,7 +13,7 @@
#include "wm5100.h"
-int wm5100_volatile_register(struct snd_soc_codec *codec, unsigned int reg)
+bool wm5100_volatile_register(struct device *dev, unsigned int reg)
{
switch (reg) {
case WM5100_SOFTWARE_RESET:
@@ -36,7 +36,7 @@
}
}
-int wm5100_readable_register(struct snd_soc_codec *codec, unsigned int reg)
+bool wm5100_readable_register(struct device *dev, unsigned int reg)
{
switch (reg) {
case WM5100_SOFTWARE_RESET:
@@ -85,6 +85,7 @@
case WM5100_MIC_DETECT_1:
case WM5100_MIC_DETECT_2:
case WM5100_MIC_DETECT_3:
+ case WM5100_MISC_CONTROL:
case WM5100_INPUT_ENABLES:
case WM5100_INPUT_ENABLES_STATUS:
case WM5100_IN1L_CONTROL:
@@ -696,836 +697,668 @@
case WM5100_HPLPF3_2:
case WM5100_HPLPF4_1:
case WM5100_HPLPF4_2:
- case WM5100_DSP1_DM_0:
- case WM5100_DSP1_DM_1:
- case WM5100_DSP1_DM_2:
- case WM5100_DSP1_DM_3:
- case WM5100_DSP1_DM_508:
- case WM5100_DSP1_DM_509:
- case WM5100_DSP1_DM_510:
- case WM5100_DSP1_DM_511:
- case WM5100_DSP1_PM_0:
- case WM5100_DSP1_PM_1:
- case WM5100_DSP1_PM_2:
- case WM5100_DSP1_PM_3:
- case WM5100_DSP1_PM_4:
- case WM5100_DSP1_PM_5:
- case WM5100_DSP1_PM_1530:
- case WM5100_DSP1_PM_1531:
- case WM5100_DSP1_PM_1532:
- case WM5100_DSP1_PM_1533:
- case WM5100_DSP1_PM_1534:
- case WM5100_DSP1_PM_1535:
- case WM5100_DSP1_ZM_0:
- case WM5100_DSP1_ZM_1:
- case WM5100_DSP1_ZM_2:
- case WM5100_DSP1_ZM_3:
- case WM5100_DSP1_ZM_2044:
- case WM5100_DSP1_ZM_2045:
- case WM5100_DSP1_ZM_2046:
- case WM5100_DSP1_ZM_2047:
- case WM5100_DSP2_DM_0:
- case WM5100_DSP2_DM_1:
- case WM5100_DSP2_DM_2:
- case WM5100_DSP2_DM_3:
- case WM5100_DSP2_DM_508:
- case WM5100_DSP2_DM_509:
- case WM5100_DSP2_DM_510:
- case WM5100_DSP2_DM_511:
- case WM5100_DSP2_PM_0:
- case WM5100_DSP2_PM_1:
- case WM5100_DSP2_PM_2:
- case WM5100_DSP2_PM_3:
- case WM5100_DSP2_PM_4:
- case WM5100_DSP2_PM_5:
- case WM5100_DSP2_PM_1530:
- case WM5100_DSP2_PM_1531:
- case WM5100_DSP2_PM_1532:
- case WM5100_DSP2_PM_1533:
- case WM5100_DSP2_PM_1534:
- case WM5100_DSP2_PM_1535:
- case WM5100_DSP2_ZM_0:
- case WM5100_DSP2_ZM_1:
- case WM5100_DSP2_ZM_2:
- case WM5100_DSP2_ZM_3:
- case WM5100_DSP2_ZM_2044:
- case WM5100_DSP2_ZM_2045:
- case WM5100_DSP2_ZM_2046:
- case WM5100_DSP2_ZM_2047:
- case WM5100_DSP3_DM_0:
- case WM5100_DSP3_DM_1:
- case WM5100_DSP3_DM_2:
- case WM5100_DSP3_DM_3:
- case WM5100_DSP3_DM_508:
- case WM5100_DSP3_DM_509:
- case WM5100_DSP3_DM_510:
- case WM5100_DSP3_DM_511:
- case WM5100_DSP3_PM_0:
- case WM5100_DSP3_PM_1:
- case WM5100_DSP3_PM_2:
- case WM5100_DSP3_PM_3:
- case WM5100_DSP3_PM_4:
- case WM5100_DSP3_PM_5:
- case WM5100_DSP3_PM_1530:
- case WM5100_DSP3_PM_1531:
- case WM5100_DSP3_PM_1532:
- case WM5100_DSP3_PM_1533:
- case WM5100_DSP3_PM_1534:
- case WM5100_DSP3_PM_1535:
- case WM5100_DSP3_ZM_0:
- case WM5100_DSP3_ZM_1:
- case WM5100_DSP3_ZM_2:
- case WM5100_DSP3_ZM_3:
- case WM5100_DSP3_ZM_2044:
- case WM5100_DSP3_ZM_2045:
- case WM5100_DSP3_ZM_2046:
- case WM5100_DSP3_ZM_2047:
return 1;
default:
return 0;
}
}
-u16 wm5100_reg_defaults[WM5100_MAX_REGISTER + 1] = {
- [0x0000] = 0x0000, /* R0 - software reset */
- [0x0001] = 0x0000, /* R1 - Device Revision */
- [0x0010] = 0x0801, /* R16 - Ctrl IF 1 */
- [0x0020] = 0x0000, /* R32 - Tone Generator 1 */
- [0x0030] = 0x0000, /* R48 - PWM Drive 1 */
- [0x0031] = 0x0100, /* R49 - PWM Drive 2 */
- [0x0032] = 0x0100, /* R50 - PWM Drive 3 */
- [0x0100] = 0x0002, /* R256 - Clocking 1 */
- [0x0101] = 0x0000, /* R257 - Clocking 3 */
- [0x0102] = 0x0011, /* R258 - Clocking 4 */
- [0x0103] = 0x0011, /* R259 - Clocking 5 */
- [0x0104] = 0x0011, /* R260 - Clocking 6 */
- [0x0107] = 0x0000, /* R263 - Clocking 7 */
- [0x0108] = 0x0000, /* R264 - Clocking 8 */
- [0x0120] = 0x0000, /* R288 - ASRC_ENABLE */
- [0x0121] = 0x0000, /* R289 - ASRC_STATUS */
- [0x0122] = 0x0000, /* R290 - ASRC_RATE1 */
- [0x0141] = 0x8000, /* R321 - ISRC 1 CTRL 1 */
- [0x0142] = 0x0000, /* R322 - ISRC 1 CTRL 2 */
- [0x0143] = 0x8000, /* R323 - ISRC 2 CTRL1 */
- [0x0144] = 0x0000, /* R324 - ISRC 2 CTRL 2 */
- [0x0182] = 0x0000, /* R386 - FLL1 Control 1 */
- [0x0183] = 0x0000, /* R387 - FLL1 Control 2 */
- [0x0184] = 0x0000, /* R388 - FLL1 Control 3 */
- [0x0186] = 0x0177, /* R390 - FLL1 Control 5 */
- [0x0187] = 0x0001, /* R391 - FLL1 Control 6 */
- [0x0188] = 0x0000, /* R392 - FLL1 EFS 1 */
- [0x01A2] = 0x0000, /* R418 - FLL2 Control 1 */
- [0x01A3] = 0x0000, /* R419 - FLL2 Control 2 */
- [0x01A4] = 0x0000, /* R420 - FLL2 Control 3 */
- [0x01A6] = 0x0177, /* R422 - FLL2 Control 5 */
- [0x01A7] = 0x0001, /* R423 - FLL2 Control 6 */
- [0x01A8] = 0x0000, /* R424 - FLL2 EFS 1 */
- [0x0200] = 0x0020, /* R512 - Mic Charge Pump 1 */
- [0x0201] = 0xB084, /* R513 - Mic Charge Pump 2 */
- [0x0202] = 0xBBDE, /* R514 - HP Charge Pump 1 */
- [0x0211] = 0x20D4, /* R529 - LDO1 Control */
- [0x0215] = 0x0062, /* R533 - Mic Bias Ctrl 1 */
- [0x0216] = 0x0062, /* R534 - Mic Bias Ctrl 2 */
- [0x0217] = 0x0062, /* R535 - Mic Bias Ctrl 3 */
- [0x0280] = 0x0004, /* R640 - Accessory Detect Mode 1 */
- [0x0288] = 0x0020, /* R648 - Headphone Detect 1 */
- [0x0289] = 0x0000, /* R649 - Headphone Detect 2 */
- [0x0290] = 0x1100, /* R656 - Mic Detect 1 */
- [0x0291] = 0x009F, /* R657 - Mic Detect 2 */
- [0x0292] = 0x0000, /* R658 - Mic Detect 3 */
- [0x0301] = 0x0000, /* R769 - Input Enables */
- [0x0302] = 0x0000, /* R770 - Input Enables Status */
- [0x0310] = 0x2280, /* R784 - Status */
- [0x0311] = 0x0080, /* R785 - IN1R Control */
- [0x0312] = 0x2280, /* R786 - IN2L Control */
- [0x0313] = 0x0080, /* R787 - IN2R Control */
- [0x0314] = 0x2280, /* R788 - IN3L Control */
- [0x0315] = 0x0080, /* R789 - IN3R Control */
- [0x0316] = 0x2280, /* R790 - IN4L Control */
- [0x0317] = 0x0080, /* R791 - IN4R Control */
- [0x0318] = 0x0000, /* R792 - RXANC_SRC */
- [0x0319] = 0x0022, /* R793 - Input Volume Ramp */
- [0x0320] = 0x0180, /* R800 - ADC Digital Volume 1L */
- [0x0321] = 0x0180, /* R801 - ADC Digital Volume 1R */
- [0x0322] = 0x0180, /* R802 - ADC Digital Volume 2L */
- [0x0323] = 0x0180, /* R803 - ADC Digital Volume 2R */
- [0x0324] = 0x0180, /* R804 - ADC Digital Volume 3L */
- [0x0325] = 0x0180, /* R805 - ADC Digital Volume 3R */
- [0x0326] = 0x0180, /* R806 - ADC Digital Volume 4L */
- [0x0327] = 0x0180, /* R807 - ADC Digital Volume 4R */
- [0x0401] = 0x0000, /* R1025 - Output Enables 2 */
- [0x0402] = 0x0000, /* R1026 - Output Status 1 */
- [0x0403] = 0x0000, /* R1027 - Output Status 2 */
- [0x0408] = 0x0000, /* R1032 - Channel Enables 1 */
- [0x0410] = 0x0080, /* R1040 - Out Volume 1L */
- [0x0411] = 0x0080, /* R1041 - Out Volume 1R */
- [0x0412] = 0x0080, /* R1042 - DAC Volume Limit 1L */
- [0x0413] = 0x0080, /* R1043 - DAC Volume Limit 1R */
- [0x0414] = 0x0080, /* R1044 - Out Volume 2L */
- [0x0415] = 0x0080, /* R1045 - Out Volume 2R */
- [0x0416] = 0x0080, /* R1046 - DAC Volume Limit 2L */
- [0x0417] = 0x0080, /* R1047 - DAC Volume Limit 2R */
- [0x0418] = 0x0080, /* R1048 - Out Volume 3L */
- [0x0419] = 0x0080, /* R1049 - Out Volume 3R */
- [0x041A] = 0x0080, /* R1050 - DAC Volume Limit 3L */
- [0x041B] = 0x0080, /* R1051 - DAC Volume Limit 3R */
- [0x041C] = 0x0080, /* R1052 - Out Volume 4L */
- [0x041D] = 0x0080, /* R1053 - Out Volume 4R */
- [0x041E] = 0x0080, /* R1054 - DAC Volume Limit 5L */
- [0x041F] = 0x0080, /* R1055 - DAC Volume Limit 5R */
- [0x0420] = 0x0080, /* R1056 - DAC Volume Limit 6L */
- [0x0421] = 0x0080, /* R1057 - DAC Volume Limit 6R */
- [0x0440] = 0x0000, /* R1088 - DAC AEC Control 1 */
- [0x0441] = 0x0022, /* R1089 - Output Volume Ramp */
- [0x0480] = 0x0180, /* R1152 - DAC Digital Volume 1L */
- [0x0481] = 0x0180, /* R1153 - DAC Digital Volume 1R */
- [0x0482] = 0x0180, /* R1154 - DAC Digital Volume 2L */
- [0x0483] = 0x0180, /* R1155 - DAC Digital Volume 2R */
- [0x0484] = 0x0180, /* R1156 - DAC Digital Volume 3L */
- [0x0485] = 0x0180, /* R1157 - DAC Digital Volume 3R */
- [0x0486] = 0x0180, /* R1158 - DAC Digital Volume 4L */
- [0x0487] = 0x0180, /* R1159 - DAC Digital Volume 4R */
- [0x0488] = 0x0180, /* R1160 - DAC Digital Volume 5L */
- [0x0489] = 0x0180, /* R1161 - DAC Digital Volume 5R */
- [0x048A] = 0x0180, /* R1162 - DAC Digital Volume 6L */
- [0x048B] = 0x0180, /* R1163 - DAC Digital Volume 6R */
- [0x04C0] = 0x0069, /* R1216 - PDM SPK1 CTRL 1 */
- [0x04C1] = 0x0000, /* R1217 - PDM SPK1 CTRL 2 */
- [0x04C2] = 0x0069, /* R1218 - PDM SPK2 CTRL 1 */
- [0x04C3] = 0x0000, /* R1219 - PDM SPK2 CTRL 2 */
- [0x0500] = 0x000C, /* R1280 - Audio IF 1_1 */
- [0x0501] = 0x0008, /* R1281 - Audio IF 1_2 */
- [0x0502] = 0x0000, /* R1282 - Audio IF 1_3 */
- [0x0503] = 0x0000, /* R1283 - Audio IF 1_4 */
- [0x0504] = 0x0000, /* R1284 - Audio IF 1_5 */
- [0x0505] = 0x0300, /* R1285 - Audio IF 1_6 */
- [0x0506] = 0x0300, /* R1286 - Audio IF 1_7 */
- [0x0507] = 0x1820, /* R1287 - Audio IF 1_8 */
- [0x0508] = 0x1820, /* R1288 - Audio IF 1_9 */
- [0x0509] = 0x0000, /* R1289 - Audio IF 1_10 */
- [0x050A] = 0x0001, /* R1290 - Audio IF 1_11 */
- [0x050B] = 0x0002, /* R1291 - Audio IF 1_12 */
- [0x050C] = 0x0003, /* R1292 - Audio IF 1_13 */
- [0x050D] = 0x0004, /* R1293 - Audio IF 1_14 */
- [0x050E] = 0x0005, /* R1294 - Audio IF 1_15 */
- [0x050F] = 0x0006, /* R1295 - Audio IF 1_16 */
- [0x0510] = 0x0007, /* R1296 - Audio IF 1_17 */
- [0x0511] = 0x0000, /* R1297 - Audio IF 1_18 */
- [0x0512] = 0x0001, /* R1298 - Audio IF 1_19 */
- [0x0513] = 0x0002, /* R1299 - Audio IF 1_20 */
- [0x0514] = 0x0003, /* R1300 - Audio IF 1_21 */
- [0x0515] = 0x0004, /* R1301 - Audio IF 1_22 */
- [0x0516] = 0x0005, /* R1302 - Audio IF 1_23 */
- [0x0517] = 0x0006, /* R1303 - Audio IF 1_24 */
- [0x0518] = 0x0007, /* R1304 - Audio IF 1_25 */
- [0x0519] = 0x0000, /* R1305 - Audio IF 1_26 */
- [0x051A] = 0x0000, /* R1306 - Audio IF 1_27 */
- [0x0540] = 0x000C, /* R1344 - Audio IF 2_1 */
- [0x0541] = 0x0008, /* R1345 - Audio IF 2_2 */
- [0x0542] = 0x0000, /* R1346 - Audio IF 2_3 */
- [0x0543] = 0x0000, /* R1347 - Audio IF 2_4 */
- [0x0544] = 0x0000, /* R1348 - Audio IF 2_5 */
- [0x0545] = 0x0300, /* R1349 - Audio IF 2_6 */
- [0x0546] = 0x0300, /* R1350 - Audio IF 2_7 */
- [0x0547] = 0x1820, /* R1351 - Audio IF 2_8 */
- [0x0548] = 0x1820, /* R1352 - Audio IF 2_9 */
- [0x0549] = 0x0000, /* R1353 - Audio IF 2_10 */
- [0x054A] = 0x0001, /* R1354 - Audio IF 2_11 */
- [0x0551] = 0x0000, /* R1361 - Audio IF 2_18 */
- [0x0552] = 0x0001, /* R1362 - Audio IF 2_19 */
- [0x0559] = 0x0000, /* R1369 - Audio IF 2_26 */
- [0x055A] = 0x0000, /* R1370 - Audio IF 2_27 */
- [0x0580] = 0x000C, /* R1408 - Audio IF 3_1 */
- [0x0581] = 0x0008, /* R1409 - Audio IF 3_2 */
- [0x0582] = 0x0000, /* R1410 - Audio IF 3_3 */
- [0x0583] = 0x0000, /* R1411 - Audio IF 3_4 */
- [0x0584] = 0x0000, /* R1412 - Audio IF 3_5 */
- [0x0585] = 0x0300, /* R1413 - Audio IF 3_6 */
- [0x0586] = 0x0300, /* R1414 - Audio IF 3_7 */
- [0x0587] = 0x1820, /* R1415 - Audio IF 3_8 */
- [0x0588] = 0x1820, /* R1416 - Audio IF 3_9 */
- [0x0589] = 0x0000, /* R1417 - Audio IF 3_10 */
- [0x058A] = 0x0001, /* R1418 - Audio IF 3_11 */
- [0x0591] = 0x0000, /* R1425 - Audio IF 3_18 */
- [0x0592] = 0x0001, /* R1426 - Audio IF 3_19 */
- [0x0599] = 0x0000, /* R1433 - Audio IF 3_26 */
- [0x059A] = 0x0000, /* R1434 - Audio IF 3_27 */
- [0x0640] = 0x0000, /* R1600 - PWM1MIX Input 1 Source */
- [0x0641] = 0x0080, /* R1601 - PWM1MIX Input 1 Volume */
- [0x0642] = 0x0000, /* R1602 - PWM1MIX Input 2 Source */
- [0x0643] = 0x0080, /* R1603 - PWM1MIX Input 2 Volume */
- [0x0644] = 0x0000, /* R1604 - PWM1MIX Input 3 Source */
- [0x0645] = 0x0080, /* R1605 - PWM1MIX Input 3 Volume */
- [0x0646] = 0x0000, /* R1606 - PWM1MIX Input 4 Source */
- [0x0647] = 0x0080, /* R1607 - PWM1MIX Input 4 Volume */
- [0x0648] = 0x0000, /* R1608 - PWM2MIX Input 1 Source */
- [0x0649] = 0x0080, /* R1609 - PWM2MIX Input 1 Volume */
- [0x064A] = 0x0000, /* R1610 - PWM2MIX Input 2 Source */
- [0x064B] = 0x0080, /* R1611 - PWM2MIX Input 2 Volume */
- [0x064C] = 0x0000, /* R1612 - PWM2MIX Input 3 Source */
- [0x064D] = 0x0080, /* R1613 - PWM2MIX Input 3 Volume */
- [0x064E] = 0x0000, /* R1614 - PWM2MIX Input 4 Source */
- [0x064F] = 0x0080, /* R1615 - PWM2MIX Input 4 Volume */
- [0x0680] = 0x0000, /* R1664 - OUT1LMIX Input 1 Source */
- [0x0681] = 0x0080, /* R1665 - OUT1LMIX Input 1 Volume */
- [0x0682] = 0x0000, /* R1666 - OUT1LMIX Input 2 Source */
- [0x0683] = 0x0080, /* R1667 - OUT1LMIX Input 2 Volume */
- [0x0684] = 0x0000, /* R1668 - OUT1LMIX Input 3 Source */
- [0x0685] = 0x0080, /* R1669 - OUT1LMIX Input 3 Volume */
- [0x0686] = 0x0000, /* R1670 - OUT1LMIX Input 4 Source */
- [0x0687] = 0x0080, /* R1671 - OUT1LMIX Input 4 Volume */
- [0x0688] = 0x0000, /* R1672 - OUT1RMIX Input 1 Source */
- [0x0689] = 0x0080, /* R1673 - OUT1RMIX Input 1 Volume */
- [0x068A] = 0x0000, /* R1674 - OUT1RMIX Input 2 Source */
- [0x068B] = 0x0080, /* R1675 - OUT1RMIX Input 2 Volume */
- [0x068C] = 0x0000, /* R1676 - OUT1RMIX Input 3 Source */
- [0x068D] = 0x0080, /* R1677 - OUT1RMIX Input 3 Volume */
- [0x068E] = 0x0000, /* R1678 - OUT1RMIX Input 4 Source */
- [0x068F] = 0x0080, /* R1679 - OUT1RMIX Input 4 Volume */
- [0x0690] = 0x0000, /* R1680 - OUT2LMIX Input 1 Source */
- [0x0691] = 0x0080, /* R1681 - OUT2LMIX Input 1 Volume */
- [0x0692] = 0x0000, /* R1682 - OUT2LMIX Input 2 Source */
- [0x0693] = 0x0080, /* R1683 - OUT2LMIX Input 2 Volume */
- [0x0694] = 0x0000, /* R1684 - OUT2LMIX Input 3 Source */
- [0x0695] = 0x0080, /* R1685 - OUT2LMIX Input 3 Volume */
- [0x0696] = 0x0000, /* R1686 - OUT2LMIX Input 4 Source */
- [0x0697] = 0x0080, /* R1687 - OUT2LMIX Input 4 Volume */
- [0x0698] = 0x0000, /* R1688 - OUT2RMIX Input 1 Source */
- [0x0699] = 0x0080, /* R1689 - OUT2RMIX Input 1 Volume */
- [0x069A] = 0x0000, /* R1690 - OUT2RMIX Input 2 Source */
- [0x069B] = 0x0080, /* R1691 - OUT2RMIX Input 2 Volume */
- [0x069C] = 0x0000, /* R1692 - OUT2RMIX Input 3 Source */
- [0x069D] = 0x0080, /* R1693 - OUT2RMIX Input 3 Volume */
- [0x069E] = 0x0000, /* R1694 - OUT2RMIX Input 4 Source */
- [0x069F] = 0x0080, /* R1695 - OUT2RMIX Input 4 Volume */
- [0x06A0] = 0x0000, /* R1696 - OUT3LMIX Input 1 Source */
- [0x06A1] = 0x0080, /* R1697 - OUT3LMIX Input 1 Volume */
- [0x06A2] = 0x0000, /* R1698 - OUT3LMIX Input 2 Source */
- [0x06A3] = 0x0080, /* R1699 - OUT3LMIX Input 2 Volume */
- [0x06A4] = 0x0000, /* R1700 - OUT3LMIX Input 3 Source */
- [0x06A5] = 0x0080, /* R1701 - OUT3LMIX Input 3 Volume */
- [0x06A6] = 0x0000, /* R1702 - OUT3LMIX Input 4 Source */
- [0x06A7] = 0x0080, /* R1703 - OUT3LMIX Input 4 Volume */
- [0x06A8] = 0x0000, /* R1704 - OUT3RMIX Input 1 Source */
- [0x06A9] = 0x0080, /* R1705 - OUT3RMIX Input 1 Volume */
- [0x06AA] = 0x0000, /* R1706 - OUT3RMIX Input 2 Source */
- [0x06AB] = 0x0080, /* R1707 - OUT3RMIX Input 2 Volume */
- [0x06AC] = 0x0000, /* R1708 - OUT3RMIX Input 3 Source */
- [0x06AD] = 0x0080, /* R1709 - OUT3RMIX Input 3 Volume */
- [0x06AE] = 0x0000, /* R1710 - OUT3RMIX Input 4 Source */
- [0x06AF] = 0x0080, /* R1711 - OUT3RMIX Input 4 Volume */
- [0x06B0] = 0x0000, /* R1712 - OUT4LMIX Input 1 Source */
- [0x06B1] = 0x0080, /* R1713 - OUT4LMIX Input 1 Volume */
- [0x06B2] = 0x0000, /* R1714 - OUT4LMIX Input 2 Source */
- [0x06B3] = 0x0080, /* R1715 - OUT4LMIX Input 2 Volume */
- [0x06B4] = 0x0000, /* R1716 - OUT4LMIX Input 3 Source */
- [0x06B5] = 0x0080, /* R1717 - OUT4LMIX Input 3 Volume */
- [0x06B6] = 0x0000, /* R1718 - OUT4LMIX Input 4 Source */
- [0x06B7] = 0x0080, /* R1719 - OUT4LMIX Input 4 Volume */
- [0x06B8] = 0x0000, /* R1720 - OUT4RMIX Input 1 Source */
- [0x06B9] = 0x0080, /* R1721 - OUT4RMIX Input 1 Volume */
- [0x06BA] = 0x0000, /* R1722 - OUT4RMIX Input 2 Source */
- [0x06BB] = 0x0080, /* R1723 - OUT4RMIX Input 2 Volume */
- [0x06BC] = 0x0000, /* R1724 - OUT4RMIX Input 3 Source */
- [0x06BD] = 0x0080, /* R1725 - OUT4RMIX Input 3 Volume */
- [0x06BE] = 0x0000, /* R1726 - OUT4RMIX Input 4 Source */
- [0x06BF] = 0x0080, /* R1727 - OUT4RMIX Input 4 Volume */
- [0x06C0] = 0x0000, /* R1728 - OUT5LMIX Input 1 Source */
- [0x06C1] = 0x0080, /* R1729 - OUT5LMIX Input 1 Volume */
- [0x06C2] = 0x0000, /* R1730 - OUT5LMIX Input 2 Source */
- [0x06C3] = 0x0080, /* R1731 - OUT5LMIX Input 2 Volume */
- [0x06C4] = 0x0000, /* R1732 - OUT5LMIX Input 3 Source */
- [0x06C5] = 0x0080, /* R1733 - OUT5LMIX Input 3 Volume */
- [0x06C6] = 0x0000, /* R1734 - OUT5LMIX Input 4 Source */
- [0x06C7] = 0x0080, /* R1735 - OUT5LMIX Input 4 Volume */
- [0x06C8] = 0x0000, /* R1736 - OUT5RMIX Input 1 Source */
- [0x06C9] = 0x0080, /* R1737 - OUT5RMIX Input 1 Volume */
- [0x06CA] = 0x0000, /* R1738 - OUT5RMIX Input 2 Source */
- [0x06CB] = 0x0080, /* R1739 - OUT5RMIX Input 2 Volume */
- [0x06CC] = 0x0000, /* R1740 - OUT5RMIX Input 3 Source */
- [0x06CD] = 0x0080, /* R1741 - OUT5RMIX Input 3 Volume */
- [0x06CE] = 0x0000, /* R1742 - OUT5RMIX Input 4 Source */
- [0x06CF] = 0x0080, /* R1743 - OUT5RMIX Input 4 Volume */
- [0x06D0] = 0x0000, /* R1744 - OUT6LMIX Input 1 Source */
- [0x06D1] = 0x0080, /* R1745 - OUT6LMIX Input 1 Volume */
- [0x06D2] = 0x0000, /* R1746 - OUT6LMIX Input 2 Source */
- [0x06D3] = 0x0080, /* R1747 - OUT6LMIX Input 2 Volume */
- [0x06D4] = 0x0000, /* R1748 - OUT6LMIX Input 3 Source */
- [0x06D5] = 0x0080, /* R1749 - OUT6LMIX Input 3 Volume */
- [0x06D6] = 0x0000, /* R1750 - OUT6LMIX Input 4 Source */
- [0x06D7] = 0x0080, /* R1751 - OUT6LMIX Input 4 Volume */
- [0x06D8] = 0x0000, /* R1752 - OUT6RMIX Input 1 Source */
- [0x06D9] = 0x0080, /* R1753 - OUT6RMIX Input 1 Volume */
- [0x06DA] = 0x0000, /* R1754 - OUT6RMIX Input 2 Source */
- [0x06DB] = 0x0080, /* R1755 - OUT6RMIX Input 2 Volume */
- [0x06DC] = 0x0000, /* R1756 - OUT6RMIX Input 3 Source */
- [0x06DD] = 0x0080, /* R1757 - OUT6RMIX Input 3 Volume */
- [0x06DE] = 0x0000, /* R1758 - OUT6RMIX Input 4 Source */
- [0x06DF] = 0x0080, /* R1759 - OUT6RMIX Input 4 Volume */
- [0x0700] = 0x0000, /* R1792 - AIF1TX1MIX Input 1 Source */
- [0x0701] = 0x0080, /* R1793 - AIF1TX1MIX Input 1 Volume */
- [0x0702] = 0x0000, /* R1794 - AIF1TX1MIX Input 2 Source */
- [0x0703] = 0x0080, /* R1795 - AIF1TX1MIX Input 2 Volume */
- [0x0704] = 0x0000, /* R1796 - AIF1TX1MIX Input 3 Source */
- [0x0705] = 0x0080, /* R1797 - AIF1TX1MIX Input 3 Volume */
- [0x0706] = 0x0000, /* R1798 - AIF1TX1MIX Input 4 Source */
- [0x0707] = 0x0080, /* R1799 - AIF1TX1MIX Input 4 Volume */
- [0x0708] = 0x0000, /* R1800 - AIF1TX2MIX Input 1 Source */
- [0x0709] = 0x0080, /* R1801 - AIF1TX2MIX Input 1 Volume */
- [0x070A] = 0x0000, /* R1802 - AIF1TX2MIX Input 2 Source */
- [0x070B] = 0x0080, /* R1803 - AIF1TX2MIX Input 2 Volume */
- [0x070C] = 0x0000, /* R1804 - AIF1TX2MIX Input 3 Source */
- [0x070D] = 0x0080, /* R1805 - AIF1TX2MIX Input 3 Volume */
- [0x070E] = 0x0000, /* R1806 - AIF1TX2MIX Input 4 Source */
- [0x070F] = 0x0080, /* R1807 - AIF1TX2MIX Input 4 Volume */
- [0x0710] = 0x0000, /* R1808 - AIF1TX3MIX Input 1 Source */
- [0x0711] = 0x0080, /* R1809 - AIF1TX3MIX Input 1 Volume */
- [0x0712] = 0x0000, /* R1810 - AIF1TX3MIX Input 2 Source */
- [0x0713] = 0x0080, /* R1811 - AIF1TX3MIX Input 2 Volume */
- [0x0714] = 0x0000, /* R1812 - AIF1TX3MIX Input 3 Source */
- [0x0715] = 0x0080, /* R1813 - AIF1TX3MIX Input 3 Volume */
- [0x0716] = 0x0000, /* R1814 - AIF1TX3MIX Input 4 Source */
- [0x0717] = 0x0080, /* R1815 - AIF1TX3MIX Input 4 Volume */
- [0x0718] = 0x0000, /* R1816 - AIF1TX4MIX Input 1 Source */
- [0x0719] = 0x0080, /* R1817 - AIF1TX4MIX Input 1 Volume */
- [0x071A] = 0x0000, /* R1818 - AIF1TX4MIX Input 2 Source */
- [0x071B] = 0x0080, /* R1819 - AIF1TX4MIX Input 2 Volume */
- [0x071C] = 0x0000, /* R1820 - AIF1TX4MIX Input 3 Source */
- [0x071D] = 0x0080, /* R1821 - AIF1TX4MIX Input 3 Volume */
- [0x071E] = 0x0000, /* R1822 - AIF1TX4MIX Input 4 Source */
- [0x071F] = 0x0080, /* R1823 - AIF1TX4MIX Input 4 Volume */
- [0x0720] = 0x0000, /* R1824 - AIF1TX5MIX Input 1 Source */
- [0x0721] = 0x0080, /* R1825 - AIF1TX5MIX Input 1 Volume */
- [0x0722] = 0x0000, /* R1826 - AIF1TX5MIX Input 2 Source */
- [0x0723] = 0x0080, /* R1827 - AIF1TX5MIX Input 2 Volume */
- [0x0724] = 0x0000, /* R1828 - AIF1TX5MIX Input 3 Source */
- [0x0725] = 0x0080, /* R1829 - AIF1TX5MIX Input 3 Volume */
- [0x0726] = 0x0000, /* R1830 - AIF1TX5MIX Input 4 Source */
- [0x0727] = 0x0080, /* R1831 - AIF1TX5MIX Input 4 Volume */
- [0x0728] = 0x0000, /* R1832 - AIF1TX6MIX Input 1 Source */
- [0x0729] = 0x0080, /* R1833 - AIF1TX6MIX Input 1 Volume */
- [0x072A] = 0x0000, /* R1834 - AIF1TX6MIX Input 2 Source */
- [0x072B] = 0x0080, /* R1835 - AIF1TX6MIX Input 2 Volume */
- [0x072C] = 0x0000, /* R1836 - AIF1TX6MIX Input 3 Source */
- [0x072D] = 0x0080, /* R1837 - AIF1TX6MIX Input 3 Volume */
- [0x072E] = 0x0000, /* R1838 - AIF1TX6MIX Input 4 Source */
- [0x072F] = 0x0080, /* R1839 - AIF1TX6MIX Input 4 Volume */
- [0x0730] = 0x0000, /* R1840 - AIF1TX7MIX Input 1 Source */
- [0x0731] = 0x0080, /* R1841 - AIF1TX7MIX Input 1 Volume */
- [0x0732] = 0x0000, /* R1842 - AIF1TX7MIX Input 2 Source */
- [0x0733] = 0x0080, /* R1843 - AIF1TX7MIX Input 2 Volume */
- [0x0734] = 0x0000, /* R1844 - AIF1TX7MIX Input 3 Source */
- [0x0735] = 0x0080, /* R1845 - AIF1TX7MIX Input 3 Volume */
- [0x0736] = 0x0000, /* R1846 - AIF1TX7MIX Input 4 Source */
- [0x0737] = 0x0080, /* R1847 - AIF1TX7MIX Input 4 Volume */
- [0x0738] = 0x0000, /* R1848 - AIF1TX8MIX Input 1 Source */
- [0x0739] = 0x0080, /* R1849 - AIF1TX8MIX Input 1 Volume */
- [0x073A] = 0x0000, /* R1850 - AIF1TX8MIX Input 2 Source */
- [0x073B] = 0x0080, /* R1851 - AIF1TX8MIX Input 2 Volume */
- [0x073C] = 0x0000, /* R1852 - AIF1TX8MIX Input 3 Source */
- [0x073D] = 0x0080, /* R1853 - AIF1TX8MIX Input 3 Volume */
- [0x073E] = 0x0000, /* R1854 - AIF1TX8MIX Input 4 Source */
- [0x073F] = 0x0080, /* R1855 - AIF1TX8MIX Input 4 Volume */
- [0x0740] = 0x0000, /* R1856 - AIF2TX1MIX Input 1 Source */
- [0x0741] = 0x0080, /* R1857 - AIF2TX1MIX Input 1 Volume */
- [0x0742] = 0x0000, /* R1858 - AIF2TX1MIX Input 2 Source */
- [0x0743] = 0x0080, /* R1859 - AIF2TX1MIX Input 2 Volume */
- [0x0744] = 0x0000, /* R1860 - AIF2TX1MIX Input 3 Source */
- [0x0745] = 0x0080, /* R1861 - AIF2TX1MIX Input 3 Volume */
- [0x0746] = 0x0000, /* R1862 - AIF2TX1MIX Input 4 Source */
- [0x0747] = 0x0080, /* R1863 - AIF2TX1MIX Input 4 Volume */
- [0x0748] = 0x0000, /* R1864 - AIF2TX2MIX Input 1 Source */
- [0x0749] = 0x0080, /* R1865 - AIF2TX2MIX Input 1 Volume */
- [0x074A] = 0x0000, /* R1866 - AIF2TX2MIX Input 2 Source */
- [0x074B] = 0x0080, /* R1867 - AIF2TX2MIX Input 2 Volume */
- [0x074C] = 0x0000, /* R1868 - AIF2TX2MIX Input 3 Source */
- [0x074D] = 0x0080, /* R1869 - AIF2TX2MIX Input 3 Volume */
- [0x074E] = 0x0000, /* R1870 - AIF2TX2MIX Input 4 Source */
- [0x074F] = 0x0080, /* R1871 - AIF2TX2MIX Input 4 Volume */
- [0x0780] = 0x0000, /* R1920 - AIF3TX1MIX Input 1 Source */
- [0x0781] = 0x0080, /* R1921 - AIF3TX1MIX Input 1 Volume */
- [0x0782] = 0x0000, /* R1922 - AIF3TX1MIX Input 2 Source */
- [0x0783] = 0x0080, /* R1923 - AIF3TX1MIX Input 2 Volume */
- [0x0784] = 0x0000, /* R1924 - AIF3TX1MIX Input 3 Source */
- [0x0785] = 0x0080, /* R1925 - AIF3TX1MIX Input 3 Volume */
- [0x0786] = 0x0000, /* R1926 - AIF3TX1MIX Input 4 Source */
- [0x0787] = 0x0080, /* R1927 - AIF3TX1MIX Input 4 Volume */
- [0x0788] = 0x0000, /* R1928 - AIF3TX2MIX Input 1 Source */
- [0x0789] = 0x0080, /* R1929 - AIF3TX2MIX Input 1 Volume */
- [0x078A] = 0x0000, /* R1930 - AIF3TX2MIX Input 2 Source */
- [0x078B] = 0x0080, /* R1931 - AIF3TX2MIX Input 2 Volume */
- [0x078C] = 0x0000, /* R1932 - AIF3TX2MIX Input 3 Source */
- [0x078D] = 0x0080, /* R1933 - AIF3TX2MIX Input 3 Volume */
- [0x078E] = 0x0000, /* R1934 - AIF3TX2MIX Input 4 Source */
- [0x078F] = 0x0080, /* R1935 - AIF3TX2MIX Input 4 Volume */
- [0x0880] = 0x0000, /* R2176 - EQ1MIX Input 1 Source */
- [0x0881] = 0x0080, /* R2177 - EQ1MIX Input 1 Volume */
- [0x0882] = 0x0000, /* R2178 - EQ1MIX Input 2 Source */
- [0x0883] = 0x0080, /* R2179 - EQ1MIX Input 2 Volume */
- [0x0884] = 0x0000, /* R2180 - EQ1MIX Input 3 Source */
- [0x0885] = 0x0080, /* R2181 - EQ1MIX Input 3 Volume */
- [0x0886] = 0x0000, /* R2182 - EQ1MIX Input 4 Source */
- [0x0887] = 0x0080, /* R2183 - EQ1MIX Input 4 Volume */
- [0x0888] = 0x0000, /* R2184 - EQ2MIX Input 1 Source */
- [0x0889] = 0x0080, /* R2185 - EQ2MIX Input 1 Volume */
- [0x088A] = 0x0000, /* R2186 - EQ2MIX Input 2 Source */
- [0x088B] = 0x0080, /* R2187 - EQ2MIX Input 2 Volume */
- [0x088C] = 0x0000, /* R2188 - EQ2MIX Input 3 Source */
- [0x088D] = 0x0080, /* R2189 - EQ2MIX Input 3 Volume */
- [0x088E] = 0x0000, /* R2190 - EQ2MIX Input 4 Source */
- [0x088F] = 0x0080, /* R2191 - EQ2MIX Input 4 Volume */
- [0x0890] = 0x0000, /* R2192 - EQ3MIX Input 1 Source */
- [0x0891] = 0x0080, /* R2193 - EQ3MIX Input 1 Volume */
- [0x0892] = 0x0000, /* R2194 - EQ3MIX Input 2 Source */
- [0x0893] = 0x0080, /* R2195 - EQ3MIX Input 2 Volume */
- [0x0894] = 0x0000, /* R2196 - EQ3MIX Input 3 Source */
- [0x0895] = 0x0080, /* R2197 - EQ3MIX Input 3 Volume */
- [0x0896] = 0x0000, /* R2198 - EQ3MIX Input 4 Source */
- [0x0897] = 0x0080, /* R2199 - EQ3MIX Input 4 Volume */
- [0x0898] = 0x0000, /* R2200 - EQ4MIX Input 1 Source */
- [0x0899] = 0x0080, /* R2201 - EQ4MIX Input 1 Volume */
- [0x089A] = 0x0000, /* R2202 - EQ4MIX Input 2 Source */
- [0x089B] = 0x0080, /* R2203 - EQ4MIX Input 2 Volume */
- [0x089C] = 0x0000, /* R2204 - EQ4MIX Input 3 Source */
- [0x089D] = 0x0080, /* R2205 - EQ4MIX Input 3 Volume */
- [0x089E] = 0x0000, /* R2206 - EQ4MIX Input 4 Source */
- [0x089F] = 0x0080, /* R2207 - EQ4MIX Input 4 Volume */
- [0x08C0] = 0x0000, /* R2240 - DRC1LMIX Input 1 Source */
- [0x08C1] = 0x0080, /* R2241 - DRC1LMIX Input 1 Volume */
- [0x08C2] = 0x0000, /* R2242 - DRC1LMIX Input 2 Source */
- [0x08C3] = 0x0080, /* R2243 - DRC1LMIX Input 2 Volume */
- [0x08C4] = 0x0000, /* R2244 - DRC1LMIX Input 3 Source */
- [0x08C5] = 0x0080, /* R2245 - DRC1LMIX Input 3 Volume */
- [0x08C6] = 0x0000, /* R2246 - DRC1LMIX Input 4 Source */
- [0x08C7] = 0x0080, /* R2247 - DRC1LMIX Input 4 Volume */
- [0x08C8] = 0x0000, /* R2248 - DRC1RMIX Input 1 Source */
- [0x08C9] = 0x0080, /* R2249 - DRC1RMIX Input 1 Volume */
- [0x08CA] = 0x0000, /* R2250 - DRC1RMIX Input 2 Source */
- [0x08CB] = 0x0080, /* R2251 - DRC1RMIX Input 2 Volume */
- [0x08CC] = 0x0000, /* R2252 - DRC1RMIX Input 3 Source */
- [0x08CD] = 0x0080, /* R2253 - DRC1RMIX Input 3 Volume */
- [0x08CE] = 0x0000, /* R2254 - DRC1RMIX Input 4 Source */
- [0x08CF] = 0x0080, /* R2255 - DRC1RMIX Input 4 Volume */
- [0x0900] = 0x0000, /* R2304 - HPLP1MIX Input 1 Source */
- [0x0901] = 0x0080, /* R2305 - HPLP1MIX Input 1 Volume */
- [0x0902] = 0x0000, /* R2306 - HPLP1MIX Input 2 Source */
- [0x0903] = 0x0080, /* R2307 - HPLP1MIX Input 2 Volume */
- [0x0904] = 0x0000, /* R2308 - HPLP1MIX Input 3 Source */
- [0x0905] = 0x0080, /* R2309 - HPLP1MIX Input 3 Volume */
- [0x0906] = 0x0000, /* R2310 - HPLP1MIX Input 4 Source */
- [0x0907] = 0x0080, /* R2311 - HPLP1MIX Input 4 Volume */
- [0x0908] = 0x0000, /* R2312 - HPLP2MIX Input 1 Source */
- [0x0909] = 0x0080, /* R2313 - HPLP2MIX Input 1 Volume */
- [0x090A] = 0x0000, /* R2314 - HPLP2MIX Input 2 Source */
- [0x090B] = 0x0080, /* R2315 - HPLP2MIX Input 2 Volume */
- [0x090C] = 0x0000, /* R2316 - HPLP2MIX Input 3 Source */
- [0x090D] = 0x0080, /* R2317 - HPLP2MIX Input 3 Volume */
- [0x090E] = 0x0000, /* R2318 - HPLP2MIX Input 4 Source */
- [0x090F] = 0x0080, /* R2319 - HPLP2MIX Input 4 Volume */
- [0x0910] = 0x0000, /* R2320 - HPLP3MIX Input 1 Source */
- [0x0911] = 0x0080, /* R2321 - HPLP3MIX Input 1 Volume */
- [0x0912] = 0x0000, /* R2322 - HPLP3MIX Input 2 Source */
- [0x0913] = 0x0080, /* R2323 - HPLP3MIX Input 2 Volume */
- [0x0914] = 0x0000, /* R2324 - HPLP3MIX Input 3 Source */
- [0x0915] = 0x0080, /* R2325 - HPLP3MIX Input 3 Volume */
- [0x0916] = 0x0000, /* R2326 - HPLP3MIX Input 4 Source */
- [0x0917] = 0x0080, /* R2327 - HPLP3MIX Input 4 Volume */
- [0x0918] = 0x0000, /* R2328 - HPLP4MIX Input 1 Source */
- [0x0919] = 0x0080, /* R2329 - HPLP4MIX Input 1 Volume */
- [0x091A] = 0x0000, /* R2330 - HPLP4MIX Input 2 Source */
- [0x091B] = 0x0080, /* R2331 - HPLP4MIX Input 2 Volume */
- [0x091C] = 0x0000, /* R2332 - HPLP4MIX Input 3 Source */
- [0x091D] = 0x0080, /* R2333 - HPLP4MIX Input 3 Volume */
- [0x091E] = 0x0000, /* R2334 - HPLP4MIX Input 4 Source */
- [0x091F] = 0x0080, /* R2335 - HPLP4MIX Input 4 Volume */
- [0x0940] = 0x0000, /* R2368 - DSP1LMIX Input 1 Source */
- [0x0941] = 0x0080, /* R2369 - DSP1LMIX Input 1 Volume */
- [0x0942] = 0x0000, /* R2370 - DSP1LMIX Input 2 Source */
- [0x0943] = 0x0080, /* R2371 - DSP1LMIX Input 2 Volume */
- [0x0944] = 0x0000, /* R2372 - DSP1LMIX Input 3 Source */
- [0x0945] = 0x0080, /* R2373 - DSP1LMIX Input 3 Volume */
- [0x0946] = 0x0000, /* R2374 - DSP1LMIX Input 4 Source */
- [0x0947] = 0x0080, /* R2375 - DSP1LMIX Input 4 Volume */
- [0x0948] = 0x0000, /* R2376 - DSP1RMIX Input 1 Source */
- [0x0949] = 0x0080, /* R2377 - DSP1RMIX Input 1 Volume */
- [0x094A] = 0x0000, /* R2378 - DSP1RMIX Input 2 Source */
- [0x094B] = 0x0080, /* R2379 - DSP1RMIX Input 2 Volume */
- [0x094C] = 0x0000, /* R2380 - DSP1RMIX Input 3 Source */
- [0x094D] = 0x0080, /* R2381 - DSP1RMIX Input 3 Volume */
- [0x094E] = 0x0000, /* R2382 - DSP1RMIX Input 4 Source */
- [0x094F] = 0x0080, /* R2383 - DSP1RMIX Input 4 Volume */
- [0x0950] = 0x0000, /* R2384 - DSP1AUX1MIX Input 1 Source */
- [0x0958] = 0x0000, /* R2392 - DSP1AUX2MIX Input 1 Source */
- [0x0960] = 0x0000, /* R2400 - DSP1AUX3MIX Input 1 Source */
- [0x0968] = 0x0000, /* R2408 - DSP1AUX4MIX Input 1 Source */
- [0x0970] = 0x0000, /* R2416 - DSP1AUX5MIX Input 1 Source */
- [0x0978] = 0x0000, /* R2424 - DSP1AUX6MIX Input 1 Source */
- [0x0980] = 0x0000, /* R2432 - DSP2LMIX Input 1 Source */
- [0x0981] = 0x0080, /* R2433 - DSP2LMIX Input 1 Volume */
- [0x0982] = 0x0000, /* R2434 - DSP2LMIX Input 2 Source */
- [0x0983] = 0x0080, /* R2435 - DSP2LMIX Input 2 Volume */
- [0x0984] = 0x0000, /* R2436 - DSP2LMIX Input 3 Source */
- [0x0985] = 0x0080, /* R2437 - DSP2LMIX Input 3 Volume */
- [0x0986] = 0x0000, /* R2438 - DSP2LMIX Input 4 Source */
- [0x0987] = 0x0080, /* R2439 - DSP2LMIX Input 4 Volume */
- [0x0988] = 0x0000, /* R2440 - DSP2RMIX Input 1 Source */
- [0x0989] = 0x0080, /* R2441 - DSP2RMIX Input 1 Volume */
- [0x098A] = 0x0000, /* R2442 - DSP2RMIX Input 2 Source */
- [0x098B] = 0x0080, /* R2443 - DSP2RMIX Input 2 Volume */
- [0x098C] = 0x0000, /* R2444 - DSP2RMIX Input 3 Source */
- [0x098D] = 0x0080, /* R2445 - DSP2RMIX Input 3 Volume */
- [0x098E] = 0x0000, /* R2446 - DSP2RMIX Input 4 Source */
- [0x098F] = 0x0080, /* R2447 - DSP2RMIX Input 4 Volume */
- [0x0990] = 0x0000, /* R2448 - DSP2AUX1MIX Input 1 Source */
- [0x0998] = 0x0000, /* R2456 - DSP2AUX2MIX Input 1 Source */
- [0x09A0] = 0x0000, /* R2464 - DSP2AUX3MIX Input 1 Source */
- [0x09A8] = 0x0000, /* R2472 - DSP2AUX4MIX Input 1 Source */
- [0x09B0] = 0x0000, /* R2480 - DSP2AUX5MIX Input 1 Source */
- [0x09B8] = 0x0000, /* R2488 - DSP2AUX6MIX Input 1 Source */
- [0x09C0] = 0x0000, /* R2496 - DSP3LMIX Input 1 Source */
- [0x09C1] = 0x0080, /* R2497 - DSP3LMIX Input 1 Volume */
- [0x09C2] = 0x0000, /* R2498 - DSP3LMIX Input 2 Source */
- [0x09C3] = 0x0080, /* R2499 - DSP3LMIX Input 2 Volume */
- [0x09C4] = 0x0000, /* R2500 - DSP3LMIX Input 3 Source */
- [0x09C5] = 0x0080, /* R2501 - DSP3LMIX Input 3 Volume */
- [0x09C6] = 0x0000, /* R2502 - DSP3LMIX Input 4 Source */
- [0x09C7] = 0x0080, /* R2503 - DSP3LMIX Input 4 Volume */
- [0x09C8] = 0x0000, /* R2504 - DSP3RMIX Input 1 Source */
- [0x09C9] = 0x0080, /* R2505 - DSP3RMIX Input 1 Volume */
- [0x09CA] = 0x0000, /* R2506 - DSP3RMIX Input 2 Source */
- [0x09CB] = 0x0080, /* R2507 - DSP3RMIX Input 2 Volume */
- [0x09CC] = 0x0000, /* R2508 - DSP3RMIX Input 3 Source */
- [0x09CD] = 0x0080, /* R2509 - DSP3RMIX Input 3 Volume */
- [0x09CE] = 0x0000, /* R2510 - DSP3RMIX Input 4 Source */
- [0x09CF] = 0x0080, /* R2511 - DSP3RMIX Input 4 Volume */
- [0x09D0] = 0x0000, /* R2512 - DSP3AUX1MIX Input 1 Source */
- [0x09D8] = 0x0000, /* R2520 - DSP3AUX2MIX Input 1 Source */
- [0x09E0] = 0x0000, /* R2528 - DSP3AUX3MIX Input 1 Source */
- [0x09E8] = 0x0000, /* R2536 - DSP3AUX4MIX Input 1 Source */
- [0x09F0] = 0x0000, /* R2544 - DSP3AUX5MIX Input 1 Source */
- [0x09F8] = 0x0000, /* R2552 - DSP3AUX6MIX Input 1 Source */
- [0x0A80] = 0x0000, /* R2688 - ASRC1LMIX Input 1 Source */
- [0x0A88] = 0x0000, /* R2696 - ASRC1RMIX Input 1 Source */
- [0x0A90] = 0x0000, /* R2704 - ASRC2LMIX Input 1 Source */
- [0x0A98] = 0x0000, /* R2712 - ASRC2RMIX Input 1 Source */
- [0x0B00] = 0x0000, /* R2816 - ISRC1DEC1MIX Input 1 Source */
- [0x0B08] = 0x0000, /* R2824 - ISRC1DEC2MIX Input 1 Source */
- [0x0B10] = 0x0000, /* R2832 - ISRC1DEC3MIX Input 1 Source */
- [0x0B18] = 0x0000, /* R2840 - ISRC1DEC4MIX Input 1 Source */
- [0x0B20] = 0x0000, /* R2848 - ISRC1INT1MIX Input 1 Source */
- [0x0B28] = 0x0000, /* R2856 - ISRC1INT2MIX Input 1 Source */
- [0x0B30] = 0x0000, /* R2864 - ISRC1INT3MIX Input 1 Source */
- [0x0B38] = 0x0000, /* R2872 - ISRC1INT4MIX Input 1 Source */
- [0x0B40] = 0x0000, /* R2880 - ISRC2DEC1MIX Input 1 Source */
- [0x0B48] = 0x0000, /* R2888 - ISRC2DEC2MIX Input 1 Source */
- [0x0B50] = 0x0000, /* R2896 - ISRC2DEC3MIX Input 1 Source */
- [0x0B58] = 0x0000, /* R2904 - ISRC2DEC4MIX Input 1 Source */
- [0x0B60] = 0x0000, /* R2912 - ISRC2INT1MIX Input 1 Source */
- [0x0B68] = 0x0000, /* R2920 - ISRC2INT2MIX Input 1 Source */
- [0x0B70] = 0x0000, /* R2928 - ISRC2INT3MIX Input 1 Source */
- [0x0B78] = 0x0000, /* R2936 - ISRC2INT4MIX Input 1 Source */
- [0x0C00] = 0xA001, /* R3072 - GPIO CTRL 1 */
- [0x0C01] = 0xA001, /* R3073 - GPIO CTRL 2 */
- [0x0C02] = 0xA001, /* R3074 - GPIO CTRL 3 */
- [0x0C03] = 0xA001, /* R3075 - GPIO CTRL 4 */
- [0x0C04] = 0xA001, /* R3076 - GPIO CTRL 5 */
- [0x0C05] = 0xA001, /* R3077 - GPIO CTRL 6 */
- [0x0C23] = 0x4003, /* R3107 - Misc Pad Ctrl 1 */
- [0x0C24] = 0x0000, /* R3108 - Misc Pad Ctrl 2 */
- [0x0C25] = 0x0000, /* R3109 - Misc Pad Ctrl 3 */
- [0x0C26] = 0x0000, /* R3110 - Misc Pad Ctrl 4 */
- [0x0C27] = 0x0000, /* R3111 - Misc Pad Ctrl 5 */
- [0x0C28] = 0x0000, /* R3112 - Misc GPIO 1 */
- [0x0D00] = 0x0000, /* R3328 - Interrupt Status 1 */
- [0x0D01] = 0x0000, /* R3329 - Interrupt Status 2 */
- [0x0D02] = 0x0000, /* R3330 - Interrupt Status 3 */
- [0x0D03] = 0x0000, /* R3331 - Interrupt Status 4 */
- [0x0D04] = 0x0000, /* R3332 - Interrupt Raw Status 2 */
- [0x0D05] = 0x0000, /* R3333 - Interrupt Raw Status 3 */
- [0x0D06] = 0x0000, /* R3334 - Interrupt Raw Status 4 */
- [0x0D07] = 0xFFFF, /* R3335 - Interrupt Status 1 Mask */
- [0x0D08] = 0xFFFF, /* R3336 - Interrupt Status 2 Mask */
- [0x0D09] = 0xFFFF, /* R3337 - Interrupt Status 3 Mask */
- [0x0D0A] = 0xFFFF, /* R3338 - Interrupt Status 4 Mask */
- [0x0D1F] = 0x0000, /* R3359 - Interrupt Control */
- [0x0D20] = 0xFFFF, /* R3360 - IRQ Debounce 1 */
- [0x0D21] = 0xFFFF, /* R3361 - IRQ Debounce 2 */
- [0x0E00] = 0x0000, /* R3584 - FX_Ctrl */
- [0x0E10] = 0x6318, /* R3600 - EQ1_1 */
- [0x0E11] = 0x6300, /* R3601 - EQ1_2 */
- [0x0E12] = 0x0FC8, /* R3602 - EQ1_3 */
- [0x0E13] = 0x03FE, /* R3603 - EQ1_4 */
- [0x0E14] = 0x00E0, /* R3604 - EQ1_5 */
- [0x0E15] = 0x1EC4, /* R3605 - EQ1_6 */
- [0x0E16] = 0xF136, /* R3606 - EQ1_7 */
- [0x0E17] = 0x0409, /* R3607 - EQ1_8 */
- [0x0E18] = 0x04CC, /* R3608 - EQ1_9 */
- [0x0E19] = 0x1C9B, /* R3609 - EQ1_10 */
- [0x0E1A] = 0xF337, /* R3610 - EQ1_11 */
- [0x0E1B] = 0x040B, /* R3611 - EQ1_12 */
- [0x0E1C] = 0x0CBB, /* R3612 - EQ1_13 */
- [0x0E1D] = 0x16F8, /* R3613 - EQ1_14 */
- [0x0E1E] = 0xF7D9, /* R3614 - EQ1_15 */
- [0x0E1F] = 0x040A, /* R3615 - EQ1_16 */
- [0x0E20] = 0x1F14, /* R3616 - EQ1_17 */
- [0x0E21] = 0x058C, /* R3617 - EQ1_18 */
- [0x0E22] = 0x0563, /* R3618 - EQ1_19 */
- [0x0E23] = 0x4000, /* R3619 - EQ1_20 */
- [0x0E26] = 0x6318, /* R3622 - EQ2_1 */
- [0x0E27] = 0x6300, /* R3623 - EQ2_2 */
- [0x0E28] = 0x0FC8, /* R3624 - EQ2_3 */
- [0x0E29] = 0x03FE, /* R3625 - EQ2_4 */
- [0x0E2A] = 0x00E0, /* R3626 - EQ2_5 */
- [0x0E2B] = 0x1EC4, /* R3627 - EQ2_6 */
- [0x0E2C] = 0xF136, /* R3628 - EQ2_7 */
- [0x0E2D] = 0x0409, /* R3629 - EQ2_8 */
- [0x0E2E] = 0x04CC, /* R3630 - EQ2_9 */
- [0x0E2F] = 0x1C9B, /* R3631 - EQ2_10 */
- [0x0E30] = 0xF337, /* R3632 - EQ2_11 */
- [0x0E31] = 0x040B, /* R3633 - EQ2_12 */
- [0x0E32] = 0x0CBB, /* R3634 - EQ2_13 */
- [0x0E33] = 0x16F8, /* R3635 - EQ2_14 */
- [0x0E34] = 0xF7D9, /* R3636 - EQ2_15 */
- [0x0E35] = 0x040A, /* R3637 - EQ2_16 */
- [0x0E36] = 0x1F14, /* R3638 - EQ2_17 */
- [0x0E37] = 0x058C, /* R3639 - EQ2_18 */
- [0x0E38] = 0x0563, /* R3640 - EQ2_19 */
- [0x0E39] = 0x4000, /* R3641 - EQ2_20 */
- [0x0E3C] = 0x6318, /* R3644 - EQ3_1 */
- [0x0E3D] = 0x6300, /* R3645 - EQ3_2 */
- [0x0E3E] = 0x0FC8, /* R3646 - EQ3_3 */
- [0x0E3F] = 0x03FE, /* R3647 - EQ3_4 */
- [0x0E40] = 0x00E0, /* R3648 - EQ3_5 */
- [0x0E41] = 0x1EC4, /* R3649 - EQ3_6 */
- [0x0E42] = 0xF136, /* R3650 - EQ3_7 */
- [0x0E43] = 0x0409, /* R3651 - EQ3_8 */
- [0x0E44] = 0x04CC, /* R3652 - EQ3_9 */
- [0x0E45] = 0x1C9B, /* R3653 - EQ3_10 */
- [0x0E46] = 0xF337, /* R3654 - EQ3_11 */
- [0x0E47] = 0x040B, /* R3655 - EQ3_12 */
- [0x0E48] = 0x0CBB, /* R3656 - EQ3_13 */
- [0x0E49] = 0x16F8, /* R3657 - EQ3_14 */
- [0x0E4A] = 0xF7D9, /* R3658 - EQ3_15 */
- [0x0E4B] = 0x040A, /* R3659 - EQ3_16 */
- [0x0E4C] = 0x1F14, /* R3660 - EQ3_17 */
- [0x0E4D] = 0x058C, /* R3661 - EQ3_18 */
- [0x0E4E] = 0x0563, /* R3662 - EQ3_19 */
- [0x0E4F] = 0x4000, /* R3663 - EQ3_20 */
- [0x0E52] = 0x6318, /* R3666 - EQ4_1 */
- [0x0E53] = 0x6300, /* R3667 - EQ4_2 */
- [0x0E54] = 0x0FC8, /* R3668 - EQ4_3 */
- [0x0E55] = 0x03FE, /* R3669 - EQ4_4 */
- [0x0E56] = 0x00E0, /* R3670 - EQ4_5 */
- [0x0E57] = 0x1EC4, /* R3671 - EQ4_6 */
- [0x0E58] = 0xF136, /* R3672 - EQ4_7 */
- [0x0E59] = 0x0409, /* R3673 - EQ4_8 */
- [0x0E5A] = 0x04CC, /* R3674 - EQ4_9 */
- [0x0E5B] = 0x1C9B, /* R3675 - EQ4_10 */
- [0x0E5C] = 0xF337, /* R3676 - EQ4_11 */
- [0x0E5D] = 0x040B, /* R3677 - EQ4_12 */
- [0x0E5E] = 0x0CBB, /* R3678 - EQ4_13 */
- [0x0E5F] = 0x16F8, /* R3679 - EQ4_14 */
- [0x0E60] = 0xF7D9, /* R3680 - EQ4_15 */
- [0x0E61] = 0x040A, /* R3681 - EQ4_16 */
- [0x0E62] = 0x1F14, /* R3682 - EQ4_17 */
- [0x0E63] = 0x058C, /* R3683 - EQ4_18 */
- [0x0E64] = 0x0563, /* R3684 - EQ4_19 */
- [0x0E65] = 0x4000, /* R3685 - EQ4_20 */
- [0x0E80] = 0x0018, /* R3712 - DRC1 ctrl1 */
- [0x0E81] = 0x0933, /* R3713 - DRC1 ctrl2 */
- [0x0E82] = 0x0018, /* R3714 - DRC1 ctrl3 */
- [0x0E83] = 0x0000, /* R3715 - DRC1 ctrl4 */
- [0x0E84] = 0x0000, /* R3716 - DRC1 ctrl5 */
- [0x0EC0] = 0x0000, /* R3776 - HPLPF1_1 */
- [0x0EC1] = 0x0000, /* R3777 - HPLPF1_2 */
- [0x0EC4] = 0x0000, /* R3780 - HPLPF2_1 */
- [0x0EC5] = 0x0000, /* R3781 - HPLPF2_2 */
- [0x0EC8] = 0x0000, /* R3784 - HPLPF3_1 */
- [0x0EC9] = 0x0000, /* R3785 - HPLPF3_2 */
- [0x0ECC] = 0x0000, /* R3788 - HPLPF4_1 */
- [0x0ECD] = 0x0000, /* R3789 - HPLPF4_2 */
- [0x4000] = 0x0000, /* R16384 - DSP1 DM 0 */
- [0x4001] = 0x0000, /* R16385 - DSP1 DM 1 */
- [0x4002] = 0x0000, /* R16386 - DSP1 DM 2 */
- [0x4003] = 0x0000, /* R16387 - DSP1 DM 3 */
- [0x41FC] = 0x0000, /* R16892 - DSP1 DM 508 */
- [0x41FD] = 0x0000, /* R16893 - DSP1 DM 509 */
- [0x41FE] = 0x0000, /* R16894 - DSP1 DM 510 */
- [0x41FF] = 0x0000, /* R16895 - DSP1 DM 511 */
- [0x4800] = 0x0000, /* R18432 - DSP1 PM 0 */
- [0x4801] = 0x0000, /* R18433 - DSP1 PM 1 */
- [0x4802] = 0x0000, /* R18434 - DSP1 PM 2 */
- [0x4803] = 0x0000, /* R18435 - DSP1 PM 3 */
- [0x4804] = 0x0000, /* R18436 - DSP1 PM 4 */
- [0x4805] = 0x0000, /* R18437 - DSP1 PM 5 */
- [0x4DFA] = 0x0000, /* R19962 - DSP1 PM 1530 */
- [0x4DFB] = 0x0000, /* R19963 - DSP1 PM 1531 */
- [0x4DFC] = 0x0000, /* R19964 - DSP1 PM 1532 */
- [0x4DFD] = 0x0000, /* R19965 - DSP1 PM 1533 */
- [0x4DFE] = 0x0000, /* R19966 - DSP1 PM 1534 */
- [0x4DFF] = 0x0000, /* R19967 - DSP1 PM 1535 */
- [0x5000] = 0x0000, /* R20480 - DSP1 ZM 0 */
- [0x5001] = 0x0000, /* R20481 - DSP1 ZM 1 */
- [0x5002] = 0x0000, /* R20482 - DSP1 ZM 2 */
- [0x5003] = 0x0000, /* R20483 - DSP1 ZM 3 */
- [0x57FC] = 0x0000, /* R22524 - DSP1 ZM 2044 */
- [0x57FD] = 0x0000, /* R22525 - DSP1 ZM 2045 */
- [0x57FE] = 0x0000, /* R22526 - DSP1 ZM 2046 */
- [0x57FF] = 0x0000, /* R22527 - DSP1 ZM 2047 */
- [0x6000] = 0x0000, /* R24576 - DSP2 DM 0 */
- [0x6001] = 0x0000, /* R24577 - DSP2 DM 1 */
- [0x6002] = 0x0000, /* R24578 - DSP2 DM 2 */
- [0x6003] = 0x0000, /* R24579 - DSP2 DM 3 */
- [0x61FC] = 0x0000, /* R25084 - DSP2 DM 508 */
- [0x61FD] = 0x0000, /* R25085 - DSP2 DM 509 */
- [0x61FE] = 0x0000, /* R25086 - DSP2 DM 510 */
- [0x61FF] = 0x0000, /* R25087 - DSP2 DM 511 */
- [0x6800] = 0x0000, /* R26624 - DSP2 PM 0 */
- [0x6801] = 0x0000, /* R26625 - DSP2 PM 1 */
- [0x6802] = 0x0000, /* R26626 - DSP2 PM 2 */
- [0x6803] = 0x0000, /* R26627 - DSP2 PM 3 */
- [0x6804] = 0x0000, /* R26628 - DSP2 PM 4 */
- [0x6805] = 0x0000, /* R26629 - DSP2 PM 5 */
- [0x6DFA] = 0x0000, /* R28154 - DSP2 PM 1530 */
- [0x6DFB] = 0x0000, /* R28155 - DSP2 PM 1531 */
- [0x6DFC] = 0x0000, /* R28156 - DSP2 PM 1532 */
- [0x6DFD] = 0x0000, /* R28157 - DSP2 PM 1533 */
- [0x6DFE] = 0x0000, /* R28158 - DSP2 PM 1534 */
- [0x6DFF] = 0x0000, /* R28159 - DSP2 PM 1535 */
- [0x7000] = 0x0000, /* R28672 - DSP2 ZM 0 */
- [0x7001] = 0x0000, /* R28673 - DSP2 ZM 1 */
- [0x7002] = 0x0000, /* R28674 - DSP2 ZM 2 */
- [0x7003] = 0x0000, /* R28675 - DSP2 ZM 3 */
- [0x77FC] = 0x0000, /* R30716 - DSP2 ZM 2044 */
- [0x77FD] = 0x0000, /* R30717 - DSP2 ZM 2045 */
- [0x77FE] = 0x0000, /* R30718 - DSP2 ZM 2046 */
- [0x77FF] = 0x0000, /* R30719 - DSP2 ZM 2047 */
- [0x8000] = 0x0000, /* R32768 - DSP3 DM 0 */
- [0x8001] = 0x0000, /* R32769 - DSP3 DM 1 */
- [0x8002] = 0x0000, /* R32770 - DSP3 DM 2 */
- [0x8003] = 0x0000, /* R32771 - DSP3 DM 3 */
- [0x81FC] = 0x0000, /* R33276 - DSP3 DM 508 */
- [0x81FD] = 0x0000, /* R33277 - DSP3 DM 509 */
- [0x81FE] = 0x0000, /* R33278 - DSP3 DM 510 */
- [0x81FF] = 0x0000, /* R33279 - DSP3 DM 511 */
- [0x8800] = 0x0000, /* R34816 - DSP3 PM 0 */
- [0x8801] = 0x0000, /* R34817 - DSP3 PM 1 */
- [0x8802] = 0x0000, /* R34818 - DSP3 PM 2 */
- [0x8803] = 0x0000, /* R34819 - DSP3 PM 3 */
- [0x8804] = 0x0000, /* R34820 - DSP3 PM 4 */
- [0x8805] = 0x0000, /* R34821 - DSP3 PM 5 */
- [0x8DFA] = 0x0000, /* R36346 - DSP3 PM 1530 */
- [0x8DFB] = 0x0000, /* R36347 - DSP3 PM 1531 */
- [0x8DFC] = 0x0000, /* R36348 - DSP3 PM 1532 */
- [0x8DFD] = 0x0000, /* R36349 - DSP3 PM 1533 */
- [0x8DFE] = 0x0000, /* R36350 - DSP3 PM 1534 */
- [0x8DFF] = 0x0000, /* R36351 - DSP3 PM 1535 */
- [0x9000] = 0x0000, /* R36864 - DSP3 ZM 0 */
- [0x9001] = 0x0000, /* R36865 - DSP3 ZM 1 */
- [0x9002] = 0x0000, /* R36866 - DSP3 ZM 2 */
- [0x9003] = 0x0000, /* R36867 - DSP3 ZM 3 */
- [0x97FC] = 0x0000, /* R38908 - DSP3 ZM 2044 */
- [0x97FD] = 0x0000, /* R38909 - DSP3 ZM 2045 */
- [0x97FE] = 0x0000, /* R38910 - DSP3 ZM 2046 */
- [0x97FF] = 0x0000 /* R38911 - DSP3 ZM 2047 */
+struct reg_default wm5100_reg_defaults[WM5100_REGISTER_COUNT] = {
+ { 0x0000, 0x0000 }, /* R0 - software reset */
+ { 0x0001, 0x0000 }, /* R1 - Device Revision */
+ { 0x0010, 0x0801 }, /* R16 - Ctrl IF 1 */
+ { 0x0020, 0x0000 }, /* R32 - Tone Generator 1 */
+ { 0x0030, 0x0000 }, /* R48 - PWM Drive 1 */
+ { 0x0031, 0x0100 }, /* R49 - PWM Drive 2 */
+ { 0x0032, 0x0100 }, /* R50 - PWM Drive 3 */
+ { 0x0100, 0x0002 }, /* R256 - Clocking 1 */
+ { 0x0101, 0x0000 }, /* R257 - Clocking 3 */
+ { 0x0102, 0x0011 }, /* R258 - Clocking 4 */
+ { 0x0103, 0x0011 }, /* R259 - Clocking 5 */
+ { 0x0104, 0x0011 }, /* R260 - Clocking 6 */
+ { 0x0107, 0x0000 }, /* R263 - Clocking 7 */
+ { 0x0108, 0x0000 }, /* R264 - Clocking 8 */
+ { 0x0120, 0x0000 }, /* R288 - ASRC_ENABLE */
+ { 0x0121, 0x0000 }, /* R289 - ASRC_STATUS */
+ { 0x0122, 0x0000 }, /* R290 - ASRC_RATE1 */
+ { 0x0141, 0x8000 }, /* R321 - ISRC 1 CTRL 1 */
+ { 0x0142, 0x0000 }, /* R322 - ISRC 1 CTRL 2 */
+ { 0x0143, 0x8000 }, /* R323 - ISRC 2 CTRL1 */
+ { 0x0144, 0x0000 }, /* R324 - ISRC 2 CTRL 2 */
+ { 0x0182, 0x0000 }, /* R386 - FLL1 Control 1 */
+ { 0x0183, 0x0000 }, /* R387 - FLL1 Control 2 */
+ { 0x0184, 0x0000 }, /* R388 - FLL1 Control 3 */
+ { 0x0186, 0x0177 }, /* R390 - FLL1 Control 5 */
+ { 0x0187, 0x0001 }, /* R391 - FLL1 Control 6 */
+ { 0x0188, 0x0000 }, /* R392 - FLL1 EFS 1 */
+ { 0x01A2, 0x0000 }, /* R418 - FLL2 Control 1 */
+ { 0x01A3, 0x0000 }, /* R419 - FLL2 Control 2 */
+ { 0x01A4, 0x0000 }, /* R420 - FLL2 Control 3 */
+ { 0x01A6, 0x0177 }, /* R422 - FLL2 Control 5 */
+ { 0x01A7, 0x0001 }, /* R423 - FLL2 Control 6 */
+ { 0x01A8, 0x0000 }, /* R424 - FLL2 EFS 1 */
+ { 0x0200, 0x0020 }, /* R512 - Mic Charge Pump 1 */
+ { 0x0201, 0xB084 }, /* R513 - Mic Charge Pump 2 */
+ { 0x0202, 0xBBDE }, /* R514 - HP Charge Pump 1 */
+ { 0x0211, 0x20D4 }, /* R529 - LDO1 Control */
+ { 0x0215, 0x0062 }, /* R533 - Mic Bias Ctrl 1 */
+ { 0x0216, 0x0062 }, /* R534 - Mic Bias Ctrl 2 */
+ { 0x0217, 0x0062 }, /* R535 - Mic Bias Ctrl 3 */
+ { 0x0280, 0x0004 }, /* R640 - Accessory Detect Mode 1 */
+ { 0x0288, 0x0020 }, /* R648 - Headphone Detect 1 */
+ { 0x0289, 0x0000 }, /* R649 - Headphone Detect 2 */
+ { 0x0290, 0x1100 }, /* R656 - Mic Detect 1 */
+ { 0x0291, 0x009F }, /* R657 - Mic Detect 2 */
+ { 0x0292, 0x0000 }, /* R658 - Mic Detect 3 */
+ { 0x0301, 0x0000 }, /* R769 - Input Enables */
+ { 0x0302, 0x0000 }, /* R770 - Input Enables Status */
+ { 0x0310, 0x2280 }, /* R784 - Status */
+ { 0x0311, 0x0080 }, /* R785 - IN1R Control */
+ { 0x0312, 0x2280 }, /* R786 - IN2L Control */
+ { 0x0313, 0x0080 }, /* R787 - IN2R Control */
+ { 0x0314, 0x2280 }, /* R788 - IN3L Control */
+ { 0x0315, 0x0080 }, /* R789 - IN3R Control */
+ { 0x0316, 0x2280 }, /* R790 - IN4L Control */
+ { 0x0317, 0x0080 }, /* R791 - IN4R Control */
+ { 0x0318, 0x0000 }, /* R792 - RXANC_SRC */
+ { 0x0319, 0x0022 }, /* R793 - Input Volume Ramp */
+ { 0x0320, 0x0180 }, /* R800 - ADC Digital Volume 1L */
+ { 0x0321, 0x0180 }, /* R801 - ADC Digital Volume 1R */
+ { 0x0322, 0x0180 }, /* R802 - ADC Digital Volume 2L */
+ { 0x0323, 0x0180 }, /* R803 - ADC Digital Volume 2R */
+ { 0x0324, 0x0180 }, /* R804 - ADC Digital Volume 3L */
+ { 0x0325, 0x0180 }, /* R805 - ADC Digital Volume 3R */
+ { 0x0326, 0x0180 }, /* R806 - ADC Digital Volume 4L */
+ { 0x0327, 0x0180 }, /* R807 - ADC Digital Volume 4R */
+ { 0x0401, 0x0000 }, /* R1025 - Output Enables 2 */
+ { 0x0402, 0x0000 }, /* R1026 - Output Status 1 */
+ { 0x0403, 0x0000 }, /* R1027 - Output Status 2 */
+ { 0x0408, 0x0000 }, /* R1032 - Channel Enables 1 */
+ { 0x0410, 0x0080 }, /* R1040 - Out Volume 1L */
+ { 0x0411, 0x0080 }, /* R1041 - Out Volume 1R */
+ { 0x0412, 0x0080 }, /* R1042 - DAC Volume Limit 1L */
+ { 0x0413, 0x0080 }, /* R1043 - DAC Volume Limit 1R */
+ { 0x0414, 0x0080 }, /* R1044 - Out Volume 2L */
+ { 0x0415, 0x0080 }, /* R1045 - Out Volume 2R */
+ { 0x0416, 0x0080 }, /* R1046 - DAC Volume Limit 2L */
+ { 0x0417, 0x0080 }, /* R1047 - DAC Volume Limit 2R */
+ { 0x0418, 0x0080 }, /* R1048 - Out Volume 3L */
+ { 0x0419, 0x0080 }, /* R1049 - Out Volume 3R */
+ { 0x041A, 0x0080 }, /* R1050 - DAC Volume Limit 3L */
+ { 0x041B, 0x0080 }, /* R1051 - DAC Volume Limit 3R */
+ { 0x041C, 0x0080 }, /* R1052 - Out Volume 4L */
+ { 0x041D, 0x0080 }, /* R1053 - Out Volume 4R */
+ { 0x041E, 0x0080 }, /* R1054 - DAC Volume Limit 5L */
+ { 0x041F, 0x0080 }, /* R1055 - DAC Volume Limit 5R */
+ { 0x0420, 0x0080 }, /* R1056 - DAC Volume Limit 6L */
+ { 0x0421, 0x0080 }, /* R1057 - DAC Volume Limit 6R */
+ { 0x0440, 0x0000 }, /* R1088 - DAC AEC Control 1 */
+ { 0x0441, 0x0022 }, /* R1089 - Output Volume Ramp */
+ { 0x0480, 0x0180 }, /* R1152 - DAC Digital Volume 1L */
+ { 0x0481, 0x0180 }, /* R1153 - DAC Digital Volume 1R */
+ { 0x0482, 0x0180 }, /* R1154 - DAC Digital Volume 2L */
+ { 0x0483, 0x0180 }, /* R1155 - DAC Digital Volume 2R */
+ { 0x0484, 0x0180 }, /* R1156 - DAC Digital Volume 3L */
+ { 0x0485, 0x0180 }, /* R1157 - DAC Digital Volume 3R */
+ { 0x0486, 0x0180 }, /* R1158 - DAC Digital Volume 4L */
+ { 0x0487, 0x0180 }, /* R1159 - DAC Digital Volume 4R */
+ { 0x0488, 0x0180 }, /* R1160 - DAC Digital Volume 5L */
+ { 0x0489, 0x0180 }, /* R1161 - DAC Digital Volume 5R */
+ { 0x048A, 0x0180 }, /* R1162 - DAC Digital Volume 6L */
+ { 0x048B, 0x0180 }, /* R1163 - DAC Digital Volume 6R */
+ { 0x04C0, 0x0069 }, /* R1216 - PDM SPK1 CTRL 1 */
+ { 0x04C1, 0x0000 }, /* R1217 - PDM SPK1 CTRL 2 */
+ { 0x04C2, 0x0069 }, /* R1218 - PDM SPK2 CTRL 1 */
+ { 0x04C3, 0x0000 }, /* R1219 - PDM SPK2 CTRL 2 */
+ { 0x0500, 0x000C }, /* R1280 - Audio IF 1_1 */
+ { 0x0501, 0x0008 }, /* R1281 - Audio IF 1_2 */
+ { 0x0502, 0x0000 }, /* R1282 - Audio IF 1_3 */
+ { 0x0503, 0x0000 }, /* R1283 - Audio IF 1_4 */
+ { 0x0504, 0x0000 }, /* R1284 - Audio IF 1_5 */
+ { 0x0505, 0x0300 }, /* R1285 - Audio IF 1_6 */
+ { 0x0506, 0x0300 }, /* R1286 - Audio IF 1_7 */
+ { 0x0507, 0x1820 }, /* R1287 - Audio IF 1_8 */
+ { 0x0508, 0x1820 }, /* R1288 - Audio IF 1_9 */
+ { 0x0509, 0x0000 }, /* R1289 - Audio IF 1_10 */
+ { 0x050A, 0x0001 }, /* R1290 - Audio IF 1_11 */
+ { 0x050B, 0x0002 }, /* R1291 - Audio IF 1_12 */
+ { 0x050C, 0x0003 }, /* R1292 - Audio IF 1_13 */
+ { 0x050D, 0x0004 }, /* R1293 - Audio IF 1_14 */
+ { 0x050E, 0x0005 }, /* R1294 - Audio IF 1_15 */
+ { 0x050F, 0x0006 }, /* R1295 - Audio IF 1_16 */
+ { 0x0510, 0x0007 }, /* R1296 - Audio IF 1_17 */
+ { 0x0511, 0x0000 }, /* R1297 - Audio IF 1_18 */
+ { 0x0512, 0x0001 }, /* R1298 - Audio IF 1_19 */
+ { 0x0513, 0x0002 }, /* R1299 - Audio IF 1_20 */
+ { 0x0514, 0x0003 }, /* R1300 - Audio IF 1_21 */
+ { 0x0515, 0x0004 }, /* R1301 - Audio IF 1_22 */
+ { 0x0516, 0x0005 }, /* R1302 - Audio IF 1_23 */
+ { 0x0517, 0x0006 }, /* R1303 - Audio IF 1_24 */
+ { 0x0518, 0x0007 }, /* R1304 - Audio IF 1_25 */
+ { 0x0519, 0x0000 }, /* R1305 - Audio IF 1_26 */
+ { 0x051A, 0x0000 }, /* R1306 - Audio IF 1_27 */
+ { 0x0540, 0x000C }, /* R1344 - Audio IF 2_1 */
+ { 0x0541, 0x0008 }, /* R1345 - Audio IF 2_2 */
+ { 0x0542, 0x0000 }, /* R1346 - Audio IF 2_3 */
+ { 0x0543, 0x0000 }, /* R1347 - Audio IF 2_4 */
+ { 0x0544, 0x0000 }, /* R1348 - Audio IF 2_5 */
+ { 0x0545, 0x0300 }, /* R1349 - Audio IF 2_6 */
+ { 0x0546, 0x0300 }, /* R1350 - Audio IF 2_7 */
+ { 0x0547, 0x1820 }, /* R1351 - Audio IF 2_8 */
+ { 0x0548, 0x1820 }, /* R1352 - Audio IF 2_9 */
+ { 0x0549, 0x0000 }, /* R1353 - Audio IF 2_10 */
+ { 0x054A, 0x0001 }, /* R1354 - Audio IF 2_11 */
+ { 0x0551, 0x0000 }, /* R1361 - Audio IF 2_18 */
+ { 0x0552, 0x0001 }, /* R1362 - Audio IF 2_19 */
+ { 0x0559, 0x0000 }, /* R1369 - Audio IF 2_26 */
+ { 0x055A, 0x0000 }, /* R1370 - Audio IF 2_27 */
+ { 0x0580, 0x000C }, /* R1408 - Audio IF 3_1 */
+ { 0x0581, 0x0008 }, /* R1409 - Audio IF 3_2 */
+ { 0x0582, 0x0000 }, /* R1410 - Audio IF 3_3 */
+ { 0x0583, 0x0000 }, /* R1411 - Audio IF 3_4 */
+ { 0x0584, 0x0000 }, /* R1412 - Audio IF 3_5 */
+ { 0x0585, 0x0300 }, /* R1413 - Audio IF 3_6 */
+ { 0x0586, 0x0300 }, /* R1414 - Audio IF 3_7 */
+ { 0x0587, 0x1820 }, /* R1415 - Audio IF 3_8 */
+ { 0x0588, 0x1820 }, /* R1416 - Audio IF 3_9 */
+ { 0x0589, 0x0000 }, /* R1417 - Audio IF 3_10 */
+ { 0x058A, 0x0001 }, /* R1418 - Audio IF 3_11 */
+ { 0x0591, 0x0000 }, /* R1425 - Audio IF 3_18 */
+ { 0x0592, 0x0001 }, /* R1426 - Audio IF 3_19 */
+ { 0x0599, 0x0000 }, /* R1433 - Audio IF 3_26 */
+ { 0x059A, 0x0000 }, /* R1434 - Audio IF 3_27 */
+ { 0x0640, 0x0000 }, /* R1600 - PWM1MIX Input 1 Source */
+ { 0x0641, 0x0080 }, /* R1601 - PWM1MIX Input 1 Volume */
+ { 0x0642, 0x0000 }, /* R1602 - PWM1MIX Input 2 Source */
+ { 0x0643, 0x0080 }, /* R1603 - PWM1MIX Input 2 Volume */
+ { 0x0644, 0x0000 }, /* R1604 - PWM1MIX Input 3 Source */
+ { 0x0645, 0x0080 }, /* R1605 - PWM1MIX Input 3 Volume */
+ { 0x0646, 0x0000 }, /* R1606 - PWM1MIX Input 4 Source */
+ { 0x0647, 0x0080 }, /* R1607 - PWM1MIX Input 4 Volume */
+ { 0x0648, 0x0000 }, /* R1608 - PWM2MIX Input 1 Source */
+ { 0x0649, 0x0080 }, /* R1609 - PWM2MIX Input 1 Volume */
+ { 0x064A, 0x0000 }, /* R1610 - PWM2MIX Input 2 Source */
+ { 0x064B, 0x0080 }, /* R1611 - PWM2MIX Input 2 Volume */
+ { 0x064C, 0x0000 }, /* R1612 - PWM2MIX Input 3 Source */
+ { 0x064D, 0x0080 }, /* R1613 - PWM2MIX Input 3 Volume */
+ { 0x064E, 0x0000 }, /* R1614 - PWM2MIX Input 4 Source */
+ { 0x064F, 0x0080 }, /* R1615 - PWM2MIX Input 4 Volume */
+ { 0x0680, 0x0000 }, /* R1664 - OUT1LMIX Input 1 Source */
+ { 0x0681, 0x0080 }, /* R1665 - OUT1LMIX Input 1 Volume */
+ { 0x0682, 0x0000 }, /* R1666 - OUT1LMIX Input 2 Source */
+ { 0x0683, 0x0080 }, /* R1667 - OUT1LMIX Input 2 Volume */
+ { 0x0684, 0x0000 }, /* R1668 - OUT1LMIX Input 3 Source */
+ { 0x0685, 0x0080 }, /* R1669 - OUT1LMIX Input 3 Volume */
+ { 0x0686, 0x0000 }, /* R1670 - OUT1LMIX Input 4 Source */
+ { 0x0687, 0x0080 }, /* R1671 - OUT1LMIX Input 4 Volume */
+ { 0x0688, 0x0000 }, /* R1672 - OUT1RMIX Input 1 Source */
+ { 0x0689, 0x0080 }, /* R1673 - OUT1RMIX Input 1 Volume */
+ { 0x068A, 0x0000 }, /* R1674 - OUT1RMIX Input 2 Source */
+ { 0x068B, 0x0080 }, /* R1675 - OUT1RMIX Input 2 Volume */
+ { 0x068C, 0x0000 }, /* R1676 - OUT1RMIX Input 3 Source */
+ { 0x068D, 0x0080 }, /* R1677 - OUT1RMIX Input 3 Volume */
+ { 0x068E, 0x0000 }, /* R1678 - OUT1RMIX Input 4 Source */
+ { 0x068F, 0x0080 }, /* R1679 - OUT1RMIX Input 4 Volume */
+ { 0x0690, 0x0000 }, /* R1680 - OUT2LMIX Input 1 Source */
+ { 0x0691, 0x0080 }, /* R1681 - OUT2LMIX Input 1 Volume */
+ { 0x0692, 0x0000 }, /* R1682 - OUT2LMIX Input 2 Source */
+ { 0x0693, 0x0080 }, /* R1683 - OUT2LMIX Input 2 Volume */
+ { 0x0694, 0x0000 }, /* R1684 - OUT2LMIX Input 3 Source */
+ { 0x0695, 0x0080 }, /* R1685 - OUT2LMIX Input 3 Volume */
+ { 0x0696, 0x0000 }, /* R1686 - OUT2LMIX Input 4 Source */
+ { 0x0697, 0x0080 }, /* R1687 - OUT2LMIX Input 4 Volume */
+ { 0x0698, 0x0000 }, /* R1688 - OUT2RMIX Input 1 Source */
+ { 0x0699, 0x0080 }, /* R1689 - OUT2RMIX Input 1 Volume */
+ { 0x069A, 0x0000 }, /* R1690 - OUT2RMIX Input 2 Source */
+ { 0x069B, 0x0080 }, /* R1691 - OUT2RMIX Input 2 Volume */
+ { 0x069C, 0x0000 }, /* R1692 - OUT2RMIX Input 3 Source */
+ { 0x069D, 0x0080 }, /* R1693 - OUT2RMIX Input 3 Volume */
+ { 0x069E, 0x0000 }, /* R1694 - OUT2RMIX Input 4 Source */
+ { 0x069F, 0x0080 }, /* R1695 - OUT2RMIX Input 4 Volume */
+ { 0x06A0, 0x0000 }, /* R1696 - OUT3LMIX Input 1 Source */
+ { 0x06A1, 0x0080 }, /* R1697 - OUT3LMIX Input 1 Volume */
+ { 0x06A2, 0x0000 }, /* R1698 - OUT3LMIX Input 2 Source */
+ { 0x06A3, 0x0080 }, /* R1699 - OUT3LMIX Input 2 Volume */
+ { 0x06A4, 0x0000 }, /* R1700 - OUT3LMIX Input 3 Source */
+ { 0x06A5, 0x0080 }, /* R1701 - OUT3LMIX Input 3 Volume */
+ { 0x06A6, 0x0000 }, /* R1702 - OUT3LMIX Input 4 Source */
+ { 0x06A7, 0x0080 }, /* R1703 - OUT3LMIX Input 4 Volume */
+ { 0x06A8, 0x0000 }, /* R1704 - OUT3RMIX Input 1 Source */
+ { 0x06A9, 0x0080 }, /* R1705 - OUT3RMIX Input 1 Volume */
+ { 0x06AA, 0x0000 }, /* R1706 - OUT3RMIX Input 2 Source */
+ { 0x06AB, 0x0080 }, /* R1707 - OUT3RMIX Input 2 Volume */
+ { 0x06AC, 0x0000 }, /* R1708 - OUT3RMIX Input 3 Source */
+ { 0x06AD, 0x0080 }, /* R1709 - OUT3RMIX Input 3 Volume */
+ { 0x06AE, 0x0000 }, /* R1710 - OUT3RMIX Input 4 Source */
+ { 0x06AF, 0x0080 }, /* R1711 - OUT3RMIX Input 4 Volume */
+ { 0x06B0, 0x0000 }, /* R1712 - OUT4LMIX Input 1 Source */
+ { 0x06B1, 0x0080 }, /* R1713 - OUT4LMIX Input 1 Volume */
+ { 0x06B2, 0x0000 }, /* R1714 - OUT4LMIX Input 2 Source */
+ { 0x06B3, 0x0080 }, /* R1715 - OUT4LMIX Input 2 Volume */
+ { 0x06B4, 0x0000 }, /* R1716 - OUT4LMIX Input 3 Source */
+ { 0x06B5, 0x0080 }, /* R1717 - OUT4LMIX Input 3 Volume */
+ { 0x06B6, 0x0000 }, /* R1718 - OUT4LMIX Input 4 Source */
+ { 0x06B7, 0x0080 }, /* R1719 - OUT4LMIX Input 4 Volume */
+ { 0x06B8, 0x0000 }, /* R1720 - OUT4RMIX Input 1 Source */
+ { 0x06B9, 0x0080 }, /* R1721 - OUT4RMIX Input 1 Volume */
+ { 0x06BA, 0x0000 }, /* R1722 - OUT4RMIX Input 2 Source */
+ { 0x06BB, 0x0080 }, /* R1723 - OUT4RMIX Input 2 Volume */
+ { 0x06BC, 0x0000 }, /* R1724 - OUT4RMIX Input 3 Source */
+ { 0x06BD, 0x0080 }, /* R1725 - OUT4RMIX Input 3 Volume */
+ { 0x06BE, 0x0000 }, /* R1726 - OUT4RMIX Input 4 Source */
+ { 0x06BF, 0x0080 }, /* R1727 - OUT4RMIX Input 4 Volume */
+ { 0x06C0, 0x0000 }, /* R1728 - OUT5LMIX Input 1 Source */
+ { 0x06C1, 0x0080 }, /* R1729 - OUT5LMIX Input 1 Volume */
+ { 0x06C2, 0x0000 }, /* R1730 - OUT5LMIX Input 2 Source */
+ { 0x06C3, 0x0080 }, /* R1731 - OUT5LMIX Input 2 Volume */
+ { 0x06C4, 0x0000 }, /* R1732 - OUT5LMIX Input 3 Source */
+ { 0x06C5, 0x0080 }, /* R1733 - OUT5LMIX Input 3 Volume */
+ { 0x06C6, 0x0000 }, /* R1734 - OUT5LMIX Input 4 Source */
+ { 0x06C7, 0x0080 }, /* R1735 - OUT5LMIX Input 4 Volume */
+ { 0x06C8, 0x0000 }, /* R1736 - OUT5RMIX Input 1 Source */
+ { 0x06C9, 0x0080 }, /* R1737 - OUT5RMIX Input 1 Volume */
+ { 0x06CA, 0x0000 }, /* R1738 - OUT5RMIX Input 2 Source */
+ { 0x06CB, 0x0080 }, /* R1739 - OUT5RMIX Input 2 Volume */
+ { 0x06CC, 0x0000 }, /* R1740 - OUT5RMIX Input 3 Source */
+ { 0x06CD, 0x0080 }, /* R1741 - OUT5RMIX Input 3 Volume */
+ { 0x06CE, 0x0000 }, /* R1742 - OUT5RMIX Input 4 Source */
+ { 0x06CF, 0x0080 }, /* R1743 - OUT5RMIX Input 4 Volume */
+ { 0x06D0, 0x0000 }, /* R1744 - OUT6LMIX Input 1 Source */
+ { 0x06D1, 0x0080 }, /* R1745 - OUT6LMIX Input 1 Volume */
+ { 0x06D2, 0x0000 }, /* R1746 - OUT6LMIX Input 2 Source */
+ { 0x06D3, 0x0080 }, /* R1747 - OUT6LMIX Input 2 Volume */
+ { 0x06D4, 0x0000 }, /* R1748 - OUT6LMIX Input 3 Source */
+ { 0x06D5, 0x0080 }, /* R1749 - OUT6LMIX Input 3 Volume */
+ { 0x06D6, 0x0000 }, /* R1750 - OUT6LMIX Input 4 Source */
+ { 0x06D7, 0x0080 }, /* R1751 - OUT6LMIX Input 4 Volume */
+ { 0x06D8, 0x0000 }, /* R1752 - OUT6RMIX Input 1 Source */
+ { 0x06D9, 0x0080 }, /* R1753 - OUT6RMIX Input 1 Volume */
+ { 0x06DA, 0x0000 }, /* R1754 - OUT6RMIX Input 2 Source */
+ { 0x06DB, 0x0080 }, /* R1755 - OUT6RMIX Input 2 Volume */
+ { 0x06DC, 0x0000 }, /* R1756 - OUT6RMIX Input 3 Source */
+ { 0x06DD, 0x0080 }, /* R1757 - OUT6RMIX Input 3 Volume */
+ { 0x06DE, 0x0000 }, /* R1758 - OUT6RMIX Input 4 Source */
+ { 0x06DF, 0x0080 }, /* R1759 - OUT6RMIX Input 4 Volume */
+ { 0x0700, 0x0000 }, /* R1792 - AIF1TX1MIX Input 1 Source */
+ { 0x0701, 0x0080 }, /* R1793 - AIF1TX1MIX Input 1 Volume */
+ { 0x0702, 0x0000 }, /* R1794 - AIF1TX1MIX Input 2 Source */
+ { 0x0703, 0x0080 }, /* R1795 - AIF1TX1MIX Input 2 Volume */
+ { 0x0704, 0x0000 }, /* R1796 - AIF1TX1MIX Input 3 Source */
+ { 0x0705, 0x0080 }, /* R1797 - AIF1TX1MIX Input 3 Volume */
+ { 0x0706, 0x0000 }, /* R1798 - AIF1TX1MIX Input 4 Source */
+ { 0x0707, 0x0080 }, /* R1799 - AIF1TX1MIX Input 4 Volume */
+ { 0x0708, 0x0000 }, /* R1800 - AIF1TX2MIX Input 1 Source */
+ { 0x0709, 0x0080 }, /* R1801 - AIF1TX2MIX Input 1 Volume */
+ { 0x070A, 0x0000 }, /* R1802 - AIF1TX2MIX Input 2 Source */
+ { 0x070B, 0x0080 }, /* R1803 - AIF1TX2MIX Input 2 Volume */
+ { 0x070C, 0x0000 }, /* R1804 - AIF1TX2MIX Input 3 Source */
+ { 0x070D, 0x0080 }, /* R1805 - AIF1TX2MIX Input 3 Volume */
+ { 0x070E, 0x0000 }, /* R1806 - AIF1TX2MIX Input 4 Source */
+ { 0x070F, 0x0080 }, /* R1807 - AIF1TX2MIX Input 4 Volume */
+ { 0x0710, 0x0000 }, /* R1808 - AIF1TX3MIX Input 1 Source */
+ { 0x0711, 0x0080 }, /* R1809 - AIF1TX3MIX Input 1 Volume */
+ { 0x0712, 0x0000 }, /* R1810 - AIF1TX3MIX Input 2 Source */
+ { 0x0713, 0x0080 }, /* R1811 - AIF1TX3MIX Input 2 Volume */
+ { 0x0714, 0x0000 }, /* R1812 - AIF1TX3MIX Input 3 Source */
+ { 0x0715, 0x0080 }, /* R1813 - AIF1TX3MIX Input 3 Volume */
+ { 0x0716, 0x0000 }, /* R1814 - AIF1TX3MIX Input 4 Source */
+ { 0x0717, 0x0080 }, /* R1815 - AIF1TX3MIX Input 4 Volume */
+ { 0x0718, 0x0000 }, /* R1816 - AIF1TX4MIX Input 1 Source */
+ { 0x0719, 0x0080 }, /* R1817 - AIF1TX4MIX Input 1 Volume */
+ { 0x071A, 0x0000 }, /* R1818 - AIF1TX4MIX Input 2 Source */
+ { 0x071B, 0x0080 }, /* R1819 - AIF1TX4MIX Input 2 Volume */
+ { 0x071C, 0x0000 }, /* R1820 - AIF1TX4MIX Input 3 Source */
+ { 0x071D, 0x0080 }, /* R1821 - AIF1TX4MIX Input 3 Volume */
+ { 0x071E, 0x0000 }, /* R1822 - AIF1TX4MIX Input 4 Source */
+ { 0x071F, 0x0080 }, /* R1823 - AIF1TX4MIX Input 4 Volume */
+ { 0x0720, 0x0000 }, /* R1824 - AIF1TX5MIX Input 1 Source */
+ { 0x0721, 0x0080 }, /* R1825 - AIF1TX5MIX Input 1 Volume */
+ { 0x0722, 0x0000 }, /* R1826 - AIF1TX5MIX Input 2 Source */
+ { 0x0723, 0x0080 }, /* R1827 - AIF1TX5MIX Input 2 Volume */
+ { 0x0724, 0x0000 }, /* R1828 - AIF1TX5MIX Input 3 Source */
+ { 0x0725, 0x0080 }, /* R1829 - AIF1TX5MIX Input 3 Volume */
+ { 0x0726, 0x0000 }, /* R1830 - AIF1TX5MIX Input 4 Source */
+ { 0x0727, 0x0080 }, /* R1831 - AIF1TX5MIX Input 4 Volume */
+ { 0x0728, 0x0000 }, /* R1832 - AIF1TX6MIX Input 1 Source */
+ { 0x0729, 0x0080 }, /* R1833 - AIF1TX6MIX Input 1 Volume */
+ { 0x072A, 0x0000 }, /* R1834 - AIF1TX6MIX Input 2 Source */
+ { 0x072B, 0x0080 }, /* R1835 - AIF1TX6MIX Input 2 Volume */
+ { 0x072C, 0x0000 }, /* R1836 - AIF1TX6MIX Input 3 Source */
+ { 0x072D, 0x0080 }, /* R1837 - AIF1TX6MIX Input 3 Volume */
+ { 0x072E, 0x0000 }, /* R1838 - AIF1TX6MIX Input 4 Source */
+ { 0x072F, 0x0080 }, /* R1839 - AIF1TX6MIX Input 4 Volume */
+ { 0x0730, 0x0000 }, /* R1840 - AIF1TX7MIX Input 1 Source */
+ { 0x0731, 0x0080 }, /* R1841 - AIF1TX7MIX Input 1 Volume */
+ { 0x0732, 0x0000 }, /* R1842 - AIF1TX7MIX Input 2 Source */
+ { 0x0733, 0x0080 }, /* R1843 - AIF1TX7MIX Input 2 Volume */
+ { 0x0734, 0x0000 }, /* R1844 - AIF1TX7MIX Input 3 Source */
+ { 0x0735, 0x0080 }, /* R1845 - AIF1TX7MIX Input 3 Volume */
+ { 0x0736, 0x0000 }, /* R1846 - AIF1TX7MIX Input 4 Source */
+ { 0x0737, 0x0080 }, /* R1847 - AIF1TX7MIX Input 4 Volume */
+ { 0x0738, 0x0000 }, /* R1848 - AIF1TX8MIX Input 1 Source */
+ { 0x0739, 0x0080 }, /* R1849 - AIF1TX8MIX Input 1 Volume */
+ { 0x073A, 0x0000 }, /* R1850 - AIF1TX8MIX Input 2 Source */
+ { 0x073B, 0x0080 }, /* R1851 - AIF1TX8MIX Input 2 Volume */
+ { 0x073C, 0x0000 }, /* R1852 - AIF1TX8MIX Input 3 Source */
+ { 0x073D, 0x0080 }, /* R1853 - AIF1TX8MIX Input 3 Volume */
+ { 0x073E, 0x0000 }, /* R1854 - AIF1TX8MIX Input 4 Source */
+ { 0x073F, 0x0080 }, /* R1855 - AIF1TX8MIX Input 4 Volume */
+ { 0x0740, 0x0000 }, /* R1856 - AIF2TX1MIX Input 1 Source */
+ { 0x0741, 0x0080 }, /* R1857 - AIF2TX1MIX Input 1 Volume */
+ { 0x0742, 0x0000 }, /* R1858 - AIF2TX1MIX Input 2 Source */
+ { 0x0743, 0x0080 }, /* R1859 - AIF2TX1MIX Input 2 Volume */
+ { 0x0744, 0x0000 }, /* R1860 - AIF2TX1MIX Input 3 Source */
+ { 0x0745, 0x0080 }, /* R1861 - AIF2TX1MIX Input 3 Volume */
+ { 0x0746, 0x0000 }, /* R1862 - AIF2TX1MIX Input 4 Source */
+ { 0x0747, 0x0080 }, /* R1863 - AIF2TX1MIX Input 4 Volume */
+ { 0x0748, 0x0000 }, /* R1864 - AIF2TX2MIX Input 1 Source */
+ { 0x0749, 0x0080 }, /* R1865 - AIF2TX2MIX Input 1 Volume */
+ { 0x074A, 0x0000 }, /* R1866 - AIF2TX2MIX Input 2 Source */
+ { 0x074B, 0x0080 }, /* R1867 - AIF2TX2MIX Input 2 Volume */
+ { 0x074C, 0x0000 }, /* R1868 - AIF2TX2MIX Input 3 Source */
+ { 0x074D, 0x0080 }, /* R1869 - AIF2TX2MIX Input 3 Volume */
+ { 0x074E, 0x0000 }, /* R1870 - AIF2TX2MIX Input 4 Source */
+ { 0x074F, 0x0080 }, /* R1871 - AIF2TX2MIX Input 4 Volume */
+ { 0x0780, 0x0000 }, /* R1920 - AIF3TX1MIX Input 1 Source */
+ { 0x0781, 0x0080 }, /* R1921 - AIF3TX1MIX Input 1 Volume */
+ { 0x0782, 0x0000 }, /* R1922 - AIF3TX1MIX Input 2 Source */
+ { 0x0783, 0x0080 }, /* R1923 - AIF3TX1MIX Input 2 Volume */
+ { 0x0784, 0x0000 }, /* R1924 - AIF3TX1MIX Input 3 Source */
+ { 0x0785, 0x0080 }, /* R1925 - AIF3TX1MIX Input 3 Volume */
+ { 0x0786, 0x0000 }, /* R1926 - AIF3TX1MIX Input 4 Source */
+ { 0x0787, 0x0080 }, /* R1927 - AIF3TX1MIX Input 4 Volume */
+ { 0x0788, 0x0000 }, /* R1928 - AIF3TX2MIX Input 1 Source */
+ { 0x0789, 0x0080 }, /* R1929 - AIF3TX2MIX Input 1 Volume */
+ { 0x078A, 0x0000 }, /* R1930 - AIF3TX2MIX Input 2 Source */
+ { 0x078B, 0x0080 }, /* R1931 - AIF3TX2MIX Input 2 Volume */
+ { 0x078C, 0x0000 }, /* R1932 - AIF3TX2MIX Input 3 Source */
+ { 0x078D, 0x0080 }, /* R1933 - AIF3TX2MIX Input 3 Volume */
+ { 0x078E, 0x0000 }, /* R1934 - AIF3TX2MIX Input 4 Source */
+ { 0x078F, 0x0080 }, /* R1935 - AIF3TX2MIX Input 4 Volume */
+ { 0x0880, 0x0000 }, /* R2176 - EQ1MIX Input 1 Source */
+ { 0x0881, 0x0080 }, /* R2177 - EQ1MIX Input 1 Volume */
+ { 0x0882, 0x0000 }, /* R2178 - EQ1MIX Input 2 Source */
+ { 0x0883, 0x0080 }, /* R2179 - EQ1MIX Input 2 Volume */
+ { 0x0884, 0x0000 }, /* R2180 - EQ1MIX Input 3 Source */
+ { 0x0885, 0x0080 }, /* R2181 - EQ1MIX Input 3 Volume */
+ { 0x0886, 0x0000 }, /* R2182 - EQ1MIX Input 4 Source */
+ { 0x0887, 0x0080 }, /* R2183 - EQ1MIX Input 4 Volume */
+ { 0x0888, 0x0000 }, /* R2184 - EQ2MIX Input 1 Source */
+ { 0x0889, 0x0080 }, /* R2185 - EQ2MIX Input 1 Volume */
+ { 0x088A, 0x0000 }, /* R2186 - EQ2MIX Input 2 Source */
+ { 0x088B, 0x0080 }, /* R2187 - EQ2MIX Input 2 Volume */
+ { 0x088C, 0x0000 }, /* R2188 - EQ2MIX Input 3 Source */
+ { 0x088D, 0x0080 }, /* R2189 - EQ2MIX Input 3 Volume */
+ { 0x088E, 0x0000 }, /* R2190 - EQ2MIX Input 4 Source */
+ { 0x088F, 0x0080 }, /* R2191 - EQ2MIX Input 4 Volume */
+ { 0x0890, 0x0000 }, /* R2192 - EQ3MIX Input 1 Source */
+ { 0x0891, 0x0080 }, /* R2193 - EQ3MIX Input 1 Volume */
+ { 0x0892, 0x0000 }, /* R2194 - EQ3MIX Input 2 Source */
+ { 0x0893, 0x0080 }, /* R2195 - EQ3MIX Input 2 Volume */
+ { 0x0894, 0x0000 }, /* R2196 - EQ3MIX Input 3 Source */
+ { 0x0895, 0x0080 }, /* R2197 - EQ3MIX Input 3 Volume */
+ { 0x0896, 0x0000 }, /* R2198 - EQ3MIX Input 4 Source */
+ { 0x0897, 0x0080 }, /* R2199 - EQ3MIX Input 4 Volume */
+ { 0x0898, 0x0000 }, /* R2200 - EQ4MIX Input 1 Source */
+ { 0x0899, 0x0080 }, /* R2201 - EQ4MIX Input 1 Volume */
+ { 0x089A, 0x0000 }, /* R2202 - EQ4MIX Input 2 Source */
+ { 0x089B, 0x0080 }, /* R2203 - EQ4MIX Input 2 Volume */
+ { 0x089C, 0x0000 }, /* R2204 - EQ4MIX Input 3 Source */
+ { 0x089D, 0x0080 }, /* R2205 - EQ4MIX Input 3 Volume */
+ { 0x089E, 0x0000 }, /* R2206 - EQ4MIX Input 4 Source */
+ { 0x089F, 0x0080 }, /* R2207 - EQ4MIX Input 4 Volume */
+ { 0x08C0, 0x0000 }, /* R2240 - DRC1LMIX Input 1 Source */
+ { 0x08C1, 0x0080 }, /* R2241 - DRC1LMIX Input 1 Volume */
+ { 0x08C2, 0x0000 }, /* R2242 - DRC1LMIX Input 2 Source */
+ { 0x08C3, 0x0080 }, /* R2243 - DRC1LMIX Input 2 Volume */
+ { 0x08C4, 0x0000 }, /* R2244 - DRC1LMIX Input 3 Source */
+ { 0x08C5, 0x0080 }, /* R2245 - DRC1LMIX Input 3 Volume */
+ { 0x08C6, 0x0000 }, /* R2246 - DRC1LMIX Input 4 Source */
+ { 0x08C7, 0x0080 }, /* R2247 - DRC1LMIX Input 4 Volume */
+ { 0x08C8, 0x0000 }, /* R2248 - DRC1RMIX Input 1 Source */
+ { 0x08C9, 0x0080 }, /* R2249 - DRC1RMIX Input 1 Volume */
+ { 0x08CA, 0x0000 }, /* R2250 - DRC1RMIX Input 2 Source */
+ { 0x08CB, 0x0080 }, /* R2251 - DRC1RMIX Input 2 Volume */
+ { 0x08CC, 0x0000 }, /* R2252 - DRC1RMIX Input 3 Source */
+ { 0x08CD, 0x0080 }, /* R2253 - DRC1RMIX Input 3 Volume */
+ { 0x08CE, 0x0000 }, /* R2254 - DRC1RMIX Input 4 Source */
+ { 0x08CF, 0x0080 }, /* R2255 - DRC1RMIX Input 4 Volume */
+ { 0x0900, 0x0000 }, /* R2304 - HPLP1MIX Input 1 Source */
+ { 0x0901, 0x0080 }, /* R2305 - HPLP1MIX Input 1 Volume */
+ { 0x0902, 0x0000 }, /* R2306 - HPLP1MIX Input 2 Source */
+ { 0x0903, 0x0080 }, /* R2307 - HPLP1MIX Input 2 Volume */
+ { 0x0904, 0x0000 }, /* R2308 - HPLP1MIX Input 3 Source */
+ { 0x0905, 0x0080 }, /* R2309 - HPLP1MIX Input 3 Volume */
+ { 0x0906, 0x0000 }, /* R2310 - HPLP1MIX Input 4 Source */
+ { 0x0907, 0x0080 }, /* R2311 - HPLP1MIX Input 4 Volume */
+ { 0x0908, 0x0000 }, /* R2312 - HPLP2MIX Input 1 Source */
+ { 0x0909, 0x0080 }, /* R2313 - HPLP2MIX Input 1 Volume */
+ { 0x090A, 0x0000 }, /* R2314 - HPLP2MIX Input 2 Source */
+ { 0x090B, 0x0080 }, /* R2315 - HPLP2MIX Input 2 Volume */
+ { 0x090C, 0x0000 }, /* R2316 - HPLP2MIX Input 3 Source */
+ { 0x090D, 0x0080 }, /* R2317 - HPLP2MIX Input 3 Volume */
+ { 0x090E, 0x0000 }, /* R2318 - HPLP2MIX Input 4 Source */
+ { 0x090F, 0x0080 }, /* R2319 - HPLP2MIX Input 4 Volume */
+ { 0x0910, 0x0000 }, /* R2320 - HPLP3MIX Input 1 Source */
+ { 0x0911, 0x0080 }, /* R2321 - HPLP3MIX Input 1 Volume */
+ { 0x0912, 0x0000 }, /* R2322 - HPLP3MIX Input 2 Source */
+ { 0x0913, 0x0080 }, /* R2323 - HPLP3MIX Input 2 Volume */
+ { 0x0914, 0x0000 }, /* R2324 - HPLP3MIX Input 3 Source */
+ { 0x0915, 0x0080 }, /* R2325 - HPLP3MIX Input 3 Volume */
+ { 0x0916, 0x0000 }, /* R2326 - HPLP3MIX Input 4 Source */
+ { 0x0917, 0x0080 }, /* R2327 - HPLP3MIX Input 4 Volume */
+ { 0x0918, 0x0000 }, /* R2328 - HPLP4MIX Input 1 Source */
+ { 0x0919, 0x0080 }, /* R2329 - HPLP4MIX Input 1 Volume */
+ { 0x091A, 0x0000 }, /* R2330 - HPLP4MIX Input 2 Source */
+ { 0x091B, 0x0080 }, /* R2331 - HPLP4MIX Input 2 Volume */
+ { 0x091C, 0x0000 }, /* R2332 - HPLP4MIX Input 3 Source */
+ { 0x091D, 0x0080 }, /* R2333 - HPLP4MIX Input 3 Volume */
+ { 0x091E, 0x0000 }, /* R2334 - HPLP4MIX Input 4 Source */
+ { 0x091F, 0x0080 }, /* R2335 - HPLP4MIX Input 4 Volume */
+ { 0x0940, 0x0000 }, /* R2368 - DSP1LMIX Input 1 Source */
+ { 0x0941, 0x0080 }, /* R2369 - DSP1LMIX Input 1 Volume */
+ { 0x0942, 0x0000 }, /* R2370 - DSP1LMIX Input 2 Source */
+ { 0x0943, 0x0080 }, /* R2371 - DSP1LMIX Input 2 Volume */
+ { 0x0944, 0x0000 }, /* R2372 - DSP1LMIX Input 3 Source */
+ { 0x0945, 0x0080 }, /* R2373 - DSP1LMIX Input 3 Volume */
+ { 0x0946, 0x0000 }, /* R2374 - DSP1LMIX Input 4 Source */
+ { 0x0947, 0x0080 }, /* R2375 - DSP1LMIX Input 4 Volume */
+ { 0x0948, 0x0000 }, /* R2376 - DSP1RMIX Input 1 Source */
+ { 0x0949, 0x0080 }, /* R2377 - DSP1RMIX Input 1 Volume */
+ { 0x094A, 0x0000 }, /* R2378 - DSP1RMIX Input 2 Source */
+ { 0x094B, 0x0080 }, /* R2379 - DSP1RMIX Input 2 Volume */
+ { 0x094C, 0x0000 }, /* R2380 - DSP1RMIX Input 3 Source */
+ { 0x094D, 0x0080 }, /* R2381 - DSP1RMIX Input 3 Volume */
+ { 0x094E, 0x0000 }, /* R2382 - DSP1RMIX Input 4 Source */
+ { 0x094F, 0x0080 }, /* R2383 - DSP1RMIX Input 4 Volume */
+ { 0x0950, 0x0000 }, /* R2384 - DSP1AUX1MIX Input 1 Source */
+ { 0x0958, 0x0000 }, /* R2392 - DSP1AUX2MIX Input 1 Source */
+ { 0x0960, 0x0000 }, /* R2400 - DSP1AUX3MIX Input 1 Source */
+ { 0x0968, 0x0000 }, /* R2408 - DSP1AUX4MIX Input 1 Source */
+ { 0x0970, 0x0000 }, /* R2416 - DSP1AUX5MIX Input 1 Source */
+ { 0x0978, 0x0000 }, /* R2424 - DSP1AUX6MIX Input 1 Source */
+ { 0x0980, 0x0000 }, /* R2432 - DSP2LMIX Input 1 Source */
+ { 0x0981, 0x0080 }, /* R2433 - DSP2LMIX Input 1 Volume */
+ { 0x0982, 0x0000 }, /* R2434 - DSP2LMIX Input 2 Source */
+ { 0x0983, 0x0080 }, /* R2435 - DSP2LMIX Input 2 Volume */
+ { 0x0984, 0x0000 }, /* R2436 - DSP2LMIX Input 3 Source */
+ { 0x0985, 0x0080 }, /* R2437 - DSP2LMIX Input 3 Volume */
+ { 0x0986, 0x0000 }, /* R2438 - DSP2LMIX Input 4 Source */
+ { 0x0987, 0x0080 }, /* R2439 - DSP2LMIX Input 4 Volume */
+ { 0x0988, 0x0000 }, /* R2440 - DSP2RMIX Input 1 Source */
+ { 0x0989, 0x0080 }, /* R2441 - DSP2RMIX Input 1 Volume */
+ { 0x098A, 0x0000 }, /* R2442 - DSP2RMIX Input 2 Source */
+ { 0x098B, 0x0080 }, /* R2443 - DSP2RMIX Input 2 Volume */
+ { 0x098C, 0x0000 }, /* R2444 - DSP2RMIX Input 3 Source */
+ { 0x098D, 0x0080 }, /* R2445 - DSP2RMIX Input 3 Volume */
+ { 0x098E, 0x0000 }, /* R2446 - DSP2RMIX Input 4 Source */
+ { 0x098F, 0x0080 }, /* R2447 - DSP2RMIX Input 4 Volume */
+ { 0x0990, 0x0000 }, /* R2448 - DSP2AUX1MIX Input 1 Source */
+ { 0x0998, 0x0000 }, /* R2456 - DSP2AUX2MIX Input 1 Source */
+ { 0x09A0, 0x0000 }, /* R2464 - DSP2AUX3MIX Input 1 Source */
+ { 0x09A8, 0x0000 }, /* R2472 - DSP2AUX4MIX Input 1 Source */
+ { 0x09B0, 0x0000 }, /* R2480 - DSP2AUX5MIX Input 1 Source */
+ { 0x09B8, 0x0000 }, /* R2488 - DSP2AUX6MIX Input 1 Source */
+ { 0x09C0, 0x0000 }, /* R2496 - DSP3LMIX Input 1 Source */
+ { 0x09C1, 0x0080 }, /* R2497 - DSP3LMIX Input 1 Volume */
+ { 0x09C2, 0x0000 }, /* R2498 - DSP3LMIX Input 2 Source */
+ { 0x09C3, 0x0080 }, /* R2499 - DSP3LMIX Input 2 Volume */
+ { 0x09C4, 0x0000 }, /* R2500 - DSP3LMIX Input 3 Source */
+ { 0x09C5, 0x0080 }, /* R2501 - DSP3LMIX Input 3 Volume */
+ { 0x09C6, 0x0000 }, /* R2502 - DSP3LMIX Input 4 Source */
+ { 0x09C7, 0x0080 }, /* R2503 - DSP3LMIX Input 4 Volume */
+ { 0x09C8, 0x0000 }, /* R2504 - DSP3RMIX Input 1 Source */
+ { 0x09C9, 0x0080 }, /* R2505 - DSP3RMIX Input 1 Volume */
+ { 0x09CA, 0x0000 }, /* R2506 - DSP3RMIX Input 2 Source */
+ { 0x09CB, 0x0080 }, /* R2507 - DSP3RMIX Input 2 Volume */
+ { 0x09CC, 0x0000 }, /* R2508 - DSP3RMIX Input 3 Source */
+ { 0x09CD, 0x0080 }, /* R2509 - DSP3RMIX Input 3 Volume */
+ { 0x09CE, 0x0000 }, /* R2510 - DSP3RMIX Input 4 Source */
+ { 0x09CF, 0x0080 }, /* R2511 - DSP3RMIX Input 4 Volume */
+ { 0x09D0, 0x0000 }, /* R2512 - DSP3AUX1MIX Input 1 Source */
+ { 0x09D8, 0x0000 }, /* R2520 - DSP3AUX2MIX Input 1 Source */
+ { 0x09E0, 0x0000 }, /* R2528 - DSP3AUX3MIX Input 1 Source */
+ { 0x09E8, 0x0000 }, /* R2536 - DSP3AUX4MIX Input 1 Source */
+ { 0x09F0, 0x0000 }, /* R2544 - DSP3AUX5MIX Input 1 Source */
+ { 0x09F8, 0x0000 }, /* R2552 - DSP3AUX6MIX Input 1 Source */
+ { 0x0A80, 0x0000 }, /* R2688 - ASRC1LMIX Input 1 Source */
+ { 0x0A88, 0x0000 }, /* R2696 - ASRC1RMIX Input 1 Source */
+ { 0x0A90, 0x0000 }, /* R2704 - ASRC2LMIX Input 1 Source */
+ { 0x0A98, 0x0000 }, /* R2712 - ASRC2RMIX Input 1 Source */
+ { 0x0B00, 0x0000 }, /* R2816 - ISRC1DEC1MIX Input 1 Source */
+ { 0x0B08, 0x0000 }, /* R2824 - ISRC1DEC2MIX Input 1 Source */
+ { 0x0B10, 0x0000 }, /* R2832 - ISRC1DEC3MIX Input 1 Source */
+ { 0x0B18, 0x0000 }, /* R2840 - ISRC1DEC4MIX Input 1 Source */
+ { 0x0B20, 0x0000 }, /* R2848 - ISRC1INT1MIX Input 1 Source */
+ { 0x0B28, 0x0000 }, /* R2856 - ISRC1INT2MIX Input 1 Source */
+ { 0x0B30, 0x0000 }, /* R2864 - ISRC1INT3MIX Input 1 Source */
+ { 0x0B38, 0x0000 }, /* R2872 - ISRC1INT4MIX Input 1 Source */
+ { 0x0B40, 0x0000 }, /* R2880 - ISRC2DEC1MIX Input 1 Source */
+ { 0x0B48, 0x0000 }, /* R2888 - ISRC2DEC2MIX Input 1 Source */
+ { 0x0B50, 0x0000 }, /* R2896 - ISRC2DEC3MIX Input 1 Source */
+ { 0x0B58, 0x0000 }, /* R2904 - ISRC2DEC4MIX Input 1 Source */
+ { 0x0B60, 0x0000 }, /* R2912 - ISRC2INT1MIX Input 1 Source */
+ { 0x0B68, 0x0000 }, /* R2920 - ISRC2INT2MIX Input 1 Source */
+ { 0x0B70, 0x0000 }, /* R2928 - ISRC2INT3MIX Input 1 Source */
+ { 0x0B78, 0x0000 }, /* R2936 - ISRC2INT4MIX Input 1 Source */
+ { 0x0C00, 0xA001 }, /* R3072 - GPIO CTRL 1 */
+ { 0x0C01, 0xA001 }, /* R3073 - GPIO CTRL 2 */
+ { 0x0C02, 0xA001 }, /* R3074 - GPIO CTRL 3 */
+ { 0x0C03, 0xA001 }, /* R3075 - GPIO CTRL 4 */
+ { 0x0C04, 0xA001 }, /* R3076 - GPIO CTRL 5 */
+ { 0x0C05, 0xA001 }, /* R3077 - GPIO CTRL 6 */
+ { 0x0C23, 0x4003 }, /* R3107 - Misc Pad Ctrl 1 */
+ { 0x0C24, 0x0000 }, /* R3108 - Misc Pad Ctrl 2 */
+ { 0x0C25, 0x0000 }, /* R3109 - Misc Pad Ctrl 3 */
+ { 0x0C26, 0x0000 }, /* R3110 - Misc Pad Ctrl 4 */
+ { 0x0C27, 0x0000 }, /* R3111 - Misc Pad Ctrl 5 */
+ { 0x0C28, 0x0000 }, /* R3112 - Misc GPIO 1 */
+ { 0x0D00, 0x0000 }, /* R3328 - Interrupt Status 1 */
+ { 0x0D01, 0x0000 }, /* R3329 - Interrupt Status 2 */
+ { 0x0D02, 0x0000 }, /* R3330 - Interrupt Status 3 */
+ { 0x0D03, 0x0000 }, /* R3331 - Interrupt Status 4 */
+ { 0x0D04, 0x0000 }, /* R3332 - Interrupt Raw Status 2 */
+ { 0x0D05, 0x0000 }, /* R3333 - Interrupt Raw Status 3 */
+ { 0x0D06, 0x0000 }, /* R3334 - Interrupt Raw Status 4 */
+ { 0x0D07, 0xFFFF }, /* R3335 - Interrupt Status 1 Mask */
+ { 0x0D08, 0xFFFF }, /* R3336 - Interrupt Status 2 Mask */
+ { 0x0D09, 0xFFFF }, /* R3337 - Interrupt Status 3 Mask */
+ { 0x0D0A, 0xFFFF }, /* R3338 - Interrupt Status 4 Mask */
+ { 0x0D1F, 0x0000 }, /* R3359 - Interrupt Control */
+ { 0x0D20, 0xFFFF }, /* R3360 - IRQ Debounce 1 */
+ { 0x0D21, 0xFFFF }, /* R3361 - IRQ Debounce 2 */
+ { 0x0E00, 0x0000 }, /* R3584 - FX_Ctrl */
+ { 0x0E10, 0x6318 }, /* R3600 - EQ1_1 */
+ { 0x0E11, 0x6300 }, /* R3601 - EQ1_2 */
+ { 0x0E12, 0x0FC8 }, /* R3602 - EQ1_3 */
+ { 0x0E13, 0x03FE }, /* R3603 - EQ1_4 */
+ { 0x0E14, 0x00E0 }, /* R3604 - EQ1_5 */
+ { 0x0E15, 0x1EC4 }, /* R3605 - EQ1_6 */
+ { 0x0E16, 0xF136 }, /* R3606 - EQ1_7 */
+ { 0x0E17, 0x0409 }, /* R3607 - EQ1_8 */
+ { 0x0E18, 0x04CC }, /* R3608 - EQ1_9 */
+ { 0x0E19, 0x1C9B }, /* R3609 - EQ1_10 */
+ { 0x0E1A, 0xF337 }, /* R3610 - EQ1_11 */
+ { 0x0E1B, 0x040B }, /* R3611 - EQ1_12 */
+ { 0x0E1C, 0x0CBB }, /* R3612 - EQ1_13 */
+ { 0x0E1D, 0x16F8 }, /* R3613 - EQ1_14 */
+ { 0x0E1E, 0xF7D9 }, /* R3614 - EQ1_15 */
+ { 0x0E1F, 0x040A }, /* R3615 - EQ1_16 */
+ { 0x0E20, 0x1F14 }, /* R3616 - EQ1_17 */
+ { 0x0E21, 0x058C }, /* R3617 - EQ1_18 */
+ { 0x0E22, 0x0563 }, /* R3618 - EQ1_19 */
+ { 0x0E23, 0x4000 }, /* R3619 - EQ1_20 */
+ { 0x0E26, 0x6318 }, /* R3622 - EQ2_1 */
+ { 0x0E27, 0x6300 }, /* R3623 - EQ2_2 */
+ { 0x0E28, 0x0FC8 }, /* R3624 - EQ2_3 */
+ { 0x0E29, 0x03FE }, /* R3625 - EQ2_4 */
+ { 0x0E2A, 0x00E0 }, /* R3626 - EQ2_5 */
+ { 0x0E2B, 0x1EC4 }, /* R3627 - EQ2_6 */
+ { 0x0E2C, 0xF136 }, /* R3628 - EQ2_7 */
+ { 0x0E2D, 0x0409 }, /* R3629 - EQ2_8 */
+ { 0x0E2E, 0x04CC }, /* R3630 - EQ2_9 */
+ { 0x0E2F, 0x1C9B }, /* R3631 - EQ2_10 */
+ { 0x0E30, 0xF337 }, /* R3632 - EQ2_11 */
+ { 0x0E31, 0x040B }, /* R3633 - EQ2_12 */
+ { 0x0E32, 0x0CBB }, /* R3634 - EQ2_13 */
+ { 0x0E33, 0x16F8 }, /* R3635 - EQ2_14 */
+ { 0x0E34, 0xF7D9 }, /* R3636 - EQ2_15 */
+ { 0x0E35, 0x040A }, /* R3637 - EQ2_16 */
+ { 0x0E36, 0x1F14 }, /* R3638 - EQ2_17 */
+ { 0x0E37, 0x058C }, /* R3639 - EQ2_18 */
+ { 0x0E38, 0x0563 }, /* R3640 - EQ2_19 */
+ { 0x0E39, 0x4000 }, /* R3641 - EQ2_20 */
+ { 0x0E3C, 0x6318 }, /* R3644 - EQ3_1 */
+ { 0x0E3D, 0x6300 }, /* R3645 - EQ3_2 */
+ { 0x0E3E, 0x0FC8 }, /* R3646 - EQ3_3 */
+ { 0x0E3F, 0x03FE }, /* R3647 - EQ3_4 */
+ { 0x0E40, 0x00E0 }, /* R3648 - EQ3_5 */
+ { 0x0E41, 0x1EC4 }, /* R3649 - EQ3_6 */
+ { 0x0E42, 0xF136 }, /* R3650 - EQ3_7 */
+ { 0x0E43, 0x0409 }, /* R3651 - EQ3_8 */
+ { 0x0E44, 0x04CC }, /* R3652 - EQ3_9 */
+ { 0x0E45, 0x1C9B }, /* R3653 - EQ3_10 */
+ { 0x0E46, 0xF337 }, /* R3654 - EQ3_11 */
+ { 0x0E47, 0x040B }, /* R3655 - EQ3_12 */
+ { 0x0E48, 0x0CBB }, /* R3656 - EQ3_13 */
+ { 0x0E49, 0x16F8 }, /* R3657 - EQ3_14 */
+ { 0x0E4A, 0xF7D9 }, /* R3658 - EQ3_15 */
+ { 0x0E4B, 0x040A }, /* R3659 - EQ3_16 */
+ { 0x0E4C, 0x1F14 }, /* R3660 - EQ3_17 */
+ { 0x0E4D, 0x058C }, /* R3661 - EQ3_18 */
+ { 0x0E4E, 0x0563 }, /* R3662 - EQ3_19 */
+ { 0x0E4F, 0x4000 }, /* R3663 - EQ3_20 */
+ { 0x0E52, 0x6318 }, /* R3666 - EQ4_1 */
+ { 0x0E53, 0x6300 }, /* R3667 - EQ4_2 */
+ { 0x0E54, 0x0FC8 }, /* R3668 - EQ4_3 */
+ { 0x0E55, 0x03FE }, /* R3669 - EQ4_4 */
+ { 0x0E56, 0x00E0 }, /* R3670 - EQ4_5 */
+ { 0x0E57, 0x1EC4 }, /* R3671 - EQ4_6 */
+ { 0x0E58, 0xF136 }, /* R3672 - EQ4_7 */
+ { 0x0E59, 0x0409 }, /* R3673 - EQ4_8 */
+ { 0x0E5A, 0x04CC }, /* R3674 - EQ4_9 */
+ { 0x0E5B, 0x1C9B }, /* R3675 - EQ4_10 */
+ { 0x0E5C, 0xF337 }, /* R3676 - EQ4_11 */
+ { 0x0E5D, 0x040B }, /* R3677 - EQ4_12 */
+ { 0x0E5E, 0x0CBB }, /* R3678 - EQ4_13 */
+ { 0x0E5F, 0x16F8 }, /* R3679 - EQ4_14 */
+ { 0x0E60, 0xF7D9 }, /* R3680 - EQ4_15 */
+ { 0x0E61, 0x040A }, /* R3681 - EQ4_16 */
+ { 0x0E62, 0x1F14 }, /* R3682 - EQ4_17 */
+ { 0x0E63, 0x058C }, /* R3683 - EQ4_18 */
+ { 0x0E64, 0x0563 }, /* R3684 - EQ4_19 */
+ { 0x0E65, 0x4000 }, /* R3685 - EQ4_20 */
+ { 0x0E80, 0x0018 }, /* R3712 - DRC1 ctrl1 */
+ { 0x0E81, 0x0933 }, /* R3713 - DRC1 ctrl2 */
+ { 0x0E82, 0x0018 }, /* R3714 - DRC1 ctrl3 */
+ { 0x0E83, 0x0000 }, /* R3715 - DRC1 ctrl4 */
+ { 0x0E84, 0x0000 }, /* R3716 - DRC1 ctrl5 */
+ { 0x0EC0, 0x0000 }, /* R3776 - HPLPF1_1 */
+ { 0x0EC1, 0x0000 }, /* R3777 - HPLPF1_2 */
+ { 0x0EC4, 0x0000 }, /* R3780 - HPLPF2_1 */
+ { 0x0EC5, 0x0000 }, /* R3781 - HPLPF2_2 */
+ { 0x0EC8, 0x0000 }, /* R3784 - HPLPF3_1 */
+ { 0x0EC9, 0x0000 }, /* R3785 - HPLPF3_2 */
+ { 0x0ECC, 0x0000 }, /* R3788 - HPLPF4_1 */
+ { 0x0ECD, 0x0000 }, /* R3789 - HPLPF4_2 */
};
diff --git a/sound/soc/codecs/wm5100.c b/sound/soc/codecs/wm5100.c
index 42d9039..8b24323 100644
--- a/sound/soc/codecs/wm5100.c
+++ b/sound/soc/codecs/wm5100.c
@@ -18,7 +18,6 @@
#include <linux/gcd.h>
#include <linux/gpio.h>
#include <linux/i2c.h>
-#include <linux/platform_device.h>
#include <linux/regulator/consumer.h>
#include <linux/regulator/fixed.h>
#include <linux/slab.h>
@@ -51,6 +50,7 @@
/* codec private data */
struct wm5100_priv {
+ struct regmap *regmap;
struct snd_soc_codec *codec;
struct regulator_bulk_data core_supplies[WM5100_NUM_CORE_SUPPLIES];
@@ -204,17 +204,15 @@
}
}
-static int wm5100_reset(struct snd_soc_codec *codec)
+static int wm5100_reset(struct wm5100_priv *wm5100)
{
- struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
-
if (wm5100->pdata.reset) {
gpio_set_value_cansleep(wm5100->pdata.reset, 0);
gpio_set_value_cansleep(wm5100->pdata.reset, 1);
return 0;
} else {
- return snd_soc_write(codec, WM5100_SOFTWARE_RESET, 0);
+ return regmap_write(wm5100->regmap, WM5100_SOFTWARE_RESET, 0);
}
}
@@ -954,7 +952,7 @@
SND_SOC_DAPM_INPUT("IN3R"),
SND_SOC_DAPM_INPUT("IN4L"),
SND_SOC_DAPM_INPUT("IN4R"),
-SND_SOC_DAPM_INPUT("TONE"),
+SND_SOC_DAPM_SIGGEN("TONE"),
SND_SOC_DAPM_PGA_E("IN1L PGA", WM5100_INPUT_ENABLES, WM5100_IN1L_ENA_SHIFT, 0,
NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
@@ -1375,7 +1373,7 @@
msleep(2);
}
- codec->cache_only = false;
+ regcache_cache_only(wm5100->regmap, false);
switch (wm5100->rev) {
case 0:
@@ -1399,7 +1397,7 @@
break;
}
- snd_soc_cache_sync(codec);
+ regcache_sync(wm5100->regmap);
}
break;
@@ -1662,7 +1660,7 @@
return 0;
}
-static struct snd_soc_dai_ops wm5100_dai_ops = {
+static const struct snd_soc_dai_ops wm5100_dai_ops = {
.set_fmt = wm5100_set_fmt,
.hw_params = wm5100_hw_params,
};
@@ -1993,6 +1991,9 @@
else
timeout = 50;
+ snd_soc_update_bits(codec, WM5100_CLOCKING_3, WM5100_SYSCLK_ENA,
+ WM5100_SYSCLK_ENA);
+
/* Poll for the lock; will use interrupt when we can test */
for (i = 0; i < timeout; i++) {
if (i2c->irq) {
@@ -2350,24 +2351,22 @@
static void wm5100_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
{
struct wm5100_priv *wm5100 = gpio_to_wm5100(chip);
- struct snd_soc_codec *codec = wm5100->codec;
- snd_soc_update_bits(codec, WM5100_GPIO_CTRL_1 + offset,
- WM5100_GP1_LVL, !!value << WM5100_GP1_LVL_SHIFT);
+ regmap_update_bits(wm5100->regmap, WM5100_GPIO_CTRL_1 + offset,
+ WM5100_GP1_LVL, !!value << WM5100_GP1_LVL_SHIFT);
}
static int wm5100_gpio_direction_out(struct gpio_chip *chip,
unsigned offset, int value)
{
struct wm5100_priv *wm5100 = gpio_to_wm5100(chip);
- struct snd_soc_codec *codec = wm5100->codec;
int val, ret;
val = (1 << WM5100_GP1_FN_SHIFT) | (!!value << WM5100_GP1_LVL_SHIFT);
- ret = snd_soc_update_bits(codec, WM5100_GPIO_CTRL_1 + offset,
- WM5100_GP1_FN_MASK | WM5100_GP1_DIR |
- WM5100_GP1_LVL, val);
+ ret = regmap_update_bits(wm5100->regmap, WM5100_GPIO_CTRL_1 + offset,
+ WM5100_GP1_FN_MASK | WM5100_GP1_DIR |
+ WM5100_GP1_LVL, val);
if (ret < 0)
return ret;
else
@@ -2377,25 +2376,24 @@
static int wm5100_gpio_get(struct gpio_chip *chip, unsigned offset)
{
struct wm5100_priv *wm5100 = gpio_to_wm5100(chip);
- struct snd_soc_codec *codec = wm5100->codec;
+ unsigned int reg;
int ret;
- ret = snd_soc_read(codec, WM5100_GPIO_CTRL_1 + offset);
+ ret = regmap_read(wm5100->regmap, WM5100_GPIO_CTRL_1 + offset, ®);
if (ret < 0)
return ret;
- return (ret & WM5100_GP1_LVL) != 0;
+ return (reg & WM5100_GP1_LVL) != 0;
}
static int wm5100_gpio_direction_in(struct gpio_chip *chip, unsigned offset)
{
struct wm5100_priv *wm5100 = gpio_to_wm5100(chip);
- struct snd_soc_codec *codec = wm5100->codec;
- return snd_soc_update_bits(codec, WM5100_GPIO_CTRL_1 + offset,
- WM5100_GP1_FN_MASK | WM5100_GP1_DIR,
- (1 << WM5100_GP1_FN_SHIFT) |
- (1 << WM5100_GP1_DIR_SHIFT));
+ return regmap_update_bits(wm5100->regmap, WM5100_GPIO_CTRL_1 + offset,
+ WM5100_GP1_FN_MASK | WM5100_GP1_DIR,
+ (1 << WM5100_GP1_FN_SHIFT) |
+ (1 << WM5100_GP1_DIR_SHIFT));
}
static struct gpio_chip wm5100_template_chip = {
@@ -2408,14 +2406,14 @@
.can_sleep = 1,
};
-static void wm5100_init_gpio(struct snd_soc_codec *codec)
+static void wm5100_init_gpio(struct i2c_client *i2c)
{
- struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
+ struct wm5100_priv *wm5100 = i2c_get_clientdata(i2c);
int ret;
wm5100->gpio_chip = wm5100_template_chip;
wm5100->gpio_chip.ngpio = 6;
- wm5100->gpio_chip.dev = codec->dev;
+ wm5100->gpio_chip.dev = &i2c->dev;
if (wm5100->pdata.gpio_base)
wm5100->gpio_chip.base = wm5100->pdata.gpio_base;
@@ -2424,24 +2422,24 @@
ret = gpiochip_add(&wm5100->gpio_chip);
if (ret != 0)
- dev_err(codec->dev, "Failed to add GPIOs: %d\n", ret);
+ dev_err(&i2c->dev, "Failed to add GPIOs: %d\n", ret);
}
-static void wm5100_free_gpio(struct snd_soc_codec *codec)
+static void wm5100_free_gpio(struct i2c_client *i2c)
{
- struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
+ struct wm5100_priv *wm5100 = i2c_get_clientdata(i2c);
int ret;
ret = gpiochip_remove(&wm5100->gpio_chip);
if (ret != 0)
- dev_err(codec->dev, "Failed to remove GPIOs: %d\n", ret);
+ dev_err(&i2c->dev, "Failed to remove GPIOs: %d\n", ret);
}
#else
-static void wm5100_init_gpio(struct snd_soc_codec *codec)
+static void wm5100_init_gpio(struct i2c_client *i2c)
{
}
-static void wm5100_free_gpio(struct snd_soc_codec *codec)
+static void wm5100_free_gpio(struct i2c_client *i2c)
{
}
#endif
@@ -2453,131 +2451,21 @@
int ret, i, irq_flags;
wm5100->codec = codec;
+ codec->control_data = wm5100->regmap;
- ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_I2C);
+ ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_REGMAP);
if (ret != 0) {
dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
return ret;
}
- for (i = 0; i < ARRAY_SIZE(wm5100->core_supplies); i++)
- wm5100->core_supplies[i].supply = wm5100_core_supply_names[i];
+ regcache_cache_only(wm5100->regmap, true);
- ret = regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm5100->core_supplies),
- wm5100->core_supplies);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to request core supplies: %d\n",
- ret);
- return ret;
- }
-
- wm5100->cpvdd = regulator_get(&i2c->dev, "CPVDD");
- if (IS_ERR(wm5100->cpvdd)) {
- ret = PTR_ERR(wm5100->cpvdd);
- dev_err(&i2c->dev, "Failed to get CPVDD: %d\n", ret);
- goto err_core;
- }
-
- wm5100->dbvdd2 = regulator_get(&i2c->dev, "DBVDD2");
- if (IS_ERR(wm5100->dbvdd2)) {
- ret = PTR_ERR(wm5100->dbvdd2);
- dev_err(&i2c->dev, "Failed to get DBVDD2: %d\n", ret);
- goto err_cpvdd;
- }
-
- wm5100->dbvdd3 = regulator_get(&i2c->dev, "DBVDD3");
- if (IS_ERR(wm5100->dbvdd3)) {
- ret = PTR_ERR(wm5100->dbvdd3);
- dev_err(&i2c->dev, "Failed to get DBVDD2: %d\n", ret);
- goto err_dbvdd2;
- }
-
- ret = regulator_bulk_enable(ARRAY_SIZE(wm5100->core_supplies),
- wm5100->core_supplies);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to enable core supplies: %d\n",
- ret);
- goto err_dbvdd3;
- }
-
- if (wm5100->pdata.ldo_ena) {
- ret = gpio_request_one(wm5100->pdata.ldo_ena,
- GPIOF_OUT_INIT_HIGH, "WM5100 LDOENA");
- if (ret < 0) {
- dev_err(&i2c->dev, "Failed to request LDOENA %d: %d\n",
- wm5100->pdata.ldo_ena, ret);
- goto err_enable;
- }
- msleep(2);
- }
-
- if (wm5100->pdata.reset) {
- ret = gpio_request_one(wm5100->pdata.reset,
- GPIOF_OUT_INIT_HIGH, "WM5100 /RESET");
- if (ret < 0) {
- dev_err(&i2c->dev, "Failed to request /RESET %d: %d\n",
- wm5100->pdata.reset, ret);
- goto err_ldo;
- }
- }
-
- ret = snd_soc_read(codec, WM5100_SOFTWARE_RESET);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to read ID register\n");
- goto err_reset;
- }
- switch (ret) {
- case 0x8997:
- case 0x5100:
- break;
-
- default:
- dev_err(codec->dev, "Device is not a WM5100, ID is %x\n", ret);
- ret = -EINVAL;
- goto err_reset;
- }
-
- ret = snd_soc_read(codec, WM5100_DEVICE_REVISION);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to read revision register\n");
- goto err_reset;
- }
- wm5100->rev = ret & WM5100_DEVICE_REVISION_MASK;
-
- dev_info(codec->dev, "revision %c\n", wm5100->rev + 'A');
-
- ret = wm5100_reset(codec);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to issue reset\n");
- goto err_reset;
- }
-
- codec->cache_only = true;
-
- wm5100_init_gpio(codec);
for (i = 0; i < ARRAY_SIZE(wm5100_dig_vu); i++)
snd_soc_update_bits(codec, wm5100_dig_vu[i], WM5100_OUT_VU,
WM5100_OUT_VU);
- for (i = 0; i < ARRAY_SIZE(wm5100->pdata.in_mode); i++) {
- snd_soc_update_bits(codec, WM5100_IN1L_CONTROL,
- WM5100_IN1_MODE_MASK |
- WM5100_IN1_DMIC_SUP_MASK,
- (wm5100->pdata.in_mode[i] <<
- WM5100_IN1_MODE_SHIFT) |
- (wm5100->pdata.dmic_sup[i] <<
- WM5100_IN1_DMIC_SUP_SHIFT));
- }
-
- for (i = 0; i < ARRAY_SIZE(wm5100->pdata.gpio_defaults); i++) {
- if (!wm5100->pdata.gpio_defaults[i])
- continue;
-
- snd_soc_write(codec, WM5100_GPIO_CTRL_1 + i,
- wm5100->pdata.gpio_defaults[i]);
- }
-
/* Don't debounce interrupts to support use of SYSCLK only */
snd_soc_write(codec, WM5100_IRQ_DEBOUNCE_1, 0);
snd_soc_write(codec, WM5100_IRQ_DEBOUNCE_2, 0);
@@ -2662,8 +2550,216 @@
err_gpio:
if (i2c->irq)
free_irq(i2c->irq, codec);
- wm5100_free_gpio(codec);
+
+ return ret;
+}
+
+static int wm5100_remove(struct snd_soc_codec *codec)
+{
+ struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
+ struct i2c_client *i2c = to_i2c_client(codec->dev);
+
+ wm5100_set_bias_level(codec, SND_SOC_BIAS_OFF);
+ if (wm5100->pdata.hp_pol) {
+ gpio_free(wm5100->pdata.hp_pol);
+ }
+ if (i2c->irq)
+ free_irq(i2c->irq, codec);
+ return 0;
+}
+
+static int wm5100_soc_volatile(struct snd_soc_codec *codec,
+ unsigned int reg)
+{
+ return true;
+}
+
+
+static struct snd_soc_codec_driver soc_codec_dev_wm5100 = {
+ .probe = wm5100_probe,
+ .remove = wm5100_remove,
+
+ .set_sysclk = wm5100_set_sysclk,
+ .set_pll = wm5100_set_fll,
+ .set_bias_level = wm5100_set_bias_level,
+ .idle_bias_off = 1,
+ .reg_cache_size = WM5100_MAX_REGISTER,
+ .volatile_register = wm5100_soc_volatile,
+
+ .seq_notifier = wm5100_seq_notifier,
+ .controls = wm5100_snd_controls,
+ .num_controls = ARRAY_SIZE(wm5100_snd_controls),
+ .dapm_widgets = wm5100_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(wm5100_dapm_widgets),
+ .dapm_routes = wm5100_dapm_routes,
+ .num_dapm_routes = ARRAY_SIZE(wm5100_dapm_routes),
+};
+
+static const struct regmap_config wm5100_regmap = {
+ .reg_bits = 16,
+ .val_bits = 16,
+
+ .max_register = WM5100_MAX_REGISTER,
+ .reg_defaults = wm5100_reg_defaults,
+ .num_reg_defaults = ARRAY_SIZE(wm5100_reg_defaults),
+ .volatile_reg = wm5100_volatile_register,
+ .readable_reg = wm5100_readable_register,
+ .cache_type = REGCACHE_RBTREE,
+};
+
+static __devinit int wm5100_i2c_probe(struct i2c_client *i2c,
+ const struct i2c_device_id *id)
+{
+ struct wm5100_pdata *pdata = dev_get_platdata(&i2c->dev);
+ struct wm5100_priv *wm5100;
+ unsigned int reg;
+ int ret, i;
+
+ wm5100 = devm_kzalloc(&i2c->dev, sizeof(struct wm5100_priv),
+ GFP_KERNEL);
+ if (wm5100 == NULL)
+ return -ENOMEM;
+
+ wm5100->regmap = regmap_init_i2c(i2c, &wm5100_regmap);
+ if (IS_ERR(wm5100->regmap)) {
+ ret = PTR_ERR(wm5100->regmap);
+ dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
+ ret);
+ goto err;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(wm5100->fll); i++)
+ init_completion(&wm5100->fll[i].lock);
+
+ if (pdata)
+ wm5100->pdata = *pdata;
+
+ i2c_set_clientdata(i2c, wm5100);
+
+ for (i = 0; i < ARRAY_SIZE(wm5100->core_supplies); i++)
+ wm5100->core_supplies[i].supply = wm5100_core_supply_names[i];
+
+ ret = regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm5100->core_supplies),
+ wm5100->core_supplies);
+ if (ret != 0) {
+ dev_err(&i2c->dev, "Failed to request core supplies: %d\n",
+ ret);
+ goto err_regmap;
+ }
+
+ wm5100->cpvdd = regulator_get(&i2c->dev, "CPVDD");
+ if (IS_ERR(wm5100->cpvdd)) {
+ ret = PTR_ERR(wm5100->cpvdd);
+ dev_err(&i2c->dev, "Failed to get CPVDD: %d\n", ret);
+ goto err_core;
+ }
+
+ wm5100->dbvdd2 = regulator_get(&i2c->dev, "DBVDD2");
+ if (IS_ERR(wm5100->dbvdd2)) {
+ ret = PTR_ERR(wm5100->dbvdd2);
+ dev_err(&i2c->dev, "Failed to get DBVDD2: %d\n", ret);
+ goto err_cpvdd;
+ }
+
+ wm5100->dbvdd3 = regulator_get(&i2c->dev, "DBVDD3");
+ if (IS_ERR(wm5100->dbvdd3)) {
+ ret = PTR_ERR(wm5100->dbvdd3);
+ dev_err(&i2c->dev, "Failed to get DBVDD2: %d\n", ret);
+ goto err_dbvdd2;
+ }
+
+ ret = regulator_bulk_enable(ARRAY_SIZE(wm5100->core_supplies),
+ wm5100->core_supplies);
+ if (ret != 0) {
+ dev_err(&i2c->dev, "Failed to enable core supplies: %d\n",
+ ret);
+ goto err_dbvdd3;
+ }
+
+ if (wm5100->pdata.ldo_ena) {
+ ret = gpio_request_one(wm5100->pdata.ldo_ena,
+ GPIOF_OUT_INIT_HIGH, "WM5100 LDOENA");
+ if (ret < 0) {
+ dev_err(&i2c->dev, "Failed to request LDOENA %d: %d\n",
+ wm5100->pdata.ldo_ena, ret);
+ goto err_enable;
+ }
+ msleep(2);
+ }
+
+ if (wm5100->pdata.reset) {
+ ret = gpio_request_one(wm5100->pdata.reset,
+ GPIOF_OUT_INIT_HIGH, "WM5100 /RESET");
+ if (ret < 0) {
+ dev_err(&i2c->dev, "Failed to request /RESET %d: %d\n",
+ wm5100->pdata.reset, ret);
+ goto err_ldo;
+ }
+ }
+
+ ret = regmap_read(wm5100->regmap, WM5100_SOFTWARE_RESET, ®);
+ if (ret < 0) {
+ dev_err(&i2c->dev, "Failed to read ID register\n");
+ goto err_reset;
+ }
+ switch (reg) {
+ case 0x8997:
+ case 0x5100:
+ break;
+
+ default:
+ dev_err(&i2c->dev, "Device is not a WM5100, ID is %x\n", reg);
+ ret = -EINVAL;
+ goto err_reset;
+ }
+
+ ret = regmap_read(wm5100->regmap, WM5100_DEVICE_REVISION, ®);
+ if (ret < 0) {
+ dev_err(&i2c->dev, "Failed to read revision register\n");
+ goto err_reset;
+ }
+ wm5100->rev = reg & WM5100_DEVICE_REVISION_MASK;
+
+ dev_info(&i2c->dev, "revision %c\n", wm5100->rev + 'A');
+
+ ret = wm5100_reset(wm5100);
+ if (ret < 0) {
+ dev_err(&i2c->dev, "Failed to issue reset\n");
+ goto err_reset;
+ }
+
+ wm5100_init_gpio(i2c);
+
+ for (i = 0; i < ARRAY_SIZE(wm5100->pdata.gpio_defaults); i++) {
+ if (!wm5100->pdata.gpio_defaults[i])
+ continue;
+
+ regmap_write(wm5100->regmap, WM5100_GPIO_CTRL_1 + i,
+ wm5100->pdata.gpio_defaults[i]);
+ }
+
+ for (i = 0; i < ARRAY_SIZE(wm5100->pdata.in_mode); i++) {
+ regmap_update_bits(wm5100->regmap, WM5100_IN1L_CONTROL,
+ WM5100_IN1_MODE_MASK |
+ WM5100_IN1_DMIC_SUP_MASK,
+ (wm5100->pdata.in_mode[i] <<
+ WM5100_IN1_MODE_SHIFT) |
+ (wm5100->pdata.dmic_sup[i] <<
+ WM5100_IN1_DMIC_SUP_SHIFT));
+ }
+
+ ret = snd_soc_register_codec(&i2c->dev,
+ &soc_codec_dev_wm5100, wm5100_dai,
+ ARRAY_SIZE(wm5100_dai));
+ if (ret < 0) {
+ dev_err(&i2c->dev, "Failed to register WM5100: %d\n", ret);
+ goto err_reset;
+ }
+
+ return ret;
+
err_reset:
+ wm5100_free_gpio(i2c);
if (wm5100->pdata.reset) {
gpio_set_value_cansleep(wm5100->pdata.reset, 1);
gpio_free(wm5100->pdata.reset);
@@ -2685,22 +2781,18 @@
err_core:
regulator_bulk_free(ARRAY_SIZE(wm5100->core_supplies),
wm5100->core_supplies);
-
+err_regmap:
+ regmap_exit(wm5100->regmap);
+err:
return ret;
}
-static int wm5100_remove(struct snd_soc_codec *codec)
+static __devexit int wm5100_i2c_remove(struct i2c_client *client)
{
- struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
- struct i2c_client *i2c = to_i2c_client(codec->dev);
+ struct wm5100_priv *wm5100 = i2c_get_clientdata(client);
- wm5100_set_bias_level(codec, SND_SOC_BIAS_OFF);
- if (wm5100->pdata.hp_pol) {
- gpio_free(wm5100->pdata.hp_pol);
- }
- if (i2c->irq)
- free_irq(i2c->irq, codec);
- wm5100_free_gpio(codec);
+ snd_soc_unregister_codec(&client->dev);
+ wm5100_free_gpio(client);
if (wm5100->pdata.reset) {
gpio_set_value_cansleep(wm5100->pdata.reset, 1);
gpio_free(wm5100->pdata.reset);
@@ -2714,69 +2806,8 @@
regulator_put(wm5100->cpvdd);
regulator_bulk_free(ARRAY_SIZE(wm5100->core_supplies),
wm5100->core_supplies);
- return 0;
-}
+ regmap_exit(wm5100->regmap);
-static struct snd_soc_codec_driver soc_codec_dev_wm5100 = {
- .probe = wm5100_probe,
- .remove = wm5100_remove,
-
- .set_sysclk = wm5100_set_sysclk,
- .set_pll = wm5100_set_fll,
- .set_bias_level = wm5100_set_bias_level,
- .idle_bias_off = 1,
-
- .seq_notifier = wm5100_seq_notifier,
- .controls = wm5100_snd_controls,
- .num_controls = ARRAY_SIZE(wm5100_snd_controls),
- .dapm_widgets = wm5100_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(wm5100_dapm_widgets),
- .dapm_routes = wm5100_dapm_routes,
- .num_dapm_routes = ARRAY_SIZE(wm5100_dapm_routes),
-
- .reg_cache_size = ARRAY_SIZE(wm5100_reg_defaults),
- .reg_word_size = sizeof(u16),
- .compress_type = SND_SOC_RBTREE_COMPRESSION,
- .reg_cache_default = wm5100_reg_defaults,
-
- .volatile_register = wm5100_volatile_register,
- .readable_register = wm5100_readable_register,
-};
-
-static __devinit int wm5100_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
-{
- struct wm5100_pdata *pdata = dev_get_platdata(&i2c->dev);
- struct wm5100_priv *wm5100;
- int ret, i;
-
- wm5100 = kzalloc(sizeof(struct wm5100_priv), GFP_KERNEL);
- if (wm5100 == NULL)
- return -ENOMEM;
-
- for (i = 0; i < ARRAY_SIZE(wm5100->fll); i++)
- init_completion(&wm5100->fll[i].lock);
-
- if (pdata)
- wm5100->pdata = *pdata;
-
- i2c_set_clientdata(i2c, wm5100);
-
- ret = snd_soc_register_codec(&i2c->dev,
- &soc_codec_dev_wm5100, wm5100_dai,
- ARRAY_SIZE(wm5100_dai));
- if (ret < 0) {
- dev_err(&i2c->dev, "Failed to register WM5100: %d\n", ret);
- kfree(wm5100);
- }
-
- return ret;
-}
-
-static __devexit int wm5100_i2c_remove(struct i2c_client *client)
-{
- snd_soc_unregister_codec(&client->dev);
- kfree(i2c_get_clientdata(client));
return 0;
}
diff --git a/sound/soc/codecs/wm5100.h b/sound/soc/codecs/wm5100.h
index 9707596..25cb601 100644
--- a/sound/soc/codecs/wm5100.h
+++ b/sound/soc/codecs/wm5100.h
@@ -15,6 +15,7 @@
#define WM5100_ASOC_H
#include <sound/soc.h>
+#include <linux/regmap.h>
int wm5100_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack);
@@ -5147,9 +5148,9 @@
#define WM5100_DSP3_ZM_END_SHIFT 0 /* DSP3_ZM_END - [15:0] */
#define WM5100_DSP3_ZM_END_WIDTH 16 /* DSP3_ZM_END - [15:0] */
-int wm5100_readable_register(struct snd_soc_codec *codec, unsigned int reg);
-int wm5100_volatile_register(struct snd_soc_codec *codec, unsigned int reg);
+bool wm5100_readable_register(struct device *dev, unsigned int reg);
+bool wm5100_volatile_register(struct device *dev, unsigned int reg);
-extern u16 wm5100_reg_defaults[WM5100_MAX_REGISTER + 1];
+extern struct reg_default wm5100_reg_defaults[WM5100_REGISTER_COUNT];
#endif
diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c
index 35f3ad83..8c4c959 100644
--- a/sound/soc/codecs/wm8350.c
+++ b/sound/soc/codecs/wm8350.c
@@ -696,7 +696,7 @@
SND_SOC_DAPM_INPUT("IN3L"),
};
-static const struct snd_soc_dapm_route audio_map[] = {
+static const struct snd_soc_dapm_route wm8350_dapm_routes[] = {
/* left playback mixer */
{"Left Playback Mixer", "Playback Switch", "Left DAC"},
@@ -777,29 +777,6 @@
{"Beep", NULL, "IN3R PGA"},
};
-static int wm8350_add_widgets(struct snd_soc_codec *codec)
-{
- struct snd_soc_dapm_context *dapm = &codec->dapm;
- int ret;
-
- ret = snd_soc_dapm_new_controls(dapm,
- wm8350_dapm_widgets,
- ARRAY_SIZE(wm8350_dapm_widgets));
- if (ret != 0) {
- dev_err(codec->dev, "dapm control register failed\n");
- return ret;
- }
-
- /* set up audio paths */
- ret = snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
- if (ret != 0) {
- dev_err(codec->dev, "DAPM route register failed\n");
- return ret;
- }
-
- return 0;
-}
-
static int wm8350_set_dai_sysclk(struct snd_soc_dai *codec_dai,
int clk_id, unsigned int freq, int dir)
{
@@ -1315,7 +1292,7 @@
return 0;
}
-static int wm8350_suspend(struct snd_soc_codec *codec, pm_message_t state)
+static int wm8350_suspend(struct snd_soc_codec *codec)
{
wm8350_set_bias_level(codec, SND_SOC_BIAS_OFF);
return 0;
@@ -1511,7 +1488,7 @@
SNDRV_PCM_FMTBIT_S20_3LE |\
SNDRV_PCM_FMTBIT_S24_LE)
-static struct snd_soc_dai_ops wm8350_dai_ops = {
+static const struct snd_soc_dai_ops wm8350_dai_ops = {
.hw_params = wm8350_pcm_hw_params,
.digital_mute = wm8350_mute,
.trigger = wm8350_pcm_trigger,
@@ -1553,7 +1530,8 @@
return -EINVAL;
}
- priv = kzalloc(sizeof(struct wm8350_data), GFP_KERNEL);
+ priv = devm_kzalloc(codec->dev, sizeof(struct wm8350_data),
+ GFP_KERNEL);
if (priv == NULL)
return -ENOMEM;
snd_soc_codec_set_drvdata(codec, priv);
@@ -1564,7 +1542,7 @@
ret = regulator_bulk_get(wm8350->dev, ARRAY_SIZE(priv->supplies),
priv->supplies);
if (ret != 0)
- goto err_priv;
+ return ret;
wm8350->codec.codec = codec;
codec->control_data = wm8350;
@@ -1633,17 +1611,9 @@
wm8350_mic_handler, 0, "Microphone detect", priv);
- snd_soc_add_controls(codec, wm8350_snd_controls,
- ARRAY_SIZE(wm8350_snd_controls));
- wm8350_add_widgets(codec);
-
wm8350_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
return 0;
-
-err_priv:
- kfree(priv);
- return ret;
}
static int wm8350_codec_remove(struct snd_soc_codec *codec)
@@ -1676,7 +1646,7 @@
wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA);
regulator_bulk_free(ARRAY_SIZE(priv->supplies), priv->supplies);
- kfree(priv);
+
return 0;
}
@@ -1688,6 +1658,13 @@
.read = wm8350_codec_read,
.write = wm8350_codec_write,
.set_bias_level = wm8350_set_bias_level,
+
+ .controls = wm8350_snd_controls,
+ .num_controls = ARRAY_SIZE(wm8350_snd_controls),
+ .dapm_widgets = wm8350_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(wm8350_dapm_widgets),
+ .dapm_routes = wm8350_dapm_routes,
+ .num_dapm_routes = ARRAY_SIZE(wm8350_dapm_routes),
};
static int __devinit wm8350_probe(struct platform_device *pdev)
@@ -1711,17 +1688,7 @@
.remove = __devexit_p(wm8350_remove),
};
-static __init int wm8350_init(void)
-{
- return platform_driver_register(&wm8350_codec_driver);
-}
-module_init(wm8350_init);
-
-static __exit void wm8350_exit(void)
-{
- platform_driver_unregister(&wm8350_codec_driver);
-}
-module_exit(wm8350_exit);
+module_platform_driver(wm8350_codec_driver);
MODULE_DESCRIPTION("ASoC WM8350 driver");
MODULE_AUTHOR("Liam Girdwood");
diff --git a/sound/soc/codecs/wm8400.c b/sound/soc/codecs/wm8400.c
index dc13be2..898979d 100644
--- a/sound/soc/codecs/wm8400.c
+++ b/sound/soc/codecs/wm8400.c
@@ -353,13 +353,6 @@
};
-/* add non dapm controls */
-static int wm8400_add_controls(struct snd_soc_codec *codec)
-{
- return snd_soc_add_controls(codec, wm8400_snd_controls,
- ARRAY_SIZE(wm8400_snd_controls));
-}
-
/*
* _DAPM_ Controls
*/
@@ -766,8 +759,8 @@
NULL, 0),
/* MICBIAS */
-SND_SOC_DAPM_MICBIAS("MICBIAS", WM8400_POWER_MANAGEMENT_1,
- WM8400_MIC1BIAS_ENA_SHIFT, 0),
+SND_SOC_DAPM_SUPPLY("MICBIAS", WM8400_POWER_MANAGEMENT_1,
+ WM8400_MIC1BIAS_ENA_SHIFT, 0, NULL, 0),
SND_SOC_DAPM_OUTPUT("LON"),
SND_SOC_DAPM_OUTPUT("LOP"),
@@ -783,7 +776,7 @@
SND_SOC_DAPM_OUTPUT("Internal DAC Sink"),
};
-static const struct snd_soc_dapm_route audio_map[] = {
+static const struct snd_soc_dapm_route wm8400_dapm_routes[] = {
/* Make DACs turn on when playing even if not mixed into any outputs */
{"Internal DAC Sink", NULL, "Left DAC"},
{"Internal DAC Sink", NULL, "Right DAC"},
@@ -909,17 +902,6 @@
{"RON", NULL, "RONMIX"},
};
-static int wm8400_add_widgets(struct snd_soc_codec *codec)
-{
- struct snd_soc_dapm_context *dapm = &codec->dapm;
-
- snd_soc_dapm_new_controls(dapm, wm8400_dapm_widgets,
- ARRAY_SIZE(wm8400_dapm_widgets));
- snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
-
- return 0;
-}
-
/*
* Clock after FLL and dividers
*/
@@ -1059,7 +1041,7 @@
wm8400_write(codec, WM8400_FLL_CONTROL_3, factors.n);
reg = wm8400_read(codec, WM8400_FLL_CONTROL_4);
- reg &= WM8400_FLL_OUTDIV_MASK;
+ reg &= ~WM8400_FLL_OUTDIV_MASK;
reg |= factors.outdiv;
wm8400_write(codec, WM8400_FLL_CONTROL_4, reg);
@@ -1316,7 +1298,7 @@
#define WM8400_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
SNDRV_PCM_FMTBIT_S24_LE)
-static struct snd_soc_dai_ops wm8400_dai_ops = {
+static const struct snd_soc_dai_ops wm8400_dai_ops = {
.hw_params = wm8400_hw_params,
.digital_mute = wm8400_mute,
.set_fmt = wm8400_set_dai_fmt,
@@ -1352,7 +1334,7 @@
.ops = &wm8400_dai_ops,
};
-static int wm8400_suspend(struct snd_soc_codec *codec, pm_message_t state)
+static int wm8400_suspend(struct snd_soc_codec *codec)
{
wm8400_set_bias_level(codec, SND_SOC_BIAS_OFF);
@@ -1383,7 +1365,8 @@
int ret;
u16 reg;
- priv = kzalloc(sizeof(struct wm8400_priv), GFP_KERNEL);
+ priv = devm_kzalloc(codec->dev, sizeof(struct wm8400_priv),
+ GFP_KERNEL);
if (priv == NULL)
return -ENOMEM;
@@ -1395,7 +1378,7 @@
ARRAY_SIZE(power), &power[0]);
if (ret != 0) {
dev_err(codec->dev, "Failed to get regulators: %d\n", ret);
- goto err;
+ return ret;
}
INIT_WORK(&priv->work, wm8400_probe_deferred);
@@ -1420,20 +1403,15 @@
ret = -EINVAL;
goto err_regulator;
}
- wm8400_add_controls(codec);
- wm8400_add_widgets(codec);
return 0;
err_regulator:
regulator_bulk_free(ARRAY_SIZE(power), power);
-err:
- kfree(priv);
return ret;
}
static int wm8400_codec_remove(struct snd_soc_codec *codec)
{
- struct wm8400_priv *priv = snd_soc_codec_get_drvdata(codec);
u16 reg;
reg = wm8400_read(codec, WM8400_POWER_MANAGEMENT_1);
@@ -1441,7 +1419,6 @@
reg & (~WM8400_CODEC_ENA));
regulator_bulk_free(ARRAY_SIZE(power), power);
- kfree(priv);
return 0;
}
@@ -1454,6 +1431,13 @@
.read = wm8400_read,
.write = wm8400_write,
.set_bias_level = wm8400_set_bias_level,
+
+ .controls = wm8400_snd_controls,
+ .num_controls = ARRAY_SIZE(wm8400_snd_controls),
+ .dapm_widgets = wm8400_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(wm8400_dapm_widgets),
+ .dapm_routes = wm8400_dapm_routes,
+ .num_dapm_routes = ARRAY_SIZE(wm8400_dapm_routes),
};
static int __devinit wm8400_probe(struct platform_device *pdev)
@@ -1477,17 +1461,7 @@
.remove = __devexit_p(wm8400_remove),
};
-static __init int wm8400_init(void)
-{
- return platform_driver_register(&wm8400_codec_driver);
-}
-module_init(wm8400_init);
-
-static __exit void wm8400_exit(void)
-{
- platform_driver_unregister(&wm8400_codec_driver);
-}
-module_exit(wm8400_exit);
+module_platform_driver(wm8400_codec_driver);
MODULE_DESCRIPTION("ASoC WM8400 driver");
MODULE_AUTHOR("Mark Brown");
diff --git a/sound/soc/codecs/wm8510.c b/sound/soc/codecs/wm8510.c
index 07c9cc7..9166126 100644
--- a/sound/soc/codecs/wm8510.c
+++ b/sound/soc/codecs/wm8510.c
@@ -17,7 +17,6 @@
#include <linux/delay.h>
#include <linux/pm.h>
#include <linux/i2c.h>
-#include <linux/platform_device.h>
#include <linux/spi/spi.h>
#include <linux/slab.h>
#include <linux/of_device.h>
@@ -182,7 +181,7 @@
SND_SOC_DAPM_OUTPUT("SPKOUTN"),
};
-static const struct snd_soc_dapm_route audio_map[] = {
+static const struct snd_soc_dapm_route wm8510_dapm_routes[] = {
/* Mono output mixer */
{"Mono Mixer", "PCM Playback Switch", "DAC"},
{"Mono Mixer", "Aux Playback Switch", "Aux Input"},
@@ -214,17 +213,6 @@
{"ADC", NULL, "Boost Mixer"},
};
-static int wm8510_add_widgets(struct snd_soc_codec *codec)
-{
- struct snd_soc_dapm_context *dapm = &codec->dapm;
-
- snd_soc_dapm_new_controls(dapm, wm8510_dapm_widgets,
- ARRAY_SIZE(wm8510_dapm_widgets));
- snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
-
- return 0;
-}
-
struct pll_ {
unsigned int pre_div:4; /* prescale - 1 */
unsigned int n:4;
@@ -509,7 +497,7 @@
#define WM8510_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
-static struct snd_soc_dai_ops wm8510_dai_ops = {
+static const struct snd_soc_dai_ops wm8510_dai_ops = {
.hw_params = wm8510_pcm_hw_params,
.digital_mute = wm8510_mute,
.set_fmt = wm8510_set_dai_fmt,
@@ -535,7 +523,7 @@
.symmetric_rates = 1,
};
-static int wm8510_suspend(struct snd_soc_codec *codec, pm_message_t state)
+static int wm8510_suspend(struct snd_soc_codec *codec)
{
wm8510_set_bias_level(codec, SND_SOC_BIAS_OFF);
return 0;
@@ -562,9 +550,6 @@
/* power on device */
wm8510_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
- snd_soc_add_controls(codec, wm8510_snd_controls,
- ARRAY_SIZE(wm8510_snd_controls));
- wm8510_add_widgets(codec);
return ret;
}
@@ -588,6 +573,13 @@
.reg_cache_size = ARRAY_SIZE(wm8510_reg),
.reg_word_size = sizeof(u16),
.reg_cache_default =wm8510_reg,
+
+ .controls = wm8510_snd_controls,
+ .num_controls = ARRAY_SIZE(wm8510_snd_controls),
+ .dapm_widgets = wm8510_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(wm8510_dapm_widgets),
+ .dapm_routes = wm8510_dapm_routes,
+ .num_dapm_routes = ARRAY_SIZE(wm8510_dapm_routes),
};
static const struct of_device_id wm8510_of_match[] = {
@@ -667,7 +659,7 @@
static struct i2c_driver wm8510_i2c_driver = {
.driver = {
- .name = "wm8510-codec",
+ .name = "wm8510",
.owner = THIS_MODULE,
.of_match_table = wm8510_of_match,
},
diff --git a/sound/soc/codecs/wm8523.c b/sound/soc/codecs/wm8523.c
index db7a681..7fea2c3 100644
--- a/sound/soc/codecs/wm8523.c
+++ b/sound/soc/codecs/wm8523.c
@@ -17,7 +17,6 @@
#include <linux/delay.h>
#include <linux/pm.h>
#include <linux/i2c.h>
-#include <linux/platform_device.h>
#include <linux/regulator/consumer.h>
#include <linux/slab.h>
#include <linux/of_device.h>
@@ -365,7 +364,7 @@
#define WM8523_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
-static struct snd_soc_dai_ops wm8523_dai_ops = {
+static const struct snd_soc_dai_ops wm8523_dai_ops = {
.startup = wm8523_startup,
.hw_params = wm8523_hw_params,
.set_sysclk = wm8523_set_dai_sysclk,
@@ -385,7 +384,7 @@
};
#ifdef CONFIG_PM
-static int wm8523_suspend(struct snd_soc_codec *codec, pm_message_t state)
+static int wm8523_suspend(struct snd_soc_codec *codec)
{
wm8523_set_bias_level(codec, SND_SOC_BIAS_OFF);
return 0;
diff --git a/sound/soc/codecs/wm8580.c b/sound/soc/codecs/wm8580.c
index 8212b3c..2112851 100644
--- a/sound/soc/codecs/wm8580.c
+++ b/sound/soc/codecs/wm8580.c
@@ -23,7 +23,6 @@
#include <linux/delay.h>
#include <linux/pm.h>
#include <linux/i2c.h>
-#include <linux/platform_device.h>
#include <linux/regulator/consumer.h>
#include <linux/slab.h>
#include <linux/of_device.h>
@@ -273,7 +272,7 @@
SND_SOC_DAPM_INPUT("AINR"),
};
-static const struct snd_soc_dapm_route audio_map[] = {
+static const struct snd_soc_dapm_route wm8580_dapm_routes[] = {
{ "VOUT1L", NULL, "DAC1" },
{ "VOUT1R", NULL, "DAC1" },
@@ -287,17 +286,6 @@
{ "ADC", NULL, "AINR" },
};
-static int wm8580_add_widgets(struct snd_soc_codec *codec)
-{
- struct snd_soc_dapm_context *dapm = &codec->dapm;
-
- snd_soc_dapm_new_controls(dapm, wm8580_dapm_widgets,
- ARRAY_SIZE(wm8580_dapm_widgets));
- snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
-
- return 0;
-}
-
/* PLL divisors */
struct _pll_div {
u32 prescale:1;
@@ -682,7 +670,7 @@
{
struct snd_soc_codec *codec = dai->codec;
struct wm8580_priv *wm8580 = snd_soc_codec_get_drvdata(codec);
- int sel, sel_mask, sel_shift;
+ int ret, sel, sel_mask, sel_shift;
switch (dai->driver->id) {
case WM8580_DAI_PAIFRX:
@@ -723,7 +711,11 @@
/* We really should validate PLL settings but not yet */
wm8580->sysclk[dai->driver->id] = freq;
- return snd_soc_update_bits(codec, WM8580_CLKSEL, sel_mask, sel);
+ ret = snd_soc_update_bits(codec, WM8580_CLKSEL, sel_mask, sel);
+ if (ret < 0)
+ return ret;
+
+ return 0;
}
static int wm8580_digital_mute(struct snd_soc_dai *codec_dai, int mute)
@@ -776,7 +768,7 @@
#define WM8580_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
-static struct snd_soc_dai_ops wm8580_dai_ops_playback = {
+static const struct snd_soc_dai_ops wm8580_dai_ops_playback = {
.set_sysclk = wm8580_set_sysclk,
.hw_params = wm8580_paif_hw_params,
.set_fmt = wm8580_set_paif_dai_fmt,
@@ -785,7 +777,7 @@
.digital_mute = wm8580_digital_mute,
};
-static struct snd_soc_dai_ops wm8580_dai_ops_capture = {
+static const struct snd_soc_dai_ops wm8580_dai_ops_capture = {
.set_sysclk = wm8580_set_sysclk,
.hw_params = wm8580_paif_hw_params,
.set_fmt = wm8580_set_paif_dai_fmt,
@@ -857,10 +849,6 @@
wm8580_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
- snd_soc_add_controls(codec, wm8580_snd_controls,
- ARRAY_SIZE(wm8580_snd_controls));
- wm8580_add_widgets(codec);
-
return 0;
err_regulator_enable:
@@ -890,6 +878,13 @@
.reg_cache_size = ARRAY_SIZE(wm8580_reg),
.reg_word_size = sizeof(u16),
.reg_cache_default = wm8580_reg,
+
+ .controls = wm8580_snd_controls,
+ .num_controls = ARRAY_SIZE(wm8580_snd_controls),
+ .dapm_widgets = wm8580_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(wm8580_dapm_widgets),
+ .dapm_routes = wm8580_dapm_routes,
+ .num_dapm_routes = ARRAY_SIZE(wm8580_dapm_routes),
};
static const struct of_device_id wm8580_of_match[] = {
diff --git a/sound/soc/codecs/wm8711.c b/sound/soc/codecs/wm8711.c
index 076bdb9..0b76d1d 100644
--- a/sound/soc/codecs/wm8711.c
+++ b/sound/soc/codecs/wm8711.c
@@ -18,7 +18,6 @@
#include <linux/delay.h>
#include <linux/pm.h>
#include <linux/i2c.h>
-#include <linux/platform_device.h>
#include <linux/spi/spi.h>
#include <linux/slab.h>
#include <linux/of_device.h>
@@ -318,7 +317,7 @@
#define WM8711_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
SNDRV_PCM_FMTBIT_S24_LE)
-static struct snd_soc_dai_ops wm8711_ops = {
+static const struct snd_soc_dai_ops wm8711_ops = {
.prepare = wm8711_pcm_prepare,
.hw_params = wm8711_hw_params,
.shutdown = wm8711_shutdown,
@@ -339,7 +338,7 @@
.ops = &wm8711_ops,
};
-static int wm8711_suspend(struct snd_soc_codec *codec, pm_message_t state)
+static int wm8711_suspend(struct snd_soc_codec *codec)
{
snd_soc_write(codec, WM8711_ACTIVE, 0x0);
wm8711_set_bias_level(codec, SND_SOC_BIAS_OFF);
@@ -375,9 +374,6 @@
snd_soc_update_bits(codec, WM8711_LOUT1V, 0x0100, 0x0100);
snd_soc_update_bits(codec, WM8711_ROUT1V, 0x0100, 0x0100);
- snd_soc_add_controls(codec, wm8711_snd_controls,
- ARRAY_SIZE(wm8711_snd_controls));
-
return ret;
}
@@ -398,6 +394,8 @@
.reg_cache_size = ARRAY_SIZE(wm8711_reg),
.reg_word_size = sizeof(u16),
.reg_cache_default = wm8711_reg,
+ .controls = wm8711_snd_controls,
+ .num_controls = ARRAY_SIZE(wm8711_snd_controls),
.dapm_widgets = wm8711_dapm_widgets,
.num_dapm_widgets = ARRAY_SIZE(wm8711_dapm_widgets),
.dapm_routes = wm8711_intercon,
diff --git a/sound/soc/codecs/wm8727.c b/sound/soc/codecs/wm8727.c
index 7488082..e817056 100644
--- a/sound/soc/codecs/wm8727.c
+++ b/sound/soc/codecs/wm8727.c
@@ -59,7 +59,7 @@
static struct platform_driver wm8727_codec_driver = {
.driver = {
- .name = "wm8727-codec",
+ .name = "wm8727",
.owner = THIS_MODULE,
},
@@ -67,17 +67,7 @@
.remove = __devexit_p(wm8727_remove),
};
-static int __init wm8727_init(void)
-{
- return platform_driver_register(&wm8727_codec_driver);
-}
-module_init(wm8727_init);
-
-static void __exit wm8727_exit(void)
-{
- platform_driver_unregister(&wm8727_codec_driver);
-}
-module_exit(wm8727_exit);
+module_platform_driver(wm8727_codec_driver);
MODULE_DESCRIPTION("ASoC wm8727 driver");
MODULE_AUTHOR("Neil Jones");
diff --git a/sound/soc/codecs/wm8728.c b/sound/soc/codecs/wm8728.c
index 04b027e..fc3d59e 100644
--- a/sound/soc/codecs/wm8728.c
+++ b/sound/soc/codecs/wm8728.c
@@ -196,7 +196,7 @@
#define WM8728_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
SNDRV_PCM_FMTBIT_S24_LE)
-static struct snd_soc_dai_ops wm8728_dai_ops = {
+static const struct snd_soc_dai_ops wm8728_dai_ops = {
.hw_params = wm8728_hw_params,
.digital_mute = wm8728_mute,
.set_fmt = wm8728_set_dai_fmt,
@@ -214,7 +214,7 @@
.ops = &wm8728_dai_ops,
};
-static int wm8728_suspend(struct snd_soc_codec *codec, pm_message_t state)
+static int wm8728_suspend(struct snd_soc_codec *codec)
{
wm8728_set_bias_level(codec, SND_SOC_BIAS_OFF);
@@ -243,9 +243,6 @@
/* power on device */
wm8728_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
- snd_soc_add_controls(codec, wm8728_snd_controls,
- ARRAY_SIZE(wm8728_snd_controls));
-
return ret;
}
@@ -264,6 +261,8 @@
.reg_cache_size = ARRAY_SIZE(wm8728_reg_defaults),
.reg_word_size = sizeof(u16),
.reg_cache_default = wm8728_reg_defaults,
+ .controls = wm8728_snd_controls,
+ .num_controls = ARRAY_SIZE(wm8728_snd_controls),
.dapm_widgets = wm8728_dapm_widgets,
.num_dapm_widgets = ARRAY_SIZE(wm8728_dapm_widgets),
.dapm_routes = wm8728_intercon,
diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c
index a7c9ae1..8821af7 100644
--- a/sound/soc/codecs/wm8731.c
+++ b/sound/soc/codecs/wm8731.c
@@ -19,7 +19,6 @@
#include <linux/pm.h>
#include <linux/i2c.h>
#include <linux/slab.h>
-#include <linux/platform_device.h>
#include <linux/regulator/consumer.h>
#include <linux/spi/spi.h>
#include <linux/of_device.h>
@@ -465,7 +464,7 @@
#define WM8731_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
SNDRV_PCM_FMTBIT_S24_LE)
-static struct snd_soc_dai_ops wm8731_dai_ops = {
+static const struct snd_soc_dai_ops wm8731_dai_ops = {
.hw_params = wm8731_hw_params,
.digital_mute = wm8731_mute,
.set_sysclk = wm8731_set_dai_sysclk,
@@ -491,7 +490,7 @@
};
#ifdef CONFIG_PM
-static int wm8731_suspend(struct snd_soc_codec *codec, pm_message_t state)
+static int wm8731_suspend(struct snd_soc_codec *codec)
{
wm8731_set_bias_level(codec, SND_SOC_BIAS_OFF);
@@ -554,9 +553,6 @@
/* Disable bypass path by default */
snd_soc_update_bits(codec, WM8731_APANA, 0x8, 0);
- snd_soc_add_controls(codec, wm8731_snd_controls,
- ARRAY_SIZE(wm8731_snd_controls));
-
/* Regulators will have been enabled by bias management */
regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies), wm8731->supplies);
@@ -596,6 +592,8 @@
.num_dapm_widgets = ARRAY_SIZE(wm8731_dapm_widgets),
.dapm_routes = wm8731_intercon,
.num_dapm_routes = ARRAY_SIZE(wm8731_intercon),
+ .controls = wm8731_snd_controls,
+ .num_controls = ARRAY_SIZE(wm8731_snd_controls),
};
static const struct of_device_id wm8731_of_match[] = {
diff --git a/sound/soc/codecs/wm8737.c b/sound/soc/codecs/wm8737.c
index f6aef58..ff95e62c 100644
--- a/sound/soc/codecs/wm8737.c
+++ b/sound/soc/codecs/wm8737.c
@@ -16,7 +16,6 @@
#include <linux/delay.h>
#include <linux/pm.h>
#include <linux/i2c.h>
-#include <linux/platform_device.h>
#include <linux/regulator/consumer.h>
#include <linux/spi/spi.h>
#include <linux/slab.h>
@@ -521,7 +520,7 @@
#define WM8737_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
-static struct snd_soc_dai_ops wm8737_dai_ops = {
+static const struct snd_soc_dai_ops wm8737_dai_ops = {
.hw_params = wm8737_hw_params,
.set_sysclk = wm8737_set_dai_sysclk,
.set_fmt = wm8737_set_dai_fmt,
@@ -540,7 +539,7 @@
};
#ifdef CONFIG_PM
-static int wm8737_suspend(struct snd_soc_codec *codec, pm_message_t state)
+static int wm8737_suspend(struct snd_soc_codec *codec)
{
wm8737_set_bias_level(codec, SND_SOC_BIAS_OFF);
return 0;
diff --git a/sound/soc/codecs/wm8741.c b/sound/soc/codecs/wm8741.c
index 57ad22a..3941f50 100644
--- a/sound/soc/codecs/wm8741.c
+++ b/sound/soc/codecs/wm8741.c
@@ -18,7 +18,6 @@
#include <linux/pm.h>
#include <linux/i2c.h>
#include <linux/spi/spi.h>
-#include <linux/platform_device.h>
#include <linux/regulator/consumer.h>
#include <linux/slab.h>
#include <linux/of_device.h>
@@ -86,24 +85,13 @@
SND_SOC_DAPM_OUTPUT("VOUTRN"),
};
-static const struct snd_soc_dapm_route intercon[] = {
+static const struct snd_soc_dapm_route wm8741_dapm_routes[] = {
{ "VOUTLP", NULL, "DACL" },
{ "VOUTLN", NULL, "DACL" },
{ "VOUTRP", NULL, "DACR" },
{ "VOUTRN", NULL, "DACR" },
};
-static int wm8741_add_widgets(struct snd_soc_codec *codec)
-{
- struct snd_soc_dapm_context *dapm = &codec->dapm;
-
- snd_soc_dapm_new_controls(dapm, wm8741_dapm_widgets,
- ARRAY_SIZE(wm8741_dapm_widgets));
- snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
-
- return 0;
-}
-
static struct {
int value;
int ratio;
@@ -382,7 +370,7 @@
#define WM8741_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
-static struct snd_soc_dai_ops wm8741_dai_ops = {
+static const struct snd_soc_dai_ops wm8741_dai_ops = {
.startup = wm8741_startup,
.hw_params = wm8741_hw_params,
.set_sysclk = wm8741_set_dai_sysclk,
@@ -457,10 +445,6 @@
snd_soc_update_bits(codec, WM8741_DACRMSB_ATTENUATION,
WM8741_UPDATERM, WM8741_UPDATERM);
- snd_soc_add_controls(codec, wm8741_snd_controls,
- ARRAY_SIZE(wm8741_snd_controls));
- wm8741_add_widgets(codec);
-
dev_dbg(codec->dev, "Successful registration\n");
return ret;
@@ -489,6 +473,13 @@
.reg_cache_size = ARRAY_SIZE(wm8741_reg_defaults),
.reg_word_size = sizeof(u16),
.reg_cache_default = wm8741_reg_defaults,
+
+ .controls = wm8741_snd_controls,
+ .num_controls = ARRAY_SIZE(wm8741_snd_controls),
+ .dapm_widgets = wm8741_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(wm8741_dapm_widgets),
+ .dapm_routes = wm8741_dapm_routes,
+ .num_dapm_routes = ARRAY_SIZE(wm8741_dapm_routes),
};
static const struct of_device_id wm8741_of_match[] = {
@@ -504,7 +495,8 @@
struct wm8741_priv *wm8741;
int ret;
- wm8741 = kzalloc(sizeof(struct wm8741_priv), GFP_KERNEL);
+ wm8741 = devm_kzalloc(&i2c->dev, sizeof(struct wm8741_priv),
+ GFP_KERNEL);
if (wm8741 == NULL)
return -ENOMEM;
@@ -513,20 +505,13 @@
ret = snd_soc_register_codec(&i2c->dev,
&soc_codec_dev_wm8741, &wm8741_dai, 1);
- if (ret != 0)
- goto err;
return ret;
-
-err:
- kfree(wm8741);
- return ret;
}
static int wm8741_i2c_remove(struct i2c_client *client)
{
snd_soc_unregister_codec(&client->dev);
- kfree(i2c_get_clientdata(client));
return 0;
}
@@ -554,7 +539,8 @@
struct wm8741_priv *wm8741;
int ret;
- wm8741 = kzalloc(sizeof(struct wm8741_priv), GFP_KERNEL);
+ wm8741 = devm_kzalloc(&spi->dev, sizeof(struct wm8741_priv),
+ GFP_KERNEL);
if (wm8741 == NULL)
return -ENOMEM;
@@ -563,15 +549,12 @@
ret = snd_soc_register_codec(&spi->dev,
&soc_codec_dev_wm8741, &wm8741_dai, 1);
- if (ret < 0)
- kfree(wm8741);
return ret;
}
static int __devexit wm8741_spi_remove(struct spi_device *spi)
{
snd_soc_unregister_codec(&spi->dev);
- kfree(spi_get_drvdata(spi));
return 0;
}
diff --git a/sound/soc/codecs/wm8750.c b/sound/soc/codecs/wm8750.c
index ca75a81..e4c50ce 100644
--- a/sound/soc/codecs/wm8750.c
+++ b/sound/soc/codecs/wm8750.c
@@ -18,7 +18,6 @@
#include <linux/delay.h>
#include <linux/pm.h>
#include <linux/i2c.h>
-#include <linux/platform_device.h>
#include <linux/spi/spi.h>
#include <linux/slab.h>
#include <linux/of_device.h>
@@ -302,7 +301,7 @@
SND_SOC_DAPM_INPUT("RINPUT3"),
};
-static const struct snd_soc_dapm_route audio_map[] = {
+static const struct snd_soc_dapm_route wm8750_dapm_routes[] = {
/* left mixer */
{"Left Mixer", "Playback Switch", "Left DAC"},
{"Left Mixer", "Left Bypass Switch", "Left Line Mux"},
@@ -396,17 +395,6 @@
{"Right ADC", NULL, "Right ADC Mux"},
};
-static int wm8750_add_widgets(struct snd_soc_codec *codec)
-{
- struct snd_soc_dapm_context *dapm = &codec->dapm;
-
- snd_soc_dapm_new_controls(dapm, wm8750_dapm_widgets,
- ARRAY_SIZE(wm8750_dapm_widgets));
- snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
-
- return 0;
-}
-
struct _coeff_div {
u32 mclk;
u32 rate;
@@ -643,7 +631,7 @@
#define WM8750_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
SNDRV_PCM_FMTBIT_S24_LE)
-static struct snd_soc_dai_ops wm8750_dai_ops = {
+static const struct snd_soc_dai_ops wm8750_dai_ops = {
.hw_params = wm8750_pcm_hw_params,
.digital_mute = wm8750_mute,
.set_fmt = wm8750_set_dai_fmt,
@@ -667,7 +655,7 @@
.ops = &wm8750_dai_ops,
};
-static int wm8750_suspend(struct snd_soc_codec *codec, pm_message_t state)
+static int wm8750_suspend(struct snd_soc_codec *codec)
{
wm8750_set_bias_level(codec, SND_SOC_BIAS_OFF);
return 0;
@@ -709,9 +697,6 @@
snd_soc_update_bits(codec, WM8750_LINVOL, 0x0100, 0x0100);
snd_soc_update_bits(codec, WM8750_RINVOL, 0x0100, 0x0100);
- snd_soc_add_controls(codec, wm8750_snd_controls,
- ARRAY_SIZE(wm8750_snd_controls));
- wm8750_add_widgets(codec);
return ret;
}
@@ -730,6 +715,13 @@
.reg_cache_size = ARRAY_SIZE(wm8750_reg),
.reg_word_size = sizeof(u16),
.reg_cache_default = wm8750_reg,
+
+ .controls = wm8750_snd_controls,
+ .num_controls = ARRAY_SIZE(wm8750_snd_controls),
+ .dapm_widgets = wm8750_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(wm8750_dapm_widgets),
+ .dapm_routes = wm8750_dapm_routes,
+ .num_dapm_routes = ARRAY_SIZE(wm8750_dapm_routes),
};
static const struct of_device_id wm8750_of_match[] = {
@@ -745,7 +737,8 @@
struct wm8750_priv *wm8750;
int ret;
- wm8750 = kzalloc(sizeof(struct wm8750_priv), GFP_KERNEL);
+ wm8750 = devm_kzalloc(&spi->dev, sizeof(struct wm8750_priv),
+ GFP_KERNEL);
if (wm8750 == NULL)
return -ENOMEM;
@@ -754,15 +747,12 @@
ret = snd_soc_register_codec(&spi->dev,
&soc_codec_dev_wm8750, &wm8750_dai, 1);
- if (ret < 0)
- kfree(wm8750);
return ret;
}
static int __devexit wm8750_spi_remove(struct spi_device *spi)
{
snd_soc_unregister_codec(&spi->dev);
- kfree(spi_get_drvdata(spi));
return 0;
}
@@ -792,7 +782,8 @@
struct wm8750_priv *wm8750;
int ret;
- wm8750 = kzalloc(sizeof(struct wm8750_priv), GFP_KERNEL);
+ wm8750 = devm_kzalloc(&i2c->dev, sizeof(struct wm8750_priv),
+ GFP_KERNEL);
if (wm8750 == NULL)
return -ENOMEM;
@@ -801,15 +792,12 @@
ret = snd_soc_register_codec(&i2c->dev,
&soc_codec_dev_wm8750, &wm8750_dai, 1);
- if (ret < 0)
- kfree(wm8750);
return ret;
}
static __devexit int wm8750_i2c_remove(struct i2c_client *client)
{
snd_soc_unregister_codec(&client->dev);
- kfree(i2c_get_clientdata(client));
return 0;
}
diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c
index 3a629d0..b114c19 100644
--- a/sound/soc/codecs/wm8753.c
+++ b/sound/soc/codecs/wm8753.c
@@ -39,7 +39,6 @@
#include <linux/pm.h>
#include <linux/i2c.h>
#include <linux/of_device.h>
-#include <linux/platform_device.h>
#include <linux/spi/spi.h>
#include <linux/slab.h>
#include <sound/core.h>
@@ -486,7 +485,7 @@
SND_SOC_DAPM_VMID("VREF"),
};
-static const struct snd_soc_dapm_route audio_map[] = {
+static const struct snd_soc_dapm_route wm8753_dapm_routes[] = {
/* left mixer */
{"Left Mixer", "Left Playback Switch", "Left DAC"},
{"Left Mixer", "Voice Playback Switch", "Voice DAC"},
@@ -640,17 +639,6 @@
{"ACOP", NULL, "ALC Mixer"},
};
-static int wm8753_add_widgets(struct snd_soc_codec *codec)
-{
- struct snd_soc_dapm_context *dapm = &codec->dapm;
-
- snd_soc_dapm_new_controls(dapm, wm8753_dapm_widgets,
- ARRAY_SIZE(wm8753_dapm_widgets));
- snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
-
- return 0;
-}
-
/* PLL divisors */
struct _pll_div {
u32 div2:1;
@@ -1326,7 +1314,7 @@
* 3. Voice disabled - HIFI over HIFI
* 4. Voice disabled - HIFI over HIFI, uses voice DAI LRC for capture
*/
-static struct snd_soc_dai_ops wm8753_dai_ops_hifi_mode = {
+static const struct snd_soc_dai_ops wm8753_dai_ops_hifi_mode = {
.hw_params = wm8753_i2s_hw_params,
.digital_mute = wm8753_mute,
.set_fmt = wm8753_hifi_set_dai_fmt,
@@ -1335,7 +1323,7 @@
.set_sysclk = wm8753_set_dai_sysclk,
};
-static struct snd_soc_dai_ops wm8753_dai_ops_voice_mode = {
+static const struct snd_soc_dai_ops wm8753_dai_ops_voice_mode = {
.hw_params = wm8753_pcm_hw_params,
.digital_mute = wm8753_mute,
.set_fmt = wm8753_voice_set_dai_fmt,
@@ -1392,7 +1380,7 @@
wm8753_set_bias_level(codec, dapm->bias_level);
}
-static int wm8753_suspend(struct snd_soc_codec *codec, pm_message_t state)
+static int wm8753_suspend(struct snd_soc_codec *codec)
{
wm8753_set_bias_level(codec, SND_SOC_BIAS_OFF);
return 0;
@@ -1467,10 +1455,6 @@
snd_soc_update_bits(codec, WM8753_LINVOL, 0x0100, 0x0100);
snd_soc_update_bits(codec, WM8753_RINVOL, 0x0100, 0x0100);
- snd_soc_add_controls(codec, wm8753_snd_controls,
- ARRAY_SIZE(wm8753_snd_controls));
- wm8753_add_widgets(codec);
-
return 0;
}
@@ -1492,6 +1476,13 @@
.reg_cache_size = ARRAY_SIZE(wm8753_reg),
.reg_word_size = sizeof(u16),
.reg_cache_default = wm8753_reg,
+
+ .controls = wm8753_snd_controls,
+ .num_controls = ARRAY_SIZE(wm8753_snd_controls),
+ .dapm_widgets = wm8753_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(wm8753_dapm_widgets),
+ .dapm_routes = wm8753_dapm_routes,
+ .num_dapm_routes = ARRAY_SIZE(wm8753_dapm_routes),
};
static const struct of_device_id wm8753_of_match[] = {
diff --git a/sound/soc/codecs/wm8770.c b/sound/soc/codecs/wm8770.c
index aa05e65..19374a9 100644
--- a/sound/soc/codecs/wm8770.c
+++ b/sound/soc/codecs/wm8770.c
@@ -16,7 +16,6 @@
#include <linux/delay.h>
#include <linux/of_device.h>
#include <linux/pm.h>
-#include <linux/platform_device.h>
#include <linux/spi/spi.h>
#include <linux/regulator/consumer.h>
#include <linux/slab.h>
@@ -528,7 +527,7 @@
#define WM8770_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
-static struct snd_soc_dai_ops wm8770_dai_ops = {
+static const struct snd_soc_dai_ops wm8770_dai_ops = {
.digital_mute = wm8770_mute,
.hw_params = wm8770_hw_params,
.set_fmt = wm8770_set_fmt,
@@ -556,7 +555,7 @@
};
#ifdef CONFIG_PM
-static int wm8770_suspend(struct snd_soc_codec *codec, pm_message_t state)
+static int wm8770_suspend(struct snd_soc_codec *codec)
{
wm8770_set_bias_level(codec, SND_SOC_BIAS_OFF);
return 0;
@@ -691,13 +690,13 @@
};
MODULE_DEVICE_TABLE(of, wm8770_of_match);
-#if defined(CONFIG_SPI_MASTER)
static int __devinit wm8770_spi_probe(struct spi_device *spi)
{
struct wm8770_priv *wm8770;
int ret;
- wm8770 = kzalloc(sizeof(struct wm8770_priv), GFP_KERNEL);
+ wm8770 = devm_kzalloc(&spi->dev, sizeof(struct wm8770_priv),
+ GFP_KERNEL);
if (!wm8770)
return -ENOMEM;
@@ -706,15 +705,13 @@
ret = snd_soc_register_codec(&spi->dev,
&soc_codec_dev_wm8770, &wm8770_dai, 1);
- if (ret < 0)
- kfree(wm8770);
+
return ret;
}
static int __devexit wm8770_spi_remove(struct spi_device *spi)
{
snd_soc_unregister_codec(&spi->dev);
- kfree(spi_get_drvdata(spi));
return 0;
}
@@ -727,28 +724,23 @@
.probe = wm8770_spi_probe,
.remove = __devexit_p(wm8770_spi_remove)
};
-#endif
static int __init wm8770_modinit(void)
{
int ret = 0;
-#if defined(CONFIG_SPI_MASTER)
ret = spi_register_driver(&wm8770_spi_driver);
if (ret) {
printk(KERN_ERR "Failed to register wm8770 SPI driver: %d\n",
ret);
}
-#endif
return ret;
}
module_init(wm8770_modinit);
static void __exit wm8770_exit(void)
{
-#if defined(CONFIG_SPI_MASTER)
spi_unregister_driver(&wm8770_spi_driver);
-#endif
}
module_exit(wm8770_exit);
diff --git a/sound/soc/codecs/wm8776.c b/sound/soc/codecs/wm8776.c
index d3b0a20..33e97d1 100644
--- a/sound/soc/codecs/wm8776.c
+++ b/sound/soc/codecs/wm8776.c
@@ -19,7 +19,6 @@
#include <linux/pm.h>
#include <linux/i2c.h>
#include <linux/of_device.h>
-#include <linux/platform_device.h>
#include <linux/spi/spi.h>
#include <linux/slab.h>
#include <sound/core.h>
@@ -328,14 +327,14 @@
#define WM8776_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
-static struct snd_soc_dai_ops wm8776_dac_ops = {
+static const struct snd_soc_dai_ops wm8776_dac_ops = {
.digital_mute = wm8776_mute,
.hw_params = wm8776_hw_params,
.set_fmt = wm8776_set_fmt,
.set_sysclk = wm8776_set_sysclk,
};
-static struct snd_soc_dai_ops wm8776_adc_ops = {
+static const struct snd_soc_dai_ops wm8776_adc_ops = {
.hw_params = wm8776_hw_params,
.set_fmt = wm8776_set_fmt,
.set_sysclk = wm8776_set_sysclk,
@@ -373,7 +372,7 @@
};
#ifdef CONFIG_PM
-static int wm8776_suspend(struct snd_soc_codec *codec, pm_message_t state)
+static int wm8776_suspend(struct snd_soc_codec *codec)
{
wm8776_set_bias_level(codec, SND_SOC_BIAS_OFF);
@@ -393,7 +392,6 @@
static int wm8776_probe(struct snd_soc_codec *codec)
{
struct wm8776_priv *wm8776 = snd_soc_codec_get_drvdata(codec);
- struct snd_soc_dapm_context *dapm = &codec->dapm;
int ret = 0;
ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8776->control_type);
@@ -415,12 +413,6 @@
snd_soc_update_bits(codec, WM8776_HPRVOL, 0x100, 0x100);
snd_soc_update_bits(codec, WM8776_DACRVOL, 0x100, 0x100);
- snd_soc_add_controls(codec, wm8776_snd_controls,
- ARRAY_SIZE(wm8776_snd_controls));
- snd_soc_dapm_new_controls(dapm, wm8776_dapm_widgets,
- ARRAY_SIZE(wm8776_dapm_widgets));
- snd_soc_dapm_add_routes(dapm, routes, ARRAY_SIZE(routes));
-
return ret;
}
@@ -440,6 +432,13 @@
.reg_cache_size = ARRAY_SIZE(wm8776_reg),
.reg_word_size = sizeof(u16),
.reg_cache_default = wm8776_reg,
+
+ .controls = wm8776_snd_controls,
+ .num_controls = ARRAY_SIZE(wm8776_snd_controls),
+ .dapm_widgets = wm8776_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(wm8776_dapm_widgets),
+ .dapm_routes = routes,
+ .num_dapm_routes = ARRAY_SIZE(routes),
};
static const struct of_device_id wm8776_of_match[] = {
@@ -454,7 +453,8 @@
struct wm8776_priv *wm8776;
int ret;
- wm8776 = kzalloc(sizeof(struct wm8776_priv), GFP_KERNEL);
+ wm8776 = devm_kzalloc(&spi->dev, sizeof(struct wm8776_priv),
+ GFP_KERNEL);
if (wm8776 == NULL)
return -ENOMEM;
@@ -463,15 +463,13 @@
ret = snd_soc_register_codec(&spi->dev,
&soc_codec_dev_wm8776, wm8776_dai, ARRAY_SIZE(wm8776_dai));
- if (ret < 0)
- kfree(wm8776);
+
return ret;
}
static int __devexit wm8776_spi_remove(struct spi_device *spi)
{
snd_soc_unregister_codec(&spi->dev);
- kfree(spi_get_drvdata(spi));
return 0;
}
@@ -493,7 +491,8 @@
struct wm8776_priv *wm8776;
int ret;
- wm8776 = kzalloc(sizeof(struct wm8776_priv), GFP_KERNEL);
+ wm8776 = devm_kzalloc(&i2c->dev, sizeof(struct wm8776_priv),
+ GFP_KERNEL);
if (wm8776 == NULL)
return -ENOMEM;
@@ -502,15 +501,13 @@
ret = snd_soc_register_codec(&i2c->dev,
&soc_codec_dev_wm8776, wm8776_dai, ARRAY_SIZE(wm8776_dai));
- if (ret < 0)
- kfree(wm8776);
+
return ret;
}
static __devexit int wm8776_i2c_remove(struct i2c_client *client)
{
snd_soc_unregister_codec(&client->dev);
- kfree(i2c_get_clientdata(client));
return 0;
}
diff --git a/sound/soc/codecs/wm8782.c b/sound/soc/codecs/wm8782.c
index f2ced71..3fdea98 100644
--- a/sound/soc/codecs/wm8782.c
+++ b/sound/soc/codecs/wm8782.c
@@ -63,17 +63,7 @@
.remove = __devexit_p(wm8782_remove),
};
-static int __init wm8782_init(void)
-{
- return platform_driver_register(&wm8782_codec_driver);
-}
-module_init(wm8782_init);
-
-static void __exit wm8782_exit(void)
-{
- platform_driver_unregister(&wm8782_codec_driver);
-}
-module_exit(wm8782_exit);
+module_platform_driver(wm8782_codec_driver);
MODULE_DESCRIPTION("ASoC WM8782 driver");
MODULE_AUTHOR("Johannes Stezenbach <js@sig21.net>");
diff --git a/sound/soc/codecs/wm8804.c b/sound/soc/codecs/wm8804.c
index 9ee072b..d54a3ca 100644
--- a/sound/soc/codecs/wm8804.c
+++ b/sound/soc/codecs/wm8804.c
@@ -542,7 +542,7 @@
}
#ifdef CONFIG_PM
-static int wm8804_suspend(struct snd_soc_codec *codec, pm_message_t state)
+static int wm8804_suspend(struct snd_soc_codec *codec)
{
wm8804_set_bias_level(codec, SND_SOC_BIAS_OFF);
return 0;
@@ -659,8 +659,6 @@
wm8804_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
- snd_soc_add_controls(codec, wm8804_snd_controls,
- ARRAY_SIZE(wm8804_snd_controls));
return 0;
err_reg_enable:
@@ -670,7 +668,7 @@
return ret;
}
-static struct snd_soc_dai_ops wm8804_dai_ops = {
+static const struct snd_soc_dai_ops wm8804_dai_ops = {
.hw_params = wm8804_hw_params,
.set_fmt = wm8804_set_fmt,
.set_sysclk = wm8804_set_sysclk,
@@ -715,7 +713,10 @@
.reg_cache_size = ARRAY_SIZE(wm8804_reg_defs),
.reg_word_size = sizeof(u8),
.reg_cache_default = wm8804_reg_defs,
- .volatile_register = wm8804_volatile
+ .volatile_register = wm8804_volatile,
+
+ .controls = wm8804_snd_controls,
+ .num_controls = ARRAY_SIZE(wm8804_snd_controls),
};
static const struct of_device_id wm8804_of_match[] = {
diff --git a/sound/soc/codecs/wm8900.c b/sound/soc/codecs/wm8900.c
index 3d0dc15..f18c554 100644
--- a/sound/soc/codecs/wm8900.c
+++ b/sound/soc/codecs/wm8900.c
@@ -24,7 +24,6 @@
#include <linux/pm.h>
#include <linux/i2c.h>
#include <linux/spi/spi.h>
-#include <linux/platform_device.h>
#include <linux/slab.h>
#include <sound/core.h>
#include <sound/pcm.h>
@@ -513,7 +512,7 @@
wm8900_rinmix_controls,
ARRAY_SIZE(wm8900_rinmix_controls)),
-SND_SOC_DAPM_MICBIAS("Mic Bias", WM8900_REG_POWER1, 4, 0),
+SND_SOC_DAPM_SUPPLY("Mic Bias", WM8900_REG_POWER1, 4, 0, NULL, 0),
SND_SOC_DAPM_ADC("ADCL", "Left HiFi Capture", WM8900_REG_POWER2, 1, 0),
SND_SOC_DAPM_ADC("ADCR", "Right HiFi Capture", WM8900_REG_POWER2, 0, 0),
@@ -543,7 +542,7 @@
};
/* Target, Path, Source */
-static const struct snd_soc_dapm_route audio_map[] = {
+static const struct snd_soc_dapm_route wm8900_dapm_routes[] = {
/* Inputs */
{"Left Input PGA", "LINPUT1 Switch", "LINPUT1"},
{"Left Input PGA", "LINPUT2 Switch", "LINPUT2"},
@@ -607,17 +606,6 @@
{"HP_R", NULL, "Headphone Amplifier"},
};
-static int wm8900_add_widgets(struct snd_soc_codec *codec)
-{
- struct snd_soc_dapm_context *dapm = &codec->dapm;
-
- snd_soc_dapm_new_controls(dapm, wm8900_dapm_widgets,
- ARRAY_SIZE(wm8900_dapm_widgets));
- snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
-
- return 0;
-}
-
static int wm8900_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai)
@@ -987,7 +975,7 @@
(SNDRV_PCM_FORMAT_S16_LE | SNDRV_PCM_FORMAT_S20_3LE | \
SNDRV_PCM_FORMAT_S24_LE)
-static struct snd_soc_dai_ops wm8900_dai_ops = {
+static const struct snd_soc_dai_ops wm8900_dai_ops = {
.hw_params = wm8900_hw_params,
.set_clkdiv = wm8900_set_dai_clkdiv,
.set_pll = wm8900_set_dai_pll,
@@ -1107,7 +1095,7 @@
return 0;
}
-static int wm8900_suspend(struct snd_soc_codec *codec, pm_message_t state)
+static int wm8900_suspend(struct snd_soc_codec *codec)
{
struct wm8900_priv *wm8900 = snd_soc_codec_get_drvdata(codec);
int fll_out = wm8900->fll_out;
@@ -1204,10 +1192,6 @@
/* Set the DAC and mixer output bias */
snd_soc_write(codec, WM8900_REG_OUTBIASCTL, 0x81);
- snd_soc_add_controls(codec, wm8900_snd_controls,
- ARRAY_SIZE(wm8900_snd_controls));
- wm8900_add_widgets(codec);
-
return 0;
}
@@ -1228,6 +1212,13 @@
.reg_cache_size = ARRAY_SIZE(wm8900_reg_defaults),
.reg_word_size = sizeof(u16),
.reg_cache_default = wm8900_reg_defaults,
+
+ .controls = wm8900_snd_controls,
+ .num_controls = ARRAY_SIZE(wm8900_snd_controls),
+ .dapm_widgets = wm8900_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(wm8900_dapm_widgets),
+ .dapm_routes = wm8900_dapm_routes,
+ .num_dapm_routes = ARRAY_SIZE(wm8900_dapm_routes),
};
#if defined(CONFIG_SPI_MASTER)
@@ -1259,7 +1250,7 @@
static struct spi_driver wm8900_spi_driver = {
.driver = {
- .name = "wm8900-codec",
+ .name = "wm8900",
.owner = THIS_MODULE,
},
.probe = wm8900_spi_probe,
@@ -1303,7 +1294,7 @@
static struct i2c_driver wm8900_i2c_driver = {
.driver = {
- .name = "wm8900-codec",
+ .name = "wm8900",
.owner = THIS_MODULE,
},
.probe = wm8900_i2c_probe,
diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c
index 4ad8ebd..c91fb2f 100644
--- a/sound/soc/codecs/wm8903.c
+++ b/sound/soc/codecs/wm8903.c
@@ -23,8 +23,9 @@
#include <linux/gpio.h>
#include <linux/pm.h>
#include <linux/i2c.h>
-#include <linux/platform_device.h>
+#include <linux/regmap.h>
#include <linux/slab.h>
+#include <linux/irq.h>
#include <sound/core.h>
#include <sound/jack.h>
#include <sound/pcm.h>
@@ -38,184 +39,85 @@
#include "wm8903.h"
/* Register defaults at reset */
-static u16 wm8903_reg_defaults[] = {
- 0x8903, /* R0 - SW Reset and ID */
- 0x0000, /* R1 - Revision Number */
- 0x0000, /* R2 */
- 0x0000, /* R3 */
- 0x0018, /* R4 - Bias Control 0 */
- 0x0000, /* R5 - VMID Control 0 */
- 0x0000, /* R6 - Mic Bias Control 0 */
- 0x0000, /* R7 */
- 0x0001, /* R8 - Analogue DAC 0 */
- 0x0000, /* R9 */
- 0x0001, /* R10 - Analogue ADC 0 */
- 0x0000, /* R11 */
- 0x0000, /* R12 - Power Management 0 */
- 0x0000, /* R13 - Power Management 1 */
- 0x0000, /* R14 - Power Management 2 */
- 0x0000, /* R15 - Power Management 3 */
- 0x0000, /* R16 - Power Management 4 */
- 0x0000, /* R17 - Power Management 5 */
- 0x0000, /* R18 - Power Management 6 */
- 0x0000, /* R19 */
- 0x0400, /* R20 - Clock Rates 0 */
- 0x0D07, /* R21 - Clock Rates 1 */
- 0x0000, /* R22 - Clock Rates 2 */
- 0x0000, /* R23 */
- 0x0050, /* R24 - Audio Interface 0 */
- 0x0242, /* R25 - Audio Interface 1 */
- 0x0008, /* R26 - Audio Interface 2 */
- 0x0022, /* R27 - Audio Interface 3 */
- 0x0000, /* R28 */
- 0x0000, /* R29 */
- 0x00C0, /* R30 - DAC Digital Volume Left */
- 0x00C0, /* R31 - DAC Digital Volume Right */
- 0x0000, /* R32 - DAC Digital 0 */
- 0x0000, /* R33 - DAC Digital 1 */
- 0x0000, /* R34 */
- 0x0000, /* R35 */
- 0x00C0, /* R36 - ADC Digital Volume Left */
- 0x00C0, /* R37 - ADC Digital Volume Right */
- 0x0000, /* R38 - ADC Digital 0 */
- 0x0073, /* R39 - Digital Microphone 0 */
- 0x09BF, /* R40 - DRC 0 */
- 0x3241, /* R41 - DRC 1 */
- 0x0020, /* R42 - DRC 2 */
- 0x0000, /* R43 - DRC 3 */
- 0x0085, /* R44 - Analogue Left Input 0 */
- 0x0085, /* R45 - Analogue Right Input 0 */
- 0x0044, /* R46 - Analogue Left Input 1 */
- 0x0044, /* R47 - Analogue Right Input 1 */
- 0x0000, /* R48 */
- 0x0000, /* R49 */
- 0x0008, /* R50 - Analogue Left Mix 0 */
- 0x0004, /* R51 - Analogue Right Mix 0 */
- 0x0000, /* R52 - Analogue Spk Mix Left 0 */
- 0x0000, /* R53 - Analogue Spk Mix Left 1 */
- 0x0000, /* R54 - Analogue Spk Mix Right 0 */
- 0x0000, /* R55 - Analogue Spk Mix Right 1 */
- 0x0000, /* R56 */
- 0x002D, /* R57 - Analogue OUT1 Left */
- 0x002D, /* R58 - Analogue OUT1 Right */
- 0x0039, /* R59 - Analogue OUT2 Left */
- 0x0039, /* R60 - Analogue OUT2 Right */
- 0x0100, /* R61 */
- 0x0139, /* R62 - Analogue OUT3 Left */
- 0x0139, /* R63 - Analogue OUT3 Right */
- 0x0000, /* R64 */
- 0x0000, /* R65 - Analogue SPK Output Control 0 */
- 0x0000, /* R66 */
- 0x0010, /* R67 - DC Servo 0 */
- 0x0100, /* R68 */
- 0x00A4, /* R69 - DC Servo 2 */
- 0x0807, /* R70 */
- 0x0000, /* R71 */
- 0x0000, /* R72 */
- 0x0000, /* R73 */
- 0x0000, /* R74 */
- 0x0000, /* R75 */
- 0x0000, /* R76 */
- 0x0000, /* R77 */
- 0x0000, /* R78 */
- 0x000E, /* R79 */
- 0x0000, /* R80 */
- 0x0000, /* R81 */
- 0x0000, /* R82 */
- 0x0000, /* R83 */
- 0x0000, /* R84 */
- 0x0000, /* R85 */
- 0x0000, /* R86 */
- 0x0006, /* R87 */
- 0x0000, /* R88 */
- 0x0000, /* R89 */
- 0x0000, /* R90 - Analogue HP 0 */
- 0x0060, /* R91 */
- 0x0000, /* R92 */
- 0x0000, /* R93 */
- 0x0000, /* R94 - Analogue Lineout 0 */
- 0x0060, /* R95 */
- 0x0000, /* R96 */
- 0x0000, /* R97 */
- 0x0000, /* R98 - Charge Pump 0 */
- 0x1F25, /* R99 */
- 0x2B19, /* R100 */
- 0x01C0, /* R101 */
- 0x01EF, /* R102 */
- 0x2B00, /* R103 */
- 0x0000, /* R104 - Class W 0 */
- 0x01C0, /* R105 */
- 0x1C10, /* R106 */
- 0x0000, /* R107 */
- 0x0000, /* R108 - Write Sequencer 0 */
- 0x0000, /* R109 - Write Sequencer 1 */
- 0x0000, /* R110 - Write Sequencer 2 */
- 0x0000, /* R111 - Write Sequencer 3 */
- 0x0000, /* R112 - Write Sequencer 4 */
- 0x0000, /* R113 */
- 0x0000, /* R114 - Control Interface */
- 0x0000, /* R115 */
- 0x00A8, /* R116 - GPIO Control 1 */
- 0x00A8, /* R117 - GPIO Control 2 */
- 0x00A8, /* R118 - GPIO Control 3 */
- 0x0220, /* R119 - GPIO Control 4 */
- 0x01A0, /* R120 - GPIO Control 5 */
- 0x0000, /* R121 - Interrupt Status 1 */
- 0xFFFF, /* R122 - Interrupt Status 1 Mask */
- 0x0000, /* R123 - Interrupt Polarity 1 */
- 0x0000, /* R124 */
- 0x0003, /* R125 */
- 0x0000, /* R126 - Interrupt Control */
- 0x0000, /* R127 */
- 0x0005, /* R128 */
- 0x0000, /* R129 - Control Interface Test 1 */
- 0x0000, /* R130 */
- 0x0000, /* R131 */
- 0x0000, /* R132 */
- 0x0000, /* R133 */
- 0x0000, /* R134 */
- 0x03FF, /* R135 */
- 0x0007, /* R136 */
- 0x0040, /* R137 */
- 0x0000, /* R138 */
- 0x0000, /* R139 */
- 0x0000, /* R140 */
- 0x0000, /* R141 */
- 0x0000, /* R142 */
- 0x0000, /* R143 */
- 0x0000, /* R144 */
- 0x0000, /* R145 */
- 0x0000, /* R146 */
- 0x0000, /* R147 */
- 0x4000, /* R148 */
- 0x6810, /* R149 - Charge Pump Test 1 */
- 0x0004, /* R150 */
- 0x0000, /* R151 */
- 0x0000, /* R152 */
- 0x0000, /* R153 */
- 0x0000, /* R154 */
- 0x0000, /* R155 */
- 0x0000, /* R156 */
- 0x0000, /* R157 */
- 0x0000, /* R158 */
- 0x0000, /* R159 */
- 0x0000, /* R160 */
- 0x0000, /* R161 */
- 0x0000, /* R162 */
- 0x0000, /* R163 */
- 0x0028, /* R164 - Clock Rate Test 4 */
- 0x0004, /* R165 */
- 0x0000, /* R166 */
- 0x0060, /* R167 */
- 0x0000, /* R168 */
- 0x0000, /* R169 */
- 0x0000, /* R170 */
- 0x0000, /* R171 */
- 0x0000, /* R172 - Analogue Output Bias 0 */
+static const struct reg_default wm8903_reg_defaults[] = {
+ { 4, 0x0018 }, /* R4 - Bias Control 0 */
+ { 5, 0x0000 }, /* R5 - VMID Control 0 */
+ { 6, 0x0000 }, /* R6 - Mic Bias Control 0 */
+ { 8, 0x0001 }, /* R8 - Analogue DAC 0 */
+ { 10, 0x0001 }, /* R10 - Analogue ADC 0 */
+ { 12, 0x0000 }, /* R12 - Power Management 0 */
+ { 13, 0x0000 }, /* R13 - Power Management 1 */
+ { 14, 0x0000 }, /* R14 - Power Management 2 */
+ { 15, 0x0000 }, /* R15 - Power Management 3 */
+ { 16, 0x0000 }, /* R16 - Power Management 4 */
+ { 17, 0x0000 }, /* R17 - Power Management 5 */
+ { 18, 0x0000 }, /* R18 - Power Management 6 */
+ { 20, 0x0400 }, /* R20 - Clock Rates 0 */
+ { 21, 0x0D07 }, /* R21 - Clock Rates 1 */
+ { 22, 0x0000 }, /* R22 - Clock Rates 2 */
+ { 24, 0x0050 }, /* R24 - Audio Interface 0 */
+ { 25, 0x0242 }, /* R25 - Audio Interface 1 */
+ { 26, 0x0008 }, /* R26 - Audio Interface 2 */
+ { 27, 0x0022 }, /* R27 - Audio Interface 3 */
+ { 30, 0x00C0 }, /* R30 - DAC Digital Volume Left */
+ { 31, 0x00C0 }, /* R31 - DAC Digital Volume Right */
+ { 32, 0x0000 }, /* R32 - DAC Digital 0 */
+ { 33, 0x0000 }, /* R33 - DAC Digital 1 */
+ { 36, 0x00C0 }, /* R36 - ADC Digital Volume Left */
+ { 37, 0x00C0 }, /* R37 - ADC Digital Volume Right */
+ { 38, 0x0000 }, /* R38 - ADC Digital 0 */
+ { 39, 0x0073 }, /* R39 - Digital Microphone 0 */
+ { 40, 0x09BF }, /* R40 - DRC 0 */
+ { 41, 0x3241 }, /* R41 - DRC 1 */
+ { 42, 0x0020 }, /* R42 - DRC 2 */
+ { 43, 0x0000 }, /* R43 - DRC 3 */
+ { 44, 0x0085 }, /* R44 - Analogue Left Input 0 */
+ { 45, 0x0085 }, /* R45 - Analogue Right Input 0 */
+ { 46, 0x0044 }, /* R46 - Analogue Left Input 1 */
+ { 47, 0x0044 }, /* R47 - Analogue Right Input 1 */
+ { 50, 0x0008 }, /* R50 - Analogue Left Mix 0 */
+ { 51, 0x0004 }, /* R51 - Analogue Right Mix 0 */
+ { 52, 0x0000 }, /* R52 - Analogue Spk Mix Left 0 */
+ { 53, 0x0000 }, /* R53 - Analogue Spk Mix Left 1 */
+ { 54, 0x0000 }, /* R54 - Analogue Spk Mix Right 0 */
+ { 55, 0x0000 }, /* R55 - Analogue Spk Mix Right 1 */
+ { 57, 0x002D }, /* R57 - Analogue OUT1 Left */
+ { 58, 0x002D }, /* R58 - Analogue OUT1 Right */
+ { 59, 0x0039 }, /* R59 - Analogue OUT2 Left */
+ { 60, 0x0039 }, /* R60 - Analogue OUT2 Right */
+ { 62, 0x0139 }, /* R62 - Analogue OUT3 Left */
+ { 63, 0x0139 }, /* R63 - Analogue OUT3 Right */
+ { 64, 0x0000 }, /* R65 - Analogue SPK Output Control 0 */
+ { 67, 0x0010 }, /* R67 - DC Servo 0 */
+ { 69, 0x00A4 }, /* R69 - DC Servo 2 */
+ { 90, 0x0000 }, /* R90 - Analogue HP 0 */
+ { 94, 0x0000 }, /* R94 - Analogue Lineout 0 */
+ { 98, 0x0000 }, /* R98 - Charge Pump 0 */
+ { 104, 0x0000 }, /* R104 - Class W 0 */
+ { 108, 0x0000 }, /* R108 - Write Sequencer 0 */
+ { 109, 0x0000 }, /* R109 - Write Sequencer 1 */
+ { 110, 0x0000 }, /* R110 - Write Sequencer 2 */
+ { 111, 0x0000 }, /* R111 - Write Sequencer 3 */
+ { 112, 0x0000 }, /* R112 - Write Sequencer 4 */
+ { 114, 0x0000 }, /* R114 - Control Interface */
+ { 116, 0x00A8 }, /* R116 - GPIO Control 1 */
+ { 117, 0x00A8 }, /* R117 - GPIO Control 2 */
+ { 118, 0x00A8 }, /* R118 - GPIO Control 3 */
+ { 119, 0x0220 }, /* R119 - GPIO Control 4 */
+ { 120, 0x01A0 }, /* R120 - GPIO Control 5 */
+ { 122, 0xFFFF }, /* R122 - Interrupt Status 1 Mask */
+ { 123, 0x0000 }, /* R123 - Interrupt Polarity 1 */
+ { 126, 0x0000 }, /* R126 - Interrupt Control */
+ { 129, 0x0000 }, /* R129 - Control Interface Test 1 */
+ { 149, 0x6810 }, /* R149 - Charge Pump Test 1 */
+ { 164, 0x0028 }, /* R164 - Clock Rate Test 4 */
+ { 172, 0x0000 }, /* R172 - Analogue Output Bias 0 */
};
struct wm8903_priv {
+ struct wm8903_platform_data *pdata;
struct snd_soc_codec *codec;
+ struct regmap *regmap;
int sysclk;
int irq;
@@ -240,7 +142,93 @@
#endif
};
-static int wm8903_volatile_register(struct snd_soc_codec *codec, unsigned int reg)
+static bool wm8903_readable_register(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case WM8903_SW_RESET_AND_ID:
+ case WM8903_REVISION_NUMBER:
+ case WM8903_BIAS_CONTROL_0:
+ case WM8903_VMID_CONTROL_0:
+ case WM8903_MIC_BIAS_CONTROL_0:
+ case WM8903_ANALOGUE_DAC_0:
+ case WM8903_ANALOGUE_ADC_0:
+ case WM8903_POWER_MANAGEMENT_0:
+ case WM8903_POWER_MANAGEMENT_1:
+ case WM8903_POWER_MANAGEMENT_2:
+ case WM8903_POWER_MANAGEMENT_3:
+ case WM8903_POWER_MANAGEMENT_4:
+ case WM8903_POWER_MANAGEMENT_5:
+ case WM8903_POWER_MANAGEMENT_6:
+ case WM8903_CLOCK_RATES_0:
+ case WM8903_CLOCK_RATES_1:
+ case WM8903_CLOCK_RATES_2:
+ case WM8903_AUDIO_INTERFACE_0:
+ case WM8903_AUDIO_INTERFACE_1:
+ case WM8903_AUDIO_INTERFACE_2:
+ case WM8903_AUDIO_INTERFACE_3:
+ case WM8903_DAC_DIGITAL_VOLUME_LEFT:
+ case WM8903_DAC_DIGITAL_VOLUME_RIGHT:
+ case WM8903_DAC_DIGITAL_0:
+ case WM8903_DAC_DIGITAL_1:
+ case WM8903_ADC_DIGITAL_VOLUME_LEFT:
+ case WM8903_ADC_DIGITAL_VOLUME_RIGHT:
+ case WM8903_ADC_DIGITAL_0:
+ case WM8903_DIGITAL_MICROPHONE_0:
+ case WM8903_DRC_0:
+ case WM8903_DRC_1:
+ case WM8903_DRC_2:
+ case WM8903_DRC_3:
+ case WM8903_ANALOGUE_LEFT_INPUT_0:
+ case WM8903_ANALOGUE_RIGHT_INPUT_0:
+ case WM8903_ANALOGUE_LEFT_INPUT_1:
+ case WM8903_ANALOGUE_RIGHT_INPUT_1:
+ case WM8903_ANALOGUE_LEFT_MIX_0:
+ case WM8903_ANALOGUE_RIGHT_MIX_0:
+ case WM8903_ANALOGUE_SPK_MIX_LEFT_0:
+ case WM8903_ANALOGUE_SPK_MIX_LEFT_1:
+ case WM8903_ANALOGUE_SPK_MIX_RIGHT_0:
+ case WM8903_ANALOGUE_SPK_MIX_RIGHT_1:
+ case WM8903_ANALOGUE_OUT1_LEFT:
+ case WM8903_ANALOGUE_OUT1_RIGHT:
+ case WM8903_ANALOGUE_OUT2_LEFT:
+ case WM8903_ANALOGUE_OUT2_RIGHT:
+ case WM8903_ANALOGUE_OUT3_LEFT:
+ case WM8903_ANALOGUE_OUT3_RIGHT:
+ case WM8903_ANALOGUE_SPK_OUTPUT_CONTROL_0:
+ case WM8903_DC_SERVO_0:
+ case WM8903_DC_SERVO_2:
+ case WM8903_DC_SERVO_READBACK_1:
+ case WM8903_DC_SERVO_READBACK_2:
+ case WM8903_DC_SERVO_READBACK_3:
+ case WM8903_DC_SERVO_READBACK_4:
+ case WM8903_ANALOGUE_HP_0:
+ case WM8903_ANALOGUE_LINEOUT_0:
+ case WM8903_CHARGE_PUMP_0:
+ case WM8903_CLASS_W_0:
+ case WM8903_WRITE_SEQUENCER_0:
+ case WM8903_WRITE_SEQUENCER_1:
+ case WM8903_WRITE_SEQUENCER_2:
+ case WM8903_WRITE_SEQUENCER_3:
+ case WM8903_WRITE_SEQUENCER_4:
+ case WM8903_CONTROL_INTERFACE:
+ case WM8903_GPIO_CONTROL_1:
+ case WM8903_GPIO_CONTROL_2:
+ case WM8903_GPIO_CONTROL_3:
+ case WM8903_GPIO_CONTROL_4:
+ case WM8903_GPIO_CONTROL_5:
+ case WM8903_INTERRUPT_STATUS_1:
+ case WM8903_INTERRUPT_STATUS_1_MASK:
+ case WM8903_INTERRUPT_POLARITY_1:
+ case WM8903_INTERRUPT_CONTROL:
+ case WM8903_CLOCK_RATE_TEST_4:
+ case WM8903_ANALOGUE_OUTPUT_BIAS_0:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static bool wm8903_volatile_register(struct device *dev, unsigned int reg)
{
switch (reg) {
case WM8903_SW_RESET_AND_ID:
@@ -258,13 +246,6 @@
}
}
-static void wm8903_reset(struct snd_soc_codec *codec)
-{
- snd_soc_write(codec, WM8903_SW_RESET_AND_ID, 0);
- memcpy(codec->reg_cache, wm8903_reg_defaults,
- sizeof(wm8903_reg_defaults));
-}
-
static int wm8903_cp_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
@@ -839,7 +820,7 @@
SND_SOC_DAPM_OUTPUT("ROP"),
SND_SOC_DAPM_OUTPUT("RON"),
-SND_SOC_DAPM_MICBIAS("Mic Bias", WM8903_MIC_BIAS_CONTROL_0, 0, 0),
+SND_SOC_DAPM_SUPPLY("MICBIAS", WM8903_MIC_BIAS_CONTROL_0, 0, 0, NULL, 0),
SND_SOC_DAPM_MUX("Left Input Mux", SND_SOC_NOPM, 0, 0, &linput_mux),
SND_SOC_DAPM_MUX("Left Input Inverting Mux", SND_SOC_NOPM, 0, 0,
@@ -948,7 +929,7 @@
static const struct snd_soc_dapm_route wm8903_intercon[] = {
{ "CLK_DSP", NULL, "CLK_SYS" },
- { "Mic Bias", NULL, "CLK_SYS" },
+ { "MICBIAS", NULL, "CLK_SYS" },
{ "HPL_DCS", NULL, "CLK_SYS" },
{ "HPR_DCS", NULL, "CLK_SYS" },
{ "LINEOUTL_DCS", NULL, "CLK_SYS" },
@@ -1732,7 +1713,7 @@
SNDRV_PCM_FMTBIT_S20_3LE |\
SNDRV_PCM_FMTBIT_S24_LE)
-static struct snd_soc_dai_ops wm8903_dai_ops = {
+static const struct snd_soc_dai_ops wm8903_dai_ops = {
.hw_params = wm8903_hw_params,
.digital_mute = wm8903_digital_mute,
.set_fmt = wm8903_set_dai_fmt,
@@ -1759,7 +1740,7 @@
.symmetric_rates = 1,
};
-static int wm8903_suspend(struct snd_soc_codec *codec, pm_message_t state)
+static int wm8903_suspend(struct snd_soc_codec *codec)
{
wm8903_set_bias_level(codec, SND_SOC_BIAS_OFF);
@@ -1768,24 +1749,12 @@
static int wm8903_resume(struct snd_soc_codec *codec)
{
- int i;
- u16 *reg_cache = codec->reg_cache;
- u16 *tmp_cache = kmemdup(reg_cache, sizeof(wm8903_reg_defaults),
- GFP_KERNEL);
+ struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
- /* Bring the codec back up to standby first to minimise pop/clicks */
+ regcache_sync(wm8903->regmap);
+
wm8903_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
- /* Sync back everything else */
- if (tmp_cache) {
- for (i = 2; i < ARRAY_SIZE(wm8903_reg_defaults); i++)
- if (tmp_cache[i] != reg_cache[i])
- snd_soc_write(codec, i, tmp_cache[i]);
- kfree(tmp_cache);
- } else {
- dev_err(codec->dev, "Failed to allocate temporary cache\n");
- }
-
return 0;
}
@@ -1808,13 +1777,18 @@
struct wm8903_priv *wm8903 = gpio_to_wm8903(chip);
struct snd_soc_codec *codec = wm8903->codec;
unsigned int mask, val;
+ int ret;
mask = WM8903_GP1_FN_MASK | WM8903_GP1_DIR_MASK;
val = (WM8903_GPn_FN_GPIO_INPUT << WM8903_GP1_FN_SHIFT) |
WM8903_GP1_DIR;
- return snd_soc_update_bits(codec, WM8903_GPIO_CONTROL_1 + offset,
- mask, val);
+ ret = snd_soc_update_bits(codec, WM8903_GPIO_CONTROL_1 + offset,
+ mask, val);
+ if (ret < 0)
+ return ret;
+
+ return 0;
}
static int wm8903_gpio_get(struct gpio_chip *chip, unsigned offset)
@@ -1834,13 +1808,18 @@
struct wm8903_priv *wm8903 = gpio_to_wm8903(chip);
struct snd_soc_codec *codec = wm8903->codec;
unsigned int mask, val;
+ int ret;
mask = WM8903_GP1_FN_MASK | WM8903_GP1_DIR_MASK | WM8903_GP1_LVL_MASK;
val = (WM8903_GPn_FN_GPIO_OUTPUT << WM8903_GP1_FN_SHIFT) |
(value << WM8903_GP2_LVL_SHIFT);
- return snd_soc_update_bits(codec, WM8903_GPIO_CONTROL_1 + offset,
- mask, val);
+ ret = snd_soc_update_bits(codec, WM8903_GPIO_CONTROL_1 + offset,
+ mask, val);
+ if (ret < 0)
+ return ret;
+
+ return 0;
}
static void wm8903_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
@@ -1867,14 +1846,14 @@
static void wm8903_init_gpio(struct snd_soc_codec *codec)
{
struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
- struct wm8903_platform_data *pdata = dev_get_platdata(codec->dev);
+ struct wm8903_platform_data *pdata = wm8903->pdata;
int ret;
wm8903->gpio_chip = wm8903_template_chip;
wm8903->gpio_chip.ngpio = WM8903_NUM_GPIO;
wm8903->gpio_chip.dev = codec->dev;
- if (pdata && pdata->gpio_base)
+ if (pdata->gpio_base)
wm8903->gpio_chip.base = pdata->gpio_base;
else
wm8903->gpio_chip.base = -1;
@@ -1905,78 +1884,65 @@
static int wm8903_probe(struct snd_soc_codec *codec)
{
- struct wm8903_platform_data *pdata = dev_get_platdata(codec->dev);
struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
+ struct wm8903_platform_data *pdata = wm8903->pdata;
int ret, i;
int trigger, irq_pol;
u16 val;
+ bool mic_gpio = false;
wm8903->codec = codec;
+ codec->control_data = wm8903->regmap;
- ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C);
+ ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP);
if (ret != 0) {
dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
return ret;
}
- val = snd_soc_read(codec, WM8903_SW_RESET_AND_ID);
- if (val != wm8903_reg_defaults[WM8903_SW_RESET_AND_ID]) {
- dev_err(codec->dev,
- "Device with ID register %x is not a WM8903\n", val);
- return -ENODEV;
- }
+ /* Set up GPIOs, detect if any are MIC detect outputs */
+ for (i = 0; i < ARRAY_SIZE(pdata->gpio_cfg); i++) {
+ if ((!pdata->gpio_cfg[i]) ||
+ (pdata->gpio_cfg[i] > WM8903_GPIO_CONFIG_ZERO))
+ continue;
- val = snd_soc_read(codec, WM8903_REVISION_NUMBER);
- dev_info(codec->dev, "WM8903 revision %c\n",
- (val & WM8903_CHIP_REV_MASK) + 'A');
+ snd_soc_write(codec, WM8903_GPIO_CONTROL_1 + i,
+ pdata->gpio_cfg[i] & 0x7fff);
- wm8903_reset(codec);
+ val = (pdata->gpio_cfg[i] & WM8903_GP1_FN_MASK)
+ >> WM8903_GP1_FN_SHIFT;
- /* Set up GPIOs and microphone detection */
- if (pdata) {
- bool mic_gpio = false;
-
- for (i = 0; i < ARRAY_SIZE(pdata->gpio_cfg); i++) {
- if (pdata->gpio_cfg[i] == WM8903_GPIO_NO_CONFIG)
- continue;
-
- snd_soc_write(codec, WM8903_GPIO_CONTROL_1 + i,
- pdata->gpio_cfg[i] & 0xffff);
-
- val = (pdata->gpio_cfg[i] & WM8903_GP1_FN_MASK)
- >> WM8903_GP1_FN_SHIFT;
-
- switch (val) {
- case WM8903_GPn_FN_MICBIAS_CURRENT_DETECT:
- case WM8903_GPn_FN_MICBIAS_SHORT_DETECT:
- mic_gpio = true;
- break;
- default:
- break;
- }
+ switch (val) {
+ case WM8903_GPn_FN_MICBIAS_CURRENT_DETECT:
+ case WM8903_GPn_FN_MICBIAS_SHORT_DETECT:
+ mic_gpio = true;
+ break;
+ default:
+ break;
}
-
- snd_soc_write(codec, WM8903_MIC_BIAS_CONTROL_0,
- pdata->micdet_cfg);
-
- /* Microphone detection needs the WSEQ clock */
- if (pdata->micdet_cfg)
- snd_soc_update_bits(codec, WM8903_WRITE_SEQUENCER_0,
- WM8903_WSEQ_ENA, WM8903_WSEQ_ENA);
-
- /* If microphone detection is enabled by pdata but
- * detected via IRQ then interrupts can be lost before
- * the machine driver has set up microphone detection
- * IRQs as the IRQs are clear on read. The detection
- * will be enabled when the machine driver configures.
- */
- WARN_ON(!mic_gpio && (pdata->micdet_cfg & WM8903_MICDET_ENA));
-
- wm8903->mic_delay = pdata->micdet_delay;
}
-
+
+ /* Set up microphone detection */
+ snd_soc_write(codec, WM8903_MIC_BIAS_CONTROL_0,
+ pdata->micdet_cfg);
+
+ /* Microphone detection needs the WSEQ clock */
+ if (pdata->micdet_cfg)
+ snd_soc_update_bits(codec, WM8903_WRITE_SEQUENCER_0,
+ WM8903_WSEQ_ENA, WM8903_WSEQ_ENA);
+
+ /* If microphone detection is enabled by pdata but
+ * detected via IRQ then interrupts can be lost before
+ * the machine driver has set up microphone detection
+ * IRQs as the IRQs are clear on read. The detection
+ * will be enabled when the machine driver configures.
+ */
+ WARN_ON(!mic_gpio && (pdata->micdet_cfg & WM8903_MICDET_ENA));
+
+ wm8903->mic_delay = pdata->micdet_delay;
+
if (wm8903->irq) {
- if (pdata && pdata->irq_active_low) {
+ if (pdata->irq_active_low) {
trigger = IRQF_TRIGGER_LOW;
irq_pol = WM8903_IRQ_POL;
} else {
@@ -2035,9 +2001,6 @@
WM8903_DAC_MUTEMODE | WM8903_DAC_MUTE,
WM8903_DAC_MUTEMODE | WM8903_DAC_MUTE);
- snd_soc_add_controls(codec, wm8903_snd_controls,
- ARRAY_SIZE(wm8903_snd_controls));
-
wm8903_init_gpio(codec);
return ret;
@@ -2062,45 +2025,198 @@
.suspend = wm8903_suspend,
.resume = wm8903_resume,
.set_bias_level = wm8903_set_bias_level,
- .reg_cache_size = ARRAY_SIZE(wm8903_reg_defaults),
- .reg_word_size = sizeof(u16),
- .reg_cache_default = wm8903_reg_defaults,
- .volatile_register = wm8903_volatile_register,
.seq_notifier = wm8903_seq_notifier,
+ .controls = wm8903_snd_controls,
+ .num_controls = ARRAY_SIZE(wm8903_snd_controls),
.dapm_widgets = wm8903_dapm_widgets,
.num_dapm_widgets = ARRAY_SIZE(wm8903_dapm_widgets),
.dapm_routes = wm8903_intercon,
.num_dapm_routes = ARRAY_SIZE(wm8903_intercon),
};
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+static const struct regmap_config wm8903_regmap = {
+ .reg_bits = 8,
+ .val_bits = 16,
+
+ .max_register = WM8903_MAX_REGISTER,
+ .volatile_reg = wm8903_volatile_register,
+ .readable_reg = wm8903_readable_register,
+
+ .cache_type = REGCACHE_RBTREE,
+ .reg_defaults = wm8903_reg_defaults,
+ .num_reg_defaults = ARRAY_SIZE(wm8903_reg_defaults),
+};
+
+static int wm8903_set_pdata_irq_trigger(struct i2c_client *i2c,
+ struct wm8903_platform_data *pdata)
+{
+ struct irq_data *irq_data = irq_get_irq_data(i2c->irq);
+ if (!irq_data) {
+ dev_err(&i2c->dev, "Invalid IRQ: %d\n",
+ i2c->irq);
+ return -EINVAL;
+ }
+
+ switch (irqd_get_trigger_type(irq_data)) {
+ case IRQ_TYPE_NONE:
+ default:
+ /*
+ * We assume the controller imposes no restrictions,
+ * so we are able to select active-high
+ */
+ /* Fall-through */
+ case IRQ_TYPE_LEVEL_HIGH:
+ pdata->irq_active_low = false;
+ break;
+ case IRQ_TYPE_LEVEL_LOW:
+ pdata->irq_active_low = true;
+ break;
+ }
+
+ return 0;
+}
+
+static int wm8903_set_pdata_from_of(struct i2c_client *i2c,
+ struct wm8903_platform_data *pdata)
+{
+ const struct device_node *np = i2c->dev.of_node;
+ u32 val32;
+ int i;
+
+ if (of_property_read_u32(np, "micdet-cfg", &val32) >= 0)
+ pdata->micdet_cfg = val32;
+
+ if (of_property_read_u32(np, "micdet-delay", &val32) >= 0)
+ pdata->micdet_delay = val32;
+
+ if (of_property_read_u32_array(np, "gpio-cfg", pdata->gpio_cfg,
+ ARRAY_SIZE(pdata->gpio_cfg)) >= 0) {
+ /*
+ * In device tree: 0 means "write 0",
+ * 0xffffffff means "don't touch".
+ *
+ * In platform data: 0 means "don't touch",
+ * 0x8000 means "write 0".
+ *
+ * Note: WM8903_GPIO_CONFIG_ZERO == 0x8000.
+ *
+ * Convert from DT to pdata representation here,
+ * so no other code needs to change.
+ */
+ for (i = 0; i < ARRAY_SIZE(pdata->gpio_cfg); i++) {
+ if (pdata->gpio_cfg[i] == 0) {
+ pdata->gpio_cfg[i] = WM8903_GPIO_CONFIG_ZERO;
+ } else if (pdata->gpio_cfg[i] == 0xffffffff) {
+ pdata->gpio_cfg[i] = 0;
+ } else if (pdata->gpio_cfg[i] > 0x7fff) {
+ dev_err(&i2c->dev, "Invalid gpio-cfg[%d] %x\n",
+ i, pdata->gpio_cfg[i]);
+ return -EINVAL;
+ }
+ }
+ }
+
+ return 0;
+}
+
static __devinit int wm8903_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
+ struct wm8903_platform_data *pdata = dev_get_platdata(&i2c->dev);
struct wm8903_priv *wm8903;
+ unsigned int val;
int ret;
- wm8903 = kzalloc(sizeof(struct wm8903_priv), GFP_KERNEL);
+ wm8903 = devm_kzalloc(&i2c->dev, sizeof(struct wm8903_priv),
+ GFP_KERNEL);
if (wm8903 == NULL)
return -ENOMEM;
+ wm8903->regmap = regmap_init_i2c(i2c, &wm8903_regmap);
+ if (IS_ERR(wm8903->regmap)) {
+ ret = PTR_ERR(wm8903->regmap);
+ dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
+ ret);
+ return ret;
+ }
+
i2c_set_clientdata(i2c, wm8903);
wm8903->irq = i2c->irq;
+ /* If no platform data was supplied, create storage for defaults */
+ if (pdata) {
+ wm8903->pdata = pdata;
+ } else {
+ wm8903->pdata = devm_kzalloc(&i2c->dev,
+ sizeof(struct wm8903_platform_data),
+ GFP_KERNEL);
+ if (wm8903->pdata == NULL) {
+ dev_err(&i2c->dev, "Failed to allocate pdata\n");
+ return -ENOMEM;
+ }
+
+ if (i2c->irq) {
+ ret = wm8903_set_pdata_irq_trigger(i2c, wm8903->pdata);
+ if (ret != 0)
+ return ret;
+ }
+
+ if (i2c->dev.of_node) {
+ ret = wm8903_set_pdata_from_of(i2c, wm8903->pdata);
+ if (ret != 0)
+ return ret;
+ }
+ }
+
+ ret = regmap_read(wm8903->regmap, WM8903_SW_RESET_AND_ID, &val);
+ if (ret != 0) {
+ dev_err(&i2c->dev, "Failed to read chip ID: %d\n", ret);
+ goto err;
+ }
+ if (val != 0x8903) {
+ dev_err(&i2c->dev, "Device with ID %x is not a WM8903\n", val);
+ ret = -ENODEV;
+ goto err;
+ }
+
+ ret = regmap_read(wm8903->regmap, WM8903_REVISION_NUMBER, &val);
+ if (ret != 0) {
+ dev_err(&i2c->dev, "Failed to read chip revision: %d\n", ret);
+ goto err;
+ }
+ dev_info(&i2c->dev, "WM8903 revision %c\n",
+ (val & WM8903_CHIP_REV_MASK) + 'A');
+
+ /* Reset the device */
+ regmap_write(wm8903->regmap, WM8903_SW_RESET_AND_ID, 0x8903);
+
ret = snd_soc_register_codec(&i2c->dev,
&soc_codec_dev_wm8903, &wm8903_dai, 1);
- if (ret < 0)
- kfree(wm8903);
+ if (ret != 0)
+ goto err;
+
+ return 0;
+err:
+ regmap_exit(wm8903->regmap);
return ret;
}
static __devexit int wm8903_i2c_remove(struct i2c_client *client)
{
+ struct wm8903_priv *wm8903 = i2c_get_clientdata(client);
+
+ regmap_exit(wm8903->regmap);
snd_soc_unregister_codec(&client->dev);
- kfree(i2c_get_clientdata(client));
+
return 0;
}
+static const struct of_device_id wm8903_of_match[] = {
+ { .compatible = "wlf,wm8903", },
+ {},
+};
+MODULE_DEVICE_TABLE(of, wm8903_of_match);
+
static const struct i2c_device_id wm8903_i2c_id[] = {
{ "wm8903", 0 },
{ }
@@ -2111,32 +2227,28 @@
.driver = {
.name = "wm8903",
.owner = THIS_MODULE,
+ .of_match_table = wm8903_of_match,
},
.probe = wm8903_i2c_probe,
.remove = __devexit_p(wm8903_i2c_remove),
.id_table = wm8903_i2c_id,
};
-#endif
static int __init wm8903_modinit(void)
{
int ret = 0;
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
ret = i2c_add_driver(&wm8903_i2c_driver);
if (ret != 0) {
printk(KERN_ERR "Failed to register wm8903 I2C driver: %d\n",
ret);
}
-#endif
return ret;
}
module_init(wm8903_modinit);
static void __exit wm8903_exit(void)
{
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
i2c_del_driver(&wm8903_i2c_driver);
-#endif
}
module_exit(wm8903_exit);
diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c
index 285ef87..f31c754 100644
--- a/sound/soc/codecs/wm8904.c
+++ b/sound/soc/codecs/wm8904.c
@@ -17,7 +17,6 @@
#include <linux/delay.h>
#include <linux/pm.h>
#include <linux/i2c.h>
-#include <linux/platform_device.h>
#include <linux/regulator/consumer.h>
#include <linux/slab.h>
#include <sound/core.h>
@@ -1196,7 +1195,7 @@
SND_SOC_DAPM_INPUT("IN3L"),
SND_SOC_DAPM_INPUT("IN3R"),
-SND_SOC_DAPM_MICBIAS("MICBIAS", WM8904_MIC_BIAS_CONTROL_0, 0, 0),
+SND_SOC_DAPM_SUPPLY("MICBIAS", WM8904_MIC_BIAS_CONTROL_0, 0, 0, NULL, 0),
SND_SOC_DAPM_MUX("Left Capture Mux", SND_SOC_NOPM, 0, 0, &lin_mux),
SND_SOC_DAPM_MUX("Left Capture Inverting Mux", SND_SOC_NOPM, 0, 0,
@@ -2205,7 +2204,7 @@
#define WM8904_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
-static struct snd_soc_dai_ops wm8904_dai_ops = {
+static const struct snd_soc_dai_ops wm8904_dai_ops = {
.set_sysclk = wm8904_set_sysclk,
.set_fmt = wm8904_set_fmt,
.set_tdm_slot = wm8904_set_tdm_slot,
@@ -2235,7 +2234,7 @@
};
#ifdef CONFIG_PM
-static int wm8904_suspend(struct snd_soc_codec *codec, pm_message_t state)
+static int wm8904_suspend(struct snd_soc_codec *codec)
{
wm8904_set_bias_level(codec, SND_SOC_BIAS_OFF);
@@ -2565,7 +2564,7 @@
static struct i2c_driver wm8904_i2c_driver = {
.driver = {
- .name = "wm8904-codec",
+ .name = "wm8904",
.owner = THIS_MODULE,
},
.probe = wm8904_i2c_probe,
diff --git a/sound/soc/codecs/wm8940.c b/sound/soc/codecs/wm8940.c
index de9ec9b..14039ea 100644
--- a/sound/soc/codecs/wm8940.c
+++ b/sound/soc/codecs/wm8940.c
@@ -28,7 +28,6 @@
#include <linux/delay.h>
#include <linux/pm.h>
#include <linux/i2c.h>
-#include <linux/platform_device.h>
#include <linux/spi/spi.h>
#include <linux/slab.h>
#include <sound/core.h>
@@ -629,8 +628,8 @@
ret = snd_soc_write(codec, WM8940_CLOCK, reg | (div << 5));
break;
case WM8940_OPCLKDIV:
- reg = snd_soc_read(codec, WM8940_ADDCNTRL) & 0xFFCF;
- ret = snd_soc_write(codec, WM8940_ADDCNTRL, reg | (div << 4));
+ reg = snd_soc_read(codec, WM8940_GPIO) & 0xFFCF;
+ ret = snd_soc_write(codec, WM8940_GPIO, reg | (div << 4));
break;
}
return ret;
@@ -644,7 +643,7 @@
SNDRV_PCM_FMTBIT_S24_LE | \
SNDRV_PCM_FMTBIT_S32_LE)
-static struct snd_soc_dai_ops wm8940_dai_ops = {
+static const struct snd_soc_dai_ops wm8940_dai_ops = {
.hw_params = wm8940_i2s_hw_params,
.set_sysclk = wm8940_set_dai_sysclk,
.digital_mute = wm8940_mute,
@@ -673,7 +672,7 @@
.symmetric_rates = 1,
};
-static int wm8940_suspend(struct snd_soc_codec *codec, pm_message_t state)
+static int wm8940_suspend(struct snd_soc_codec *codec)
{
return wm8940_set_bias_level(codec, SND_SOC_BIAS_OFF);
}
@@ -780,7 +779,7 @@
static struct i2c_driver wm8940_i2c_driver = {
.driver = {
- .name = "wm8940-codec",
+ .name = "wm8940",
.owner = THIS_MODULE,
},
.probe = wm8940_i2c_probe,
diff --git a/sound/soc/codecs/wm8955.c b/sound/soc/codecs/wm8955.c
index 3c71987..9245481 100644
--- a/sound/soc/codecs/wm8955.c
+++ b/sound/soc/codecs/wm8955.c
@@ -16,7 +16,6 @@
#include <linux/delay.h>
#include <linux/pm.h>
#include <linux/i2c.h>
-#include <linux/platform_device.h>
#include <linux/regulator/consumer.h>
#include <linux/slab.h>
#include <sound/core.h>
@@ -859,7 +858,7 @@
#define WM8955_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
-static struct snd_soc_dai_ops wm8955_dai_ops = {
+static const struct snd_soc_dai_ops wm8955_dai_ops = {
.set_sysclk = wm8955_set_sysclk,
.set_fmt = wm8955_set_fmt,
.hw_params = wm8955_hw_params,
@@ -879,7 +878,7 @@
};
#ifdef CONFIG_PM
-static int wm8955_suspend(struct snd_soc_codec *codec, pm_message_t state)
+static int wm8955_suspend(struct snd_soc_codec *codec)
{
wm8955_set_bias_level(codec, SND_SOC_BIAS_OFF);
@@ -1038,7 +1037,7 @@
static struct i2c_driver wm8955_i2c_driver = {
.driver = {
- .name = "wm8955-codec",
+ .name = "wm8955",
.owner = THIS_MODULE,
},
.probe = wm8955_i2c_probe,
diff --git a/sound/soc/codecs/wm8958-dsp2.c b/sound/soc/codecs/wm8958-dsp2.c
index 5a14d5c..8d4ea43 100644
--- a/sound/soc/codecs/wm8958-dsp2.c
+++ b/sound/soc/codecs/wm8958-dsp2.c
@@ -55,7 +55,8 @@
return 0;
if (fw->size < 32) {
- dev_err(codec->dev, "%s: firmware too short\n", name);
+ dev_err(codec->dev, "%s: firmware too short (%d bytes)\n",
+ name, fw->size);
goto err;
}
diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c
index 2df253c..e5caae3 100644
--- a/sound/soc/codecs/wm8960.c
+++ b/sound/soc/codecs/wm8960.c
@@ -14,7 +14,6 @@
#include <linux/delay.h>
#include <linux/pm.h>
#include <linux/i2c.h>
-#include <linux/platform_device.h>
#include <linux/slab.h>
#include <sound/core.h>
#include <sound/pcm.h>
@@ -26,8 +25,6 @@
#include "wm8960.h"
-#define AUDIO_NAME "wm8960"
-
/* R25 - Power 1 */
#define WM8960_VMID_MASK 0x180
#define WM8960_VREF 0x40
@@ -265,7 +262,7 @@
SND_SOC_DAPM_INPUT("LINPUT3"),
SND_SOC_DAPM_INPUT("RINPUT3"),
-SND_SOC_DAPM_MICBIAS("MICB", WM8960_POWER1, 1, 0),
+SND_SOC_DAPM_SUPPLY("MICB", WM8960_POWER1, 1, 0, NULL, 0),
SND_SOC_DAPM_MIXER("Left Boost Mixer", WM8960_POWER1, 5, 0,
wm8960_lin_boost, ARRAY_SIZE(wm8960_lin_boost)),
@@ -546,30 +543,24 @@
static int wm8960_mute(struct snd_soc_dai *dai, int mute)
{
struct snd_soc_codec *codec = dai->codec;
- u16 mute_reg = snd_soc_read(codec, WM8960_DACCTL1) & 0xfff7;
if (mute)
- snd_soc_write(codec, WM8960_DACCTL1, mute_reg | 0x8);
+ snd_soc_update_bits(codec, WM8960_DACCTL1, 0x8, 0x8);
else
- snd_soc_write(codec, WM8960_DACCTL1, mute_reg);
+ snd_soc_update_bits(codec, WM8960_DACCTL1, 0x8, 0);
return 0;
}
static int wm8960_set_bias_level_out3(struct snd_soc_codec *codec,
enum snd_soc_bias_level level)
{
- u16 reg;
-
switch (level) {
case SND_SOC_BIAS_ON:
break;
case SND_SOC_BIAS_PREPARE:
/* Set VMID to 2x50k */
- reg = snd_soc_read(codec, WM8960_POWER1);
- reg &= ~0x180;
- reg |= 0x80;
- snd_soc_write(codec, WM8960_POWER1, reg);
+ snd_soc_update_bits(codec, WM8960_POWER1, 0x180, 0x80);
break;
case SND_SOC_BIAS_STANDBY:
@@ -582,23 +573,19 @@
WM8960_BUFDCOPEN | WM8960_BUFIOEN);
/* Enable & ramp VMID at 2x50k */
- reg = snd_soc_read(codec, WM8960_POWER1);
- reg |= 0x80;
- snd_soc_write(codec, WM8960_POWER1, reg);
+ snd_soc_update_bits(codec, WM8960_POWER1, 0x80, 0x80);
msleep(100);
/* Enable VREF */
- snd_soc_write(codec, WM8960_POWER1, reg | WM8960_VREF);
+ snd_soc_update_bits(codec, WM8960_POWER1, WM8960_VREF,
+ WM8960_VREF);
/* Disable anti-pop features */
snd_soc_write(codec, WM8960_APOP1, WM8960_BUFIOEN);
}
/* Set VMID to 2x250k */
- reg = snd_soc_read(codec, WM8960_POWER1);
- reg &= ~0x180;
- reg |= 0x100;
- snd_soc_write(codec, WM8960_POWER1, reg);
+ snd_soc_update_bits(codec, WM8960_POWER1, 0x180, 0x100);
break;
case SND_SOC_BIAS_OFF:
@@ -790,10 +777,8 @@
/* Disable the PLL: even if we are changing the frequency the
* PLL needs to be disabled while we do so. */
- snd_soc_write(codec, WM8960_CLOCK1,
- snd_soc_read(codec, WM8960_CLOCK1) & ~1);
- snd_soc_write(codec, WM8960_POWER2,
- snd_soc_read(codec, WM8960_POWER2) & ~1);
+ snd_soc_update_bits(codec, WM8960_CLOCK1, 0x1, 0);
+ snd_soc_update_bits(codec, WM8960_POWER2, 0x1, 0);
if (!freq_in || !freq_out)
return 0;
@@ -812,11 +797,9 @@
snd_soc_write(codec, WM8960_PLL1, reg);
/* Turn it on */
- snd_soc_write(codec, WM8960_POWER2,
- snd_soc_read(codec, WM8960_POWER2) | 1);
+ snd_soc_update_bits(codec, WM8960_POWER2, 0x1, 0x1);
msleep(250);
- snd_soc_write(codec, WM8960_CLOCK1,
- snd_soc_read(codec, WM8960_CLOCK1) | 1);
+ snd_soc_update_bits(codec, WM8960_CLOCK1, 0x1, 0x1);
return 0;
}
@@ -869,7 +852,7 @@
(SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
SNDRV_PCM_FMTBIT_S24_LE)
-static struct snd_soc_dai_ops wm8960_dai_ops = {
+static const struct snd_soc_dai_ops wm8960_dai_ops = {
.hw_params = wm8960_hw_params,
.digital_mute = wm8960_mute,
.set_fmt = wm8960_set_dai_fmt,
@@ -895,7 +878,7 @@
.symmetric_rates = 1,
};
-static int wm8960_suspend(struct snd_soc_codec *codec, pm_message_t state)
+static int wm8960_suspend(struct snd_soc_codec *codec)
{
struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
@@ -916,7 +899,6 @@
struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
struct wm8960_data *pdata = dev_get_platdata(codec->dev);
int ret;
- u16 reg;
wm8960->set_bias_level = wm8960_set_bias_level_out3;
@@ -947,26 +929,16 @@
wm8960->set_bias_level(codec, SND_SOC_BIAS_STANDBY);
/* Latch the update bits */
- reg = snd_soc_read(codec, WM8960_LINVOL);
- snd_soc_write(codec, WM8960_LINVOL, reg | 0x100);
- reg = snd_soc_read(codec, WM8960_RINVOL);
- snd_soc_write(codec, WM8960_RINVOL, reg | 0x100);
- reg = snd_soc_read(codec, WM8960_LADC);
- snd_soc_write(codec, WM8960_LADC, reg | 0x100);
- reg = snd_soc_read(codec, WM8960_RADC);
- snd_soc_write(codec, WM8960_RADC, reg | 0x100);
- reg = snd_soc_read(codec, WM8960_LDAC);
- snd_soc_write(codec, WM8960_LDAC, reg | 0x100);
- reg = snd_soc_read(codec, WM8960_RDAC);
- snd_soc_write(codec, WM8960_RDAC, reg | 0x100);
- reg = snd_soc_read(codec, WM8960_LOUT1);
- snd_soc_write(codec, WM8960_LOUT1, reg | 0x100);
- reg = snd_soc_read(codec, WM8960_ROUT1);
- snd_soc_write(codec, WM8960_ROUT1, reg | 0x100);
- reg = snd_soc_read(codec, WM8960_LOUT2);
- snd_soc_write(codec, WM8960_LOUT2, reg | 0x100);
- reg = snd_soc_read(codec, WM8960_ROUT2);
- snd_soc_write(codec, WM8960_ROUT2, reg | 0x100);
+ snd_soc_update_bits(codec, WM8960_LINVOL, 0x100, 0x100);
+ snd_soc_update_bits(codec, WM8960_RINVOL, 0x100, 0x100);
+ snd_soc_update_bits(codec, WM8960_LADC, 0x100, 0x100);
+ snd_soc_update_bits(codec, WM8960_RADC, 0x100, 0x100);
+ snd_soc_update_bits(codec, WM8960_LDAC, 0x100, 0x100);
+ snd_soc_update_bits(codec, WM8960_RDAC, 0x100, 0x100);
+ snd_soc_update_bits(codec, WM8960_LOUT1, 0x100, 0x100);
+ snd_soc_update_bits(codec, WM8960_ROUT1, 0x100, 0x100);
+ snd_soc_update_bits(codec, WM8960_LOUT2, 0x100, 0x100);
+ snd_soc_update_bits(codec, WM8960_ROUT2, 0x100, 0x100);
snd_soc_add_controls(codec, wm8960_snd_controls,
ARRAY_SIZE(wm8960_snd_controls));
@@ -995,14 +967,14 @@
.reg_cache_default = wm8960_reg,
};
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
static __devinit int wm8960_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
struct wm8960_priv *wm8960;
int ret;
- wm8960 = kzalloc(sizeof(struct wm8960_priv), GFP_KERNEL);
+ wm8960 = devm_kzalloc(&i2c->dev, sizeof(struct wm8960_priv),
+ GFP_KERNEL);
if (wm8960 == NULL)
return -ENOMEM;
@@ -1011,15 +983,13 @@
ret = snd_soc_register_codec(&i2c->dev,
&soc_codec_dev_wm8960, &wm8960_dai, 1);
- if (ret < 0)
- kfree(wm8960);
+
return ret;
}
static __devexit int wm8960_i2c_remove(struct i2c_client *client)
{
snd_soc_unregister_codec(&client->dev);
- kfree(i2c_get_clientdata(client));
return 0;
}
@@ -1031,34 +1001,29 @@
static struct i2c_driver wm8960_i2c_driver = {
.driver = {
- .name = "wm8960-codec",
+ .name = "wm8960",
.owner = THIS_MODULE,
},
.probe = wm8960_i2c_probe,
.remove = __devexit_p(wm8960_i2c_remove),
.id_table = wm8960_i2c_id,
};
-#endif
static int __init wm8960_modinit(void)
{
int ret = 0;
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
ret = i2c_add_driver(&wm8960_i2c_driver);
if (ret != 0) {
printk(KERN_ERR "Failed to register WM8960 I2C driver: %d\n",
ret);
}
-#endif
return ret;
}
module_init(wm8960_modinit);
static void __exit wm8960_exit(void)
{
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
i2c_del_driver(&wm8960_i2c_driver);
-#endif
}
module_exit(wm8960_exit);
diff --git a/sound/soc/codecs/wm8961.c b/sound/soc/codecs/wm8961.c
index 9568c8a..4f20c72 100644
--- a/sound/soc/codecs/wm8961.c
+++ b/sound/soc/codecs/wm8961.c
@@ -17,7 +17,6 @@
#include <linux/delay.h>
#include <linux/pm.h>
#include <linux/i2c.h>
-#include <linux/platform_device.h>
#include <linux/slab.h>
#include <sound/core.h>
#include <sound/pcm.h>
@@ -423,11 +422,11 @@
}
if (event & SND_SOC_DAPM_PRE_PMD) {
- /* Enable the amplifier */
+ /* Disable the amplifier */
spk_reg &= ~(WM8961_SPKL_ENA | WM8961_SPKR_ENA);
snd_soc_write(codec, WM8961_CLASS_D_CONTROL_1, spk_reg);
- /* Enable the PGA */
+ /* Disable the PGA */
pwr_reg &= ~(WM8961_SPKL_PGA | WM8961_SPKR_PGA);
snd_soc_write(codec, WM8961_PWR_MGMT_2, pwr_reg);
}
@@ -531,7 +530,7 @@
SND_SOC_DAPM_ADC("ADCL", "HiFi Capture", WM8961_PWR_MGMT_1, 3, 0),
SND_SOC_DAPM_ADC("ADCR", "HiFi Capture", WM8961_PWR_MGMT_1, 2, 0),
-SND_SOC_DAPM_MICBIAS("MICBIAS", WM8961_PWR_MGMT_1, 1, 0),
+SND_SOC_DAPM_SUPPLY("MICBIAS", WM8961_PWR_MGMT_1, 1, 0, NULL, 0),
SND_SOC_DAPM_MUX("DACL Sidetone", SND_SOC_NOPM, 0, 0, &dacl_mux),
SND_SOC_DAPM_MUX("DACR Sidetone", SND_SOC_NOPM, 0, 0, &dacr_mux),
@@ -929,7 +928,7 @@
(SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
SNDRV_PCM_FMTBIT_S24_LE)
-static struct snd_soc_dai_ops wm8961_dai_ops = {
+static const struct snd_soc_dai_ops wm8961_dai_ops = {
.hw_params = wm8961_hw_params,
.set_sysclk = wm8961_set_sysclk,
.set_fmt = wm8961_set_fmt,
@@ -1039,7 +1038,7 @@
}
#ifdef CONFIG_PM
-static int wm8961_suspend(struct snd_soc_codec *codec, pm_message_t state)
+static int wm8961_suspend(struct snd_soc_codec *codec)
{
wm8961_set_bias_level(codec, SND_SOC_BIAS_OFF);
@@ -1048,18 +1047,7 @@
static int wm8961_resume(struct snd_soc_codec *codec)
{
- u16 *reg_cache = codec->reg_cache;
- int i;
-
- for (i = 0; i < codec->driver->reg_cache_size; i++) {
- if (reg_cache[i] == wm8961_reg_defaults[i])
- continue;
-
- if (i == WM8961_SOFTWARE_RESET)
- continue;
-
- snd_soc_write(codec, i, reg_cache[i]);
- }
+ snd_soc_cache_sync(codec);
wm8961_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
@@ -1082,14 +1070,14 @@
.volatile_register = wm8961_volatile_register,
};
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
static __devinit int wm8961_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
struct wm8961_priv *wm8961;
int ret;
- wm8961 = kzalloc(sizeof(struct wm8961_priv), GFP_KERNEL);
+ wm8961 = devm_kzalloc(&i2c->dev, sizeof(struct wm8961_priv),
+ GFP_KERNEL);
if (wm8961 == NULL)
return -ENOMEM;
@@ -1097,15 +1085,14 @@
ret = snd_soc_register_codec(&i2c->dev,
&soc_codec_dev_wm8961, &wm8961_dai, 1);
- if (ret < 0)
- kfree(wm8961);
+
return ret;
}
static __devexit int wm8961_i2c_remove(struct i2c_client *client)
{
snd_soc_unregister_codec(&client->dev);
- kfree(i2c_get_clientdata(client));
+
return 0;
}
@@ -1117,34 +1104,29 @@
static struct i2c_driver wm8961_i2c_driver = {
.driver = {
- .name = "wm8961-codec",
+ .name = "wm8961",
.owner = THIS_MODULE,
},
.probe = wm8961_i2c_probe,
.remove = __devexit_p(wm8961_i2c_remove),
.id_table = wm8961_i2c_id,
};
-#endif
static int __init wm8961_modinit(void)
{
int ret = 0;
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
ret = i2c_add_driver(&wm8961_i2c_driver);
if (ret != 0) {
printk(KERN_ERR "Failed to register wm8961 I2C driver: %d\n",
ret);
}
-#endif
return ret;
}
module_init(wm8961_modinit);
static void __exit wm8961_exit(void)
{
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
i2c_del_driver(&wm8961_i2c_driver);
-#endif
}
module_exit(wm8961_exit);
diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c
index 53edd9a..296de4e 100644
--- a/sound/soc/codecs/wm8962.c
+++ b/sound/soc/codecs/wm8962.c
@@ -20,7 +20,7 @@
#include <linux/gpio.h>
#include <linux/i2c.h>
#include <linux/input.h>
-#include <linux/platform_device.h>
+#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
#include <linux/slab.h>
#include <linux/workqueue.h>
@@ -50,6 +50,7 @@
/* codec private data */
struct wm8962_priv {
+ struct regmap *regmap;
struct snd_soc_codec *codec;
int sysclk;
@@ -95,7 +96,7 @@
struct wm8962_priv *wm8962 = container_of(nb, struct wm8962_priv, \
disable_nb[n]); \
if (event & REGULATOR_EVENT_DISABLE) { \
- wm8962->codec->cache_sync = 1; \
+ regcache_cache_only(wm8962->regmap, true); \
} \
return 0; \
}
@@ -109,691 +110,691 @@
WM8962_REGULATOR_EVENT(6)
WM8962_REGULATOR_EVENT(7)
-static const u16 wm8962_reg[WM8962_MAX_REGISTER + 1] = {
- [0] = 0x009F, /* R0 - Left Input volume */
- [1] = 0x049F, /* R1 - Right Input volume */
- [2] = 0x0000, /* R2 - HPOUTL volume */
- [3] = 0x0000, /* R3 - HPOUTR volume */
- [4] = 0x0020, /* R4 - Clocking1 */
- [5] = 0x0018, /* R5 - ADC & DAC Control 1 */
- [6] = 0x2008, /* R6 - ADC & DAC Control 2 */
- [7] = 0x000A, /* R7 - Audio Interface 0 */
- [8] = 0x01E4, /* R8 - Clocking2 */
- [9] = 0x0300, /* R9 - Audio Interface 1 */
- [10] = 0x00C0, /* R10 - Left DAC volume */
- [11] = 0x00C0, /* R11 - Right DAC volume */
+static struct reg_default wm8962_reg[] = {
+ { 0, 0x009F }, /* R0 - Left Input volume */
+ { 1, 0x049F }, /* R1 - Right Input volume */
+ { 2, 0x0000 }, /* R2 - HPOUTL volume */
+ { 3, 0x0000 }, /* R3 - HPOUTR volume */
+ { 4, 0x0020 }, /* R4 - Clocking1 */
+ { 5, 0x0018 }, /* R5 - ADC & DAC Control 1 */
+ { 6, 0x2008 }, /* R6 - ADC & DAC Control 2 */
+ { 7, 0x000A }, /* R7 - Audio Interface 0 */
+ { 8, 0x01E4 }, /* R8 - Clocking2 */
+ { 9, 0x0300 }, /* R9 - Audio Interface 1 */
+ { 10, 0x00C0 }, /* R10 - Left DAC volume */
+ { 11, 0x00C0 }, /* R11 - Right DAC volume */
- [14] = 0x0040, /* R14 - Audio Interface 2 */
- [15] = 0x6243, /* R15 - Software Reset */
+ { 14, 0x0040 }, /* R14 - Audio Interface 2 */
+ { 15, 0x6243 }, /* R15 - Software Reset */
- [17] = 0x007B, /* R17 - ALC1 */
- [18] = 0x0000, /* R18 - ALC2 */
- [19] = 0x1C32, /* R19 - ALC3 */
- [20] = 0x3200, /* R20 - Noise Gate */
- [21] = 0x00C0, /* R21 - Left ADC volume */
- [22] = 0x00C0, /* R22 - Right ADC volume */
- [23] = 0x0160, /* R23 - Additional control(1) */
- [24] = 0x0000, /* R24 - Additional control(2) */
- [25] = 0x0000, /* R25 - Pwr Mgmt (1) */
- [26] = 0x0000, /* R26 - Pwr Mgmt (2) */
- [27] = 0x0010, /* R27 - Additional Control (3) */
- [28] = 0x0000, /* R28 - Anti-pop */
+ { 17, 0x007B }, /* R17 - ALC1 */
+ { 18, 0x0000 }, /* R18 - ALC2 */
+ { 19, 0x1C32 }, /* R19 - ALC3 */
+ { 20, 0x3200 }, /* R20 - Noise Gate */
+ { 21, 0x00C0 }, /* R21 - Left ADC volume */
+ { 22, 0x00C0 }, /* R22 - Right ADC volume */
+ { 23, 0x0160 }, /* R23 - Additional control(1) */
+ { 24, 0x0000 }, /* R24 - Additional control(2) */
+ { 25, 0x0000 }, /* R25 - Pwr Mgmt (1) */
+ { 26, 0x0000 }, /* R26 - Pwr Mgmt (2) */
+ { 27, 0x0010 }, /* R27 - Additional Control (3) */
+ { 28, 0x0000 }, /* R28 - Anti-pop */
- [30] = 0x005E, /* R30 - Clocking 3 */
- [31] = 0x0000, /* R31 - Input mixer control (1) */
- [32] = 0x0145, /* R32 - Left input mixer volume */
- [33] = 0x0145, /* R33 - Right input mixer volume */
- [34] = 0x0009, /* R34 - Input mixer control (2) */
- [35] = 0x0003, /* R35 - Input bias control */
- [37] = 0x0008, /* R37 - Left input PGA control */
- [38] = 0x0008, /* R38 - Right input PGA control */
+ { 30, 0x005E }, /* R30 - Clocking 3 */
+ { 31, 0x0000 }, /* R31 - Input mixer control (1) */
+ { 32, 0x0145 }, /* R32 - Left input mixer volume */
+ { 33, 0x0145 }, /* R33 - Right input mixer volume */
+ { 34, 0x0009 }, /* R34 - Input mixer control (2) */
+ { 35, 0x0003 }, /* R35 - Input bias control */
+ { 37, 0x0008 }, /* R37 - Left input PGA control */
+ { 38, 0x0008 }, /* R38 - Right input PGA control */
- [40] = 0x0000, /* R40 - SPKOUTL volume */
- [41] = 0x0000, /* R41 - SPKOUTR volume */
+ { 40, 0x0000 }, /* R40 - SPKOUTL volume */
+ { 41, 0x0000 }, /* R41 - SPKOUTR volume */
- [47] = 0x0000, /* R47 - Thermal Shutdown Status */
- [48] = 0x8027, /* R48 - Additional Control (4) */
- [49] = 0x0010, /* R49 - Class D Control 1 */
+ { 47, 0x0000 }, /* R47 - Thermal Shutdown Status */
+ { 48, 0x8027 }, /* R48 - Additional Control (4) */
+ { 49, 0x0010 }, /* R49 - Class D Control 1 */
- [51] = 0x0003, /* R51 - Class D Control 2 */
+ { 51, 0x0003 }, /* R51 - Class D Control 2 */
- [56] = 0x0506, /* R56 - Clocking 4 */
- [57] = 0x0000, /* R57 - DAC DSP Mixing (1) */
- [58] = 0x0000, /* R58 - DAC DSP Mixing (2) */
+ { 56, 0x0506 }, /* R56 - Clocking 4 */
+ { 57, 0x0000 }, /* R57 - DAC DSP Mixing (1) */
+ { 58, 0x0000 }, /* R58 - DAC DSP Mixing (2) */
- [60] = 0x0300, /* R60 - DC Servo 0 */
- [61] = 0x0300, /* R61 - DC Servo 1 */
+ { 60, 0x0300 }, /* R60 - DC Servo 0 */
+ { 61, 0x0300 }, /* R61 - DC Servo 1 */
- [64] = 0x0810, /* R64 - DC Servo 4 */
+ { 64, 0x0810 }, /* R64 - DC Servo 4 */
- [66] = 0x0000, /* R66 - DC Servo 6 */
+ { 66, 0x0000 }, /* R66 - DC Servo 6 */
- [68] = 0x001B, /* R68 - Analogue PGA Bias */
- [69] = 0x0000, /* R69 - Analogue HP 0 */
+ { 68, 0x001B }, /* R68 - Analogue PGA Bias */
+ { 69, 0x0000 }, /* R69 - Analogue HP 0 */
- [71] = 0x01FB, /* R71 - Analogue HP 2 */
- [72] = 0x0000, /* R72 - Charge Pump 1 */
+ { 71, 0x01FB }, /* R71 - Analogue HP 2 */
+ { 72, 0x0000 }, /* R72 - Charge Pump 1 */
- [82] = 0x0004, /* R82 - Charge Pump B */
+ { 82, 0x0004 }, /* R82 - Charge Pump B */
- [87] = 0x0000, /* R87 - Write Sequencer Control 1 */
+ { 87, 0x0000 }, /* R87 - Write Sequencer Control 1 */
- [90] = 0x0000, /* R90 - Write Sequencer Control 2 */
+ { 90, 0x0000 }, /* R90 - Write Sequencer Control 2 */
- [93] = 0x0000, /* R93 - Write Sequencer Control 3 */
- [94] = 0x0000, /* R94 - Control Interface */
+ { 93, 0x0000 }, /* R93 - Write Sequencer Control 3 */
+ { 94, 0x0000 }, /* R94 - Control Interface */
- [99] = 0x0000, /* R99 - Mixer Enables */
- [100] = 0x0000, /* R100 - Headphone Mixer (1) */
- [101] = 0x0000, /* R101 - Headphone Mixer (2) */
- [102] = 0x013F, /* R102 - Headphone Mixer (3) */
- [103] = 0x013F, /* R103 - Headphone Mixer (4) */
+ { 99, 0x0000 }, /* R99 - Mixer Enables */
+ { 100, 0x0000 }, /* R100 - Headphone Mixer (1) */
+ { 101, 0x0000 }, /* R101 - Headphone Mixer (2) */
+ { 102, 0x013F }, /* R102 - Headphone Mixer (3) */
+ { 103, 0x013F }, /* R103 - Headphone Mixer (4) */
- [105] = 0x0000, /* R105 - Speaker Mixer (1) */
- [106] = 0x0000, /* R106 - Speaker Mixer (2) */
- [107] = 0x013F, /* R107 - Speaker Mixer (3) */
- [108] = 0x013F, /* R108 - Speaker Mixer (4) */
- [109] = 0x0003, /* R109 - Speaker Mixer (5) */
- [110] = 0x0002, /* R110 - Beep Generator (1) */
+ { 105, 0x0000 }, /* R105 - Speaker Mixer (1) */
+ { 106, 0x0000 }, /* R106 - Speaker Mixer (2) */
+ { 107, 0x013F }, /* R107 - Speaker Mixer (3) */
+ { 108, 0x013F }, /* R108 - Speaker Mixer (4) */
+ { 109, 0x0003 }, /* R109 - Speaker Mixer (5) */
+ { 110, 0x0002 }, /* R110 - Beep Generator (1) */
- [115] = 0x0006, /* R115 - Oscillator Trim (3) */
- [116] = 0x0026, /* R116 - Oscillator Trim (4) */
+ { 115, 0x0006 }, /* R115 - Oscillator Trim (3) */
+ { 116, 0x0026 }, /* R116 - Oscillator Trim (4) */
- [119] = 0x0000, /* R119 - Oscillator Trim (7) */
+ { 119, 0x0000 }, /* R119 - Oscillator Trim (7) */
- [124] = 0x0011, /* R124 - Analogue Clocking1 */
- [125] = 0x004B, /* R125 - Analogue Clocking2 */
- [126] = 0x000D, /* R126 - Analogue Clocking3 */
- [127] = 0x0000, /* R127 - PLL Software Reset */
+ { 124, 0x0011 }, /* R124 - Analogue Clocking1 */
+ { 125, 0x004B }, /* R125 - Analogue Clocking2 */
+ { 126, 0x000D }, /* R126 - Analogue Clocking3 */
+ { 127, 0x0000 }, /* R127 - PLL Software Reset */
- [129] = 0x0000, /* R129 - PLL2 */
+ { 129, 0x0000 }, /* R129 - PLL2 */
- [131] = 0x0000, /* R131 - PLL 4 */
+ { 131, 0x0000 }, /* R131 - PLL 4 */
- [136] = 0x0067, /* R136 - PLL 9 */
- [137] = 0x001C, /* R137 - PLL 10 */
- [138] = 0x0071, /* R138 - PLL 11 */
- [139] = 0x00C7, /* R139 - PLL 12 */
- [140] = 0x0067, /* R140 - PLL 13 */
- [141] = 0x0048, /* R141 - PLL 14 */
- [142] = 0x0022, /* R142 - PLL 15 */
- [143] = 0x0097, /* R143 - PLL 16 */
+ { 136, 0x0067 }, /* R136 - PLL 9 */
+ { 137, 0x001C }, /* R137 - PLL 10 */
+ { 138, 0x0071 }, /* R138 - PLL 11 */
+ { 139, 0x00C7 }, /* R139 - PLL 12 */
+ { 140, 0x0067 }, /* R140 - PLL 13 */
+ { 141, 0x0048 }, /* R141 - PLL 14 */
+ { 142, 0x0022 }, /* R142 - PLL 15 */
+ { 143, 0x0097 }, /* R143 - PLL 16 */
- [155] = 0x000C, /* R155 - FLL Control (1) */
- [156] = 0x0039, /* R156 - FLL Control (2) */
- [157] = 0x0180, /* R157 - FLL Control (3) */
+ { 155, 0x000C }, /* R155 - FLL Control (1) */
+ { 156, 0x0039 }, /* R156 - FLL Control (2) */
+ { 157, 0x0180 }, /* R157 - FLL Control (3) */
- [159] = 0x0032, /* R159 - FLL Control (5) */
- [160] = 0x0018, /* R160 - FLL Control (6) */
- [161] = 0x007D, /* R161 - FLL Control (7) */
- [162] = 0x0008, /* R162 - FLL Control (8) */
+ { 159, 0x0032 }, /* R159 - FLL Control (5) */
+ { 160, 0x0018 }, /* R160 - FLL Control (6) */
+ { 161, 0x007D }, /* R161 - FLL Control (7) */
+ { 162, 0x0008 }, /* R162 - FLL Control (8) */
- [252] = 0x0005, /* R252 - General test 1 */
+ { 252, 0x0005 }, /* R252 - General test 1 */
- [256] = 0x0000, /* R256 - DF1 */
- [257] = 0x0000, /* R257 - DF2 */
- [258] = 0x0000, /* R258 - DF3 */
- [259] = 0x0000, /* R259 - DF4 */
- [260] = 0x0000, /* R260 - DF5 */
- [261] = 0x0000, /* R261 - DF6 */
- [262] = 0x0000, /* R262 - DF7 */
+ { 256, 0x0000 }, /* R256 - DF1 */
+ { 257, 0x0000 }, /* R257 - DF2 */
+ { 258, 0x0000 }, /* R258 - DF3 */
+ { 259, 0x0000 }, /* R259 - DF4 */
+ { 260, 0x0000 }, /* R260 - DF5 */
+ { 261, 0x0000 }, /* R261 - DF6 */
+ { 262, 0x0000 }, /* R262 - DF7 */
- [264] = 0x0000, /* R264 - LHPF1 */
- [265] = 0x0000, /* R265 - LHPF2 */
+ { 264, 0x0000 }, /* R264 - LHPF1 */
+ { 265, 0x0000 }, /* R265 - LHPF2 */
- [268] = 0x0000, /* R268 - THREED1 */
- [269] = 0x0000, /* R269 - THREED2 */
- [270] = 0x0000, /* R270 - THREED3 */
- [271] = 0x0000, /* R271 - THREED4 */
+ { 268, 0x0000 }, /* R268 - THREED1 */
+ { 269, 0x0000 }, /* R269 - THREED2 */
+ { 270, 0x0000 }, /* R270 - THREED3 */
+ { 271, 0x0000 }, /* R271 - THREED4 */
- [276] = 0x000C, /* R276 - DRC 1 */
- [277] = 0x0925, /* R277 - DRC 2 */
- [278] = 0x0000, /* R278 - DRC 3 */
- [279] = 0x0000, /* R279 - DRC 4 */
- [280] = 0x0000, /* R280 - DRC 5 */
+ { 276, 0x000C }, /* R276 - DRC 1 */
+ { 277, 0x0925 }, /* R277 - DRC 2 */
+ { 278, 0x0000 }, /* R278 - DRC 3 */
+ { 279, 0x0000 }, /* R279 - DRC 4 */
+ { 280, 0x0000 }, /* R280 - DRC 5 */
- [285] = 0x0000, /* R285 - Tloopback */
+ { 285, 0x0000 }, /* R285 - Tloopback */
- [335] = 0x0004, /* R335 - EQ1 */
- [336] = 0x6318, /* R336 - EQ2 */
- [337] = 0x6300, /* R337 - EQ3 */
- [338] = 0x0FCA, /* R338 - EQ4 */
- [339] = 0x0400, /* R339 - EQ5 */
- [340] = 0x00D8, /* R340 - EQ6 */
- [341] = 0x1EB5, /* R341 - EQ7 */
- [342] = 0xF145, /* R342 - EQ8 */
- [343] = 0x0B75, /* R343 - EQ9 */
- [344] = 0x01C5, /* R344 - EQ10 */
- [345] = 0x1C58, /* R345 - EQ11 */
- [346] = 0xF373, /* R346 - EQ12 */
- [347] = 0x0A54, /* R347 - EQ13 */
- [348] = 0x0558, /* R348 - EQ14 */
- [349] = 0x168E, /* R349 - EQ15 */
- [350] = 0xF829, /* R350 - EQ16 */
- [351] = 0x07AD, /* R351 - EQ17 */
- [352] = 0x1103, /* R352 - EQ18 */
- [353] = 0x0564, /* R353 - EQ19 */
- [354] = 0x0559, /* R354 - EQ20 */
- [355] = 0x4000, /* R355 - EQ21 */
- [356] = 0x6318, /* R356 - EQ22 */
- [357] = 0x6300, /* R357 - EQ23 */
- [358] = 0x0FCA, /* R358 - EQ24 */
- [359] = 0x0400, /* R359 - EQ25 */
- [360] = 0x00D8, /* R360 - EQ26 */
- [361] = 0x1EB5, /* R361 - EQ27 */
- [362] = 0xF145, /* R362 - EQ28 */
- [363] = 0x0B75, /* R363 - EQ29 */
- [364] = 0x01C5, /* R364 - EQ30 */
- [365] = 0x1C58, /* R365 - EQ31 */
- [366] = 0xF373, /* R366 - EQ32 */
- [367] = 0x0A54, /* R367 - EQ33 */
- [368] = 0x0558, /* R368 - EQ34 */
- [369] = 0x168E, /* R369 - EQ35 */
- [370] = 0xF829, /* R370 - EQ36 */
- [371] = 0x07AD, /* R371 - EQ37 */
- [372] = 0x1103, /* R372 - EQ38 */
- [373] = 0x0564, /* R373 - EQ39 */
- [374] = 0x0559, /* R374 - EQ40 */
- [375] = 0x4000, /* R375 - EQ41 */
+ { 335, 0x0004 }, /* R335 - EQ1 */
+ { 336, 0x6318 }, /* R336 - EQ2 */
+ { 337, 0x6300 }, /* R337 - EQ3 */
+ { 338, 0x0FCA }, /* R338 - EQ4 */
+ { 339, 0x0400 }, /* R339 - EQ5 */
+ { 340, 0x00D8 }, /* R340 - EQ6 */
+ { 341, 0x1EB5 }, /* R341 - EQ7 */
+ { 342, 0xF145 }, /* R342 - EQ8 */
+ { 343, 0x0B75 }, /* R343 - EQ9 */
+ { 344, 0x01C5 }, /* R344 - EQ10 */
+ { 345, 0x1C58 }, /* R345 - EQ11 */
+ { 346, 0xF373 }, /* R346 - EQ12 */
+ { 347, 0x0A54 }, /* R347 - EQ13 */
+ { 348, 0x0558 }, /* R348 - EQ14 */
+ { 349, 0x168E }, /* R349 - EQ15 */
+ { 350, 0xF829 }, /* R350 - EQ16 */
+ { 351, 0x07AD }, /* R351 - EQ17 */
+ { 352, 0x1103 }, /* R352 - EQ18 */
+ { 353, 0x0564 }, /* R353 - EQ19 */
+ { 354, 0x0559 }, /* R354 - EQ20 */
+ { 355, 0x4000 }, /* R355 - EQ21 */
+ { 356, 0x6318 }, /* R356 - EQ22 */
+ { 357, 0x6300 }, /* R357 - EQ23 */
+ { 358, 0x0FCA }, /* R358 - EQ24 */
+ { 359, 0x0400 }, /* R359 - EQ25 */
+ { 360, 0x00D8 }, /* R360 - EQ26 */
+ { 361, 0x1EB5 }, /* R361 - EQ27 */
+ { 362, 0xF145 }, /* R362 - EQ28 */
+ { 363, 0x0B75 }, /* R363 - EQ29 */
+ { 364, 0x01C5 }, /* R364 - EQ30 */
+ { 365, 0x1C58 }, /* R365 - EQ31 */
+ { 366, 0xF373 }, /* R366 - EQ32 */
+ { 367, 0x0A54 }, /* R367 - EQ33 */
+ { 368, 0x0558 }, /* R368 - EQ34 */
+ { 369, 0x168E }, /* R369 - EQ35 */
+ { 370, 0xF829 }, /* R370 - EQ36 */
+ { 371, 0x07AD }, /* R371 - EQ37 */
+ { 372, 0x1103 }, /* R372 - EQ38 */
+ { 373, 0x0564 }, /* R373 - EQ39 */
+ { 374, 0x0559 }, /* R374 - EQ40 */
+ { 375, 0x4000 }, /* R375 - EQ41 */
- [513] = 0x0000, /* R513 - GPIO 2 */
- [514] = 0x0000, /* R514 - GPIO 3 */
+ { 513, 0x0000 }, /* R513 - GPIO 2 */
+ { 514, 0x0000 }, /* R514 - GPIO 3 */
- [516] = 0x8100, /* R516 - GPIO 5 */
- [517] = 0x8100, /* R517 - GPIO 6 */
+ { 516, 0x8100 }, /* R516 - GPIO 5 */
+ { 517, 0x8100 }, /* R517 - GPIO 6 */
- [560] = 0x0000, /* R560 - Interrupt Status 1 */
- [561] = 0x0000, /* R561 - Interrupt Status 2 */
+ { 560, 0x0000 }, /* R560 - Interrupt Status 1 */
+ { 561, 0x0000 }, /* R561 - Interrupt Status 2 */
- [568] = 0x0030, /* R568 - Interrupt Status 1 Mask */
- [569] = 0xFFED, /* R569 - Interrupt Status 2 Mask */
+ { 568, 0x0030 }, /* R568 - Interrupt Status 1 Mask */
+ { 569, 0xFFED }, /* R569 - Interrupt Status 2 Mask */
- [576] = 0x0000, /* R576 - Interrupt Control */
+ { 576, 0x0000 }, /* R576 - Interrupt Control */
- [584] = 0x002D, /* R584 - IRQ Debounce */
+ { 584, 0x002D }, /* R584 - IRQ Debounce */
- [586] = 0x0000, /* R586 - MICINT Source Pol */
+ { 586, 0x0000 }, /* R586 - MICINT Source Pol */
- [768] = 0x1C00, /* R768 - DSP2 Power Management */
+ { 768, 0x1C00 }, /* R768 - DSP2 Power Management */
- [1037] = 0x0000, /* R1037 - DSP2_ExecControl */
+ { 1037, 0x0000 }, /* R1037 - DSP2_ExecControl */
- [8192] = 0x0000, /* R8192 - DSP2 Instruction RAM 0 */
+ { 8192, 0x0000 }, /* R8192 - DSP2 Instruction RAM 0 */
- [9216] = 0x0030, /* R9216 - DSP2 Address RAM 2 */
- [9217] = 0x0000, /* R9217 - DSP2 Address RAM 1 */
- [9218] = 0x0000, /* R9218 - DSP2 Address RAM 0 */
+ { 9216, 0x0030 }, /* R9216 - DSP2 Address RAM 2 */
+ { 9217, 0x0000 }, /* R9217 - DSP2 Address RAM 1 */
+ { 9218, 0x0000 }, /* R9218 - DSP2 Address RAM 0 */
- [12288] = 0x0000, /* R12288 - DSP2 Data1 RAM 1 */
- [12289] = 0x0000, /* R12289 - DSP2 Data1 RAM 0 */
+ { 12288, 0x0000 }, /* R12288 - DSP2 Data1 RAM 1 */
+ { 12289, 0x0000 }, /* R12289 - DSP2 Data1 RAM 0 */
- [13312] = 0x0000, /* R13312 - DSP2 Data2 RAM 1 */
- [13313] = 0x0000, /* R13313 - DSP2 Data2 RAM 0 */
+ { 13312, 0x0000 }, /* R13312 - DSP2 Data2 RAM 1 */
+ { 13313, 0x0000 }, /* R13313 - DSP2 Data2 RAM 0 */
- [14336] = 0x0000, /* R14336 - DSP2 Data3 RAM 1 */
- [14337] = 0x0000, /* R14337 - DSP2 Data3 RAM 0 */
+ { 14336, 0x0000 }, /* R14336 - DSP2 Data3 RAM 1 */
+ { 14337, 0x0000 }, /* R14337 - DSP2 Data3 RAM 0 */
- [15360] = 0x000A, /* R15360 - DSP2 Coeff RAM 0 */
+ { 15360, 0x000A }, /* R15360 - DSP2 Coeff RAM 0 */
- [16384] = 0x0000, /* R16384 - RETUNEADC_SHARED_COEFF_1 */
- [16385] = 0x0000, /* R16385 - RETUNEADC_SHARED_COEFF_0 */
- [16386] = 0x0000, /* R16386 - RETUNEDAC_SHARED_COEFF_1 */
- [16387] = 0x0000, /* R16387 - RETUNEDAC_SHARED_COEFF_0 */
- [16388] = 0x0000, /* R16388 - SOUNDSTAGE_ENABLES_1 */
- [16389] = 0x0000, /* R16389 - SOUNDSTAGE_ENABLES_0 */
+ { 16384, 0x0000 }, /* R16384 - RETUNEADC_SHARED_COEFF_1 */
+ { 16385, 0x0000 }, /* R16385 - RETUNEADC_SHARED_COEFF_0 */
+ { 16386, 0x0000 }, /* R16386 - RETUNEDAC_SHARED_COEFF_1 */
+ { 16387, 0x0000 }, /* R16387 - RETUNEDAC_SHARED_COEFF_0 */
+ { 16388, 0x0000 }, /* R16388 - SOUNDSTAGE_ENABLES_1 */
+ { 16389, 0x0000 }, /* R16389 - SOUNDSTAGE_ENABLES_0 */
- [16896] = 0x0002, /* R16896 - HDBASS_AI_1 */
- [16897] = 0xBD12, /* R16897 - HDBASS_AI_0 */
- [16898] = 0x007C, /* R16898 - HDBASS_AR_1 */
- [16899] = 0x586C, /* R16899 - HDBASS_AR_0 */
- [16900] = 0x0053, /* R16900 - HDBASS_B_1 */
- [16901] = 0x8121, /* R16901 - HDBASS_B_0 */
- [16902] = 0x003F, /* R16902 - HDBASS_K_1 */
- [16903] = 0x8BD8, /* R16903 - HDBASS_K_0 */
- [16904] = 0x0032, /* R16904 - HDBASS_N1_1 */
- [16905] = 0xF52D, /* R16905 - HDBASS_N1_0 */
- [16906] = 0x0065, /* R16906 - HDBASS_N2_1 */
- [16907] = 0xAC8C, /* R16907 - HDBASS_N2_0 */
- [16908] = 0x006B, /* R16908 - HDBASS_N3_1 */
- [16909] = 0xE087, /* R16909 - HDBASS_N3_0 */
- [16910] = 0x0072, /* R16910 - HDBASS_N4_1 */
- [16911] = 0x1483, /* R16911 - HDBASS_N4_0 */
- [16912] = 0x0072, /* R16912 - HDBASS_N5_1 */
- [16913] = 0x1483, /* R16913 - HDBASS_N5_0 */
- [16914] = 0x0043, /* R16914 - HDBASS_X1_1 */
- [16915] = 0x3525, /* R16915 - HDBASS_X1_0 */
- [16916] = 0x0006, /* R16916 - HDBASS_X2_1 */
- [16917] = 0x6A4A, /* R16917 - HDBASS_X2_0 */
- [16918] = 0x0043, /* R16918 - HDBASS_X3_1 */
- [16919] = 0x6079, /* R16919 - HDBASS_X3_0 */
- [16920] = 0x0008, /* R16920 - HDBASS_ATK_1 */
- [16921] = 0x0000, /* R16921 - HDBASS_ATK_0 */
- [16922] = 0x0001, /* R16922 - HDBASS_DCY_1 */
- [16923] = 0x0000, /* R16923 - HDBASS_DCY_0 */
- [16924] = 0x0059, /* R16924 - HDBASS_PG_1 */
- [16925] = 0x999A, /* R16925 - HDBASS_PG_0 */
+ { 16896, 0x0002 }, /* R16896 - HDBASS_AI_1 */
+ { 16897, 0xBD12 }, /* R16897 - HDBASS_AI_0 */
+ { 16898, 0x007C }, /* R16898 - HDBASS_AR_1 */
+ { 16899, 0x586C }, /* R16899 - HDBASS_AR_0 */
+ { 16900, 0x0053 }, /* R16900 - HDBASS_B_1 */
+ { 16901, 0x8121 }, /* R16901 - HDBASS_B_0 */
+ { 16902, 0x003F }, /* R16902 - HDBASS_K_1 */
+ { 16903, 0x8BD8 }, /* R16903 - HDBASS_K_0 */
+ { 16904, 0x0032 }, /* R16904 - HDBASS_N1_1 */
+ { 16905, 0xF52D }, /* R16905 - HDBASS_N1_0 */
+ { 16906, 0x0065 }, /* R16906 - HDBASS_N2_1 */
+ { 16907, 0xAC8C }, /* R16907 - HDBASS_N2_0 */
+ { 16908, 0x006B }, /* R16908 - HDBASS_N3_1 */
+ { 16909, 0xE087 }, /* R16909 - HDBASS_N3_0 */
+ { 16910, 0x0072 }, /* R16910 - HDBASS_N4_1 */
+ { 16911, 0x1483 }, /* R16911 - HDBASS_N4_0 */
+ { 16912, 0x0072 }, /* R16912 - HDBASS_N5_1 */
+ { 16913, 0x1483 }, /* R16913 - HDBASS_N5_0 */
+ { 16914, 0x0043 }, /* R16914 - HDBASS_X1_1 */
+ { 16915, 0x3525 }, /* R16915 - HDBASS_X1_0 */
+ { 16916, 0x0006 }, /* R16916 - HDBASS_X2_1 */
+ { 16917, 0x6A4A }, /* R16917 - HDBASS_X2_0 */
+ { 16918, 0x0043 }, /* R16918 - HDBASS_X3_1 */
+ { 16919, 0x6079 }, /* R16919 - HDBASS_X3_0 */
+ { 16920, 0x0008 }, /* R16920 - HDBASS_ATK_1 */
+ { 16921, 0x0000 }, /* R16921 - HDBASS_ATK_0 */
+ { 16922, 0x0001 }, /* R16922 - HDBASS_DCY_1 */
+ { 16923, 0x0000 }, /* R16923 - HDBASS_DCY_0 */
+ { 16924, 0x0059 }, /* R16924 - HDBASS_PG_1 */
+ { 16925, 0x999A }, /* R16925 - HDBASS_PG_0 */
- [17048] = 0x0083, /* R17408 - HPF_C_1 */
- [17049] = 0x98AD, /* R17409 - HPF_C_0 */
+ { 17048, 0x0083 }, /* R17408 - HPF_C_1 */
+ { 17049, 0x98AD }, /* R17409 - HPF_C_0 */
- [17920] = 0x007F, /* R17920 - ADCL_RETUNE_C1_1 */
- [17921] = 0xFFFF, /* R17921 - ADCL_RETUNE_C1_0 */
- [17922] = 0x0000, /* R17922 - ADCL_RETUNE_C2_1 */
- [17923] = 0x0000, /* R17923 - ADCL_RETUNE_C2_0 */
- [17924] = 0x0000, /* R17924 - ADCL_RETUNE_C3_1 */
- [17925] = 0x0000, /* R17925 - ADCL_RETUNE_C3_0 */
- [17926] = 0x0000, /* R17926 - ADCL_RETUNE_C4_1 */
- [17927] = 0x0000, /* R17927 - ADCL_RETUNE_C4_0 */
- [17928] = 0x0000, /* R17928 - ADCL_RETUNE_C5_1 */
- [17929] = 0x0000, /* R17929 - ADCL_RETUNE_C5_0 */
- [17930] = 0x0000, /* R17930 - ADCL_RETUNE_C6_1 */
- [17931] = 0x0000, /* R17931 - ADCL_RETUNE_C6_0 */
- [17932] = 0x0000, /* R17932 - ADCL_RETUNE_C7_1 */
- [17933] = 0x0000, /* R17933 - ADCL_RETUNE_C7_0 */
- [17934] = 0x0000, /* R17934 - ADCL_RETUNE_C8_1 */
- [17935] = 0x0000, /* R17935 - ADCL_RETUNE_C8_0 */
- [17936] = 0x0000, /* R17936 - ADCL_RETUNE_C9_1 */
- [17937] = 0x0000, /* R17937 - ADCL_RETUNE_C9_0 */
- [17938] = 0x0000, /* R17938 - ADCL_RETUNE_C10_1 */
- [17939] = 0x0000, /* R17939 - ADCL_RETUNE_C10_0 */
- [17940] = 0x0000, /* R17940 - ADCL_RETUNE_C11_1 */
- [17941] = 0x0000, /* R17941 - ADCL_RETUNE_C11_0 */
- [17942] = 0x0000, /* R17942 - ADCL_RETUNE_C12_1 */
- [17943] = 0x0000, /* R17943 - ADCL_RETUNE_C12_0 */
- [17944] = 0x0000, /* R17944 - ADCL_RETUNE_C13_1 */
- [17945] = 0x0000, /* R17945 - ADCL_RETUNE_C13_0 */
- [17946] = 0x0000, /* R17946 - ADCL_RETUNE_C14_1 */
- [17947] = 0x0000, /* R17947 - ADCL_RETUNE_C14_0 */
- [17948] = 0x0000, /* R17948 - ADCL_RETUNE_C15_1 */
- [17949] = 0x0000, /* R17949 - ADCL_RETUNE_C15_0 */
- [17950] = 0x0000, /* R17950 - ADCL_RETUNE_C16_1 */
- [17951] = 0x0000, /* R17951 - ADCL_RETUNE_C16_0 */
- [17952] = 0x0000, /* R17952 - ADCL_RETUNE_C17_1 */
- [17953] = 0x0000, /* R17953 - ADCL_RETUNE_C17_0 */
- [17954] = 0x0000, /* R17954 - ADCL_RETUNE_C18_1 */
- [17955] = 0x0000, /* R17955 - ADCL_RETUNE_C18_0 */
- [17956] = 0x0000, /* R17956 - ADCL_RETUNE_C19_1 */
- [17957] = 0x0000, /* R17957 - ADCL_RETUNE_C19_0 */
- [17958] = 0x0000, /* R17958 - ADCL_RETUNE_C20_1 */
- [17959] = 0x0000, /* R17959 - ADCL_RETUNE_C20_0 */
- [17960] = 0x0000, /* R17960 - ADCL_RETUNE_C21_1 */
- [17961] = 0x0000, /* R17961 - ADCL_RETUNE_C21_0 */
- [17962] = 0x0000, /* R17962 - ADCL_RETUNE_C22_1 */
- [17963] = 0x0000, /* R17963 - ADCL_RETUNE_C22_0 */
- [17964] = 0x0000, /* R17964 - ADCL_RETUNE_C23_1 */
- [17965] = 0x0000, /* R17965 - ADCL_RETUNE_C23_0 */
- [17966] = 0x0000, /* R17966 - ADCL_RETUNE_C24_1 */
- [17967] = 0x0000, /* R17967 - ADCL_RETUNE_C24_0 */
- [17968] = 0x0000, /* R17968 - ADCL_RETUNE_C25_1 */
- [17969] = 0x0000, /* R17969 - ADCL_RETUNE_C25_0 */
- [17970] = 0x0000, /* R17970 - ADCL_RETUNE_C26_1 */
- [17971] = 0x0000, /* R17971 - ADCL_RETUNE_C26_0 */
- [17972] = 0x0000, /* R17972 - ADCL_RETUNE_C27_1 */
- [17973] = 0x0000, /* R17973 - ADCL_RETUNE_C27_0 */
- [17974] = 0x0000, /* R17974 - ADCL_RETUNE_C28_1 */
- [17975] = 0x0000, /* R17975 - ADCL_RETUNE_C28_0 */
- [17976] = 0x0000, /* R17976 - ADCL_RETUNE_C29_1 */
- [17977] = 0x0000, /* R17977 - ADCL_RETUNE_C29_0 */
- [17978] = 0x0000, /* R17978 - ADCL_RETUNE_C30_1 */
- [17979] = 0x0000, /* R17979 - ADCL_RETUNE_C30_0 */
- [17980] = 0x0000, /* R17980 - ADCL_RETUNE_C31_1 */
- [17981] = 0x0000, /* R17981 - ADCL_RETUNE_C31_0 */
- [17982] = 0x0000, /* R17982 - ADCL_RETUNE_C32_1 */
- [17983] = 0x0000, /* R17983 - ADCL_RETUNE_C32_0 */
+ { 17920, 0x007F }, /* R17920 - ADCL_RETUNE_C1_1 */
+ { 17921, 0xFFFF }, /* R17921 - ADCL_RETUNE_C1_0 */
+ { 17922, 0x0000 }, /* R17922 - ADCL_RETUNE_C2_1 */
+ { 17923, 0x0000 }, /* R17923 - ADCL_RETUNE_C2_0 */
+ { 17924, 0x0000 }, /* R17924 - ADCL_RETUNE_C3_1 */
+ { 17925, 0x0000 }, /* R17925 - ADCL_RETUNE_C3_0 */
+ { 17926, 0x0000 }, /* R17926 - ADCL_RETUNE_C4_1 */
+ { 17927, 0x0000 }, /* R17927 - ADCL_RETUNE_C4_0 */
+ { 17928, 0x0000 }, /* R17928 - ADCL_RETUNE_C5_1 */
+ { 17929, 0x0000 }, /* R17929 - ADCL_RETUNE_C5_0 */
+ { 17930, 0x0000 }, /* R17930 - ADCL_RETUNE_C6_1 */
+ { 17931, 0x0000 }, /* R17931 - ADCL_RETUNE_C6_0 */
+ { 17932, 0x0000 }, /* R17932 - ADCL_RETUNE_C7_1 */
+ { 17933, 0x0000 }, /* R17933 - ADCL_RETUNE_C7_0 */
+ { 17934, 0x0000 }, /* R17934 - ADCL_RETUNE_C8_1 */
+ { 17935, 0x0000 }, /* R17935 - ADCL_RETUNE_C8_0 */
+ { 17936, 0x0000 }, /* R17936 - ADCL_RETUNE_C9_1 */
+ { 17937, 0x0000 }, /* R17937 - ADCL_RETUNE_C9_0 */
+ { 17938, 0x0000 }, /* R17938 - ADCL_RETUNE_C10_1 */
+ { 17939, 0x0000 }, /* R17939 - ADCL_RETUNE_C10_0 */
+ { 17940, 0x0000 }, /* R17940 - ADCL_RETUNE_C11_1 */
+ { 17941, 0x0000 }, /* R17941 - ADCL_RETUNE_C11_0 */
+ { 17942, 0x0000 }, /* R17942 - ADCL_RETUNE_C12_1 */
+ { 17943, 0x0000 }, /* R17943 - ADCL_RETUNE_C12_0 */
+ { 17944, 0x0000 }, /* R17944 - ADCL_RETUNE_C13_1 */
+ { 17945, 0x0000 }, /* R17945 - ADCL_RETUNE_C13_0 */
+ { 17946, 0x0000 }, /* R17946 - ADCL_RETUNE_C14_1 */
+ { 17947, 0x0000 }, /* R17947 - ADCL_RETUNE_C14_0 */
+ { 17948, 0x0000 }, /* R17948 - ADCL_RETUNE_C15_1 */
+ { 17949, 0x0000 }, /* R17949 - ADCL_RETUNE_C15_0 */
+ { 17950, 0x0000 }, /* R17950 - ADCL_RETUNE_C16_1 */
+ { 17951, 0x0000 }, /* R17951 - ADCL_RETUNE_C16_0 */
+ { 17952, 0x0000 }, /* R17952 - ADCL_RETUNE_C17_1 */
+ { 17953, 0x0000 }, /* R17953 - ADCL_RETUNE_C17_0 */
+ { 17954, 0x0000 }, /* R17954 - ADCL_RETUNE_C18_1 */
+ { 17955, 0x0000 }, /* R17955 - ADCL_RETUNE_C18_0 */
+ { 17956, 0x0000 }, /* R17956 - ADCL_RETUNE_C19_1 */
+ { 17957, 0x0000 }, /* R17957 - ADCL_RETUNE_C19_0 */
+ { 17958, 0x0000 }, /* R17958 - ADCL_RETUNE_C20_1 */
+ { 17959, 0x0000 }, /* R17959 - ADCL_RETUNE_C20_0 */
+ { 17960, 0x0000 }, /* R17960 - ADCL_RETUNE_C21_1 */
+ { 17961, 0x0000 }, /* R17961 - ADCL_RETUNE_C21_0 */
+ { 17962, 0x0000 }, /* R17962 - ADCL_RETUNE_C22_1 */
+ { 17963, 0x0000 }, /* R17963 - ADCL_RETUNE_C22_0 */
+ { 17964, 0x0000 }, /* R17964 - ADCL_RETUNE_C23_1 */
+ { 17965, 0x0000 }, /* R17965 - ADCL_RETUNE_C23_0 */
+ { 17966, 0x0000 }, /* R17966 - ADCL_RETUNE_C24_1 */
+ { 17967, 0x0000 }, /* R17967 - ADCL_RETUNE_C24_0 */
+ { 17968, 0x0000 }, /* R17968 - ADCL_RETUNE_C25_1 */
+ { 17969, 0x0000 }, /* R17969 - ADCL_RETUNE_C25_0 */
+ { 17970, 0x0000 }, /* R17970 - ADCL_RETUNE_C26_1 */
+ { 17971, 0x0000 }, /* R17971 - ADCL_RETUNE_C26_0 */
+ { 17972, 0x0000 }, /* R17972 - ADCL_RETUNE_C27_1 */
+ { 17973, 0x0000 }, /* R17973 - ADCL_RETUNE_C27_0 */
+ { 17974, 0x0000 }, /* R17974 - ADCL_RETUNE_C28_1 */
+ { 17975, 0x0000 }, /* R17975 - ADCL_RETUNE_C28_0 */
+ { 17976, 0x0000 }, /* R17976 - ADCL_RETUNE_C29_1 */
+ { 17977, 0x0000 }, /* R17977 - ADCL_RETUNE_C29_0 */
+ { 17978, 0x0000 }, /* R17978 - ADCL_RETUNE_C30_1 */
+ { 17979, 0x0000 }, /* R17979 - ADCL_RETUNE_C30_0 */
+ { 17980, 0x0000 }, /* R17980 - ADCL_RETUNE_C31_1 */
+ { 17981, 0x0000 }, /* R17981 - ADCL_RETUNE_C31_0 */
+ { 17982, 0x0000 }, /* R17982 - ADCL_RETUNE_C32_1 */
+ { 17983, 0x0000 }, /* R17983 - ADCL_RETUNE_C32_0 */
- [18432] = 0x0020, /* R18432 - RETUNEADC_PG2_1 */
- [18433] = 0x0000, /* R18433 - RETUNEADC_PG2_0 */
- [18434] = 0x0040, /* R18434 - RETUNEADC_PG_1 */
- [18435] = 0x0000, /* R18435 - RETUNEADC_PG_0 */
+ { 18432, 0x0020 }, /* R18432 - RETUNEADC_PG2_1 */
+ { 18433, 0x0000 }, /* R18433 - RETUNEADC_PG2_0 */
+ { 18434, 0x0040 }, /* R18434 - RETUNEADC_PG_1 */
+ { 18435, 0x0000 }, /* R18435 - RETUNEADC_PG_0 */
- [18944] = 0x007F, /* R18944 - ADCR_RETUNE_C1_1 */
- [18945] = 0xFFFF, /* R18945 - ADCR_RETUNE_C1_0 */
- [18946] = 0x0000, /* R18946 - ADCR_RETUNE_C2_1 */
- [18947] = 0x0000, /* R18947 - ADCR_RETUNE_C2_0 */
- [18948] = 0x0000, /* R18948 - ADCR_RETUNE_C3_1 */
- [18949] = 0x0000, /* R18949 - ADCR_RETUNE_C3_0 */
- [18950] = 0x0000, /* R18950 - ADCR_RETUNE_C4_1 */
- [18951] = 0x0000, /* R18951 - ADCR_RETUNE_C4_0 */
- [18952] = 0x0000, /* R18952 - ADCR_RETUNE_C5_1 */
- [18953] = 0x0000, /* R18953 - ADCR_RETUNE_C5_0 */
- [18954] = 0x0000, /* R18954 - ADCR_RETUNE_C6_1 */
- [18955] = 0x0000, /* R18955 - ADCR_RETUNE_C6_0 */
- [18956] = 0x0000, /* R18956 - ADCR_RETUNE_C7_1 */
- [18957] = 0x0000, /* R18957 - ADCR_RETUNE_C7_0 */
- [18958] = 0x0000, /* R18958 - ADCR_RETUNE_C8_1 */
- [18959] = 0x0000, /* R18959 - ADCR_RETUNE_C8_0 */
- [18960] = 0x0000, /* R18960 - ADCR_RETUNE_C9_1 */
- [18961] = 0x0000, /* R18961 - ADCR_RETUNE_C9_0 */
- [18962] = 0x0000, /* R18962 - ADCR_RETUNE_C10_1 */
- [18963] = 0x0000, /* R18963 - ADCR_RETUNE_C10_0 */
- [18964] = 0x0000, /* R18964 - ADCR_RETUNE_C11_1 */
- [18965] = 0x0000, /* R18965 - ADCR_RETUNE_C11_0 */
- [18966] = 0x0000, /* R18966 - ADCR_RETUNE_C12_1 */
- [18967] = 0x0000, /* R18967 - ADCR_RETUNE_C12_0 */
- [18968] = 0x0000, /* R18968 - ADCR_RETUNE_C13_1 */
- [18969] = 0x0000, /* R18969 - ADCR_RETUNE_C13_0 */
- [18970] = 0x0000, /* R18970 - ADCR_RETUNE_C14_1 */
- [18971] = 0x0000, /* R18971 - ADCR_RETUNE_C14_0 */
- [18972] = 0x0000, /* R18972 - ADCR_RETUNE_C15_1 */
- [18973] = 0x0000, /* R18973 - ADCR_RETUNE_C15_0 */
- [18974] = 0x0000, /* R18974 - ADCR_RETUNE_C16_1 */
- [18975] = 0x0000, /* R18975 - ADCR_RETUNE_C16_0 */
- [18976] = 0x0000, /* R18976 - ADCR_RETUNE_C17_1 */
- [18977] = 0x0000, /* R18977 - ADCR_RETUNE_C17_0 */
- [18978] = 0x0000, /* R18978 - ADCR_RETUNE_C18_1 */
- [18979] = 0x0000, /* R18979 - ADCR_RETUNE_C18_0 */
- [18980] = 0x0000, /* R18980 - ADCR_RETUNE_C19_1 */
- [18981] = 0x0000, /* R18981 - ADCR_RETUNE_C19_0 */
- [18982] = 0x0000, /* R18982 - ADCR_RETUNE_C20_1 */
- [18983] = 0x0000, /* R18983 - ADCR_RETUNE_C20_0 */
- [18984] = 0x0000, /* R18984 - ADCR_RETUNE_C21_1 */
- [18985] = 0x0000, /* R18985 - ADCR_RETUNE_C21_0 */
- [18986] = 0x0000, /* R18986 - ADCR_RETUNE_C22_1 */
- [18987] = 0x0000, /* R18987 - ADCR_RETUNE_C22_0 */
- [18988] = 0x0000, /* R18988 - ADCR_RETUNE_C23_1 */
- [18989] = 0x0000, /* R18989 - ADCR_RETUNE_C23_0 */
- [18990] = 0x0000, /* R18990 - ADCR_RETUNE_C24_1 */
- [18991] = 0x0000, /* R18991 - ADCR_RETUNE_C24_0 */
- [18992] = 0x0000, /* R18992 - ADCR_RETUNE_C25_1 */
- [18993] = 0x0000, /* R18993 - ADCR_RETUNE_C25_0 */
- [18994] = 0x0000, /* R18994 - ADCR_RETUNE_C26_1 */
- [18995] = 0x0000, /* R18995 - ADCR_RETUNE_C26_0 */
- [18996] = 0x0000, /* R18996 - ADCR_RETUNE_C27_1 */
- [18997] = 0x0000, /* R18997 - ADCR_RETUNE_C27_0 */
- [18998] = 0x0000, /* R18998 - ADCR_RETUNE_C28_1 */
- [18999] = 0x0000, /* R18999 - ADCR_RETUNE_C28_0 */
- [19000] = 0x0000, /* R19000 - ADCR_RETUNE_C29_1 */
- [19001] = 0x0000, /* R19001 - ADCR_RETUNE_C29_0 */
- [19002] = 0x0000, /* R19002 - ADCR_RETUNE_C30_1 */
- [19003] = 0x0000, /* R19003 - ADCR_RETUNE_C30_0 */
- [19004] = 0x0000, /* R19004 - ADCR_RETUNE_C31_1 */
- [19005] = 0x0000, /* R19005 - ADCR_RETUNE_C31_0 */
- [19006] = 0x0000, /* R19006 - ADCR_RETUNE_C32_1 */
- [19007] = 0x0000, /* R19007 - ADCR_RETUNE_C32_0 */
+ { 18944, 0x007F }, /* R18944 - ADCR_RETUNE_C1_1 */
+ { 18945, 0xFFFF }, /* R18945 - ADCR_RETUNE_C1_0 */
+ { 18946, 0x0000 }, /* R18946 - ADCR_RETUNE_C2_1 */
+ { 18947, 0x0000 }, /* R18947 - ADCR_RETUNE_C2_0 */
+ { 18948, 0x0000 }, /* R18948 - ADCR_RETUNE_C3_1 */
+ { 18949, 0x0000 }, /* R18949 - ADCR_RETUNE_C3_0 */
+ { 18950, 0x0000 }, /* R18950 - ADCR_RETUNE_C4_1 */
+ { 18951, 0x0000 }, /* R18951 - ADCR_RETUNE_C4_0 */
+ { 18952, 0x0000 }, /* R18952 - ADCR_RETUNE_C5_1 */
+ { 18953, 0x0000 }, /* R18953 - ADCR_RETUNE_C5_0 */
+ { 18954, 0x0000 }, /* R18954 - ADCR_RETUNE_C6_1 */
+ { 18955, 0x0000 }, /* R18955 - ADCR_RETUNE_C6_0 */
+ { 18956, 0x0000 }, /* R18956 - ADCR_RETUNE_C7_1 */
+ { 18957, 0x0000 }, /* R18957 - ADCR_RETUNE_C7_0 */
+ { 18958, 0x0000 }, /* R18958 - ADCR_RETUNE_C8_1 */
+ { 18959, 0x0000 }, /* R18959 - ADCR_RETUNE_C8_0 */
+ { 18960, 0x0000 }, /* R18960 - ADCR_RETUNE_C9_1 */
+ { 18961, 0x0000 }, /* R18961 - ADCR_RETUNE_C9_0 */
+ { 18962, 0x0000 }, /* R18962 - ADCR_RETUNE_C10_1 */
+ { 18963, 0x0000 }, /* R18963 - ADCR_RETUNE_C10_0 */
+ { 18964, 0x0000 }, /* R18964 - ADCR_RETUNE_C11_1 */
+ { 18965, 0x0000 }, /* R18965 - ADCR_RETUNE_C11_0 */
+ { 18966, 0x0000 }, /* R18966 - ADCR_RETUNE_C12_1 */
+ { 18967, 0x0000 }, /* R18967 - ADCR_RETUNE_C12_0 */
+ { 18968, 0x0000 }, /* R18968 - ADCR_RETUNE_C13_1 */
+ { 18969, 0x0000 }, /* R18969 - ADCR_RETUNE_C13_0 */
+ { 18970, 0x0000 }, /* R18970 - ADCR_RETUNE_C14_1 */
+ { 18971, 0x0000 }, /* R18971 - ADCR_RETUNE_C14_0 */
+ { 18972, 0x0000 }, /* R18972 - ADCR_RETUNE_C15_1 */
+ { 18973, 0x0000 }, /* R18973 - ADCR_RETUNE_C15_0 */
+ { 18974, 0x0000 }, /* R18974 - ADCR_RETUNE_C16_1 */
+ { 18975, 0x0000 }, /* R18975 - ADCR_RETUNE_C16_0 */
+ { 18976, 0x0000 }, /* R18976 - ADCR_RETUNE_C17_1 */
+ { 18977, 0x0000 }, /* R18977 - ADCR_RETUNE_C17_0 */
+ { 18978, 0x0000 }, /* R18978 - ADCR_RETUNE_C18_1 */
+ { 18979, 0x0000 }, /* R18979 - ADCR_RETUNE_C18_0 */
+ { 18980, 0x0000 }, /* R18980 - ADCR_RETUNE_C19_1 */
+ { 18981, 0x0000 }, /* R18981 - ADCR_RETUNE_C19_0 */
+ { 18982, 0x0000 }, /* R18982 - ADCR_RETUNE_C20_1 */
+ { 18983, 0x0000 }, /* R18983 - ADCR_RETUNE_C20_0 */
+ { 18984, 0x0000 }, /* R18984 - ADCR_RETUNE_C21_1 */
+ { 18985, 0x0000 }, /* R18985 - ADCR_RETUNE_C21_0 */
+ { 18986, 0x0000 }, /* R18986 - ADCR_RETUNE_C22_1 */
+ { 18987, 0x0000 }, /* R18987 - ADCR_RETUNE_C22_0 */
+ { 18988, 0x0000 }, /* R18988 - ADCR_RETUNE_C23_1 */
+ { 18989, 0x0000 }, /* R18989 - ADCR_RETUNE_C23_0 */
+ { 18990, 0x0000 }, /* R18990 - ADCR_RETUNE_C24_1 */
+ { 18991, 0x0000 }, /* R18991 - ADCR_RETUNE_C24_0 */
+ { 18992, 0x0000 }, /* R18992 - ADCR_RETUNE_C25_1 */
+ { 18993, 0x0000 }, /* R18993 - ADCR_RETUNE_C25_0 */
+ { 18994, 0x0000 }, /* R18994 - ADCR_RETUNE_C26_1 */
+ { 18995, 0x0000 }, /* R18995 - ADCR_RETUNE_C26_0 */
+ { 18996, 0x0000 }, /* R18996 - ADCR_RETUNE_C27_1 */
+ { 18997, 0x0000 }, /* R18997 - ADCR_RETUNE_C27_0 */
+ { 18998, 0x0000 }, /* R18998 - ADCR_RETUNE_C28_1 */
+ { 18999, 0x0000 }, /* R18999 - ADCR_RETUNE_C28_0 */
+ { 19000, 0x0000 }, /* R19000 - ADCR_RETUNE_C29_1 */
+ { 19001, 0x0000 }, /* R19001 - ADCR_RETUNE_C29_0 */
+ { 19002, 0x0000 }, /* R19002 - ADCR_RETUNE_C30_1 */
+ { 19003, 0x0000 }, /* R19003 - ADCR_RETUNE_C30_0 */
+ { 19004, 0x0000 }, /* R19004 - ADCR_RETUNE_C31_1 */
+ { 19005, 0x0000 }, /* R19005 - ADCR_RETUNE_C31_0 */
+ { 19006, 0x0000 }, /* R19006 - ADCR_RETUNE_C32_1 */
+ { 19007, 0x0000 }, /* R19007 - ADCR_RETUNE_C32_0 */
- [19456] = 0x007F, /* R19456 - DACL_RETUNE_C1_1 */
- [19457] = 0xFFFF, /* R19457 - DACL_RETUNE_C1_0 */
- [19458] = 0x0000, /* R19458 - DACL_RETUNE_C2_1 */
- [19459] = 0x0000, /* R19459 - DACL_RETUNE_C2_0 */
- [19460] = 0x0000, /* R19460 - DACL_RETUNE_C3_1 */
- [19461] = 0x0000, /* R19461 - DACL_RETUNE_C3_0 */
- [19462] = 0x0000, /* R19462 - DACL_RETUNE_C4_1 */
- [19463] = 0x0000, /* R19463 - DACL_RETUNE_C4_0 */
- [19464] = 0x0000, /* R19464 - DACL_RETUNE_C5_1 */
- [19465] = 0x0000, /* R19465 - DACL_RETUNE_C5_0 */
- [19466] = 0x0000, /* R19466 - DACL_RETUNE_C6_1 */
- [19467] = 0x0000, /* R19467 - DACL_RETUNE_C6_0 */
- [19468] = 0x0000, /* R19468 - DACL_RETUNE_C7_1 */
- [19469] = 0x0000, /* R19469 - DACL_RETUNE_C7_0 */
- [19470] = 0x0000, /* R19470 - DACL_RETUNE_C8_1 */
- [19471] = 0x0000, /* R19471 - DACL_RETUNE_C8_0 */
- [19472] = 0x0000, /* R19472 - DACL_RETUNE_C9_1 */
- [19473] = 0x0000, /* R19473 - DACL_RETUNE_C9_0 */
- [19474] = 0x0000, /* R19474 - DACL_RETUNE_C10_1 */
- [19475] = 0x0000, /* R19475 - DACL_RETUNE_C10_0 */
- [19476] = 0x0000, /* R19476 - DACL_RETUNE_C11_1 */
- [19477] = 0x0000, /* R19477 - DACL_RETUNE_C11_0 */
- [19478] = 0x0000, /* R19478 - DACL_RETUNE_C12_1 */
- [19479] = 0x0000, /* R19479 - DACL_RETUNE_C12_0 */
- [19480] = 0x0000, /* R19480 - DACL_RETUNE_C13_1 */
- [19481] = 0x0000, /* R19481 - DACL_RETUNE_C13_0 */
- [19482] = 0x0000, /* R19482 - DACL_RETUNE_C14_1 */
- [19483] = 0x0000, /* R19483 - DACL_RETUNE_C14_0 */
- [19484] = 0x0000, /* R19484 - DACL_RETUNE_C15_1 */
- [19485] = 0x0000, /* R19485 - DACL_RETUNE_C15_0 */
- [19486] = 0x0000, /* R19486 - DACL_RETUNE_C16_1 */
- [19487] = 0x0000, /* R19487 - DACL_RETUNE_C16_0 */
- [19488] = 0x0000, /* R19488 - DACL_RETUNE_C17_1 */
- [19489] = 0x0000, /* R19489 - DACL_RETUNE_C17_0 */
- [19490] = 0x0000, /* R19490 - DACL_RETUNE_C18_1 */
- [19491] = 0x0000, /* R19491 - DACL_RETUNE_C18_0 */
- [19492] = 0x0000, /* R19492 - DACL_RETUNE_C19_1 */
- [19493] = 0x0000, /* R19493 - DACL_RETUNE_C19_0 */
- [19494] = 0x0000, /* R19494 - DACL_RETUNE_C20_1 */
- [19495] = 0x0000, /* R19495 - DACL_RETUNE_C20_0 */
- [19496] = 0x0000, /* R19496 - DACL_RETUNE_C21_1 */
- [19497] = 0x0000, /* R19497 - DACL_RETUNE_C21_0 */
- [19498] = 0x0000, /* R19498 - DACL_RETUNE_C22_1 */
- [19499] = 0x0000, /* R19499 - DACL_RETUNE_C22_0 */
- [19500] = 0x0000, /* R19500 - DACL_RETUNE_C23_1 */
- [19501] = 0x0000, /* R19501 - DACL_RETUNE_C23_0 */
- [19502] = 0x0000, /* R19502 - DACL_RETUNE_C24_1 */
- [19503] = 0x0000, /* R19503 - DACL_RETUNE_C24_0 */
- [19504] = 0x0000, /* R19504 - DACL_RETUNE_C25_1 */
- [19505] = 0x0000, /* R19505 - DACL_RETUNE_C25_0 */
- [19506] = 0x0000, /* R19506 - DACL_RETUNE_C26_1 */
- [19507] = 0x0000, /* R19507 - DACL_RETUNE_C26_0 */
- [19508] = 0x0000, /* R19508 - DACL_RETUNE_C27_1 */
- [19509] = 0x0000, /* R19509 - DACL_RETUNE_C27_0 */
- [19510] = 0x0000, /* R19510 - DACL_RETUNE_C28_1 */
- [19511] = 0x0000, /* R19511 - DACL_RETUNE_C28_0 */
- [19512] = 0x0000, /* R19512 - DACL_RETUNE_C29_1 */
- [19513] = 0x0000, /* R19513 - DACL_RETUNE_C29_0 */
- [19514] = 0x0000, /* R19514 - DACL_RETUNE_C30_1 */
- [19515] = 0x0000, /* R19515 - DACL_RETUNE_C30_0 */
- [19516] = 0x0000, /* R19516 - DACL_RETUNE_C31_1 */
- [19517] = 0x0000, /* R19517 - DACL_RETUNE_C31_0 */
- [19518] = 0x0000, /* R19518 - DACL_RETUNE_C32_1 */
- [19519] = 0x0000, /* R19519 - DACL_RETUNE_C32_0 */
+ { 19456, 0x007F }, /* R19456 - DACL_RETUNE_C1_1 */
+ { 19457, 0xFFFF }, /* R19457 - DACL_RETUNE_C1_0 */
+ { 19458, 0x0000 }, /* R19458 - DACL_RETUNE_C2_1 */
+ { 19459, 0x0000 }, /* R19459 - DACL_RETUNE_C2_0 */
+ { 19460, 0x0000 }, /* R19460 - DACL_RETUNE_C3_1 */
+ { 19461, 0x0000 }, /* R19461 - DACL_RETUNE_C3_0 */
+ { 19462, 0x0000 }, /* R19462 - DACL_RETUNE_C4_1 */
+ { 19463, 0x0000 }, /* R19463 - DACL_RETUNE_C4_0 */
+ { 19464, 0x0000 }, /* R19464 - DACL_RETUNE_C5_1 */
+ { 19465, 0x0000 }, /* R19465 - DACL_RETUNE_C5_0 */
+ { 19466, 0x0000 }, /* R19466 - DACL_RETUNE_C6_1 */
+ { 19467, 0x0000 }, /* R19467 - DACL_RETUNE_C6_0 */
+ { 19468, 0x0000 }, /* R19468 - DACL_RETUNE_C7_1 */
+ { 19469, 0x0000 }, /* R19469 - DACL_RETUNE_C7_0 */
+ { 19470, 0x0000 }, /* R19470 - DACL_RETUNE_C8_1 */
+ { 19471, 0x0000 }, /* R19471 - DACL_RETUNE_C8_0 */
+ { 19472, 0x0000 }, /* R19472 - DACL_RETUNE_C9_1 */
+ { 19473, 0x0000 }, /* R19473 - DACL_RETUNE_C9_0 */
+ { 19474, 0x0000 }, /* R19474 - DACL_RETUNE_C10_1 */
+ { 19475, 0x0000 }, /* R19475 - DACL_RETUNE_C10_0 */
+ { 19476, 0x0000 }, /* R19476 - DACL_RETUNE_C11_1 */
+ { 19477, 0x0000 }, /* R19477 - DACL_RETUNE_C11_0 */
+ { 19478, 0x0000 }, /* R19478 - DACL_RETUNE_C12_1 */
+ { 19479, 0x0000 }, /* R19479 - DACL_RETUNE_C12_0 */
+ { 19480, 0x0000 }, /* R19480 - DACL_RETUNE_C13_1 */
+ { 19481, 0x0000 }, /* R19481 - DACL_RETUNE_C13_0 */
+ { 19482, 0x0000 }, /* R19482 - DACL_RETUNE_C14_1 */
+ { 19483, 0x0000 }, /* R19483 - DACL_RETUNE_C14_0 */
+ { 19484, 0x0000 }, /* R19484 - DACL_RETUNE_C15_1 */
+ { 19485, 0x0000 }, /* R19485 - DACL_RETUNE_C15_0 */
+ { 19486, 0x0000 }, /* R19486 - DACL_RETUNE_C16_1 */
+ { 19487, 0x0000 }, /* R19487 - DACL_RETUNE_C16_0 */
+ { 19488, 0x0000 }, /* R19488 - DACL_RETUNE_C17_1 */
+ { 19489, 0x0000 }, /* R19489 - DACL_RETUNE_C17_0 */
+ { 19490, 0x0000 }, /* R19490 - DACL_RETUNE_C18_1 */
+ { 19491, 0x0000 }, /* R19491 - DACL_RETUNE_C18_0 */
+ { 19492, 0x0000 }, /* R19492 - DACL_RETUNE_C19_1 */
+ { 19493, 0x0000 }, /* R19493 - DACL_RETUNE_C19_0 */
+ { 19494, 0x0000 }, /* R19494 - DACL_RETUNE_C20_1 */
+ { 19495, 0x0000 }, /* R19495 - DACL_RETUNE_C20_0 */
+ { 19496, 0x0000 }, /* R19496 - DACL_RETUNE_C21_1 */
+ { 19497, 0x0000 }, /* R19497 - DACL_RETUNE_C21_0 */
+ { 19498, 0x0000 }, /* R19498 - DACL_RETUNE_C22_1 */
+ { 19499, 0x0000 }, /* R19499 - DACL_RETUNE_C22_0 */
+ { 19500, 0x0000 }, /* R19500 - DACL_RETUNE_C23_1 */
+ { 19501, 0x0000 }, /* R19501 - DACL_RETUNE_C23_0 */
+ { 19502, 0x0000 }, /* R19502 - DACL_RETUNE_C24_1 */
+ { 19503, 0x0000 }, /* R19503 - DACL_RETUNE_C24_0 */
+ { 19504, 0x0000 }, /* R19504 - DACL_RETUNE_C25_1 */
+ { 19505, 0x0000 }, /* R19505 - DACL_RETUNE_C25_0 */
+ { 19506, 0x0000 }, /* R19506 - DACL_RETUNE_C26_1 */
+ { 19507, 0x0000 }, /* R19507 - DACL_RETUNE_C26_0 */
+ { 19508, 0x0000 }, /* R19508 - DACL_RETUNE_C27_1 */
+ { 19509, 0x0000 }, /* R19509 - DACL_RETUNE_C27_0 */
+ { 19510, 0x0000 }, /* R19510 - DACL_RETUNE_C28_1 */
+ { 19511, 0x0000 }, /* R19511 - DACL_RETUNE_C28_0 */
+ { 19512, 0x0000 }, /* R19512 - DACL_RETUNE_C29_1 */
+ { 19513, 0x0000 }, /* R19513 - DACL_RETUNE_C29_0 */
+ { 19514, 0x0000 }, /* R19514 - DACL_RETUNE_C30_1 */
+ { 19515, 0x0000 }, /* R19515 - DACL_RETUNE_C30_0 */
+ { 19516, 0x0000 }, /* R19516 - DACL_RETUNE_C31_1 */
+ { 19517, 0x0000 }, /* R19517 - DACL_RETUNE_C31_0 */
+ { 19518, 0x0000 }, /* R19518 - DACL_RETUNE_C32_1 */
+ { 19519, 0x0000 }, /* R19519 - DACL_RETUNE_C32_0 */
- [19968] = 0x0020, /* R19968 - RETUNEDAC_PG2_1 */
- [19969] = 0x0000, /* R19969 - RETUNEDAC_PG2_0 */
- [19970] = 0x0040, /* R19970 - RETUNEDAC_PG_1 */
- [19971] = 0x0000, /* R19971 - RETUNEDAC_PG_0 */
+ { 19968, 0x0020 }, /* R19968 - RETUNEDAC_PG2_1 */
+ { 19969, 0x0000 }, /* R19969 - RETUNEDAC_PG2_0 */
+ { 19970, 0x0040 }, /* R19970 - RETUNEDAC_PG_1 */
+ { 19971, 0x0000 }, /* R19971 - RETUNEDAC_PG_0 */
- [20480] = 0x007F, /* R20480 - DACR_RETUNE_C1_1 */
- [20481] = 0xFFFF, /* R20481 - DACR_RETUNE_C1_0 */
- [20482] = 0x0000, /* R20482 - DACR_RETUNE_C2_1 */
- [20483] = 0x0000, /* R20483 - DACR_RETUNE_C2_0 */
- [20484] = 0x0000, /* R20484 - DACR_RETUNE_C3_1 */
- [20485] = 0x0000, /* R20485 - DACR_RETUNE_C3_0 */
- [20486] = 0x0000, /* R20486 - DACR_RETUNE_C4_1 */
- [20487] = 0x0000, /* R20487 - DACR_RETUNE_C4_0 */
- [20488] = 0x0000, /* R20488 - DACR_RETUNE_C5_1 */
- [20489] = 0x0000, /* R20489 - DACR_RETUNE_C5_0 */
- [20490] = 0x0000, /* R20490 - DACR_RETUNE_C6_1 */
- [20491] = 0x0000, /* R20491 - DACR_RETUNE_C6_0 */
- [20492] = 0x0000, /* R20492 - DACR_RETUNE_C7_1 */
- [20493] = 0x0000, /* R20493 - DACR_RETUNE_C7_0 */
- [20494] = 0x0000, /* R20494 - DACR_RETUNE_C8_1 */
- [20495] = 0x0000, /* R20495 - DACR_RETUNE_C8_0 */
- [20496] = 0x0000, /* R20496 - DACR_RETUNE_C9_1 */
- [20497] = 0x0000, /* R20497 - DACR_RETUNE_C9_0 */
- [20498] = 0x0000, /* R20498 - DACR_RETUNE_C10_1 */
- [20499] = 0x0000, /* R20499 - DACR_RETUNE_C10_0 */
- [20500] = 0x0000, /* R20500 - DACR_RETUNE_C11_1 */
- [20501] = 0x0000, /* R20501 - DACR_RETUNE_C11_0 */
- [20502] = 0x0000, /* R20502 - DACR_RETUNE_C12_1 */
- [20503] = 0x0000, /* R20503 - DACR_RETUNE_C12_0 */
- [20504] = 0x0000, /* R20504 - DACR_RETUNE_C13_1 */
- [20505] = 0x0000, /* R20505 - DACR_RETUNE_C13_0 */
- [20506] = 0x0000, /* R20506 - DACR_RETUNE_C14_1 */
- [20507] = 0x0000, /* R20507 - DACR_RETUNE_C14_0 */
- [20508] = 0x0000, /* R20508 - DACR_RETUNE_C15_1 */
- [20509] = 0x0000, /* R20509 - DACR_RETUNE_C15_0 */
- [20510] = 0x0000, /* R20510 - DACR_RETUNE_C16_1 */
- [20511] = 0x0000, /* R20511 - DACR_RETUNE_C16_0 */
- [20512] = 0x0000, /* R20512 - DACR_RETUNE_C17_1 */
- [20513] = 0x0000, /* R20513 - DACR_RETUNE_C17_0 */
- [20514] = 0x0000, /* R20514 - DACR_RETUNE_C18_1 */
- [20515] = 0x0000, /* R20515 - DACR_RETUNE_C18_0 */
- [20516] = 0x0000, /* R20516 - DACR_RETUNE_C19_1 */
- [20517] = 0x0000, /* R20517 - DACR_RETUNE_C19_0 */
- [20518] = 0x0000, /* R20518 - DACR_RETUNE_C20_1 */
- [20519] = 0x0000, /* R20519 - DACR_RETUNE_C20_0 */
- [20520] = 0x0000, /* R20520 - DACR_RETUNE_C21_1 */
- [20521] = 0x0000, /* R20521 - DACR_RETUNE_C21_0 */
- [20522] = 0x0000, /* R20522 - DACR_RETUNE_C22_1 */
- [20523] = 0x0000, /* R20523 - DACR_RETUNE_C22_0 */
- [20524] = 0x0000, /* R20524 - DACR_RETUNE_C23_1 */
- [20525] = 0x0000, /* R20525 - DACR_RETUNE_C23_0 */
- [20526] = 0x0000, /* R20526 - DACR_RETUNE_C24_1 */
- [20527] = 0x0000, /* R20527 - DACR_RETUNE_C24_0 */
- [20528] = 0x0000, /* R20528 - DACR_RETUNE_C25_1 */
- [20529] = 0x0000, /* R20529 - DACR_RETUNE_C25_0 */
- [20530] = 0x0000, /* R20530 - DACR_RETUNE_C26_1 */
- [20531] = 0x0000, /* R20531 - DACR_RETUNE_C26_0 */
- [20532] = 0x0000, /* R20532 - DACR_RETUNE_C27_1 */
- [20533] = 0x0000, /* R20533 - DACR_RETUNE_C27_0 */
- [20534] = 0x0000, /* R20534 - DACR_RETUNE_C28_1 */
- [20535] = 0x0000, /* R20535 - DACR_RETUNE_C28_0 */
- [20536] = 0x0000, /* R20536 - DACR_RETUNE_C29_1 */
- [20537] = 0x0000, /* R20537 - DACR_RETUNE_C29_0 */
- [20538] = 0x0000, /* R20538 - DACR_RETUNE_C30_1 */
- [20539] = 0x0000, /* R20539 - DACR_RETUNE_C30_0 */
- [20540] = 0x0000, /* R20540 - DACR_RETUNE_C31_1 */
- [20541] = 0x0000, /* R20541 - DACR_RETUNE_C31_0 */
- [20542] = 0x0000, /* R20542 - DACR_RETUNE_C32_1 */
- [20543] = 0x0000, /* R20543 - DACR_RETUNE_C32_0 */
+ { 20480, 0x007F }, /* R20480 - DACR_RETUNE_C1_1 */
+ { 20481, 0xFFFF }, /* R20481 - DACR_RETUNE_C1_0 */
+ { 20482, 0x0000 }, /* R20482 - DACR_RETUNE_C2_1 */
+ { 20483, 0x0000 }, /* R20483 - DACR_RETUNE_C2_0 */
+ { 20484, 0x0000 }, /* R20484 - DACR_RETUNE_C3_1 */
+ { 20485, 0x0000 }, /* R20485 - DACR_RETUNE_C3_0 */
+ { 20486, 0x0000 }, /* R20486 - DACR_RETUNE_C4_1 */
+ { 20487, 0x0000 }, /* R20487 - DACR_RETUNE_C4_0 */
+ { 20488, 0x0000 }, /* R20488 - DACR_RETUNE_C5_1 */
+ { 20489, 0x0000 }, /* R20489 - DACR_RETUNE_C5_0 */
+ { 20490, 0x0000 }, /* R20490 - DACR_RETUNE_C6_1 */
+ { 20491, 0x0000 }, /* R20491 - DACR_RETUNE_C6_0 */
+ { 20492, 0x0000 }, /* R20492 - DACR_RETUNE_C7_1 */
+ { 20493, 0x0000 }, /* R20493 - DACR_RETUNE_C7_0 */
+ { 20494, 0x0000 }, /* R20494 - DACR_RETUNE_C8_1 */
+ { 20495, 0x0000 }, /* R20495 - DACR_RETUNE_C8_0 */
+ { 20496, 0x0000 }, /* R20496 - DACR_RETUNE_C9_1 */
+ { 20497, 0x0000 }, /* R20497 - DACR_RETUNE_C9_0 */
+ { 20498, 0x0000 }, /* R20498 - DACR_RETUNE_C10_1 */
+ { 20499, 0x0000 }, /* R20499 - DACR_RETUNE_C10_0 */
+ { 20500, 0x0000 }, /* R20500 - DACR_RETUNE_C11_1 */
+ { 20501, 0x0000 }, /* R20501 - DACR_RETUNE_C11_0 */
+ { 20502, 0x0000 }, /* R20502 - DACR_RETUNE_C12_1 */
+ { 20503, 0x0000 }, /* R20503 - DACR_RETUNE_C12_0 */
+ { 20504, 0x0000 }, /* R20504 - DACR_RETUNE_C13_1 */
+ { 20505, 0x0000 }, /* R20505 - DACR_RETUNE_C13_0 */
+ { 20506, 0x0000 }, /* R20506 - DACR_RETUNE_C14_1 */
+ { 20507, 0x0000 }, /* R20507 - DACR_RETUNE_C14_0 */
+ { 20508, 0x0000 }, /* R20508 - DACR_RETUNE_C15_1 */
+ { 20509, 0x0000 }, /* R20509 - DACR_RETUNE_C15_0 */
+ { 20510, 0x0000 }, /* R20510 - DACR_RETUNE_C16_1 */
+ { 20511, 0x0000 }, /* R20511 - DACR_RETUNE_C16_0 */
+ { 20512, 0x0000 }, /* R20512 - DACR_RETUNE_C17_1 */
+ { 20513, 0x0000 }, /* R20513 - DACR_RETUNE_C17_0 */
+ { 20514, 0x0000 }, /* R20514 - DACR_RETUNE_C18_1 */
+ { 20515, 0x0000 }, /* R20515 - DACR_RETUNE_C18_0 */
+ { 20516, 0x0000 }, /* R20516 - DACR_RETUNE_C19_1 */
+ { 20517, 0x0000 }, /* R20517 - DACR_RETUNE_C19_0 */
+ { 20518, 0x0000 }, /* R20518 - DACR_RETUNE_C20_1 */
+ { 20519, 0x0000 }, /* R20519 - DACR_RETUNE_C20_0 */
+ { 20520, 0x0000 }, /* R20520 - DACR_RETUNE_C21_1 */
+ { 20521, 0x0000 }, /* R20521 - DACR_RETUNE_C21_0 */
+ { 20522, 0x0000 }, /* R20522 - DACR_RETUNE_C22_1 */
+ { 20523, 0x0000 }, /* R20523 - DACR_RETUNE_C22_0 */
+ { 20524, 0x0000 }, /* R20524 - DACR_RETUNE_C23_1 */
+ { 20525, 0x0000 }, /* R20525 - DACR_RETUNE_C23_0 */
+ { 20526, 0x0000 }, /* R20526 - DACR_RETUNE_C24_1 */
+ { 20527, 0x0000 }, /* R20527 - DACR_RETUNE_C24_0 */
+ { 20528, 0x0000 }, /* R20528 - DACR_RETUNE_C25_1 */
+ { 20529, 0x0000 }, /* R20529 - DACR_RETUNE_C25_0 */
+ { 20530, 0x0000 }, /* R20530 - DACR_RETUNE_C26_1 */
+ { 20531, 0x0000 }, /* R20531 - DACR_RETUNE_C26_0 */
+ { 20532, 0x0000 }, /* R20532 - DACR_RETUNE_C27_1 */
+ { 20533, 0x0000 }, /* R20533 - DACR_RETUNE_C27_0 */
+ { 20534, 0x0000 }, /* R20534 - DACR_RETUNE_C28_1 */
+ { 20535, 0x0000 }, /* R20535 - DACR_RETUNE_C28_0 */
+ { 20536, 0x0000 }, /* R20536 - DACR_RETUNE_C29_1 */
+ { 20537, 0x0000 }, /* R20537 - DACR_RETUNE_C29_0 */
+ { 20538, 0x0000 }, /* R20538 - DACR_RETUNE_C30_1 */
+ { 20539, 0x0000 }, /* R20539 - DACR_RETUNE_C30_0 */
+ { 20540, 0x0000 }, /* R20540 - DACR_RETUNE_C31_1 */
+ { 20541, 0x0000 }, /* R20541 - DACR_RETUNE_C31_0 */
+ { 20542, 0x0000 }, /* R20542 - DACR_RETUNE_C32_1 */
+ { 20543, 0x0000 }, /* R20543 - DACR_RETUNE_C32_0 */
- [20992] = 0x008C, /* R20992 - VSS_XHD2_1 */
- [20993] = 0x0200, /* R20993 - VSS_XHD2_0 */
- [20994] = 0x0035, /* R20994 - VSS_XHD3_1 */
- [20995] = 0x0700, /* R20995 - VSS_XHD3_0 */
- [20996] = 0x003A, /* R20996 - VSS_XHN1_1 */
- [20997] = 0x4100, /* R20997 - VSS_XHN1_0 */
- [20998] = 0x008B, /* R20998 - VSS_XHN2_1 */
- [20999] = 0x7D00, /* R20999 - VSS_XHN2_0 */
- [21000] = 0x003A, /* R21000 - VSS_XHN3_1 */
- [21001] = 0x4100, /* R21001 - VSS_XHN3_0 */
- [21002] = 0x008C, /* R21002 - VSS_XLA_1 */
- [21003] = 0xFEE8, /* R21003 - VSS_XLA_0 */
- [21004] = 0x0078, /* R21004 - VSS_XLB_1 */
- [21005] = 0x0000, /* R21005 - VSS_XLB_0 */
- [21006] = 0x003F, /* R21006 - VSS_XLG_1 */
- [21007] = 0xB260, /* R21007 - VSS_XLG_0 */
- [21008] = 0x002D, /* R21008 - VSS_PG2_1 */
- [21009] = 0x1818, /* R21009 - VSS_PG2_0 */
- [21010] = 0x0020, /* R21010 - VSS_PG_1 */
- [21011] = 0x0000, /* R21011 - VSS_PG_0 */
- [21012] = 0x00F1, /* R21012 - VSS_XTD1_1 */
- [21013] = 0x8340, /* R21013 - VSS_XTD1_0 */
- [21014] = 0x00FB, /* R21014 - VSS_XTD2_1 */
- [21015] = 0x8300, /* R21015 - VSS_XTD2_0 */
- [21016] = 0x00EE, /* R21016 - VSS_XTD3_1 */
- [21017] = 0xAEC0, /* R21017 - VSS_XTD3_0 */
- [21018] = 0x00FB, /* R21018 - VSS_XTD4_1 */
- [21019] = 0xAC40, /* R21019 - VSS_XTD4_0 */
- [21020] = 0x00F1, /* R21020 - VSS_XTD5_1 */
- [21021] = 0x7F80, /* R21021 - VSS_XTD5_0 */
- [21022] = 0x00F4, /* R21022 - VSS_XTD6_1 */
- [21023] = 0x3B40, /* R21023 - VSS_XTD6_0 */
- [21024] = 0x00F5, /* R21024 - VSS_XTD7_1 */
- [21025] = 0xFB00, /* R21025 - VSS_XTD7_0 */
- [21026] = 0x00EA, /* R21026 - VSS_XTD8_1 */
- [21027] = 0x10C0, /* R21027 - VSS_XTD8_0 */
- [21028] = 0x00FC, /* R21028 - VSS_XTD9_1 */
- [21029] = 0xC580, /* R21029 - VSS_XTD9_0 */
- [21030] = 0x00E2, /* R21030 - VSS_XTD10_1 */
- [21031] = 0x75C0, /* R21031 - VSS_XTD10_0 */
- [21032] = 0x0004, /* R21032 - VSS_XTD11_1 */
- [21033] = 0xB480, /* R21033 - VSS_XTD11_0 */
- [21034] = 0x00D4, /* R21034 - VSS_XTD12_1 */
- [21035] = 0xF980, /* R21035 - VSS_XTD12_0 */
- [21036] = 0x0004, /* R21036 - VSS_XTD13_1 */
- [21037] = 0x9140, /* R21037 - VSS_XTD13_0 */
- [21038] = 0x00D8, /* R21038 - VSS_XTD14_1 */
- [21039] = 0xA480, /* R21039 - VSS_XTD14_0 */
- [21040] = 0x0002, /* R21040 - VSS_XTD15_1 */
- [21041] = 0x3DC0, /* R21041 - VSS_XTD15_0 */
- [21042] = 0x00CF, /* R21042 - VSS_XTD16_1 */
- [21043] = 0x7A80, /* R21043 - VSS_XTD16_0 */
- [21044] = 0x00DC, /* R21044 - VSS_XTD17_1 */
- [21045] = 0x0600, /* R21045 - VSS_XTD17_0 */
- [21046] = 0x00F2, /* R21046 - VSS_XTD18_1 */
- [21047] = 0xDAC0, /* R21047 - VSS_XTD18_0 */
- [21048] = 0x00BA, /* R21048 - VSS_XTD19_1 */
- [21049] = 0xF340, /* R21049 - VSS_XTD19_0 */
- [21050] = 0x000A, /* R21050 - VSS_XTD20_1 */
- [21051] = 0x7940, /* R21051 - VSS_XTD20_0 */
- [21052] = 0x001C, /* R21052 - VSS_XTD21_1 */
- [21053] = 0x0680, /* R21053 - VSS_XTD21_0 */
- [21054] = 0x00FD, /* R21054 - VSS_XTD22_1 */
- [21055] = 0x2D00, /* R21055 - VSS_XTD22_0 */
- [21056] = 0x001C, /* R21056 - VSS_XTD23_1 */
- [21057] = 0xE840, /* R21057 - VSS_XTD23_0 */
- [21058] = 0x000D, /* R21058 - VSS_XTD24_1 */
- [21059] = 0xDC40, /* R21059 - VSS_XTD24_0 */
- [21060] = 0x00FC, /* R21060 - VSS_XTD25_1 */
- [21061] = 0x9D00, /* R21061 - VSS_XTD25_0 */
- [21062] = 0x0009, /* R21062 - VSS_XTD26_1 */
- [21063] = 0x5580, /* R21063 - VSS_XTD26_0 */
- [21064] = 0x00FE, /* R21064 - VSS_XTD27_1 */
- [21065] = 0x7E80, /* R21065 - VSS_XTD27_0 */
- [21066] = 0x000E, /* R21066 - VSS_XTD28_1 */
- [21067] = 0xAB40, /* R21067 - VSS_XTD28_0 */
- [21068] = 0x00F9, /* R21068 - VSS_XTD29_1 */
- [21069] = 0x9880, /* R21069 - VSS_XTD29_0 */
- [21070] = 0x0009, /* R21070 - VSS_XTD30_1 */
- [21071] = 0x87C0, /* R21071 - VSS_XTD30_0 */
- [21072] = 0x00FD, /* R21072 - VSS_XTD31_1 */
- [21073] = 0x2C40, /* R21073 - VSS_XTD31_0 */
- [21074] = 0x0009, /* R21074 - VSS_XTD32_1 */
- [21075] = 0x4800, /* R21075 - VSS_XTD32_0 */
- [21076] = 0x0003, /* R21076 - VSS_XTS1_1 */
- [21077] = 0x5F40, /* R21077 - VSS_XTS1_0 */
- [21078] = 0x0000, /* R21078 - VSS_XTS2_1 */
- [21079] = 0x8700, /* R21079 - VSS_XTS2_0 */
- [21080] = 0x00FA, /* R21080 - VSS_XTS3_1 */
- [21081] = 0xE4C0, /* R21081 - VSS_XTS3_0 */
- [21082] = 0x0000, /* R21082 - VSS_XTS4_1 */
- [21083] = 0x0B40, /* R21083 - VSS_XTS4_0 */
- [21084] = 0x0004, /* R21084 - VSS_XTS5_1 */
- [21085] = 0xE180, /* R21085 - VSS_XTS5_0 */
- [21086] = 0x0001, /* R21086 - VSS_XTS6_1 */
- [21087] = 0x1F40, /* R21087 - VSS_XTS6_0 */
- [21088] = 0x00F8, /* R21088 - VSS_XTS7_1 */
- [21089] = 0xB000, /* R21089 - VSS_XTS7_0 */
- [21090] = 0x00FB, /* R21090 - VSS_XTS8_1 */
- [21091] = 0xCBC0, /* R21091 - VSS_XTS8_0 */
- [21092] = 0x0004, /* R21092 - VSS_XTS9_1 */
- [21093] = 0xF380, /* R21093 - VSS_XTS9_0 */
- [21094] = 0x0007, /* R21094 - VSS_XTS10_1 */
- [21095] = 0xDF40, /* R21095 - VSS_XTS10_0 */
- [21096] = 0x00FF, /* R21096 - VSS_XTS11_1 */
- [21097] = 0x0700, /* R21097 - VSS_XTS11_0 */
- [21098] = 0x00EF, /* R21098 - VSS_XTS12_1 */
- [21099] = 0xD700, /* R21099 - VSS_XTS12_0 */
- [21100] = 0x00FB, /* R21100 - VSS_XTS13_1 */
- [21101] = 0xAF40, /* R21101 - VSS_XTS13_0 */
- [21102] = 0x0010, /* R21102 - VSS_XTS14_1 */
- [21103] = 0x8A80, /* R21103 - VSS_XTS14_0 */
- [21104] = 0x0011, /* R21104 - VSS_XTS15_1 */
- [21105] = 0x07C0, /* R21105 - VSS_XTS15_0 */
- [21106] = 0x00E0, /* R21106 - VSS_XTS16_1 */
- [21107] = 0x0800, /* R21107 - VSS_XTS16_0 */
- [21108] = 0x00D2, /* R21108 - VSS_XTS17_1 */
- [21109] = 0x7600, /* R21109 - VSS_XTS17_0 */
- [21110] = 0x0020, /* R21110 - VSS_XTS18_1 */
- [21111] = 0xCF40, /* R21111 - VSS_XTS18_0 */
- [21112] = 0x0030, /* R21112 - VSS_XTS19_1 */
- [21113] = 0x2340, /* R21113 - VSS_XTS19_0 */
- [21114] = 0x00FD, /* R21114 - VSS_XTS20_1 */
- [21115] = 0x69C0, /* R21115 - VSS_XTS20_0 */
- [21116] = 0x0028, /* R21116 - VSS_XTS21_1 */
- [21117] = 0x3500, /* R21117 - VSS_XTS21_0 */
- [21118] = 0x0006, /* R21118 - VSS_XTS22_1 */
- [21119] = 0x3300, /* R21119 - VSS_XTS22_0 */
- [21120] = 0x00D9, /* R21120 - VSS_XTS23_1 */
- [21121] = 0xF6C0, /* R21121 - VSS_XTS23_0 */
- [21122] = 0x00F3, /* R21122 - VSS_XTS24_1 */
- [21123] = 0x3340, /* R21123 - VSS_XTS24_0 */
- [21124] = 0x000F, /* R21124 - VSS_XTS25_1 */
- [21125] = 0x4200, /* R21125 - VSS_XTS25_0 */
- [21126] = 0x0004, /* R21126 - VSS_XTS26_1 */
- [21127] = 0x0C80, /* R21127 - VSS_XTS26_0 */
- [21128] = 0x00FB, /* R21128 - VSS_XTS27_1 */
- [21129] = 0x3F80, /* R21129 - VSS_XTS27_0 */
- [21130] = 0x00F7, /* R21130 - VSS_XTS28_1 */
- [21131] = 0x57C0, /* R21131 - VSS_XTS28_0 */
- [21132] = 0x0003, /* R21132 - VSS_XTS29_1 */
- [21133] = 0x5400, /* R21133 - VSS_XTS29_0 */
- [21134] = 0x0000, /* R21134 - VSS_XTS30_1 */
- [21135] = 0xC6C0, /* R21135 - VSS_XTS30_0 */
- [21136] = 0x0003, /* R21136 - VSS_XTS31_1 */
- [21137] = 0x12C0, /* R21137 - VSS_XTS31_0 */
- [21138] = 0x00FD, /* R21138 - VSS_XTS32_1 */
- [21139] = 0x8580, /* R21139 - VSS_XTS32_0 */
+ { 20992, 0x008C }, /* R20992 - VSS_XHD2_1 */
+ { 20993, 0x0200 }, /* R20993 - VSS_XHD2_0 */
+ { 20994, 0x0035 }, /* R20994 - VSS_XHD3_1 */
+ { 20995, 0x0700 }, /* R20995 - VSS_XHD3_0 */
+ { 20996, 0x003A }, /* R20996 - VSS_XHN1_1 */
+ { 20997, 0x4100 }, /* R20997 - VSS_XHN1_0 */
+ { 20998, 0x008B }, /* R20998 - VSS_XHN2_1 */
+ { 20999, 0x7D00 }, /* R20999 - VSS_XHN2_0 */
+ { 21000, 0x003A }, /* R21000 - VSS_XHN3_1 */
+ { 21001, 0x4100 }, /* R21001 - VSS_XHN3_0 */
+ { 21002, 0x008C }, /* R21002 - VSS_XLA_1 */
+ { 21003, 0xFEE8 }, /* R21003 - VSS_XLA_0 */
+ { 21004, 0x0078 }, /* R21004 - VSS_XLB_1 */
+ { 21005, 0x0000 }, /* R21005 - VSS_XLB_0 */
+ { 21006, 0x003F }, /* R21006 - VSS_XLG_1 */
+ { 21007, 0xB260 }, /* R21007 - VSS_XLG_0 */
+ { 21008, 0x002D }, /* R21008 - VSS_PG2_1 */
+ { 21009, 0x1818 }, /* R21009 - VSS_PG2_0 */
+ { 21010, 0x0020 }, /* R21010 - VSS_PG_1 */
+ { 21011, 0x0000 }, /* R21011 - VSS_PG_0 */
+ { 21012, 0x00F1 }, /* R21012 - VSS_XTD1_1 */
+ { 21013, 0x8340 }, /* R21013 - VSS_XTD1_0 */
+ { 21014, 0x00FB }, /* R21014 - VSS_XTD2_1 */
+ { 21015, 0x8300 }, /* R21015 - VSS_XTD2_0 */
+ { 21016, 0x00EE }, /* R21016 - VSS_XTD3_1 */
+ { 21017, 0xAEC0 }, /* R21017 - VSS_XTD3_0 */
+ { 21018, 0x00FB }, /* R21018 - VSS_XTD4_1 */
+ { 21019, 0xAC40 }, /* R21019 - VSS_XTD4_0 */
+ { 21020, 0x00F1 }, /* R21020 - VSS_XTD5_1 */
+ { 21021, 0x7F80 }, /* R21021 - VSS_XTD5_0 */
+ { 21022, 0x00F4 }, /* R21022 - VSS_XTD6_1 */
+ { 21023, 0x3B40 }, /* R21023 - VSS_XTD6_0 */
+ { 21024, 0x00F5 }, /* R21024 - VSS_XTD7_1 */
+ { 21025, 0xFB00 }, /* R21025 - VSS_XTD7_0 */
+ { 21026, 0x00EA }, /* R21026 - VSS_XTD8_1 */
+ { 21027, 0x10C0 }, /* R21027 - VSS_XTD8_0 */
+ { 21028, 0x00FC }, /* R21028 - VSS_XTD9_1 */
+ { 21029, 0xC580 }, /* R21029 - VSS_XTD9_0 */
+ { 21030, 0x00E2 }, /* R21030 - VSS_XTD10_1 */
+ { 21031, 0x75C0 }, /* R21031 - VSS_XTD10_0 */
+ { 21032, 0x0004 }, /* R21032 - VSS_XTD11_1 */
+ { 21033, 0xB480 }, /* R21033 - VSS_XTD11_0 */
+ { 21034, 0x00D4 }, /* R21034 - VSS_XTD12_1 */
+ { 21035, 0xF980 }, /* R21035 - VSS_XTD12_0 */
+ { 21036, 0x0004 }, /* R21036 - VSS_XTD13_1 */
+ { 21037, 0x9140 }, /* R21037 - VSS_XTD13_0 */
+ { 21038, 0x00D8 }, /* R21038 - VSS_XTD14_1 */
+ { 21039, 0xA480 }, /* R21039 - VSS_XTD14_0 */
+ { 21040, 0x0002 }, /* R21040 - VSS_XTD15_1 */
+ { 21041, 0x3DC0 }, /* R21041 - VSS_XTD15_0 */
+ { 21042, 0x00CF }, /* R21042 - VSS_XTD16_1 */
+ { 21043, 0x7A80 }, /* R21043 - VSS_XTD16_0 */
+ { 21044, 0x00DC }, /* R21044 - VSS_XTD17_1 */
+ { 21045, 0x0600 }, /* R21045 - VSS_XTD17_0 */
+ { 21046, 0x00F2 }, /* R21046 - VSS_XTD18_1 */
+ { 21047, 0xDAC0 }, /* R21047 - VSS_XTD18_0 */
+ { 21048, 0x00BA }, /* R21048 - VSS_XTD19_1 */
+ { 21049, 0xF340 }, /* R21049 - VSS_XTD19_0 */
+ { 21050, 0x000A }, /* R21050 - VSS_XTD20_1 */
+ { 21051, 0x7940 }, /* R21051 - VSS_XTD20_0 */
+ { 21052, 0x001C }, /* R21052 - VSS_XTD21_1 */
+ { 21053, 0x0680 }, /* R21053 - VSS_XTD21_0 */
+ { 21054, 0x00FD }, /* R21054 - VSS_XTD22_1 */
+ { 21055, 0x2D00 }, /* R21055 - VSS_XTD22_0 */
+ { 21056, 0x001C }, /* R21056 - VSS_XTD23_1 */
+ { 21057, 0xE840 }, /* R21057 - VSS_XTD23_0 */
+ { 21058, 0x000D }, /* R21058 - VSS_XTD24_1 */
+ { 21059, 0xDC40 }, /* R21059 - VSS_XTD24_0 */
+ { 21060, 0x00FC }, /* R21060 - VSS_XTD25_1 */
+ { 21061, 0x9D00 }, /* R21061 - VSS_XTD25_0 */
+ { 21062, 0x0009 }, /* R21062 - VSS_XTD26_1 */
+ { 21063, 0x5580 }, /* R21063 - VSS_XTD26_0 */
+ { 21064, 0x00FE }, /* R21064 - VSS_XTD27_1 */
+ { 21065, 0x7E80 }, /* R21065 - VSS_XTD27_0 */
+ { 21066, 0x000E }, /* R21066 - VSS_XTD28_1 */
+ { 21067, 0xAB40 }, /* R21067 - VSS_XTD28_0 */
+ { 21068, 0x00F9 }, /* R21068 - VSS_XTD29_1 */
+ { 21069, 0x9880 }, /* R21069 - VSS_XTD29_0 */
+ { 21070, 0x0009 }, /* R21070 - VSS_XTD30_1 */
+ { 21071, 0x87C0 }, /* R21071 - VSS_XTD30_0 */
+ { 21072, 0x00FD }, /* R21072 - VSS_XTD31_1 */
+ { 21073, 0x2C40 }, /* R21073 - VSS_XTD31_0 */
+ { 21074, 0x0009 }, /* R21074 - VSS_XTD32_1 */
+ { 21075, 0x4800 }, /* R21075 - VSS_XTD32_0 */
+ { 21076, 0x0003 }, /* R21076 - VSS_XTS1_1 */
+ { 21077, 0x5F40 }, /* R21077 - VSS_XTS1_0 */
+ { 21078, 0x0000 }, /* R21078 - VSS_XTS2_1 */
+ { 21079, 0x8700 }, /* R21079 - VSS_XTS2_0 */
+ { 21080, 0x00FA }, /* R21080 - VSS_XTS3_1 */
+ { 21081, 0xE4C0 }, /* R21081 - VSS_XTS3_0 */
+ { 21082, 0x0000 }, /* R21082 - VSS_XTS4_1 */
+ { 21083, 0x0B40 }, /* R21083 - VSS_XTS4_0 */
+ { 21084, 0x0004 }, /* R21084 - VSS_XTS5_1 */
+ { 21085, 0xE180 }, /* R21085 - VSS_XTS5_0 */
+ { 21086, 0x0001 }, /* R21086 - VSS_XTS6_1 */
+ { 21087, 0x1F40 }, /* R21087 - VSS_XTS6_0 */
+ { 21088, 0x00F8 }, /* R21088 - VSS_XTS7_1 */
+ { 21089, 0xB000 }, /* R21089 - VSS_XTS7_0 */
+ { 21090, 0x00FB }, /* R21090 - VSS_XTS8_1 */
+ { 21091, 0xCBC0 }, /* R21091 - VSS_XTS8_0 */
+ { 21092, 0x0004 }, /* R21092 - VSS_XTS9_1 */
+ { 21093, 0xF380 }, /* R21093 - VSS_XTS9_0 */
+ { 21094, 0x0007 }, /* R21094 - VSS_XTS10_1 */
+ { 21095, 0xDF40 }, /* R21095 - VSS_XTS10_0 */
+ { 21096, 0x00FF }, /* R21096 - VSS_XTS11_1 */
+ { 21097, 0x0700 }, /* R21097 - VSS_XTS11_0 */
+ { 21098, 0x00EF }, /* R21098 - VSS_XTS12_1 */
+ { 21099, 0xD700 }, /* R21099 - VSS_XTS12_0 */
+ { 21100, 0x00FB }, /* R21100 - VSS_XTS13_1 */
+ { 21101, 0xAF40 }, /* R21101 - VSS_XTS13_0 */
+ { 21102, 0x0010 }, /* R21102 - VSS_XTS14_1 */
+ { 21103, 0x8A80 }, /* R21103 - VSS_XTS14_0 */
+ { 21104, 0x0011 }, /* R21104 - VSS_XTS15_1 */
+ { 21105, 0x07C0 }, /* R21105 - VSS_XTS15_0 */
+ { 21106, 0x00E0 }, /* R21106 - VSS_XTS16_1 */
+ { 21107, 0x0800 }, /* R21107 - VSS_XTS16_0 */
+ { 21108, 0x00D2 }, /* R21108 - VSS_XTS17_1 */
+ { 21109, 0x7600 }, /* R21109 - VSS_XTS17_0 */
+ { 21110, 0x0020 }, /* R21110 - VSS_XTS18_1 */
+ { 21111, 0xCF40 }, /* R21111 - VSS_XTS18_0 */
+ { 21112, 0x0030 }, /* R21112 - VSS_XTS19_1 */
+ { 21113, 0x2340 }, /* R21113 - VSS_XTS19_0 */
+ { 21114, 0x00FD }, /* R21114 - VSS_XTS20_1 */
+ { 21115, 0x69C0 }, /* R21115 - VSS_XTS20_0 */
+ { 21116, 0x0028 }, /* R21116 - VSS_XTS21_1 */
+ { 21117, 0x3500 }, /* R21117 - VSS_XTS21_0 */
+ { 21118, 0x0006 }, /* R21118 - VSS_XTS22_1 */
+ { 21119, 0x3300 }, /* R21119 - VSS_XTS22_0 */
+ { 21120, 0x00D9 }, /* R21120 - VSS_XTS23_1 */
+ { 21121, 0xF6C0 }, /* R21121 - VSS_XTS23_0 */
+ { 21122, 0x00F3 }, /* R21122 - VSS_XTS24_1 */
+ { 21123, 0x3340 }, /* R21123 - VSS_XTS24_0 */
+ { 21124, 0x000F }, /* R21124 - VSS_XTS25_1 */
+ { 21125, 0x4200 }, /* R21125 - VSS_XTS25_0 */
+ { 21126, 0x0004 }, /* R21126 - VSS_XTS26_1 */
+ { 21127, 0x0C80 }, /* R21127 - VSS_XTS26_0 */
+ { 21128, 0x00FB }, /* R21128 - VSS_XTS27_1 */
+ { 21129, 0x3F80 }, /* R21129 - VSS_XTS27_0 */
+ { 21130, 0x00F7 }, /* R21130 - VSS_XTS28_1 */
+ { 21131, 0x57C0 }, /* R21131 - VSS_XTS28_0 */
+ { 21132, 0x0003 }, /* R21132 - VSS_XTS29_1 */
+ { 21133, 0x5400 }, /* R21133 - VSS_XTS29_0 */
+ { 21134, 0x0000 }, /* R21134 - VSS_XTS30_1 */
+ { 21135, 0xC6C0 }, /* R21135 - VSS_XTS30_0 */
+ { 21136, 0x0003 }, /* R21136 - VSS_XTS31_1 */
+ { 21137, 0x12C0 }, /* R21137 - VSS_XTS31_0 */
+ { 21138, 0x00FD }, /* R21138 - VSS_XTS32_1 */
+ { 21139, 0x8580 }, /* R21139 - VSS_XTS32_0 */
};
static const struct wm8962_reg_access {
@@ -802,7 +803,7 @@
u16 vol;
} wm8962_reg_access[WM8962_MAX_REGISTER + 1] = {
[0] = { 0x00FF, 0x01FF, 0x0000 }, /* R0 - Left Input volume */
- [1] = { 0xFEFF, 0x01FF, 0xFFFF }, /* R1 - Right Input volume */
+ [1] = { 0xFEFF, 0x01FF, 0x0000 }, /* R1 - Right Input volume */
[2] = { 0x00FF, 0x01FF, 0x0000 }, /* R2 - HPOUTL volume */
[3] = { 0x00FF, 0x01FF, 0x0000 }, /* R3 - HPOUTR volume */
[4] = { 0x07FE, 0x07FE, 0xFFFF }, /* R4 - Clocking1 */
@@ -1943,7 +1944,7 @@
[21139] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21139 - VSS_XTS32_0 */
};
-static int wm8962_volatile_register(struct snd_soc_codec *codec, unsigned int reg)
+static bool wm8962_volatile_register(struct device *dev, unsigned int reg)
{
if (wm8962_reg_access[reg].vol)
return 1;
@@ -1951,7 +1952,7 @@
return 0;
}
-static int wm8962_readable_register(struct snd_soc_codec *codec, unsigned int reg)
+static bool wm8962_readable_register(struct device *dev, unsigned int reg)
{
if (wm8962_reg_access[reg].read)
return 1;
@@ -1959,15 +1960,15 @@
return 0;
}
-static int wm8962_reset(struct snd_soc_codec *codec)
+static int wm8962_reset(struct wm8962_priv *wm8962)
{
int ret;
- ret = snd_soc_write(codec, WM8962_SOFTWARE_RESET, 0x6243);
+ ret = regmap_write(wm8962->regmap, WM8962_SOFTWARE_RESET, 0x6243);
if (ret != 0)
return ret;
- return snd_soc_write(codec, WM8962_PLL_SOFTWARE_RESET, 0);
+ return regmap_write(wm8962->regmap, WM8962_PLL_SOFTWARE_RESET, 0);
}
static const DECLARE_TLV_DB_SCALE(inpga_tlv, -2325, 75, 0);
@@ -2345,6 +2346,10 @@
int src;
int fll;
+ /* Ignore attempts to run the event during startup */
+ if (codec->dapm.bias_level == SND_SOC_BIAS_OFF)
+ return 0;
+
src = snd_soc_read(codec, WM8962_CLOCKING2) & WM8962_SYSCLK_SRC_MASK;
switch (src) {
@@ -2670,7 +2675,7 @@
SND_SOC_DAPM_INPUT("IN3R"),
SND_SOC_DAPM_INPUT("IN4L"),
SND_SOC_DAPM_INPUT("IN4R"),
-SND_SOC_DAPM_INPUT("Beep"),
+SND_SOC_DAPM_SIGGEN("Beep"),
SND_SOC_DAPM_INPUT("DMICDAT"),
SND_SOC_DAPM_SUPPLY("MICBIAS", WM8962_PWR_MGMT_1, 1, 0, NULL, 0),
@@ -2684,6 +2689,8 @@
SND_SOC_DAPM_SUPPLY_S("DSP2", 1, WM8962_DSP2_POWER_MANAGEMENT,
WM8962_DSP2_ENA_SHIFT, 0, dsp2_event,
SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
+SND_SOC_DAPM_SUPPLY("TEMP_HP", WM8962_ADDITIONAL_CONTROL_4, 2, 0, NULL, 0),
+SND_SOC_DAPM_SUPPLY("TEMP_SPK", WM8962_ADDITIONAL_CONTROL_4, 1, 0, NULL, 0),
SND_SOC_DAPM_MIXER("INPGAL", WM8962_LEFT_INPUT_PGA_CONTROL, 4, 0,
inpgal, ARRAY_SIZE(inpgal)),
@@ -2839,6 +2846,9 @@
{ "HPOUTL", NULL, "HPOUT" },
{ "HPOUTR", NULL, "HPOUT" },
+
+ { "HPOUTL", NULL, "TEMP_HP" },
+ { "HPOUTR", NULL, "TEMP_HP" },
};
static const struct snd_soc_dapm_route wm8962_spk_mono_intercon[] = {
@@ -2855,6 +2865,7 @@
{ "Speaker Output", NULL, "Speaker PGA" },
{ "Speaker Output", NULL, "SYSCLK" },
{ "Speaker Output", NULL, "TOCLK" },
+ { "Speaker Output", NULL, "TEMP_SPK" },
{ "SPKOUT", NULL, "Speaker Output" },
};
@@ -2883,10 +2894,12 @@
{ "SPKOUTL Output", NULL, "SPKOUTL PGA" },
{ "SPKOUTL Output", NULL, "SYSCLK" },
{ "SPKOUTL Output", NULL, "TOCLK" },
+ { "SPKOUTL Output", NULL, "TEMP_SPK" },
{ "SPKOUTR Output", NULL, "SPKOUTR PGA" },
{ "SPKOUTR Output", NULL, "SYSCLK" },
{ "SPKOUTR Output", NULL, "TOCLK" },
+ { "SPKOUTR Output", NULL, "TEMP_SPK" },
{ "SPKOUTL", NULL, "SPKOUTL Output" },
{ "SPKOUTR", NULL, "SPKOUTR Output" },
@@ -2931,33 +2944,6 @@
return 0;
}
-static void wm8962_sync_cache(struct snd_soc_codec *codec)
-{
- u16 *reg_cache = codec->reg_cache;
- int i;
-
- if (!codec->cache_sync)
- return;
-
- dev_dbg(codec->dev, "Syncing cache\n");
-
- codec->cache_only = 0;
-
- /* Sync back cached values if they're different from the
- * hardware default.
- */
- for (i = 1; i < codec->driver->reg_cache_size; i++) {
- if (i == WM8962_SOFTWARE_RESET)
- continue;
- if (reg_cache[i] == wm8962_reg[i])
- continue;
-
- snd_soc_write(codec, i, reg_cache[i]);
- }
-
- codec->cache_sync = 0;
-}
-
/* -1 for reserved values */
static const int bclk_divs[] = {
1, -1, 2, 3, 4, -1, 6, 8, -1, 12, 16, 24, -1, 32, 32, 32
@@ -3085,7 +3071,8 @@
return ret;
}
- wm8962_sync_cache(codec);
+ regcache_cache_only(wm8962->regmap, false);
+ regcache_sync(wm8962->regmap);
snd_soc_update_bits(codec, WM8962_ANTI_POP,
WM8962_STARTUP_BIAS_ENA |
@@ -3399,6 +3386,7 @@
unsigned long timeout;
int ret;
int fll1 = snd_soc_read(codec, WM8962_FLL_CONTROL_1) & WM8962_FLL_ENA;
+ int sysclk = snd_soc_read(codec, WM8962_CLOCKING2) & WM8962_SYSCLK_ENA;
/* Any change? */
if (source == wm8962->fll_src && Fref == wm8962->fll_fref &&
@@ -3459,6 +3447,9 @@
try_wait_for_completion(&wm8962->fll_lock);
+ if (sysclk)
+ fll1 |= WM8962_FLL_ENA;
+
snd_soc_update_bits(codec, WM8962_FLL_CONTROL_1,
WM8962_FLL_FRAC | WM8962_FLL_REFCLK_SRC_MASK |
WM8962_FLL_ENA, fll1);
@@ -3511,7 +3502,7 @@
#define WM8962_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
-static struct snd_soc_dai_ops wm8962_dai_ops = {
+static const struct snd_soc_dai_ops wm8962_dai_ops = {
.hw_params = wm8962_hw_params,
.set_sysclk = wm8962_set_dai_sysclk,
.set_fmt = wm8962_set_dai_fmt,
@@ -3662,6 +3653,14 @@
snd_soc_jack_report(wm8962->jack, 0,
SND_JACK_MICROPHONE | SND_JACK_BTN_0);
+ if (jack) {
+ snd_soc_dapm_force_enable_pin(&codec->dapm, "SYSCLK");
+ snd_soc_dapm_force_enable_pin(&codec->dapm, "MICBIAS");
+ } else {
+ snd_soc_dapm_disable_pin(&codec->dapm, "SYSCLK");
+ snd_soc_dapm_disable_pin(&codec->dapm, "MICBIAS");
+ }
+
return 0;
}
EXPORT_SYMBOL_GPL(wm8962_mic_detect);
@@ -3879,13 +3878,17 @@
{
struct wm8962_priv *wm8962 = gpio_to_wm8962(chip);
struct snd_soc_codec *codec = wm8962->codec;
- int val;
+ int ret, val;
/* Force function 1 (logic output) */
val = (1 << WM8962_GP2_FN_SHIFT) | (value << WM8962_GP2_LVL_SHIFT);
- return snd_soc_update_bits(codec, WM8962_GPIO_BASE + offset,
- WM8962_GP2_FN_MASK | WM8962_GP2_LVL, val);
+ ret = snd_soc_update_bits(codec, WM8962_GPIO_BASE + offset,
+ WM8962_GP2_FN_MASK | WM8962_GP2_LVL, val);
+ if (ret < 0)
+ return ret;
+
+ return 0;
}
static struct gpio_chip wm8962_template_chip = {
@@ -3946,26 +3949,12 @@
bool dmicclk, dmicdat;
wm8962->codec = codec;
- INIT_DELAYED_WORK(&wm8962->mic_work, wm8962_mic_work);
- init_completion(&wm8962->fll_lock);
+ codec->control_data = wm8962->regmap;
- codec->cache_sync = 1;
- codec->dapm.idle_bias_off = 1;
-
- ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_I2C);
+ ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_REGMAP);
if (ret != 0) {
dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- goto err;
- }
-
- for (i = 0; i < ARRAY_SIZE(wm8962->supplies); i++)
- wm8962->supplies[i].supply = wm8962_supply_names[i];
-
- ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8962->supplies),
- wm8962->supplies);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
- goto err;
+ return ret;
}
wm8962->disable_nb[0].notifier_call = wm8962_regulator_event_0;
@@ -3988,43 +3977,6 @@
}
}
- ret = regulator_bulk_enable(ARRAY_SIZE(wm8962->supplies),
- wm8962->supplies);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
- goto err_get;
- }
-
- ret = snd_soc_read(codec, WM8962_SOFTWARE_RESET);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to read ID register\n");
- goto err_enable;
- }
- if (ret != wm8962_reg[WM8962_SOFTWARE_RESET]) {
- dev_err(codec->dev, "Device is not a WM8962, ID %x != %x\n",
- ret, wm8962_reg[WM8962_SOFTWARE_RESET]);
- ret = -EINVAL;
- goto err_enable;
- }
-
- ret = snd_soc_read(codec, WM8962_RIGHT_INPUT_VOLUME);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to read device revision: %d\n",
- ret);
- goto err_enable;
- }
-
- dev_info(codec->dev, "customer id %x revision %c\n",
- (ret & WM8962_CUST_ID_MASK) >> WM8962_CUST_ID_SHIFT,
- ((ret & WM8962_CHIP_REV_MASK) >> WM8962_CHIP_REV_SHIFT)
- + 'A');
-
- ret = wm8962_reset(codec);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to issue reset\n");
- goto err_enable;
- }
-
/* SYSCLK defaults to on; make sure it is off so we can safely
* write to registers if the device is declocked.
*/
@@ -4039,8 +3991,6 @@
WM8962_OSC_ENA | WM8962_PLL2_ENA | WM8962_PLL3_ENA,
0);
- regulator_bulk_disable(ARRAY_SIZE(wm8962->supplies), wm8962->supplies);
-
if (pdata) {
/* Apply static configuration for GPIOs */
for (i = 0; i < ARRAY_SIZE(pdata->gpio_init); i++)
@@ -4091,6 +4041,12 @@
/* Stereo control for EQ */
snd_soc_update_bits(codec, WM8962_EQ1, WM8962_EQ_SHARED_COEFF, 0);
+ /* Don't debouce interrupts so we don't need SYSCLK */
+ snd_soc_update_bits(codec, WM8962_IRQ_DEBOUNCE,
+ WM8962_FLL_LOCK_DB | WM8962_PLL3_LOCK_DB |
+ WM8962_PLL2_LOCK_DB | WM8962_TEMP_SHUT_DB,
+ 0);
+
wm8962_add_widgets(codec);
/* Save boards having to disable DMIC when not in use */
@@ -4150,13 +4106,6 @@
}
return 0;
-
-err_enable:
- regulator_bulk_disable(ARRAY_SIZE(wm8962->supplies), wm8962->supplies);
-err_get:
- regulator_bulk_free(ARRAY_SIZE(wm8962->supplies), wm8962->supplies);
-err:
- return ret;
}
static int wm8962_remove(struct snd_soc_codec *codec)
@@ -4174,21 +4123,36 @@
for (i = 0; i < ARRAY_SIZE(wm8962->supplies); i++)
regulator_unregister_notifier(wm8962->supplies[i].consumer,
&wm8962->disable_nb[i]);
- regulator_bulk_free(ARRAY_SIZE(wm8962->supplies), wm8962->supplies);
return 0;
}
+static int wm8962_soc_volatile(struct snd_soc_codec *codec,
+ unsigned int reg)
+{
+ return true;
+}
+
+
static struct snd_soc_codec_driver soc_codec_dev_wm8962 = {
.probe = wm8962_probe,
.remove = wm8962_remove,
.set_bias_level = wm8962_set_bias_level,
- .reg_cache_size = WM8962_MAX_REGISTER + 1,
- .reg_word_size = sizeof(u16),
- .reg_cache_default = wm8962_reg,
- .volatile_register = wm8962_volatile_register,
- .readable_register = wm8962_readable_register,
.set_pll = wm8962_set_fll,
+ .reg_cache_size = WM8962_MAX_REGISTER,
+ .volatile_register = wm8962_soc_volatile,
+};
+
+static const struct regmap_config wm8962_regmap = {
+ .reg_bits = 16,
+ .val_bits = 16,
+
+ .max_register = WM8962_MAX_REGISTER,
+ .reg_defaults = wm8962_reg,
+ .num_reg_defaults = ARRAY_SIZE(wm8962_reg),
+ .volatile_reg = wm8962_volatile_register,
+ .readable_reg = wm8962_readable_register,
+ .cache_type = REGCACHE_RBTREE,
};
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
@@ -4196,28 +4160,112 @@
const struct i2c_device_id *id)
{
struct wm8962_priv *wm8962;
- int ret;
+ unsigned int reg;
+ int ret, i;
- wm8962 = kzalloc(sizeof(struct wm8962_priv), GFP_KERNEL);
+ wm8962 = devm_kzalloc(&i2c->dev, sizeof(struct wm8962_priv),
+ GFP_KERNEL);
if (wm8962 == NULL)
return -ENOMEM;
i2c_set_clientdata(i2c, wm8962);
+ INIT_DELAYED_WORK(&wm8962->mic_work, wm8962_mic_work);
+ init_completion(&wm8962->fll_lock);
wm8962->irq = i2c->irq;
+ for (i = 0; i < ARRAY_SIZE(wm8962->supplies); i++)
+ wm8962->supplies[i].supply = wm8962_supply_names[i];
+
+ ret = regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm8962->supplies),
+ wm8962->supplies);
+ if (ret != 0) {
+ dev_err(&i2c->dev, "Failed to request supplies: %d\n", ret);
+ goto err;
+ }
+
+ ret = regulator_bulk_enable(ARRAY_SIZE(wm8962->supplies),
+ wm8962->supplies);
+ if (ret != 0) {
+ dev_err(&i2c->dev, "Failed to enable supplies: %d\n", ret);
+ goto err_get;
+ }
+
+ wm8962->regmap = regmap_init_i2c(i2c, &wm8962_regmap);
+ if (IS_ERR(wm8962->regmap)) {
+ ret = PTR_ERR(wm8962->regmap);
+ dev_err(&i2c->dev, "Failed to allocate regmap: %d\n", ret);
+ goto err_enable;
+ }
+
+ /*
+ * We haven't marked the chip revision as volatile due to
+ * sharing a register with the right input volume; explicitly
+ * bypass the cache to read it.
+ */
+ regcache_cache_bypass(wm8962->regmap, true);
+
+ ret = regmap_read(wm8962->regmap, WM8962_SOFTWARE_RESET, ®);
+ if (ret < 0) {
+ dev_err(&i2c->dev, "Failed to read ID register\n");
+ goto err_regmap;
+ }
+ if (reg != 0x6243) {
+ dev_err(&i2c->dev,
+ "Device is not a WM8962, ID %x != 0x6243\n", ret);
+ ret = -EINVAL;
+ goto err_regmap;
+ }
+
+ ret = regmap_read(wm8962->regmap, WM8962_RIGHT_INPUT_VOLUME, ®);
+ if (ret < 0) {
+ dev_err(&i2c->dev, "Failed to read device revision: %d\n",
+ ret);
+ goto err_regmap;
+ }
+
+ dev_info(&i2c->dev, "customer id %x revision %c\n",
+ (reg & WM8962_CUST_ID_MASK) >> WM8962_CUST_ID_SHIFT,
+ ((reg & WM8962_CHIP_REV_MASK) >> WM8962_CHIP_REV_SHIFT)
+ + 'A');
+
+ regcache_cache_bypass(wm8962->regmap, false);
+
+ ret = wm8962_reset(wm8962);
+ if (ret < 0) {
+ dev_err(&i2c->dev, "Failed to issue reset\n");
+ goto err_regmap;
+ }
+
+ regcache_cache_only(wm8962->regmap, true);
+
ret = snd_soc_register_codec(&i2c->dev,
&soc_codec_dev_wm8962, &wm8962_dai, 1);
if (ret < 0)
- kfree(wm8962);
+ goto err_regmap;
+ /* The drivers should power up as needed */
+ regulator_bulk_disable(ARRAY_SIZE(wm8962->supplies), wm8962->supplies);
+
+ return 0;
+
+err_regmap:
+ regmap_exit(wm8962->regmap);
+err_enable:
+ regulator_bulk_disable(ARRAY_SIZE(wm8962->supplies), wm8962->supplies);
+err_get:
+ regulator_bulk_free(ARRAY_SIZE(wm8962->supplies), wm8962->supplies);
+err:
return ret;
}
static __devexit int wm8962_i2c_remove(struct i2c_client *client)
{
+ struct wm8962_priv *wm8962 = dev_get_drvdata(&client->dev);
+
snd_soc_unregister_codec(&client->dev);
- kfree(i2c_get_clientdata(client));
+ regmap_exit(wm8962->regmap);
+ regulator_bulk_free(ARRAY_SIZE(wm8962->supplies), wm8962->supplies);
return 0;
}
diff --git a/sound/soc/codecs/wm8971.c b/sound/soc/codecs/wm8971.c
index b444b29..4af8936 100644
--- a/sound/soc/codecs/wm8971.c
+++ b/sound/soc/codecs/wm8971.c
@@ -19,7 +19,6 @@
#include <linux/delay.h>
#include <linux/pm.h>
#include <linux/i2c.h>
-#include <linux/platform_device.h>
#include <linux/slab.h>
#include <sound/core.h>
#include <sound/pcm.h>
@@ -224,7 +223,7 @@
SND_SOC_DAPM_DAC("Left DAC", "Left Playback", WM8971_PWR2, 8, 0),
SND_SOC_DAPM_PGA("Mono Out 1", WM8971_PWR2, 2, 0, NULL, 0),
- SND_SOC_DAPM_MICBIAS("Mic Bias", WM8971_PWR1, 1, 0),
+ SND_SOC_DAPM_SUPPLY("Mic Bias", WM8971_PWR1, 1, 0, NULL, 0),
SND_SOC_DAPM_ADC("Right ADC", "Right Capture", WM8971_PWR1, 2, 0),
SND_SOC_DAPM_ADC("Left ADC", "Left Capture", WM8971_PWR1, 3, 0),
@@ -567,7 +566,7 @@
#define WM8971_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
SNDRV_PCM_FMTBIT_S24_LE)
-static struct snd_soc_dai_ops wm8971_dai_ops = {
+static const struct snd_soc_dai_ops wm8971_dai_ops = {
.hw_params = wm8971_pcm_hw_params,
.digital_mute = wm8971_mute,
.set_fmt = wm8971_set_dai_fmt,
@@ -600,7 +599,7 @@
wm8971_set_bias_level(codec, codec->dapm.bias_level);
}
-static int wm8971_suspend(struct snd_soc_codec *codec, pm_message_t state)
+static int wm8971_suspend(struct snd_soc_codec *codec)
{
wm8971_set_bias_level(codec, SND_SOC_BIAS_OFF);
return 0;
@@ -725,7 +724,7 @@
static struct i2c_driver wm8971_i2c_driver = {
.driver = {
- .name = "wm8971-codec",
+ .name = "wm8971",
.owner = THIS_MODULE,
},
.probe = wm8971_i2c_probe,
diff --git a/sound/soc/codecs/wm8974.c b/sound/soc/codecs/wm8974.c
index 9352f1e..4a6a7b5 100644
--- a/sound/soc/codecs/wm8974.c
+++ b/sound/soc/codecs/wm8974.c
@@ -17,7 +17,6 @@
#include <linux/delay.h>
#include <linux/pm.h>
#include <linux/i2c.h>
-#include <linux/platform_device.h>
#include <linux/slab.h>
#include <sound/core.h>
#include <sound/pcm.h>
@@ -226,7 +225,7 @@
SND_SOC_DAPM_MIXER("Boost Mixer", WM8974_POWER2, 4, 0,
wm8974_boost_mixer, ARRAY_SIZE(wm8974_boost_mixer)),
-SND_SOC_DAPM_MICBIAS("Mic Bias", WM8974_POWER1, 4, 0),
+SND_SOC_DAPM_SUPPLY("Mic Bias", WM8974_POWER1, 4, 0, NULL, 0),
SND_SOC_DAPM_INPUT("MICN"),
SND_SOC_DAPM_INPUT("MICP"),
@@ -557,7 +556,7 @@
#define WM8974_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
SNDRV_PCM_FMTBIT_S24_LE)
-static struct snd_soc_dai_ops wm8974_ops = {
+static const struct snd_soc_dai_ops wm8974_ops = {
.hw_params = wm8974_pcm_hw_params,
.digital_mute = wm8974_mute,
.set_fmt = wm8974_set_dai_fmt,
@@ -583,7 +582,7 @@
.symmetric_rates = 1,
};
-static int wm8974_suspend(struct snd_soc_codec *codec, pm_message_t state)
+static int wm8974_suspend(struct snd_soc_codec *codec)
{
wm8974_set_bias_level(codec, SND_SOC_BIAS_OFF);
return 0;
@@ -672,7 +671,7 @@
static struct i2c_driver wm8974_i2c_driver = {
.driver = {
- .name = "wm8974-codec",
+ .name = "wm8974",
.owner = THIS_MODULE,
},
.probe = wm8974_i2c_probe,
diff --git a/sound/soc/codecs/wm8978.c b/sound/soc/codecs/wm8978.c
index 41ca4d9..85d514d 100644
--- a/sound/soc/codecs/wm8978.c
+++ b/sound/soc/codecs/wm8978.c
@@ -18,7 +18,6 @@
#include <linux/delay.h>
#include <linux/pm.h>
#include <linux/i2c.h>
-#include <linux/platform_device.h>
#include <linux/slab.h>
#include <sound/core.h>
#include <sound/pcm.h>
@@ -865,7 +864,7 @@
#define WM8978_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
-static struct snd_soc_dai_ops wm8978_dai_ops = {
+static const struct snd_soc_dai_ops wm8978_dai_ops = {
.hw_params = wm8978_hw_params,
.digital_mute = wm8978_mute,
.set_fmt = wm8978_set_dai_fmt,
@@ -893,7 +892,7 @@
.ops = &wm8978_dai_ops,
};
-static int wm8978_suspend(struct snd_soc_codec *codec, pm_message_t state)
+static int wm8978_suspend(struct snd_soc_codec *codec)
{
wm8978_set_bias_level(codec, SND_SOC_BIAS_OFF);
/* Also switch PLL off */
diff --git a/sound/soc/codecs/wm8983.c b/sound/soc/codecs/wm8983.c
index 93ee284..cebde56 100644
--- a/sound/soc/codecs/wm8983.c
+++ b/sound/soc/codecs/wm8983.c
@@ -481,7 +481,8 @@
SND_SOC_DAPM_PGA("OUT4 Out", WM8983_POWER_MANAGEMENT_3,
8, 0, NULL, 0),
- SND_SOC_DAPM_MICBIAS("Mic Bias", WM8983_POWER_MANAGEMENT_1, 4, 0),
+ SND_SOC_DAPM_SUPPLY("Mic Bias", WM8983_POWER_MANAGEMENT_1, 4, 0,
+ NULL, 0),
SND_SOC_DAPM_INPUT("LIN"),
SND_SOC_DAPM_INPUT("LIP"),
@@ -973,7 +974,7 @@
}
#ifdef CONFIG_PM
-static int wm8983_suspend(struct snd_soc_codec *codec, pm_message_t state)
+static int wm8983_suspend(struct snd_soc_codec *codec)
{
wm8983_set_bias_level(codec, SND_SOC_BIAS_OFF);
return 0;
@@ -1034,7 +1035,7 @@
return 0;
}
-static struct snd_soc_dai_ops wm8983_dai_ops = {
+static const struct snd_soc_dai_ops wm8983_dai_ops = {
.digital_mute = wm8983_dac_mute,
.hw_params = wm8983_hw_params,
.set_fmt = wm8983_set_fmt,
diff --git a/sound/soc/codecs/wm8985.c b/sound/soc/codecs/wm8985.c
index bae510a..c0c86b3 100644
--- a/sound/soc/codecs/wm8985.c
+++ b/sound/soc/codecs/wm8985.c
@@ -411,7 +411,8 @@
SND_SOC_DAPM_PGA("Right Speaker Out", WM8985_POWER_MANAGEMENT_3,
6, 0, NULL, 0),
- SND_SOC_DAPM_MICBIAS("Mic Bias", WM8985_POWER_MANAGEMENT_1, 4, 0),
+ SND_SOC_DAPM_SUPPLY("Mic Bias", WM8985_POWER_MANAGEMENT_1, 4, 0,
+ NULL, 0),
SND_SOC_DAPM_INPUT("LIN"),
SND_SOC_DAPM_INPUT("LIP"),
@@ -944,7 +945,7 @@
}
#ifdef CONFIG_PM
-static int wm8985_suspend(struct snd_soc_codec *codec, pm_message_t state)
+static int wm8985_suspend(struct snd_soc_codec *codec)
{
wm8985_set_bias_level(codec, SND_SOC_BIAS_OFF);
return 0;
@@ -1030,7 +1031,7 @@
return ret;
}
-static struct snd_soc_dai_ops wm8985_dai_ops = {
+static const struct snd_soc_dai_ops wm8985_dai_ops = {
.digital_mute = wm8985_dac_mute,
.hw_params = wm8985_hw_params,
.set_fmt = wm8985_set_fmt,
diff --git a/sound/soc/codecs/wm8988.c b/sound/soc/codecs/wm8988.c
index 2e9eba7..ab52963 100644
--- a/sound/soc/codecs/wm8988.c
+++ b/sound/soc/codecs/wm8988.c
@@ -18,7 +18,6 @@
#include <linux/pm.h>
#include <linux/i2c.h>
#include <linux/spi/spi.h>
-#include <linux/platform_device.h>
#include <linux/slab.h>
#include <sound/core.h>
#include <sound/pcm.h>
@@ -267,7 +266,7 @@
SOC_DAPM_ENUM("Route", monomux);
static const struct snd_soc_dapm_widget wm8988_dapm_widgets[] = {
- SND_SOC_DAPM_MICBIAS("Mic Bias", WM8988_PWR1, 1, 0),
+ SND_SOC_DAPM_SUPPLY("Mic Bias", WM8988_PWR1, 1, 0, NULL, 0),
SND_SOC_DAPM_MUX("Differential Mux", SND_SOC_NOPM, 0, 0,
&wm8988_diffmux_controls),
@@ -701,7 +700,7 @@
#define WM8988_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
SNDRV_PCM_FMTBIT_S24_LE)
-static struct snd_soc_dai_ops wm8988_ops = {
+static const struct snd_soc_dai_ops wm8988_ops = {
.startup = wm8988_pcm_startup,
.hw_params = wm8988_pcm_hw_params,
.set_fmt = wm8988_set_dai_fmt,
@@ -729,7 +728,7 @@
.symmetric_rates = 1,
};
-static int wm8988_suspend(struct snd_soc_codec *codec, pm_message_t state)
+static int wm8988_suspend(struct snd_soc_codec *codec)
{
wm8988_set_bias_level(codec, SND_SOC_BIAS_OFF);
return 0;
@@ -823,7 +822,7 @@
static struct spi_driver wm8988_spi_driver = {
.driver = {
- .name = "wm8988-codec",
+ .name = "wm8988",
.owner = THIS_MODULE,
},
.probe = wm8988_spi_probe,
diff --git a/sound/soc/codecs/wm8990.c b/sound/soc/codecs/wm8990.c
index d29a962..e538eda 100644
--- a/sound/soc/codecs/wm8990.c
+++ b/sound/soc/codecs/wm8990.c
@@ -17,7 +17,6 @@
#include <linux/delay.h>
#include <linux/pm.h>
#include <linux/i2c.h>
-#include <linux/platform_device.h>
#include <linux/slab.h>
#include <sound/core.h>
#include <sound/pcm.h>
@@ -776,8 +775,8 @@
NULL, 0),
/* MICBIAS */
-SND_SOC_DAPM_MICBIAS("MICBIAS", WM8990_POWER_MANAGEMENT_1,
- WM8990_MICBIAS_ENA_BIT, 0),
+SND_SOC_DAPM_SUPPLY("MICBIAS", WM8990_POWER_MANAGEMENT_1,
+ WM8990_MICBIAS_ENA_BIT, 0, NULL, 0),
SND_SOC_DAPM_OUTPUT("LON"),
SND_SOC_DAPM_OUTPUT("LOP"),
@@ -1287,7 +1286,7 @@
* 1. ADC/DAC on Primary Interface
* 2. ADC on Primary Interface/DAC on secondary
*/
-static struct snd_soc_dai_ops wm8990_dai_ops = {
+static const struct snd_soc_dai_ops wm8990_dai_ops = {
.hw_params = wm8990_hw_params,
.digital_mute = wm8990_mute,
.set_fmt = wm8990_set_dai_fmt,
@@ -1314,7 +1313,7 @@
.ops = &wm8990_dai_ops,
};
-static int wm8990_suspend(struct snd_soc_codec *codec, pm_message_t state)
+static int wm8990_suspend(struct snd_soc_codec *codec)
{
wm8990_set_bias_level(codec, SND_SOC_BIAS_OFF);
return 0;
@@ -1418,7 +1417,7 @@
static struct i2c_driver wm8990_i2c_driver = {
.driver = {
- .name = "wm8990-codec",
+ .name = "wm8990",
.owner = THIS_MODULE,
},
.probe = wm8990_i2c_probe,
diff --git a/sound/soc/codecs/wm8991.c b/sound/soc/codecs/wm8991.c
index c9ab3ba..7ee40da 100644
--- a/sound/soc/codecs/wm8991.c
+++ b/sound/soc/codecs/wm8991.c
@@ -18,7 +18,6 @@
#include <linux/delay.h>
#include <linux/pm.h>
#include <linux/i2c.h>
-#include <linux/platform_device.h>
#include <linux/slab.h>
#include <sound/core.h>
#include <sound/pcm.h>
@@ -770,8 +769,8 @@
NULL, 0),
/* MICBIAS */
- SND_SOC_DAPM_MICBIAS("MICBIAS", WM8991_POWER_MANAGEMENT_1,
- WM8991_MICBIAS_ENA_BIT, 0),
+ SND_SOC_DAPM_SUPPLY("MICBIAS", WM8991_POWER_MANAGEMENT_1,
+ WM8991_MICBIAS_ENA_BIT, 0, NULL, 0),
SND_SOC_DAPM_OUTPUT("LON"),
SND_SOC_DAPM_OUTPUT("LOP"),
@@ -1241,7 +1240,7 @@
return 0;
}
-static int wm8991_suspend(struct snd_soc_codec *codec, pm_message_t state)
+static int wm8991_suspend(struct snd_soc_codec *codec)
{
wm8991_set_bias_level(codec, SND_SOC_BIAS_OFF);
return 0;
@@ -1311,7 +1310,7 @@
#define WM8991_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
SNDRV_PCM_FMTBIT_S24_LE)
-static struct snd_soc_dai_ops wm8991_ops = {
+static const struct snd_soc_dai_ops wm8991_ops = {
.hw_params = wm8991_hw_params,
.digital_mute = wm8991_mute,
.set_fmt = wm8991_set_dai_fmt,
diff --git a/sound/soc/codecs/wm8993.c b/sound/soc/codecs/wm8993.c
index d1a142f4..2b40c93 100644
--- a/sound/soc/codecs/wm8993.c
+++ b/sound/soc/codecs/wm8993.c
@@ -934,28 +934,6 @@
{ "Right Headphone Mux", "DAC", "DACR" },
};
-static void wm8993_cache_restore(struct snd_soc_codec *codec)
-{
- u16 *cache = codec->reg_cache;
- int i;
-
- if (!codec->cache_sync)
- return;
-
- /* Reenable hardware writes */
- codec->cache_only = 0;
-
- /* Restore the register settings */
- for (i = 1; i < WM8993_MAX_REGISTER; i++) {
- if (cache[i] == wm8993_reg_defaults[i])
- continue;
- snd_soc_write(codec, i, cache[i]);
- }
-
- /* We're in sync again */
- codec->cache_sync = 0;
-}
-
static int wm8993_set_bias_level(struct snd_soc_codec *codec,
enum snd_soc_bias_level level)
{
@@ -979,7 +957,7 @@
if (ret != 0)
return ret;
- wm8993_cache_restore(codec);
+ snd_soc_cache_sync(codec);
/* Tune DC servo configuration */
snd_soc_write(codec, 0x44, 3);
@@ -1394,7 +1372,7 @@
return 0;
}
-static struct snd_soc_dai_ops wm8993_ops = {
+static const struct snd_soc_dai_ops wm8993_ops = {
.set_sysclk = wm8993_set_sysclk,
.set_fmt = wm8993_set_dai_fmt,
.hw_params = wm8993_hw_params,
@@ -1544,7 +1522,7 @@
}
#ifdef CONFIG_PM
-static int wm8993_suspend(struct snd_soc_codec *codec, pm_message_t state)
+static int wm8993_suspend(struct snd_soc_codec *codec)
{
struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec);
int fll_fout = wm8993->fll_fout;
@@ -1613,7 +1591,8 @@
struct wm8993_priv *wm8993;
int ret;
- wm8993 = kzalloc(sizeof(struct wm8993_priv), GFP_KERNEL);
+ wm8993 = devm_kzalloc(&i2c->dev, sizeof(struct wm8993_priv),
+ GFP_KERNEL);
if (wm8993 == NULL)
return -ENOMEM;
@@ -1621,8 +1600,6 @@
ret = snd_soc_register_codec(&i2c->dev,
&soc_codec_dev_wm8993, &wm8993_dai, 1);
- if (ret < 0)
- kfree(wm8993);
return ret;
}
@@ -1641,7 +1618,7 @@
static struct i2c_driver wm8993_i2c_driver = {
.driver = {
- .name = "wm8993-codec",
+ .name = "wm8993",
.owner = THIS_MODULE,
},
.probe = wm8993_i2c_probe,
diff --git a/sound/soc/codecs/wm8994-tables.c b/sound/soc/codecs/wm8994-tables.c
deleted file mode 100644
index df5a8b9..0000000
--- a/sound/soc/codecs/wm8994-tables.c
+++ /dev/null
@@ -1,3147 +0,0 @@
-#include "wm8994.h"
-
-const struct wm8994_access_mask wm8994_access_masks[WM8994_CACHE_SIZE] = {
- { 0xFFFF, 0xFFFF }, /* R0 - Software Reset */
- { 0x3B37, 0x3B37 }, /* R1 - Power Management (1) */
- { 0x6BF0, 0x6BF0 }, /* R2 - Power Management (2) */
- { 0x3FF0, 0x3FF0 }, /* R3 - Power Management (3) */
- { 0x3F3F, 0x3F3F }, /* R4 - Power Management (4) */
- { 0x3F0F, 0x3F0F }, /* R5 - Power Management (5) */
- { 0x003F, 0x003F }, /* R6 - Power Management (6) */
- { 0x0000, 0x0000 }, /* R7 */
- { 0x0000, 0x0000 }, /* R8 */
- { 0x0000, 0x0000 }, /* R9 */
- { 0x0000, 0x0000 }, /* R10 */
- { 0x0000, 0x0000 }, /* R11 */
- { 0x0000, 0x0000 }, /* R12 */
- { 0x0000, 0x0000 }, /* R13 */
- { 0x0000, 0x0000 }, /* R14 */
- { 0x0000, 0x0000 }, /* R15 */
- { 0x0000, 0x0000 }, /* R16 */
- { 0x0000, 0x0000 }, /* R17 */
- { 0x0000, 0x0000 }, /* R18 */
- { 0x0000, 0x0000 }, /* R19 */
- { 0x0000, 0x0000 }, /* R20 */
- { 0x01C0, 0x01C0 }, /* R21 - Input Mixer (1) */
- { 0x0000, 0x0000 }, /* R22 */
- { 0x0000, 0x0000 }, /* R23 */
- { 0x00DF, 0x01DF }, /* R24 - Left Line Input 1&2 Volume */
- { 0x00DF, 0x01DF }, /* R25 - Left Line Input 3&4 Volume */
- { 0x00DF, 0x01DF }, /* R26 - Right Line Input 1&2 Volume */
- { 0x00DF, 0x01DF }, /* R27 - Right Line Input 3&4 Volume */
- { 0x00FF, 0x01FF }, /* R28 - Left Output Volume */
- { 0x00FF, 0x01FF }, /* R29 - Right Output Volume */
- { 0x0077, 0x0077 }, /* R30 - Line Outputs Volume */
- { 0x0030, 0x0030 }, /* R31 - HPOUT2 Volume */
- { 0x00FF, 0x01FF }, /* R32 - Left OPGA Volume */
- { 0x00FF, 0x01FF }, /* R33 - Right OPGA Volume */
- { 0x007F, 0x007F }, /* R34 - SPKMIXL Attenuation */
- { 0x017F, 0x017F }, /* R35 - SPKMIXR Attenuation */
- { 0x003F, 0x003F }, /* R36 - SPKOUT Mixers */
- { 0x003F, 0x003F }, /* R37 - ClassD */
- { 0x00FF, 0x01FF }, /* R38 - Speaker Volume Left */
- { 0x00FF, 0x01FF }, /* R39 - Speaker Volume Right */
- { 0x00FF, 0x00FF }, /* R40 - Input Mixer (2) */
- { 0x01B7, 0x01B7 }, /* R41 - Input Mixer (3) */
- { 0x01B7, 0x01B7 }, /* R42 - Input Mixer (4) */
- { 0x01C7, 0x01C7 }, /* R43 - Input Mixer (5) */
- { 0x01C7, 0x01C7 }, /* R44 - Input Mixer (6) */
- { 0x01FF, 0x01FF }, /* R45 - Output Mixer (1) */
- { 0x01FF, 0x01FF }, /* R46 - Output Mixer (2) */
- { 0x0FFF, 0x0FFF }, /* R47 - Output Mixer (3) */
- { 0x0FFF, 0x0FFF }, /* R48 - Output Mixer (4) */
- { 0x0FFF, 0x0FFF }, /* R49 - Output Mixer (5) */
- { 0x0FFF, 0x0FFF }, /* R50 - Output Mixer (6) */
- { 0x0038, 0x0038 }, /* R51 - HPOUT2 Mixer */
- { 0x0077, 0x0077 }, /* R52 - Line Mixer (1) */
- { 0x0077, 0x0077 }, /* R53 - Line Mixer (2) */
- { 0x03FF, 0x03FF }, /* R54 - Speaker Mixer */
- { 0x00C1, 0x00C1 }, /* R55 - Additional Control */
- { 0x00F0, 0x00F0 }, /* R56 - AntiPOP (1) */
- { 0x01EF, 0x01EF }, /* R57 - AntiPOP (2) */
- { 0x00FF, 0x00FF }, /* R58 - MICBIAS */
- { 0x000F, 0x000F }, /* R59 - LDO 1 */
- { 0x0007, 0x0007 }, /* R60 - LDO 2 */
- { 0xFFFF, 0xFFFF }, /* R61 */
- { 0xFFFF, 0xFFFF }, /* R62 */
- { 0x0000, 0x0000 }, /* R63 */
- { 0x0000, 0x0000 }, /* R64 */
- { 0x0000, 0x0000 }, /* R65 */
- { 0x0000, 0x0000 }, /* R66 */
- { 0x0000, 0x0000 }, /* R67 */
- { 0x0000, 0x0000 }, /* R68 */
- { 0x0000, 0x0000 }, /* R69 */
- { 0x0000, 0x0000 }, /* R70 */
- { 0x0000, 0x0000 }, /* R71 */
- { 0x0000, 0x0000 }, /* R72 */
- { 0x0000, 0x0000 }, /* R73 */
- { 0x0000, 0x0000 }, /* R74 */
- { 0x0000, 0x0000 }, /* R75 */
- { 0x8000, 0x8000 }, /* R76 - Charge Pump (1) */
- { 0x0000, 0x0000 }, /* R77 */
- { 0x0000, 0x0000 }, /* R78 */
- { 0x0000, 0x0000 }, /* R79 */
- { 0x0000, 0x0000 }, /* R80 */
- { 0x0301, 0x0301 }, /* R81 - Class W (1) */
- { 0x0000, 0x0000 }, /* R82 */
- { 0x0000, 0x0000 }, /* R83 */
- { 0x333F, 0x333F }, /* R84 - DC Servo (1) */
- { 0x0FEF, 0x0FEF }, /* R85 - DC Servo (2) */
- { 0x0000, 0x0000 }, /* R86 */
- { 0xFFFF, 0xFFFF }, /* R87 - DC Servo (4) */
- { 0x0333, 0x0000 }, /* R88 - DC Servo Readback */
- { 0x0000, 0x0000 }, /* R89 */
- { 0x0000, 0x0000 }, /* R90 */
- { 0x0000, 0x0000 }, /* R91 */
- { 0x0000, 0x0000 }, /* R92 */
- { 0x0000, 0x0000 }, /* R93 */
- { 0x0000, 0x0000 }, /* R94 */
- { 0x0000, 0x0000 }, /* R95 */
- { 0x00EE, 0x00EE }, /* R96 - Analogue HP (1) */
- { 0x0000, 0x0000 }, /* R97 */
- { 0x0000, 0x0000 }, /* R98 */
- { 0x0000, 0x0000 }, /* R99 */
- { 0x0000, 0x0000 }, /* R100 */
- { 0x0000, 0x0000 }, /* R101 */
- { 0x0000, 0x0000 }, /* R102 */
- { 0x0000, 0x0000 }, /* R103 */
- { 0x0000, 0x0000 }, /* R104 */
- { 0x0000, 0x0000 }, /* R105 */
- { 0x0000, 0x0000 }, /* R106 */
- { 0x0000, 0x0000 }, /* R107 */
- { 0x0000, 0x0000 }, /* R108 */
- { 0x0000, 0x0000 }, /* R109 */
- { 0x0000, 0x0000 }, /* R110 */
- { 0x0000, 0x0000 }, /* R111 */
- { 0x0000, 0x0000 }, /* R112 */
- { 0x0000, 0x0000 }, /* R113 */
- { 0x0000, 0x0000 }, /* R114 */
- { 0x0000, 0x0000 }, /* R115 */
- { 0x0000, 0x0000 }, /* R116 */
- { 0x0000, 0x0000 }, /* R117 */
- { 0x0000, 0x0000 }, /* R118 */
- { 0x0000, 0x0000 }, /* R119 */
- { 0x0000, 0x0000 }, /* R120 */
- { 0x0000, 0x0000 }, /* R121 */
- { 0x0000, 0x0000 }, /* R122 */
- { 0x0000, 0x0000 }, /* R123 */
- { 0x0000, 0x0000 }, /* R124 */
- { 0x0000, 0x0000 }, /* R125 */
- { 0x0000, 0x0000 }, /* R126 */
- { 0x0000, 0x0000 }, /* R127 */
- { 0x0000, 0x0000 }, /* R128 */
- { 0x0000, 0x0000 }, /* R129 */
- { 0x0000, 0x0000 }, /* R130 */
- { 0x0000, 0x0000 }, /* R131 */
- { 0x0000, 0x0000 }, /* R132 */
- { 0x0000, 0x0000 }, /* R133 */
- { 0x0000, 0x0000 }, /* R134 */
- { 0x0000, 0x0000 }, /* R135 */
- { 0x0000, 0x0000 }, /* R136 */
- { 0x0000, 0x0000 }, /* R137 */
- { 0x0000, 0x0000 }, /* R138 */
- { 0x0000, 0x0000 }, /* R139 */
- { 0x0000, 0x0000 }, /* R140 */
- { 0x0000, 0x0000 }, /* R141 */
- { 0x0000, 0x0000 }, /* R142 */
- { 0x0000, 0x0000 }, /* R143 */
- { 0x0000, 0x0000 }, /* R144 */
- { 0x0000, 0x0000 }, /* R145 */
- { 0x0000, 0x0000 }, /* R146 */
- { 0x0000, 0x0000 }, /* R147 */
- { 0x0000, 0x0000 }, /* R148 */
- { 0x0000, 0x0000 }, /* R149 */
- { 0x0000, 0x0000 }, /* R150 */
- { 0x0000, 0x0000 }, /* R151 */
- { 0x0000, 0x0000 }, /* R152 */
- { 0x0000, 0x0000 }, /* R153 */
- { 0x0000, 0x0000 }, /* R154 */
- { 0x0000, 0x0000 }, /* R155 */
- { 0x0000, 0x0000 }, /* R156 */
- { 0x0000, 0x0000 }, /* R157 */
- { 0x0000, 0x0000 }, /* R158 */
- { 0x0000, 0x0000 }, /* R159 */
- { 0x0000, 0x0000 }, /* R160 */
- { 0x0000, 0x0000 }, /* R161 */
- { 0x0000, 0x0000 }, /* R162 */
- { 0x0000, 0x0000 }, /* R163 */
- { 0x0000, 0x0000 }, /* R164 */
- { 0x0000, 0x0000 }, /* R165 */
- { 0x0000, 0x0000 }, /* R166 */
- { 0x0000, 0x0000 }, /* R167 */
- { 0x0000, 0x0000 }, /* R168 */
- { 0x0000, 0x0000 }, /* R169 */
- { 0x0000, 0x0000 }, /* R170 */
- { 0x0000, 0x0000 }, /* R171 */
- { 0x0000, 0x0000 }, /* R172 */
- { 0x0000, 0x0000 }, /* R173 */
- { 0x0000, 0x0000 }, /* R174 */
- { 0x0000, 0x0000 }, /* R175 */
- { 0x0000, 0x0000 }, /* R176 */
- { 0x0000, 0x0000 }, /* R177 */
- { 0x0000, 0x0000 }, /* R178 */
- { 0x0000, 0x0000 }, /* R179 */
- { 0x0000, 0x0000 }, /* R180 */
- { 0x0000, 0x0000 }, /* R181 */
- { 0x0000, 0x0000 }, /* R182 */
- { 0x0000, 0x0000 }, /* R183 */
- { 0x0000, 0x0000 }, /* R184 */
- { 0x0000, 0x0000 }, /* R185 */
- { 0x0000, 0x0000 }, /* R186 */
- { 0x0000, 0x0000 }, /* R187 */
- { 0x0000, 0x0000 }, /* R188 */
- { 0x0000, 0x0000 }, /* R189 */
- { 0x0000, 0x0000 }, /* R190 */
- { 0x0000, 0x0000 }, /* R191 */
- { 0x0000, 0x0000 }, /* R192 */
- { 0x0000, 0x0000 }, /* R193 */
- { 0x0000, 0x0000 }, /* R194 */
- { 0x0000, 0x0000 }, /* R195 */
- { 0x0000, 0x0000 }, /* R196 */
- { 0x0000, 0x0000 }, /* R197 */
- { 0x0000, 0x0000 }, /* R198 */
- { 0x0000, 0x0000 }, /* R199 */
- { 0x0000, 0x0000 }, /* R200 */
- { 0x0000, 0x0000 }, /* R201 */
- { 0x0000, 0x0000 }, /* R202 */
- { 0x0000, 0x0000 }, /* R203 */
- { 0x0000, 0x0000 }, /* R204 */
- { 0x0000, 0x0000 }, /* R205 */
- { 0x0000, 0x0000 }, /* R206 */
- { 0x0000, 0x0000 }, /* R207 */
- { 0xFFFF, 0xFFFF }, /* R208 */
- { 0xFFFF, 0xFFFF }, /* R209 */
- { 0xFFFF, 0xFFFF }, /* R210 */
- { 0x0000, 0x0000 }, /* R211 */
- { 0x0000, 0x0000 }, /* R212 */
- { 0x0000, 0x0000 }, /* R213 */
- { 0x0000, 0x0000 }, /* R214 */
- { 0x0000, 0x0000 }, /* R215 */
- { 0x0000, 0x0000 }, /* R216 */
- { 0x0000, 0x0000 }, /* R217 */
- { 0x0000, 0x0000 }, /* R218 */
- { 0x0000, 0x0000 }, /* R219 */
- { 0x0000, 0x0000 }, /* R220 */
- { 0x0000, 0x0000 }, /* R221 */
- { 0x0000, 0x0000 }, /* R222 */
- { 0x0000, 0x0000 }, /* R223 */
- { 0x0000, 0x0000 }, /* R224 */
- { 0x0000, 0x0000 }, /* R225 */
- { 0x0000, 0x0000 }, /* R226 */
- { 0x0000, 0x0000 }, /* R227 */
- { 0x0000, 0x0000 }, /* R228 */
- { 0x0000, 0x0000 }, /* R229 */
- { 0x0000, 0x0000 }, /* R230 */
- { 0x0000, 0x0000 }, /* R231 */
- { 0x0000, 0x0000 }, /* R232 */
- { 0x0000, 0x0000 }, /* R233 */
- { 0x0000, 0x0000 }, /* R234 */
- { 0x0000, 0x0000 }, /* R235 */
- { 0x0000, 0x0000 }, /* R236 */
- { 0x0000, 0x0000 }, /* R237 */
- { 0x0000, 0x0000 }, /* R238 */
- { 0x0000, 0x0000 }, /* R239 */
- { 0x0000, 0x0000 }, /* R240 */
- { 0x0000, 0x0000 }, /* R241 */
- { 0x0000, 0x0000 }, /* R242 */
- { 0x0000, 0x0000 }, /* R243 */
- { 0x0000, 0x0000 }, /* R244 */
- { 0x0000, 0x0000 }, /* R245 */
- { 0x0000, 0x0000 }, /* R246 */
- { 0x0000, 0x0000 }, /* R247 */
- { 0x0000, 0x0000 }, /* R248 */
- { 0x0000, 0x0000 }, /* R249 */
- { 0x0000, 0x0000 }, /* R250 */
- { 0x0000, 0x0000 }, /* R251 */
- { 0x0000, 0x0000 }, /* R252 */
- { 0x0000, 0x0000 }, /* R253 */
- { 0x0000, 0x0000 }, /* R254 */
- { 0x0000, 0x0000 }, /* R255 */
- { 0x000F, 0x0000 }, /* R256 - Chip Revision */
- { 0x0074, 0x0074 }, /* R257 - Control Interface */
- { 0x0000, 0x0000 }, /* R258 */
- { 0x0000, 0x0000 }, /* R259 */
- { 0x0000, 0x0000 }, /* R260 */
- { 0x0000, 0x0000 }, /* R261 */
- { 0x0000, 0x0000 }, /* R262 */
- { 0x0000, 0x0000 }, /* R263 */
- { 0x0000, 0x0000 }, /* R264 */
- { 0x0000, 0x0000 }, /* R265 */
- { 0x0000, 0x0000 }, /* R266 */
- { 0x0000, 0x0000 }, /* R267 */
- { 0x0000, 0x0000 }, /* R268 */
- { 0x0000, 0x0000 }, /* R269 */
- { 0x0000, 0x0000 }, /* R270 */
- { 0x0000, 0x0000 }, /* R271 */
- { 0x807F, 0x837F }, /* R272 - Write Sequencer Ctrl (1) */
- { 0x017F, 0x0000 }, /* R273 - Write Sequencer Ctrl (2) */
- { 0x0000, 0x0000 }, /* R274 */
- { 0x0000, 0x0000 }, /* R275 */
- { 0x0000, 0x0000 }, /* R276 */
- { 0x0000, 0x0000 }, /* R277 */
- { 0x0000, 0x0000 }, /* R278 */
- { 0x0000, 0x0000 }, /* R279 */
- { 0x0000, 0x0000 }, /* R280 */
- { 0x0000, 0x0000 }, /* R281 */
- { 0x0000, 0x0000 }, /* R282 */
- { 0x0000, 0x0000 }, /* R283 */
- { 0x0000, 0x0000 }, /* R284 */
- { 0x0000, 0x0000 }, /* R285 */
- { 0x0000, 0x0000 }, /* R286 */
- { 0x0000, 0x0000 }, /* R287 */
- { 0x0000, 0x0000 }, /* R288 */
- { 0x0000, 0x0000 }, /* R289 */
- { 0x0000, 0x0000 }, /* R290 */
- { 0x0000, 0x0000 }, /* R291 */
- { 0x0000, 0x0000 }, /* R292 */
- { 0x0000, 0x0000 }, /* R293 */
- { 0x0000, 0x0000 }, /* R294 */
- { 0x0000, 0x0000 }, /* R295 */
- { 0x0000, 0x0000 }, /* R296 */
- { 0x0000, 0x0000 }, /* R297 */
- { 0x0000, 0x0000 }, /* R298 */
- { 0x0000, 0x0000 }, /* R299 */
- { 0x0000, 0x0000 }, /* R300 */
- { 0x0000, 0x0000 }, /* R301 */
- { 0x0000, 0x0000 }, /* R302 */
- { 0x0000, 0x0000 }, /* R303 */
- { 0x0000, 0x0000 }, /* R304 */
- { 0x0000, 0x0000 }, /* R305 */
- { 0x0000, 0x0000 }, /* R306 */
- { 0x0000, 0x0000 }, /* R307 */
- { 0x0000, 0x0000 }, /* R308 */
- { 0x0000, 0x0000 }, /* R309 */
- { 0x0000, 0x0000 }, /* R310 */
- { 0x0000, 0x0000 }, /* R311 */
- { 0x0000, 0x0000 }, /* R312 */
- { 0x0000, 0x0000 }, /* R313 */
- { 0x0000, 0x0000 }, /* R314 */
- { 0x0000, 0x0000 }, /* R315 */
- { 0x0000, 0x0000 }, /* R316 */
- { 0x0000, 0x0000 }, /* R317 */
- { 0x0000, 0x0000 }, /* R318 */
- { 0x0000, 0x0000 }, /* R319 */
- { 0x0000, 0x0000 }, /* R320 */
- { 0x0000, 0x0000 }, /* R321 */
- { 0x0000, 0x0000 }, /* R322 */
- { 0x0000, 0x0000 }, /* R323 */
- { 0x0000, 0x0000 }, /* R324 */
- { 0x0000, 0x0000 }, /* R325 */
- { 0x0000, 0x0000 }, /* R326 */
- { 0x0000, 0x0000 }, /* R327 */
- { 0x0000, 0x0000 }, /* R328 */
- { 0x0000, 0x0000 }, /* R329 */
- { 0x0000, 0x0000 }, /* R330 */
- { 0x0000, 0x0000 }, /* R331 */
- { 0x0000, 0x0000 }, /* R332 */
- { 0x0000, 0x0000 }, /* R333 */
- { 0x0000, 0x0000 }, /* R334 */
- { 0x0000, 0x0000 }, /* R335 */
- { 0x0000, 0x0000 }, /* R336 */
- { 0x0000, 0x0000 }, /* R337 */
- { 0x0000, 0x0000 }, /* R338 */
- { 0x0000, 0x0000 }, /* R339 */
- { 0x0000, 0x0000 }, /* R340 */
- { 0x0000, 0x0000 }, /* R341 */
- { 0x0000, 0x0000 }, /* R342 */
- { 0x0000, 0x0000 }, /* R343 */
- { 0x0000, 0x0000 }, /* R344 */
- { 0x0000, 0x0000 }, /* R345 */
- { 0x0000, 0x0000 }, /* R346 */
- { 0x0000, 0x0000 }, /* R347 */
- { 0x0000, 0x0000 }, /* R348 */
- { 0x0000, 0x0000 }, /* R349 */
- { 0x0000, 0x0000 }, /* R350 */
- { 0x0000, 0x0000 }, /* R351 */
- { 0x0000, 0x0000 }, /* R352 */
- { 0x0000, 0x0000 }, /* R353 */
- { 0x0000, 0x0000 }, /* R354 */
- { 0x0000, 0x0000 }, /* R355 */
- { 0x0000, 0x0000 }, /* R356 */
- { 0x0000, 0x0000 }, /* R357 */
- { 0x0000, 0x0000 }, /* R358 */
- { 0x0000, 0x0000 }, /* R359 */
- { 0x0000, 0x0000 }, /* R360 */
- { 0x0000, 0x0000 }, /* R361 */
- { 0x0000, 0x0000 }, /* R362 */
- { 0x0000, 0x0000 }, /* R363 */
- { 0x0000, 0x0000 }, /* R364 */
- { 0x0000, 0x0000 }, /* R365 */
- { 0x0000, 0x0000 }, /* R366 */
- { 0x0000, 0x0000 }, /* R367 */
- { 0x0000, 0x0000 }, /* R368 */
- { 0x0000, 0x0000 }, /* R369 */
- { 0x0000, 0x0000 }, /* R370 */
- { 0x0000, 0x0000 }, /* R371 */
- { 0x0000, 0x0000 }, /* R372 */
- { 0x0000, 0x0000 }, /* R373 */
- { 0x0000, 0x0000 }, /* R374 */
- { 0x0000, 0x0000 }, /* R375 */
- { 0x0000, 0x0000 }, /* R376 */
- { 0x0000, 0x0000 }, /* R377 */
- { 0x0000, 0x0000 }, /* R378 */
- { 0x0000, 0x0000 }, /* R379 */
- { 0x0000, 0x0000 }, /* R380 */
- { 0x0000, 0x0000 }, /* R381 */
- { 0x0000, 0x0000 }, /* R382 */
- { 0x0000, 0x0000 }, /* R383 */
- { 0x0000, 0x0000 }, /* R384 */
- { 0x0000, 0x0000 }, /* R385 */
- { 0x0000, 0x0000 }, /* R386 */
- { 0x0000, 0x0000 }, /* R387 */
- { 0x0000, 0x0000 }, /* R388 */
- { 0x0000, 0x0000 }, /* R389 */
- { 0x0000, 0x0000 }, /* R390 */
- { 0x0000, 0x0000 }, /* R391 */
- { 0x0000, 0x0000 }, /* R392 */
- { 0x0000, 0x0000 }, /* R393 */
- { 0x0000, 0x0000 }, /* R394 */
- { 0x0000, 0x0000 }, /* R395 */
- { 0x0000, 0x0000 }, /* R396 */
- { 0x0000, 0x0000 }, /* R397 */
- { 0x0000, 0x0000 }, /* R398 */
- { 0x0000, 0x0000 }, /* R399 */
- { 0x0000, 0x0000 }, /* R400 */
- { 0x0000, 0x0000 }, /* R401 */
- { 0x0000, 0x0000 }, /* R402 */
- { 0x0000, 0x0000 }, /* R403 */
- { 0x0000, 0x0000 }, /* R404 */
- { 0x0000, 0x0000 }, /* R405 */
- { 0x0000, 0x0000 }, /* R406 */
- { 0x0000, 0x0000 }, /* R407 */
- { 0x0000, 0x0000 }, /* R408 */
- { 0x0000, 0x0000 }, /* R409 */
- { 0x0000, 0x0000 }, /* R410 */
- { 0x0000, 0x0000 }, /* R411 */
- { 0x0000, 0x0000 }, /* R412 */
- { 0x0000, 0x0000 }, /* R413 */
- { 0x0000, 0x0000 }, /* R414 */
- { 0x0000, 0x0000 }, /* R415 */
- { 0x0000, 0x0000 }, /* R416 */
- { 0x0000, 0x0000 }, /* R417 */
- { 0x0000, 0x0000 }, /* R418 */
- { 0x0000, 0x0000 }, /* R419 */
- { 0x0000, 0x0000 }, /* R420 */
- { 0x0000, 0x0000 }, /* R421 */
- { 0x0000, 0x0000 }, /* R422 */
- { 0x0000, 0x0000 }, /* R423 */
- { 0x0000, 0x0000 }, /* R424 */
- { 0x0000, 0x0000 }, /* R425 */
- { 0x0000, 0x0000 }, /* R426 */
- { 0x0000, 0x0000 }, /* R427 */
- { 0x0000, 0x0000 }, /* R428 */
- { 0x0000, 0x0000 }, /* R429 */
- { 0x0000, 0x0000 }, /* R430 */
- { 0x0000, 0x0000 }, /* R431 */
- { 0x0000, 0x0000 }, /* R432 */
- { 0x0000, 0x0000 }, /* R433 */
- { 0x0000, 0x0000 }, /* R434 */
- { 0x0000, 0x0000 }, /* R435 */
- { 0x0000, 0x0000 }, /* R436 */
- { 0x0000, 0x0000 }, /* R437 */
- { 0x0000, 0x0000 }, /* R438 */
- { 0x0000, 0x0000 }, /* R439 */
- { 0x0000, 0x0000 }, /* R440 */
- { 0x0000, 0x0000 }, /* R441 */
- { 0x0000, 0x0000 }, /* R442 */
- { 0x0000, 0x0000 }, /* R443 */
- { 0x0000, 0x0000 }, /* R444 */
- { 0x0000, 0x0000 }, /* R445 */
- { 0x0000, 0x0000 }, /* R446 */
- { 0x0000, 0x0000 }, /* R447 */
- { 0x0000, 0x0000 }, /* R448 */
- { 0x0000, 0x0000 }, /* R449 */
- { 0x0000, 0x0000 }, /* R450 */
- { 0x0000, 0x0000 }, /* R451 */
- { 0x0000, 0x0000 }, /* R452 */
- { 0x0000, 0x0000 }, /* R453 */
- { 0x0000, 0x0000 }, /* R454 */
- { 0x0000, 0x0000 }, /* R455 */
- { 0x0000, 0x0000 }, /* R456 */
- { 0x0000, 0x0000 }, /* R457 */
- { 0x0000, 0x0000 }, /* R458 */
- { 0x0000, 0x0000 }, /* R459 */
- { 0x0000, 0x0000 }, /* R460 */
- { 0x0000, 0x0000 }, /* R461 */
- { 0x0000, 0x0000 }, /* R462 */
- { 0x0000, 0x0000 }, /* R463 */
- { 0x0000, 0x0000 }, /* R464 */
- { 0x0000, 0x0000 }, /* R465 */
- { 0x0000, 0x0000 }, /* R466 */
- { 0x0000, 0x0000 }, /* R467 */
- { 0x0000, 0x0000 }, /* R468 */
- { 0x0000, 0x0000 }, /* R469 */
- { 0x0000, 0x0000 }, /* R470 */
- { 0x0000, 0x0000 }, /* R471 */
- { 0x0000, 0x0000 }, /* R472 */
- { 0x0000, 0x0000 }, /* R473 */
- { 0x0000, 0x0000 }, /* R474 */
- { 0x0000, 0x0000 }, /* R475 */
- { 0x0000, 0x0000 }, /* R476 */
- { 0x0000, 0x0000 }, /* R477 */
- { 0x0000, 0x0000 }, /* R478 */
- { 0x0000, 0x0000 }, /* R479 */
- { 0x0000, 0x0000 }, /* R480 */
- { 0x0000, 0x0000 }, /* R481 */
- { 0x0000, 0x0000 }, /* R482 */
- { 0x0000, 0x0000 }, /* R483 */
- { 0x0000, 0x0000 }, /* R484 */
- { 0x0000, 0x0000 }, /* R485 */
- { 0x0000, 0x0000 }, /* R486 */
- { 0x0000, 0x0000 }, /* R487 */
- { 0x0000, 0x0000 }, /* R488 */
- { 0x0000, 0x0000 }, /* R489 */
- { 0x0000, 0x0000 }, /* R490 */
- { 0x0000, 0x0000 }, /* R491 */
- { 0x0000, 0x0000 }, /* R492 */
- { 0x0000, 0x0000 }, /* R493 */
- { 0x0000, 0x0000 }, /* R494 */
- { 0x0000, 0x0000 }, /* R495 */
- { 0x0000, 0x0000 }, /* R496 */
- { 0x0000, 0x0000 }, /* R497 */
- { 0x0000, 0x0000 }, /* R498 */
- { 0x0000, 0x0000 }, /* R499 */
- { 0x0000, 0x0000 }, /* R500 */
- { 0x0000, 0x0000 }, /* R501 */
- { 0x0000, 0x0000 }, /* R502 */
- { 0x0000, 0x0000 }, /* R503 */
- { 0x0000, 0x0000 }, /* R504 */
- { 0x0000, 0x0000 }, /* R505 */
- { 0x0000, 0x0000 }, /* R506 */
- { 0x0000, 0x0000 }, /* R507 */
- { 0x0000, 0x0000 }, /* R508 */
- { 0x0000, 0x0000 }, /* R509 */
- { 0x0000, 0x0000 }, /* R510 */
- { 0x0000, 0x0000 }, /* R511 */
- { 0x001F, 0x001F }, /* R512 - AIF1 Clocking (1) */
- { 0x003F, 0x003F }, /* R513 - AIF1 Clocking (2) */
- { 0x0000, 0x0000 }, /* R514 */
- { 0x0000, 0x0000 }, /* R515 */
- { 0x001F, 0x001F }, /* R516 - AIF2 Clocking (1) */
- { 0x003F, 0x003F }, /* R517 - AIF2 Clocking (2) */
- { 0x0000, 0x0000 }, /* R518 */
- { 0x0000, 0x0000 }, /* R519 */
- { 0x001F, 0x001F }, /* R520 - Clocking (1) */
- { 0x0777, 0x0777 }, /* R521 - Clocking (2) */
- { 0x0000, 0x0000 }, /* R522 */
- { 0x0000, 0x0000 }, /* R523 */
- { 0x0000, 0x0000 }, /* R524 */
- { 0x0000, 0x0000 }, /* R525 */
- { 0x0000, 0x0000 }, /* R526 */
- { 0x0000, 0x0000 }, /* R527 */
- { 0x00FF, 0x00FF }, /* R528 - AIF1 Rate */
- { 0x00FF, 0x00FF }, /* R529 - AIF2 Rate */
- { 0x000F, 0x0000 }, /* R530 - Rate Status */
- { 0x0000, 0x0000 }, /* R531 */
- { 0x0000, 0x0000 }, /* R532 */
- { 0x0000, 0x0000 }, /* R533 */
- { 0x0000, 0x0000 }, /* R534 */
- { 0x0000, 0x0000 }, /* R535 */
- { 0x0000, 0x0000 }, /* R536 */
- { 0x0000, 0x0000 }, /* R537 */
- { 0x0000, 0x0000 }, /* R538 */
- { 0x0000, 0x0000 }, /* R539 */
- { 0x0000, 0x0000 }, /* R540 */
- { 0x0000, 0x0000 }, /* R541 */
- { 0x0000, 0x0000 }, /* R542 */
- { 0x0000, 0x0000 }, /* R543 */
- { 0x0007, 0x0007 }, /* R544 - FLL1 Control (1) */
- { 0x3F77, 0x3F77 }, /* R545 - FLL1 Control (2) */
- { 0xFFFF, 0xFFFF }, /* R546 - FLL1 Control (3) */
- { 0x7FEF, 0x7FEF }, /* R547 - FLL1 Control (4) */
- { 0x1FDB, 0x1FDB }, /* R548 - FLL1 Control (5) */
- { 0x0000, 0x0000 }, /* R549 */
- { 0x0000, 0x0000 }, /* R550 */
- { 0x0000, 0x0000 }, /* R551 */
- { 0x0000, 0x0000 }, /* R552 */
- { 0x0000, 0x0000 }, /* R553 */
- { 0x0000, 0x0000 }, /* R554 */
- { 0x0000, 0x0000 }, /* R555 */
- { 0x0000, 0x0000 }, /* R556 */
- { 0x0000, 0x0000 }, /* R557 */
- { 0x0000, 0x0000 }, /* R558 */
- { 0x0000, 0x0000 }, /* R559 */
- { 0x0000, 0x0000 }, /* R560 */
- { 0x0000, 0x0000 }, /* R561 */
- { 0x0000, 0x0000 }, /* R562 */
- { 0x0000, 0x0000 }, /* R563 */
- { 0x0000, 0x0000 }, /* R564 */
- { 0x0000, 0x0000 }, /* R565 */
- { 0x0000, 0x0000 }, /* R566 */
- { 0x0000, 0x0000 }, /* R567 */
- { 0x0000, 0x0000 }, /* R568 */
- { 0x0000, 0x0000 }, /* R569 */
- { 0x0000, 0x0000 }, /* R570 */
- { 0x0000, 0x0000 }, /* R571 */
- { 0x0000, 0x0000 }, /* R572 */
- { 0x0000, 0x0000 }, /* R573 */
- { 0x0000, 0x0000 }, /* R574 */
- { 0x0000, 0x0000 }, /* R575 */
- { 0x0007, 0x0007 }, /* R576 - FLL2 Control (1) */
- { 0x3F77, 0x3F77 }, /* R577 - FLL2 Control (2) */
- { 0xFFFF, 0xFFFF }, /* R578 - FLL2 Control (3) */
- { 0x7FEF, 0x7FEF }, /* R579 - FLL2 Control (4) */
- { 0x1FDB, 0x1FDB }, /* R580 - FLL2 Control (5) */
- { 0x0000, 0x0000 }, /* R581 */
- { 0x0000, 0x0000 }, /* R582 */
- { 0x0000, 0x0000 }, /* R583 */
- { 0x0000, 0x0000 }, /* R584 */
- { 0x0000, 0x0000 }, /* R585 */
- { 0x0000, 0x0000 }, /* R586 */
- { 0x0000, 0x0000 }, /* R587 */
- { 0x0000, 0x0000 }, /* R588 */
- { 0x0000, 0x0000 }, /* R589 */
- { 0x0000, 0x0000 }, /* R590 */
- { 0x0000, 0x0000 }, /* R591 */
- { 0x0000, 0x0000 }, /* R592 */
- { 0x0000, 0x0000 }, /* R593 */
- { 0x0000, 0x0000 }, /* R594 */
- { 0x0000, 0x0000 }, /* R595 */
- { 0x0000, 0x0000 }, /* R596 */
- { 0x0000, 0x0000 }, /* R597 */
- { 0x0000, 0x0000 }, /* R598 */
- { 0x0000, 0x0000 }, /* R599 */
- { 0x0000, 0x0000 }, /* R600 */
- { 0x0000, 0x0000 }, /* R601 */
- { 0x0000, 0x0000 }, /* R602 */
- { 0x0000, 0x0000 }, /* R603 */
- { 0x0000, 0x0000 }, /* R604 */
- { 0x0000, 0x0000 }, /* R605 */
- { 0x0000, 0x0000 }, /* R606 */
- { 0x0000, 0x0000 }, /* R607 */
- { 0x0000, 0x0000 }, /* R608 */
- { 0x0000, 0x0000 }, /* R609 */
- { 0x0000, 0x0000 }, /* R610 */
- { 0x0000, 0x0000 }, /* R611 */
- { 0x0000, 0x0000 }, /* R612 */
- { 0x0000, 0x0000 }, /* R613 */
- { 0x0000, 0x0000 }, /* R614 */
- { 0x0000, 0x0000 }, /* R615 */
- { 0x0000, 0x0000 }, /* R616 */
- { 0x0000, 0x0000 }, /* R617 */
- { 0x0000, 0x0000 }, /* R618 */
- { 0x0000, 0x0000 }, /* R619 */
- { 0x0000, 0x0000 }, /* R620 */
- { 0x0000, 0x0000 }, /* R621 */
- { 0x0000, 0x0000 }, /* R622 */
- { 0x0000, 0x0000 }, /* R623 */
- { 0x0000, 0x0000 }, /* R624 */
- { 0x0000, 0x0000 }, /* R625 */
- { 0x0000, 0x0000 }, /* R626 */
- { 0x0000, 0x0000 }, /* R627 */
- { 0x0000, 0x0000 }, /* R628 */
- { 0x0000, 0x0000 }, /* R629 */
- { 0x0000, 0x0000 }, /* R630 */
- { 0x0000, 0x0000 }, /* R631 */
- { 0x0000, 0x0000 }, /* R632 */
- { 0x0000, 0x0000 }, /* R633 */
- { 0x0000, 0x0000 }, /* R634 */
- { 0x0000, 0x0000 }, /* R635 */
- { 0x0000, 0x0000 }, /* R636 */
- { 0x0000, 0x0000 }, /* R637 */
- { 0x0000, 0x0000 }, /* R638 */
- { 0x0000, 0x0000 }, /* R639 */
- { 0x0000, 0x0000 }, /* R640 */
- { 0x0000, 0x0000 }, /* R641 */
- { 0x0000, 0x0000 }, /* R642 */
- { 0x0000, 0x0000 }, /* R643 */
- { 0x0000, 0x0000 }, /* R644 */
- { 0x0000, 0x0000 }, /* R645 */
- { 0x0000, 0x0000 }, /* R646 */
- { 0x0000, 0x0000 }, /* R647 */
- { 0x0000, 0x0000 }, /* R648 */
- { 0x0000, 0x0000 }, /* R649 */
- { 0x0000, 0x0000 }, /* R650 */
- { 0x0000, 0x0000 }, /* R651 */
- { 0x0000, 0x0000 }, /* R652 */
- { 0x0000, 0x0000 }, /* R653 */
- { 0x0000, 0x0000 }, /* R654 */
- { 0x0000, 0x0000 }, /* R655 */
- { 0x0000, 0x0000 }, /* R656 */
- { 0x0000, 0x0000 }, /* R657 */
- { 0x0000, 0x0000 }, /* R658 */
- { 0x0000, 0x0000 }, /* R659 */
- { 0x0000, 0x0000 }, /* R660 */
- { 0x0000, 0x0000 }, /* R661 */
- { 0x0000, 0x0000 }, /* R662 */
- { 0x0000, 0x0000 }, /* R663 */
- { 0x0000, 0x0000 }, /* R664 */
- { 0x0000, 0x0000 }, /* R665 */
- { 0x0000, 0x0000 }, /* R666 */
- { 0x0000, 0x0000 }, /* R667 */
- { 0x0000, 0x0000 }, /* R668 */
- { 0x0000, 0x0000 }, /* R669 */
- { 0x0000, 0x0000 }, /* R670 */
- { 0x0000, 0x0000 }, /* R671 */
- { 0x0000, 0x0000 }, /* R672 */
- { 0x0000, 0x0000 }, /* R673 */
- { 0x0000, 0x0000 }, /* R674 */
- { 0x0000, 0x0000 }, /* R675 */
- { 0x0000, 0x0000 }, /* R676 */
- { 0x0000, 0x0000 }, /* R677 */
- { 0x0000, 0x0000 }, /* R678 */
- { 0x0000, 0x0000 }, /* R679 */
- { 0x0000, 0x0000 }, /* R680 */
- { 0x0000, 0x0000 }, /* R681 */
- { 0x0000, 0x0000 }, /* R682 */
- { 0x0000, 0x0000 }, /* R683 */
- { 0x0000, 0x0000 }, /* R684 */
- { 0x0000, 0x0000 }, /* R685 */
- { 0x0000, 0x0000 }, /* R686 */
- { 0x0000, 0x0000 }, /* R687 */
- { 0x0000, 0x0000 }, /* R688 */
- { 0x0000, 0x0000 }, /* R689 */
- { 0x0000, 0x0000 }, /* R690 */
- { 0x0000, 0x0000 }, /* R691 */
- { 0x0000, 0x0000 }, /* R692 */
- { 0x0000, 0x0000 }, /* R693 */
- { 0x0000, 0x0000 }, /* R694 */
- { 0x0000, 0x0000 }, /* R695 */
- { 0x0000, 0x0000 }, /* R696 */
- { 0x0000, 0x0000 }, /* R697 */
- { 0x0000, 0x0000 }, /* R698 */
- { 0x0000, 0x0000 }, /* R699 */
- { 0x0000, 0x0000 }, /* R700 */
- { 0x0000, 0x0000 }, /* R701 */
- { 0x0000, 0x0000 }, /* R702 */
- { 0x0000, 0x0000 }, /* R703 */
- { 0x0000, 0x0000 }, /* R704 */
- { 0x0000, 0x0000 }, /* R705 */
- { 0x0000, 0x0000 }, /* R706 */
- { 0x0000, 0x0000 }, /* R707 */
- { 0x0000, 0x0000 }, /* R708 */
- { 0x0000, 0x0000 }, /* R709 */
- { 0x0000, 0x0000 }, /* R710 */
- { 0x0000, 0x0000 }, /* R711 */
- { 0x0000, 0x0000 }, /* R712 */
- { 0x0000, 0x0000 }, /* R713 */
- { 0x0000, 0x0000 }, /* R714 */
- { 0x0000, 0x0000 }, /* R715 */
- { 0x0000, 0x0000 }, /* R716 */
- { 0x0000, 0x0000 }, /* R717 */
- { 0x0000, 0x0000 }, /* R718 */
- { 0x0000, 0x0000 }, /* R719 */
- { 0x0000, 0x0000 }, /* R720 */
- { 0x0000, 0x0000 }, /* R721 */
- { 0x0000, 0x0000 }, /* R722 */
- { 0x0000, 0x0000 }, /* R723 */
- { 0x0000, 0x0000 }, /* R724 */
- { 0x0000, 0x0000 }, /* R725 */
- { 0x0000, 0x0000 }, /* R726 */
- { 0x0000, 0x0000 }, /* R727 */
- { 0x0000, 0x0000 }, /* R728 */
- { 0x0000, 0x0000 }, /* R729 */
- { 0x0000, 0x0000 }, /* R730 */
- { 0x0000, 0x0000 }, /* R731 */
- { 0x0000, 0x0000 }, /* R732 */
- { 0x0000, 0x0000 }, /* R733 */
- { 0x0000, 0x0000 }, /* R734 */
- { 0x0000, 0x0000 }, /* R735 */
- { 0x0000, 0x0000 }, /* R736 */
- { 0x0000, 0x0000 }, /* R737 */
- { 0x0000, 0x0000 }, /* R738 */
- { 0x0000, 0x0000 }, /* R739 */
- { 0x0000, 0x0000 }, /* R740 */
- { 0x0000, 0x0000 }, /* R741 */
- { 0x0000, 0x0000 }, /* R742 */
- { 0x0000, 0x0000 }, /* R743 */
- { 0x0000, 0x0000 }, /* R744 */
- { 0x0000, 0x0000 }, /* R745 */
- { 0x0000, 0x0000 }, /* R746 */
- { 0x0000, 0x0000 }, /* R747 */
- { 0x0000, 0x0000 }, /* R748 */
- { 0x0000, 0x0000 }, /* R749 */
- { 0x0000, 0x0000 }, /* R750 */
- { 0x0000, 0x0000 }, /* R751 */
- { 0x0000, 0x0000 }, /* R752 */
- { 0x0000, 0x0000 }, /* R753 */
- { 0x0000, 0x0000 }, /* R754 */
- { 0x0000, 0x0000 }, /* R755 */
- { 0x0000, 0x0000 }, /* R756 */
- { 0x0000, 0x0000 }, /* R757 */
- { 0x0000, 0x0000 }, /* R758 */
- { 0x0000, 0x0000 }, /* R759 */
- { 0x0000, 0x0000 }, /* R760 */
- { 0x0000, 0x0000 }, /* R761 */
- { 0x0000, 0x0000 }, /* R762 */
- { 0x0000, 0x0000 }, /* R763 */
- { 0x0000, 0x0000 }, /* R764 */
- { 0x0000, 0x0000 }, /* R765 */
- { 0x0000, 0x0000 }, /* R766 */
- { 0x0000, 0x0000 }, /* R767 */
- { 0xE1F8, 0xE1F8 }, /* R768 - AIF1 Control (1) */
- { 0xCD1F, 0xCD1F }, /* R769 - AIF1 Control (2) */
- { 0xF000, 0xF000 }, /* R770 - AIF1 Master/Slave */
- { 0x01F0, 0x01F0 }, /* R771 - AIF1 BCLK */
- { 0x0FFF, 0x0FFF }, /* R772 - AIF1ADC LRCLK */
- { 0x0FFF, 0x0FFF }, /* R773 - AIF1DAC LRCLK */
- { 0x0003, 0x0003 }, /* R774 - AIF1DAC Data */
- { 0x0003, 0x0003 }, /* R775 - AIF1ADC Data */
- { 0x0000, 0x0000 }, /* R776 */
- { 0x0000, 0x0000 }, /* R777 */
- { 0x0000, 0x0000 }, /* R778 */
- { 0x0000, 0x0000 }, /* R779 */
- { 0x0000, 0x0000 }, /* R780 */
- { 0x0000, 0x0000 }, /* R781 */
- { 0x0000, 0x0000 }, /* R782 */
- { 0x0000, 0x0000 }, /* R783 */
- { 0xF1F8, 0xF1F8 }, /* R784 - AIF2 Control (1) */
- { 0xFD1F, 0xFD1F }, /* R785 - AIF2 Control (2) */
- { 0xF000, 0xF000 }, /* R786 - AIF2 Master/Slave */
- { 0x01F0, 0x01F0 }, /* R787 - AIF2 BCLK */
- { 0x0FFF, 0x0FFF }, /* R788 - AIF2ADC LRCLK */
- { 0x0FFF, 0x0FFF }, /* R789 - AIF2DAC LRCLK */
- { 0x0003, 0x0003 }, /* R790 - AIF2DAC Data */
- { 0x0003, 0x0003 }, /* R791 - AIF2ADC Data */
- { 0x0000, 0x0000 }, /* R792 */
- { 0x0000, 0x0000 }, /* R793 */
- { 0x0000, 0x0000 }, /* R794 */
- { 0x0000, 0x0000 }, /* R795 */
- { 0x0000, 0x0000 }, /* R796 */
- { 0x0000, 0x0000 }, /* R797 */
- { 0x0000, 0x0000 }, /* R798 */
- { 0x0000, 0x0000 }, /* R799 */
- { 0x0000, 0x0000 }, /* R800 */
- { 0x0000, 0x0000 }, /* R801 */
- { 0x0000, 0x0000 }, /* R802 */
- { 0x0000, 0x0000 }, /* R803 */
- { 0x0000, 0x0000 }, /* R804 */
- { 0x0000, 0x0000 }, /* R805 */
- { 0x0000, 0x0000 }, /* R806 */
- { 0x0000, 0x0000 }, /* R807 */
- { 0x0000, 0x0000 }, /* R808 */
- { 0x0000, 0x0000 }, /* R809 */
- { 0x0000, 0x0000 }, /* R810 */
- { 0x0000, 0x0000 }, /* R811 */
- { 0x0000, 0x0000 }, /* R812 */
- { 0x0000, 0x0000 }, /* R813 */
- { 0x0000, 0x0000 }, /* R814 */
- { 0x0000, 0x0000 }, /* R815 */
- { 0x0000, 0x0000 }, /* R816 */
- { 0x0000, 0x0000 }, /* R817 */
- { 0x0000, 0x0000 }, /* R818 */
- { 0x0000, 0x0000 }, /* R819 */
- { 0x0000, 0x0000 }, /* R820 */
- { 0x0000, 0x0000 }, /* R821 */
- { 0x0000, 0x0000 }, /* R822 */
- { 0x0000, 0x0000 }, /* R823 */
- { 0x0000, 0x0000 }, /* R824 */
- { 0x0000, 0x0000 }, /* R825 */
- { 0x0000, 0x0000 }, /* R826 */
- { 0x0000, 0x0000 }, /* R827 */
- { 0x0000, 0x0000 }, /* R828 */
- { 0x0000, 0x0000 }, /* R829 */
- { 0x0000, 0x0000 }, /* R830 */
- { 0x0000, 0x0000 }, /* R831 */
- { 0x0000, 0x0000 }, /* R832 */
- { 0x0000, 0x0000 }, /* R833 */
- { 0x0000, 0x0000 }, /* R834 */
- { 0x0000, 0x0000 }, /* R835 */
- { 0x0000, 0x0000 }, /* R836 */
- { 0x0000, 0x0000 }, /* R837 */
- { 0x0000, 0x0000 }, /* R838 */
- { 0x0000, 0x0000 }, /* R839 */
- { 0x0000, 0x0000 }, /* R840 */
- { 0x0000, 0x0000 }, /* R841 */
- { 0x0000, 0x0000 }, /* R842 */
- { 0x0000, 0x0000 }, /* R843 */
- { 0x0000, 0x0000 }, /* R844 */
- { 0x0000, 0x0000 }, /* R845 */
- { 0x0000, 0x0000 }, /* R846 */
- { 0x0000, 0x0000 }, /* R847 */
- { 0x0000, 0x0000 }, /* R848 */
- { 0x0000, 0x0000 }, /* R849 */
- { 0x0000, 0x0000 }, /* R850 */
- { 0x0000, 0x0000 }, /* R851 */
- { 0x0000, 0x0000 }, /* R852 */
- { 0x0000, 0x0000 }, /* R853 */
- { 0x0000, 0x0000 }, /* R854 */
- { 0x0000, 0x0000 }, /* R855 */
- { 0x0000, 0x0000 }, /* R856 */
- { 0x0000, 0x0000 }, /* R857 */
- { 0x0000, 0x0000 }, /* R858 */
- { 0x0000, 0x0000 }, /* R859 */
- { 0x0000, 0x0000 }, /* R860 */
- { 0x0000, 0x0000 }, /* R861 */
- { 0x0000, 0x0000 }, /* R862 */
- { 0x0000, 0x0000 }, /* R863 */
- { 0x0000, 0x0000 }, /* R864 */
- { 0x0000, 0x0000 }, /* R865 */
- { 0x0000, 0x0000 }, /* R866 */
- { 0x0000, 0x0000 }, /* R867 */
- { 0x0000, 0x0000 }, /* R868 */
- { 0x0000, 0x0000 }, /* R869 */
- { 0x0000, 0x0000 }, /* R870 */
- { 0x0000, 0x0000 }, /* R871 */
- { 0x0000, 0x0000 }, /* R872 */
- { 0x0000, 0x0000 }, /* R873 */
- { 0x0000, 0x0000 }, /* R874 */
- { 0x0000, 0x0000 }, /* R875 */
- { 0x0000, 0x0000 }, /* R876 */
- { 0x0000, 0x0000 }, /* R877 */
- { 0x0000, 0x0000 }, /* R878 */
- { 0x0000, 0x0000 }, /* R879 */
- { 0x0000, 0x0000 }, /* R880 */
- { 0x0000, 0x0000 }, /* R881 */
- { 0x0000, 0x0000 }, /* R882 */
- { 0x0000, 0x0000 }, /* R883 */
- { 0x0000, 0x0000 }, /* R884 */
- { 0x0000, 0x0000 }, /* R885 */
- { 0x0000, 0x0000 }, /* R886 */
- { 0x0000, 0x0000 }, /* R887 */
- { 0x0000, 0x0000 }, /* R888 */
- { 0x0000, 0x0000 }, /* R889 */
- { 0x0000, 0x0000 }, /* R890 */
- { 0x0000, 0x0000 }, /* R891 */
- { 0x0000, 0x0000 }, /* R892 */
- { 0x0000, 0x0000 }, /* R893 */
- { 0x0000, 0x0000 }, /* R894 */
- { 0x0000, 0x0000 }, /* R895 */
- { 0x0000, 0x0000 }, /* R896 */
- { 0x0000, 0x0000 }, /* R897 */
- { 0x0000, 0x0000 }, /* R898 */
- { 0x0000, 0x0000 }, /* R899 */
- { 0x0000, 0x0000 }, /* R900 */
- { 0x0000, 0x0000 }, /* R901 */
- { 0x0000, 0x0000 }, /* R902 */
- { 0x0000, 0x0000 }, /* R903 */
- { 0x0000, 0x0000 }, /* R904 */
- { 0x0000, 0x0000 }, /* R905 */
- { 0x0000, 0x0000 }, /* R906 */
- { 0x0000, 0x0000 }, /* R907 */
- { 0x0000, 0x0000 }, /* R908 */
- { 0x0000, 0x0000 }, /* R909 */
- { 0x0000, 0x0000 }, /* R910 */
- { 0x0000, 0x0000 }, /* R911 */
- { 0x0000, 0x0000 }, /* R912 */
- { 0x0000, 0x0000 }, /* R913 */
- { 0x0000, 0x0000 }, /* R914 */
- { 0x0000, 0x0000 }, /* R915 */
- { 0x0000, 0x0000 }, /* R916 */
- { 0x0000, 0x0000 }, /* R917 */
- { 0x0000, 0x0000 }, /* R918 */
- { 0x0000, 0x0000 }, /* R919 */
- { 0x0000, 0x0000 }, /* R920 */
- { 0x0000, 0x0000 }, /* R921 */
- { 0x0000, 0x0000 }, /* R922 */
- { 0x0000, 0x0000 }, /* R923 */
- { 0x0000, 0x0000 }, /* R924 */
- { 0x0000, 0x0000 }, /* R925 */
- { 0x0000, 0x0000 }, /* R926 */
- { 0x0000, 0x0000 }, /* R927 */
- { 0x0000, 0x0000 }, /* R928 */
- { 0x0000, 0x0000 }, /* R929 */
- { 0x0000, 0x0000 }, /* R930 */
- { 0x0000, 0x0000 }, /* R931 */
- { 0x0000, 0x0000 }, /* R932 */
- { 0x0000, 0x0000 }, /* R933 */
- { 0x0000, 0x0000 }, /* R934 */
- { 0x0000, 0x0000 }, /* R935 */
- { 0x0000, 0x0000 }, /* R936 */
- { 0x0000, 0x0000 }, /* R937 */
- { 0x0000, 0x0000 }, /* R938 */
- { 0x0000, 0x0000 }, /* R939 */
- { 0x0000, 0x0000 }, /* R940 */
- { 0x0000, 0x0000 }, /* R941 */
- { 0x0000, 0x0000 }, /* R942 */
- { 0x0000, 0x0000 }, /* R943 */
- { 0x0000, 0x0000 }, /* R944 */
- { 0x0000, 0x0000 }, /* R945 */
- { 0x0000, 0x0000 }, /* R946 */
- { 0x0000, 0x0000 }, /* R947 */
- { 0x0000, 0x0000 }, /* R948 */
- { 0x0000, 0x0000 }, /* R949 */
- { 0x0000, 0x0000 }, /* R950 */
- { 0x0000, 0x0000 }, /* R951 */
- { 0x0000, 0x0000 }, /* R952 */
- { 0x0000, 0x0000 }, /* R953 */
- { 0x0000, 0x0000 }, /* R954 */
- { 0x0000, 0x0000 }, /* R955 */
- { 0x0000, 0x0000 }, /* R956 */
- { 0x0000, 0x0000 }, /* R957 */
- { 0x0000, 0x0000 }, /* R958 */
- { 0x0000, 0x0000 }, /* R959 */
- { 0x0000, 0x0000 }, /* R960 */
- { 0x0000, 0x0000 }, /* R961 */
- { 0x0000, 0x0000 }, /* R962 */
- { 0x0000, 0x0000 }, /* R963 */
- { 0x0000, 0x0000 }, /* R964 */
- { 0x0000, 0x0000 }, /* R965 */
- { 0x0000, 0x0000 }, /* R966 */
- { 0x0000, 0x0000 }, /* R967 */
- { 0x0000, 0x0000 }, /* R968 */
- { 0x0000, 0x0000 }, /* R969 */
- { 0x0000, 0x0000 }, /* R970 */
- { 0x0000, 0x0000 }, /* R971 */
- { 0x0000, 0x0000 }, /* R972 */
- { 0x0000, 0x0000 }, /* R973 */
- { 0x0000, 0x0000 }, /* R974 */
- { 0x0000, 0x0000 }, /* R975 */
- { 0x0000, 0x0000 }, /* R976 */
- { 0x0000, 0x0000 }, /* R977 */
- { 0x0000, 0x0000 }, /* R978 */
- { 0x0000, 0x0000 }, /* R979 */
- { 0x0000, 0x0000 }, /* R980 */
- { 0x0000, 0x0000 }, /* R981 */
- { 0x0000, 0x0000 }, /* R982 */
- { 0x0000, 0x0000 }, /* R983 */
- { 0x0000, 0x0000 }, /* R984 */
- { 0x0000, 0x0000 }, /* R985 */
- { 0x0000, 0x0000 }, /* R986 */
- { 0x0000, 0x0000 }, /* R987 */
- { 0x0000, 0x0000 }, /* R988 */
- { 0x0000, 0x0000 }, /* R989 */
- { 0x0000, 0x0000 }, /* R990 */
- { 0x0000, 0x0000 }, /* R991 */
- { 0x0000, 0x0000 }, /* R992 */
- { 0x0000, 0x0000 }, /* R993 */
- { 0x0000, 0x0000 }, /* R994 */
- { 0x0000, 0x0000 }, /* R995 */
- { 0x0000, 0x0000 }, /* R996 */
- { 0x0000, 0x0000 }, /* R997 */
- { 0x0000, 0x0000 }, /* R998 */
- { 0x0000, 0x0000 }, /* R999 */
- { 0x0000, 0x0000 }, /* R1000 */
- { 0x0000, 0x0000 }, /* R1001 */
- { 0x0000, 0x0000 }, /* R1002 */
- { 0x0000, 0x0000 }, /* R1003 */
- { 0x0000, 0x0000 }, /* R1004 */
- { 0x0000, 0x0000 }, /* R1005 */
- { 0x0000, 0x0000 }, /* R1006 */
- { 0x0000, 0x0000 }, /* R1007 */
- { 0x0000, 0x0000 }, /* R1008 */
- { 0x0000, 0x0000 }, /* R1009 */
- { 0x0000, 0x0000 }, /* R1010 */
- { 0x0000, 0x0000 }, /* R1011 */
- { 0x0000, 0x0000 }, /* R1012 */
- { 0x0000, 0x0000 }, /* R1013 */
- { 0x0000, 0x0000 }, /* R1014 */
- { 0x0000, 0x0000 }, /* R1015 */
- { 0x0000, 0x0000 }, /* R1016 */
- { 0x0000, 0x0000 }, /* R1017 */
- { 0x0000, 0x0000 }, /* R1018 */
- { 0x0000, 0x0000 }, /* R1019 */
- { 0x0000, 0x0000 }, /* R1020 */
- { 0x0000, 0x0000 }, /* R1021 */
- { 0x0000, 0x0000 }, /* R1022 */
- { 0x0000, 0x0000 }, /* R1023 */
- { 0x00FF, 0x01FF }, /* R1024 - AIF1 ADC1 Left Volume */
- { 0x00FF, 0x01FF }, /* R1025 - AIF1 ADC1 Right Volume */
- { 0x00FF, 0x01FF }, /* R1026 - AIF1 DAC1 Left Volume */
- { 0x00FF, 0x01FF }, /* R1027 - AIF1 DAC1 Right Volume */
- { 0x00FF, 0x01FF }, /* R1028 - AIF1 ADC2 Left Volume */
- { 0x00FF, 0x01FF }, /* R1029 - AIF1 ADC2 Right Volume */
- { 0x00FF, 0x01FF }, /* R1030 - AIF1 DAC2 Left Volume */
- { 0x00FF, 0x01FF }, /* R1031 - AIF1 DAC2 Right Volume */
- { 0x0000, 0x0000 }, /* R1032 */
- { 0x0000, 0x0000 }, /* R1033 */
- { 0x0000, 0x0000 }, /* R1034 */
- { 0x0000, 0x0000 }, /* R1035 */
- { 0x0000, 0x0000 }, /* R1036 */
- { 0x0000, 0x0000 }, /* R1037 */
- { 0x0000, 0x0000 }, /* R1038 */
- { 0x0000, 0x0000 }, /* R1039 */
- { 0xF800, 0xF800 }, /* R1040 - AIF1 ADC1 Filters */
- { 0x7800, 0x7800 }, /* R1041 - AIF1 ADC2 Filters */
- { 0x0000, 0x0000 }, /* R1042 */
- { 0x0000, 0x0000 }, /* R1043 */
- { 0x0000, 0x0000 }, /* R1044 */
- { 0x0000, 0x0000 }, /* R1045 */
- { 0x0000, 0x0000 }, /* R1046 */
- { 0x0000, 0x0000 }, /* R1047 */
- { 0x0000, 0x0000 }, /* R1048 */
- { 0x0000, 0x0000 }, /* R1049 */
- { 0x0000, 0x0000 }, /* R1050 */
- { 0x0000, 0x0000 }, /* R1051 */
- { 0x0000, 0x0000 }, /* R1052 */
- { 0x0000, 0x0000 }, /* R1053 */
- { 0x0000, 0x0000 }, /* R1054 */
- { 0x0000, 0x0000 }, /* R1055 */
- { 0x02B6, 0x02B6 }, /* R1056 - AIF1 DAC1 Filters (1) */
- { 0x3F00, 0x3F00 }, /* R1057 - AIF1 DAC1 Filters (2) */
- { 0x02B6, 0x02B6 }, /* R1058 - AIF1 DAC2 Filters (1) */
- { 0x3F00, 0x3F00 }, /* R1059 - AIF1 DAC2 Filters (2) */
- { 0x0000, 0x0000 }, /* R1060 */
- { 0x0000, 0x0000 }, /* R1061 */
- { 0x0000, 0x0000 }, /* R1062 */
- { 0x0000, 0x0000 }, /* R1063 */
- { 0x0000, 0x0000 }, /* R1064 */
- { 0x0000, 0x0000 }, /* R1065 */
- { 0x0000, 0x0000 }, /* R1066 */
- { 0x0000, 0x0000 }, /* R1067 */
- { 0x0000, 0x0000 }, /* R1068 */
- { 0x0000, 0x0000 }, /* R1069 */
- { 0x0000, 0x0000 }, /* R1070 */
- { 0x0000, 0x0000 }, /* R1071 */
- { 0x006F, 0x006F }, /* R1072 - AIF1 DAC1 Noise Gate */
- { 0x006F, 0x006F }, /* R1073 - AIF1 DAC2 Noise Gate */
- { 0x0000, 0x0000 }, /* R1074 */
- { 0x0000, 0x0000 }, /* R1075 */
- { 0x0000, 0x0000 }, /* R1076 */
- { 0x0000, 0x0000 }, /* R1077 */
- { 0x0000, 0x0000 }, /* R1078 */
- { 0x0000, 0x0000 }, /* R1079 */
- { 0x0000, 0x0000 }, /* R1080 */
- { 0x0000, 0x0000 }, /* R1081 */
- { 0x0000, 0x0000 }, /* R1082 */
- { 0x0000, 0x0000 }, /* R1083 */
- { 0x0000, 0x0000 }, /* R1084 */
- { 0x0000, 0x0000 }, /* R1085 */
- { 0x0000, 0x0000 }, /* R1086 */
- { 0x0000, 0x0000 }, /* R1087 */
- { 0xFFFF, 0xFFFF }, /* R1088 - AIF1 DRC1 (1) */
- { 0x1FFF, 0x1FFF }, /* R1089 - AIF1 DRC1 (2) */
- { 0xFFFF, 0xFFFF }, /* R1090 - AIF1 DRC1 (3) */
- { 0x07FF, 0x07FF }, /* R1091 - AIF1 DRC1 (4) */
- { 0x03FF, 0x03FF }, /* R1092 - AIF1 DRC1 (5) */
- { 0x0000, 0x0000 }, /* R1093 */
- { 0x0000, 0x0000 }, /* R1094 */
- { 0x0000, 0x0000 }, /* R1095 */
- { 0x0000, 0x0000 }, /* R1096 */
- { 0x0000, 0x0000 }, /* R1097 */
- { 0x0000, 0x0000 }, /* R1098 */
- { 0x0000, 0x0000 }, /* R1099 */
- { 0x0000, 0x0000 }, /* R1100 */
- { 0x0000, 0x0000 }, /* R1101 */
- { 0x0000, 0x0000 }, /* R1102 */
- { 0x0000, 0x0000 }, /* R1103 */
- { 0xFFFF, 0xFFFF }, /* R1104 - AIF1 DRC2 (1) */
- { 0x1FFF, 0x1FFF }, /* R1105 - AIF1 DRC2 (2) */
- { 0xFFFF, 0xFFFF }, /* R1106 - AIF1 DRC2 (3) */
- { 0x07FF, 0x07FF }, /* R1107 - AIF1 DRC2 (4) */
- { 0x03FF, 0x03FF }, /* R1108 - AIF1 DRC2 (5) */
- { 0x0000, 0x0000 }, /* R1109 */
- { 0x0000, 0x0000 }, /* R1110 */
- { 0x0000, 0x0000 }, /* R1111 */
- { 0x0000, 0x0000 }, /* R1112 */
- { 0x0000, 0x0000 }, /* R1113 */
- { 0x0000, 0x0000 }, /* R1114 */
- { 0x0000, 0x0000 }, /* R1115 */
- { 0x0000, 0x0000 }, /* R1116 */
- { 0x0000, 0x0000 }, /* R1117 */
- { 0x0000, 0x0000 }, /* R1118 */
- { 0x0000, 0x0000 }, /* R1119 */
- { 0x0000, 0x0000 }, /* R1120 */
- { 0x0000, 0x0000 }, /* R1121 */
- { 0x0000, 0x0000 }, /* R1122 */
- { 0x0000, 0x0000 }, /* R1123 */
- { 0x0000, 0x0000 }, /* R1124 */
- { 0x0000, 0x0000 }, /* R1125 */
- { 0x0000, 0x0000 }, /* R1126 */
- { 0x0000, 0x0000 }, /* R1127 */
- { 0x0000, 0x0000 }, /* R1128 */
- { 0x0000, 0x0000 }, /* R1129 */
- { 0x0000, 0x0000 }, /* R1130 */
- { 0x0000, 0x0000 }, /* R1131 */
- { 0x0000, 0x0000 }, /* R1132 */
- { 0x0000, 0x0000 }, /* R1133 */
- { 0x0000, 0x0000 }, /* R1134 */
- { 0x0000, 0x0000 }, /* R1135 */
- { 0x0000, 0x0000 }, /* R1136 */
- { 0x0000, 0x0000 }, /* R1137 */
- { 0x0000, 0x0000 }, /* R1138 */
- { 0x0000, 0x0000 }, /* R1139 */
- { 0x0000, 0x0000 }, /* R1140 */
- { 0x0000, 0x0000 }, /* R1141 */
- { 0x0000, 0x0000 }, /* R1142 */
- { 0x0000, 0x0000 }, /* R1143 */
- { 0x0000, 0x0000 }, /* R1144 */
- { 0x0000, 0x0000 }, /* R1145 */
- { 0x0000, 0x0000 }, /* R1146 */
- { 0x0000, 0x0000 }, /* R1147 */
- { 0x0000, 0x0000 }, /* R1148 */
- { 0x0000, 0x0000 }, /* R1149 */
- { 0x0000, 0x0000 }, /* R1150 */
- { 0x0000, 0x0000 }, /* R1151 */
- { 0xFFFF, 0xFFFF }, /* R1152 - AIF1 DAC1 EQ Gains (1) */
- { 0xFFC0, 0xFFC0 }, /* R1153 - AIF1 DAC1 EQ Gains (2) */
- { 0xFFFF, 0xFFFF }, /* R1154 - AIF1 DAC1 EQ Band 1 A */
- { 0xFFFF, 0xFFFF }, /* R1155 - AIF1 DAC1 EQ Band 1 B */
- { 0xFFFF, 0xFFFF }, /* R1156 - AIF1 DAC1 EQ Band 1 PG */
- { 0xFFFF, 0xFFFF }, /* R1157 - AIF1 DAC1 EQ Band 2 A */
- { 0xFFFF, 0xFFFF }, /* R1158 - AIF1 DAC1 EQ Band 2 B */
- { 0xFFFF, 0xFFFF }, /* R1159 - AIF1 DAC1 EQ Band 2 C */
- { 0xFFFF, 0xFFFF }, /* R1160 - AIF1 DAC1 EQ Band 2 PG */
- { 0xFFFF, 0xFFFF }, /* R1161 - AIF1 DAC1 EQ Band 3 A */
- { 0xFFFF, 0xFFFF }, /* R1162 - AIF1 DAC1 EQ Band 3 B */
- { 0xFFFF, 0xFFFF }, /* R1163 - AIF1 DAC1 EQ Band 3 C */
- { 0xFFFF, 0xFFFF }, /* R1164 - AIF1 DAC1 EQ Band 3 PG */
- { 0xFFFF, 0xFFFF }, /* R1165 - AIF1 DAC1 EQ Band 4 A */
- { 0xFFFF, 0xFFFF }, /* R1166 - AIF1 DAC1 EQ Band 4 B */
- { 0xFFFF, 0xFFFF }, /* R1167 - AIF1 DAC1 EQ Band 4 C */
- { 0xFFFF, 0xFFFF }, /* R1168 - AIF1 DAC1 EQ Band 4 PG */
- { 0xFFFF, 0xFFFF }, /* R1169 - AIF1 DAC1 EQ Band 5 A */
- { 0xFFFF, 0xFFFF }, /* R1170 - AIF1 DAC1 EQ Band 5 B */
- { 0xFFFF, 0xFFFF }, /* R1171 - AIF1 DAC1 EQ Band 5 PG */
- { 0x0000, 0x0000 }, /* R1172 */
- { 0x0000, 0x0000 }, /* R1173 */
- { 0x0000, 0x0000 }, /* R1174 */
- { 0x0000, 0x0000 }, /* R1175 */
- { 0x0000, 0x0000 }, /* R1176 */
- { 0x0000, 0x0000 }, /* R1177 */
- { 0x0000, 0x0000 }, /* R1178 */
- { 0x0000, 0x0000 }, /* R1179 */
- { 0x0000, 0x0000 }, /* R1180 */
- { 0x0000, 0x0000 }, /* R1181 */
- { 0x0000, 0x0000 }, /* R1182 */
- { 0x0000, 0x0000 }, /* R1183 */
- { 0xFFFF, 0xFFFF }, /* R1184 - AIF1 DAC2 EQ Gains (1) */
- { 0xFFC0, 0xFFC0 }, /* R1185 - AIF1 DAC2 EQ Gains (2) */
- { 0xFFFF, 0xFFFF }, /* R1186 - AIF1 DAC2 EQ Band 1 A */
- { 0xFFFF, 0xFFFF }, /* R1187 - AIF1 DAC2 EQ Band 1 B */
- { 0xFFFF, 0xFFFF }, /* R1188 - AIF1 DAC2 EQ Band 1 PG */
- { 0xFFFF, 0xFFFF }, /* R1189 - AIF1 DAC2 EQ Band 2 A */
- { 0xFFFF, 0xFFFF }, /* R1190 - AIF1 DAC2 EQ Band 2 B */
- { 0xFFFF, 0xFFFF }, /* R1191 - AIF1 DAC2 EQ Band 2 C */
- { 0xFFFF, 0xFFFF }, /* R1192 - AIF1 DAC2 EQ Band 2 PG */
- { 0xFFFF, 0xFFFF }, /* R1193 - AIF1 DAC2 EQ Band 3 A */
- { 0xFFFF, 0xFFFF }, /* R1194 - AIF1 DAC2 EQ Band 3 B */
- { 0xFFFF, 0xFFFF }, /* R1195 - AIF1 DAC2 EQ Band 3 C */
- { 0xFFFF, 0xFFFF }, /* R1196 - AIF1 DAC2 EQ Band 3 PG */
- { 0xFFFF, 0xFFFF }, /* R1197 - AIF1 DAC2 EQ Band 4 A */
- { 0xFFFF, 0xFFFF }, /* R1198 - AIF1 DAC2 EQ Band 4 B */
- { 0xFFFF, 0xFFFF }, /* R1199 - AIF1 DAC2 EQ Band 4 C */
- { 0xFFFF, 0xFFFF }, /* R1200 - AIF1 DAC2 EQ Band 4 PG */
- { 0xFFFF, 0xFFFF }, /* R1201 - AIF1 DAC2 EQ Band 5 A */
- { 0xFFFF, 0xFFFF }, /* R1202 - AIF1 DAC2 EQ Band 5 B */
- { 0xFFFF, 0xFFFF }, /* R1203 - AIF1 DAC2 EQ Band 5 PG */
- { 0x0000, 0x0000 }, /* R1204 */
- { 0x0000, 0x0000 }, /* R1205 */
- { 0x0000, 0x0000 }, /* R1206 */
- { 0x0000, 0x0000 }, /* R1207 */
- { 0x0000, 0x0000 }, /* R1208 */
- { 0x0000, 0x0000 }, /* R1209 */
- { 0x0000, 0x0000 }, /* R1210 */
- { 0x0000, 0x0000 }, /* R1211 */
- { 0x0000, 0x0000 }, /* R1212 */
- { 0x0000, 0x0000 }, /* R1213 */
- { 0x0000, 0x0000 }, /* R1214 */
- { 0x0000, 0x0000 }, /* R1215 */
- { 0x0000, 0x0000 }, /* R1216 */
- { 0x0000, 0x0000 }, /* R1217 */
- { 0x0000, 0x0000 }, /* R1218 */
- { 0x0000, 0x0000 }, /* R1219 */
- { 0x0000, 0x0000 }, /* R1220 */
- { 0x0000, 0x0000 }, /* R1221 */
- { 0x0000, 0x0000 }, /* R1222 */
- { 0x0000, 0x0000 }, /* R1223 */
- { 0x0000, 0x0000 }, /* R1224 */
- { 0x0000, 0x0000 }, /* R1225 */
- { 0x0000, 0x0000 }, /* R1226 */
- { 0x0000, 0x0000 }, /* R1227 */
- { 0x0000, 0x0000 }, /* R1228 */
- { 0x0000, 0x0000 }, /* R1229 */
- { 0x0000, 0x0000 }, /* R1230 */
- { 0x0000, 0x0000 }, /* R1231 */
- { 0x0000, 0x0000 }, /* R1232 */
- { 0x0000, 0x0000 }, /* R1233 */
- { 0x0000, 0x0000 }, /* R1234 */
- { 0x0000, 0x0000 }, /* R1235 */
- { 0x0000, 0x0000 }, /* R1236 */
- { 0x0000, 0x0000 }, /* R1237 */
- { 0x0000, 0x0000 }, /* R1238 */
- { 0x0000, 0x0000 }, /* R1239 */
- { 0x0000, 0x0000 }, /* R1240 */
- { 0x0000, 0x0000 }, /* R1241 */
- { 0x0000, 0x0000 }, /* R1242 */
- { 0x0000, 0x0000 }, /* R1243 */
- { 0x0000, 0x0000 }, /* R1244 */
- { 0x0000, 0x0000 }, /* R1245 */
- { 0x0000, 0x0000 }, /* R1246 */
- { 0x0000, 0x0000 }, /* R1247 */
- { 0x0000, 0x0000 }, /* R1248 */
- { 0x0000, 0x0000 }, /* R1249 */
- { 0x0000, 0x0000 }, /* R1250 */
- { 0x0000, 0x0000 }, /* R1251 */
- { 0x0000, 0x0000 }, /* R1252 */
- { 0x0000, 0x0000 }, /* R1253 */
- { 0x0000, 0x0000 }, /* R1254 */
- { 0x0000, 0x0000 }, /* R1255 */
- { 0x0000, 0x0000 }, /* R1256 */
- { 0x0000, 0x0000 }, /* R1257 */
- { 0x0000, 0x0000 }, /* R1258 */
- { 0x0000, 0x0000 }, /* R1259 */
- { 0x0000, 0x0000 }, /* R1260 */
- { 0x0000, 0x0000 }, /* R1261 */
- { 0x0000, 0x0000 }, /* R1262 */
- { 0x0000, 0x0000 }, /* R1263 */
- { 0x0000, 0x0000 }, /* R1264 */
- { 0x0000, 0x0000 }, /* R1265 */
- { 0x0000, 0x0000 }, /* R1266 */
- { 0x0000, 0x0000 }, /* R1267 */
- { 0x0000, 0x0000 }, /* R1268 */
- { 0x0000, 0x0000 }, /* R1269 */
- { 0x0000, 0x0000 }, /* R1270 */
- { 0x0000, 0x0000 }, /* R1271 */
- { 0x0000, 0x0000 }, /* R1272 */
- { 0x0000, 0x0000 }, /* R1273 */
- { 0x0000, 0x0000 }, /* R1274 */
- { 0x0000, 0x0000 }, /* R1275 */
- { 0x0000, 0x0000 }, /* R1276 */
- { 0x0000, 0x0000 }, /* R1277 */
- { 0x0000, 0x0000 }, /* R1278 */
- { 0x0000, 0x0000 }, /* R1279 */
- { 0x00FF, 0x01FF }, /* R1280 - AIF2 ADC Left Volume */
- { 0x00FF, 0x01FF }, /* R1281 - AIF2 ADC Right Volume */
- { 0x00FF, 0x01FF }, /* R1282 - AIF2 DAC Left Volume */
- { 0x00FF, 0x01FF }, /* R1283 - AIF2 DAC Right Volume */
- { 0x0000, 0x0000 }, /* R1284 */
- { 0x0000, 0x0000 }, /* R1285 */
- { 0x0000, 0x0000 }, /* R1286 */
- { 0x0000, 0x0000 }, /* R1287 */
- { 0x0000, 0x0000 }, /* R1288 */
- { 0x0000, 0x0000 }, /* R1289 */
- { 0x0000, 0x0000 }, /* R1290 */
- { 0x0000, 0x0000 }, /* R1291 */
- { 0x0000, 0x0000 }, /* R1292 */
- { 0x0000, 0x0000 }, /* R1293 */
- { 0x0000, 0x0000 }, /* R1294 */
- { 0x0000, 0x0000 }, /* R1295 */
- { 0xF800, 0xF800 }, /* R1296 - AIF2 ADC Filters */
- { 0x0000, 0x0000 }, /* R1297 */
- { 0x0000, 0x0000 }, /* R1298 */
- { 0x0000, 0x0000 }, /* R1299 */
- { 0x0000, 0x0000 }, /* R1300 */
- { 0x0000, 0x0000 }, /* R1301 */
- { 0x0000, 0x0000 }, /* R1302 */
- { 0x0000, 0x0000 }, /* R1303 */
- { 0x0000, 0x0000 }, /* R1304 */
- { 0x0000, 0x0000 }, /* R1305 */
- { 0x0000, 0x0000 }, /* R1306 */
- { 0x0000, 0x0000 }, /* R1307 */
- { 0x0000, 0x0000 }, /* R1308 */
- { 0x0000, 0x0000 }, /* R1309 */
- { 0x0000, 0x0000 }, /* R1310 */
- { 0x0000, 0x0000 }, /* R1311 */
- { 0x02B6, 0x02B6 }, /* R1312 - AIF2 DAC Filters (1) */
- { 0x3F00, 0x3F00 }, /* R1313 - AIF2 DAC Filters (2) */
- { 0x0000, 0x0000 }, /* R1314 */
- { 0x0000, 0x0000 }, /* R1315 */
- { 0x0000, 0x0000 }, /* R1316 */
- { 0x0000, 0x0000 }, /* R1317 */
- { 0x0000, 0x0000 }, /* R1318 */
- { 0x0000, 0x0000 }, /* R1319 */
- { 0x0000, 0x0000 }, /* R1320 */
- { 0x0000, 0x0000 }, /* R1321 */
- { 0x0000, 0x0000 }, /* R1322 */
- { 0x0000, 0x0000 }, /* R1323 */
- { 0x0000, 0x0000 }, /* R1324 */
- { 0x0000, 0x0000 }, /* R1325 */
- { 0x0000, 0x0000 }, /* R1326 */
- { 0x0000, 0x0000 }, /* R1327 */
- { 0x006F, 0x006F }, /* R1328 - AIF2 DAC Noise Gate */
- { 0x0000, 0x0000 }, /* R1329 */
- { 0x0000, 0x0000 }, /* R1330 */
- { 0x0000, 0x0000 }, /* R1331 */
- { 0x0000, 0x0000 }, /* R1332 */
- { 0x0000, 0x0000 }, /* R1333 */
- { 0x0000, 0x0000 }, /* R1334 */
- { 0x0000, 0x0000 }, /* R1335 */
- { 0x0000, 0x0000 }, /* R1336 */
- { 0x0000, 0x0000 }, /* R1337 */
- { 0x0000, 0x0000 }, /* R1338 */
- { 0x0000, 0x0000 }, /* R1339 */
- { 0x0000, 0x0000 }, /* R1340 */
- { 0x0000, 0x0000 }, /* R1341 */
- { 0x0000, 0x0000 }, /* R1342 */
- { 0x0000, 0x0000 }, /* R1343 */
- { 0xFFFF, 0xFFFF }, /* R1344 - AIF2 DRC (1) */
- { 0x1FFF, 0x1FFF }, /* R1345 - AIF2 DRC (2) */
- { 0xFFFF, 0xFFFF }, /* R1346 - AIF2 DRC (3) */
- { 0x07FF, 0x07FF }, /* R1347 - AIF2 DRC (4) */
- { 0x03FF, 0x03FF }, /* R1348 - AIF2 DRC (5) */
- { 0x0000, 0x0000 }, /* R1349 */
- { 0x0000, 0x0000 }, /* R1350 */
- { 0x0000, 0x0000 }, /* R1351 */
- { 0x0000, 0x0000 }, /* R1352 */
- { 0x0000, 0x0000 }, /* R1353 */
- { 0x0000, 0x0000 }, /* R1354 */
- { 0x0000, 0x0000 }, /* R1355 */
- { 0x0000, 0x0000 }, /* R1356 */
- { 0x0000, 0x0000 }, /* R1357 */
- { 0x0000, 0x0000 }, /* R1358 */
- { 0x0000, 0x0000 }, /* R1359 */
- { 0x0000, 0x0000 }, /* R1360 */
- { 0x0000, 0x0000 }, /* R1361 */
- { 0x0000, 0x0000 }, /* R1362 */
- { 0x0000, 0x0000 }, /* R1363 */
- { 0x0000, 0x0000 }, /* R1364 */
- { 0x0000, 0x0000 }, /* R1365 */
- { 0x0000, 0x0000 }, /* R1366 */
- { 0x0000, 0x0000 }, /* R1367 */
- { 0x0000, 0x0000 }, /* R1368 */
- { 0x0000, 0x0000 }, /* R1369 */
- { 0x0000, 0x0000 }, /* R1370 */
- { 0x0000, 0x0000 }, /* R1371 */
- { 0x0000, 0x0000 }, /* R1372 */
- { 0x0000, 0x0000 }, /* R1373 */
- { 0x0000, 0x0000 }, /* R1374 */
- { 0x0000, 0x0000 }, /* R1375 */
- { 0x0000, 0x0000 }, /* R1376 */
- { 0x0000, 0x0000 }, /* R1377 */
- { 0x0000, 0x0000 }, /* R1378 */
- { 0x0000, 0x0000 }, /* R1379 */
- { 0x0000, 0x0000 }, /* R1380 */
- { 0x0000, 0x0000 }, /* R1381 */
- { 0x0000, 0x0000 }, /* R1382 */
- { 0x0000, 0x0000 }, /* R1383 */
- { 0x0000, 0x0000 }, /* R1384 */
- { 0x0000, 0x0000 }, /* R1385 */
- { 0x0000, 0x0000 }, /* R1386 */
- { 0x0000, 0x0000 }, /* R1387 */
- { 0x0000, 0x0000 }, /* R1388 */
- { 0x0000, 0x0000 }, /* R1389 */
- { 0x0000, 0x0000 }, /* R1390 */
- { 0x0000, 0x0000 }, /* R1391 */
- { 0x0000, 0x0000 }, /* R1392 */
- { 0x0000, 0x0000 }, /* R1393 */
- { 0x0000, 0x0000 }, /* R1394 */
- { 0x0000, 0x0000 }, /* R1395 */
- { 0x0000, 0x0000 }, /* R1396 */
- { 0x0000, 0x0000 }, /* R1397 */
- { 0x0000, 0x0000 }, /* R1398 */
- { 0x0000, 0x0000 }, /* R1399 */
- { 0x0000, 0x0000 }, /* R1400 */
- { 0x0000, 0x0000 }, /* R1401 */
- { 0x0000, 0x0000 }, /* R1402 */
- { 0x0000, 0x0000 }, /* R1403 */
- { 0x0000, 0x0000 }, /* R1404 */
- { 0x0000, 0x0000 }, /* R1405 */
- { 0x0000, 0x0000 }, /* R1406 */
- { 0x0000, 0x0000 }, /* R1407 */
- { 0xFFFF, 0xFFFF }, /* R1408 - AIF2 EQ Gains (1) */
- { 0xFFC0, 0xFFC0 }, /* R1409 - AIF2 EQ Gains (2) */
- { 0xFFFF, 0xFFFF }, /* R1410 - AIF2 EQ Band 1 A */
- { 0xFFFF, 0xFFFF }, /* R1411 - AIF2 EQ Band 1 B */
- { 0xFFFF, 0xFFFF }, /* R1412 - AIF2 EQ Band 1 PG */
- { 0xFFFF, 0xFFFF }, /* R1413 - AIF2 EQ Band 2 A */
- { 0xFFFF, 0xFFFF }, /* R1414 - AIF2 EQ Band 2 B */
- { 0xFFFF, 0xFFFF }, /* R1415 - AIF2 EQ Band 2 C */
- { 0xFFFF, 0xFFFF }, /* R1416 - AIF2 EQ Band 2 PG */
- { 0xFFFF, 0xFFFF }, /* R1417 - AIF2 EQ Band 3 A */
- { 0xFFFF, 0xFFFF }, /* R1418 - AIF2 EQ Band 3 B */
- { 0xFFFF, 0xFFFF }, /* R1419 - AIF2 EQ Band 3 C */
- { 0xFFFF, 0xFFFF }, /* R1420 - AIF2 EQ Band 3 PG */
- { 0xFFFF, 0xFFFF }, /* R1421 - AIF2 EQ Band 4 A */
- { 0xFFFF, 0xFFFF }, /* R1422 - AIF2 EQ Band 4 B */
- { 0xFFFF, 0xFFFF }, /* R1423 - AIF2 EQ Band 4 C */
- { 0xFFFF, 0xFFFF }, /* R1424 - AIF2 EQ Band 4 PG */
- { 0xFFFF, 0xFFFF }, /* R1425 - AIF2 EQ Band 5 A */
- { 0xFFFF, 0xFFFF }, /* R1426 - AIF2 EQ Band 5 B */
- { 0xFFFF, 0xFFFF }, /* R1427 - AIF2 EQ Band 5 PG */
- { 0x0000, 0x0000 }, /* R1428 */
- { 0x0000, 0x0000 }, /* R1429 */
- { 0x0000, 0x0000 }, /* R1430 */
- { 0x0000, 0x0000 }, /* R1431 */
- { 0x0000, 0x0000 }, /* R1432 */
- { 0x0000, 0x0000 }, /* R1433 */
- { 0x0000, 0x0000 }, /* R1434 */
- { 0x0000, 0x0000 }, /* R1435 */
- { 0x0000, 0x0000 }, /* R1436 */
- { 0x0000, 0x0000 }, /* R1437 */
- { 0x0000, 0x0000 }, /* R1438 */
- { 0x0000, 0x0000 }, /* R1439 */
- { 0x0000, 0x0000 }, /* R1440 */
- { 0x0000, 0x0000 }, /* R1441 */
- { 0x0000, 0x0000 }, /* R1442 */
- { 0x0000, 0x0000 }, /* R1443 */
- { 0x0000, 0x0000 }, /* R1444 */
- { 0x0000, 0x0000 }, /* R1445 */
- { 0x0000, 0x0000 }, /* R1446 */
- { 0x0000, 0x0000 }, /* R1447 */
- { 0x0000, 0x0000 }, /* R1448 */
- { 0x0000, 0x0000 }, /* R1449 */
- { 0x0000, 0x0000 }, /* R1450 */
- { 0x0000, 0x0000 }, /* R1451 */
- { 0x0000, 0x0000 }, /* R1452 */
- { 0x0000, 0x0000 }, /* R1453 */
- { 0x0000, 0x0000 }, /* R1454 */
- { 0x0000, 0x0000 }, /* R1455 */
- { 0x0000, 0x0000 }, /* R1456 */
- { 0x0000, 0x0000 }, /* R1457 */
- { 0x0000, 0x0000 }, /* R1458 */
- { 0x0000, 0x0000 }, /* R1459 */
- { 0x0000, 0x0000 }, /* R1460 */
- { 0x0000, 0x0000 }, /* R1461 */
- { 0x0000, 0x0000 }, /* R1462 */
- { 0x0000, 0x0000 }, /* R1463 */
- { 0x0000, 0x0000 }, /* R1464 */
- { 0x0000, 0x0000 }, /* R1465 */
- { 0x0000, 0x0000 }, /* R1466 */
- { 0x0000, 0x0000 }, /* R1467 */
- { 0x0000, 0x0000 }, /* R1468 */
- { 0x0000, 0x0000 }, /* R1469 */
- { 0x0000, 0x0000 }, /* R1470 */
- { 0x0000, 0x0000 }, /* R1471 */
- { 0x0000, 0x0000 }, /* R1472 */
- { 0x0000, 0x0000 }, /* R1473 */
- { 0x0000, 0x0000 }, /* R1474 */
- { 0x0000, 0x0000 }, /* R1475 */
- { 0x0000, 0x0000 }, /* R1476 */
- { 0x0000, 0x0000 }, /* R1477 */
- { 0x0000, 0x0000 }, /* R1478 */
- { 0x0000, 0x0000 }, /* R1479 */
- { 0x0000, 0x0000 }, /* R1480 */
- { 0x0000, 0x0000 }, /* R1481 */
- { 0x0000, 0x0000 }, /* R1482 */
- { 0x0000, 0x0000 }, /* R1483 */
- { 0x0000, 0x0000 }, /* R1484 */
- { 0x0000, 0x0000 }, /* R1485 */
- { 0x0000, 0x0000 }, /* R1486 */
- { 0x0000, 0x0000 }, /* R1487 */
- { 0x0000, 0x0000 }, /* R1488 */
- { 0x0000, 0x0000 }, /* R1489 */
- { 0x0000, 0x0000 }, /* R1490 */
- { 0x0000, 0x0000 }, /* R1491 */
- { 0x0000, 0x0000 }, /* R1492 */
- { 0x0000, 0x0000 }, /* R1493 */
- { 0x0000, 0x0000 }, /* R1494 */
- { 0x0000, 0x0000 }, /* R1495 */
- { 0x0000, 0x0000 }, /* R1496 */
- { 0x0000, 0x0000 }, /* R1497 */
- { 0x0000, 0x0000 }, /* R1498 */
- { 0x0000, 0x0000 }, /* R1499 */
- { 0x0000, 0x0000 }, /* R1500 */
- { 0x0000, 0x0000 }, /* R1501 */
- { 0x0000, 0x0000 }, /* R1502 */
- { 0x0000, 0x0000 }, /* R1503 */
- { 0x0000, 0x0000 }, /* R1504 */
- { 0x0000, 0x0000 }, /* R1505 */
- { 0x0000, 0x0000 }, /* R1506 */
- { 0x0000, 0x0000 }, /* R1507 */
- { 0x0000, 0x0000 }, /* R1508 */
- { 0x0000, 0x0000 }, /* R1509 */
- { 0x0000, 0x0000 }, /* R1510 */
- { 0x0000, 0x0000 }, /* R1511 */
- { 0x0000, 0x0000 }, /* R1512 */
- { 0x0000, 0x0000 }, /* R1513 */
- { 0x0000, 0x0000 }, /* R1514 */
- { 0x0000, 0x0000 }, /* R1515 */
- { 0x0000, 0x0000 }, /* R1516 */
- { 0x0000, 0x0000 }, /* R1517 */
- { 0x0000, 0x0000 }, /* R1518 */
- { 0x0000, 0x0000 }, /* R1519 */
- { 0x0000, 0x0000 }, /* R1520 */
- { 0x0000, 0x0000 }, /* R1521 */
- { 0x0000, 0x0000 }, /* R1522 */
- { 0x0000, 0x0000 }, /* R1523 */
- { 0x0000, 0x0000 }, /* R1524 */
- { 0x0000, 0x0000 }, /* R1525 */
- { 0x0000, 0x0000 }, /* R1526 */
- { 0x0000, 0x0000 }, /* R1527 */
- { 0x0000, 0x0000 }, /* R1528 */
- { 0x0000, 0x0000 }, /* R1529 */
- { 0x0000, 0x0000 }, /* R1530 */
- { 0x0000, 0x0000 }, /* R1531 */
- { 0x0000, 0x0000 }, /* R1532 */
- { 0x0000, 0x0000 }, /* R1533 */
- { 0x0000, 0x0000 }, /* R1534 */
- { 0x0000, 0x0000 }, /* R1535 */
- { 0x01EF, 0x01EF }, /* R1536 - DAC1 Mixer Volumes */
- { 0x0037, 0x0037 }, /* R1537 - DAC1 Left Mixer Routing */
- { 0x0037, 0x0037 }, /* R1538 - DAC1 Right Mixer Routing */
- { 0x01EF, 0x01EF }, /* R1539 - DAC2 Mixer Volumes */
- { 0x0037, 0x0037 }, /* R1540 - DAC2 Left Mixer Routing */
- { 0x0037, 0x0037 }, /* R1541 - DAC2 Right Mixer Routing */
- { 0x0003, 0x0003 }, /* R1542 - AIF1 ADC1 Left Mixer Routing */
- { 0x0003, 0x0003 }, /* R1543 - AIF1 ADC1 Right Mixer Routing */
- { 0x0003, 0x0003 }, /* R1544 - AIF1 ADC2 Left Mixer Routing */
- { 0x0003, 0x0003 }, /* R1545 - AIF1 ADC2 Right mixer Routing */
- { 0x0000, 0x0000 }, /* R1546 */
- { 0x0000, 0x0000 }, /* R1547 */
- { 0x0000, 0x0000 }, /* R1548 */
- { 0x0000, 0x0000 }, /* R1549 */
- { 0x0000, 0x0000 }, /* R1550 */
- { 0x0000, 0x0000 }, /* R1551 */
- { 0x02FF, 0x03FF }, /* R1552 - DAC1 Left Volume */
- { 0x02FF, 0x03FF }, /* R1553 - DAC1 Right Volume */
- { 0x02FF, 0x03FF }, /* R1554 - DAC2 Left Volume */
- { 0x02FF, 0x03FF }, /* R1555 - DAC2 Right Volume */
- { 0x0003, 0x0003 }, /* R1556 - DAC Softmute */
- { 0x0000, 0x0000 }, /* R1557 */
- { 0x0000, 0x0000 }, /* R1558 */
- { 0x0000, 0x0000 }, /* R1559 */
- { 0x0000, 0x0000 }, /* R1560 */
- { 0x0000, 0x0000 }, /* R1561 */
- { 0x0000, 0x0000 }, /* R1562 */
- { 0x0000, 0x0000 }, /* R1563 */
- { 0x0000, 0x0000 }, /* R1564 */
- { 0x0000, 0x0000 }, /* R1565 */
- { 0x0000, 0x0000 }, /* R1566 */
- { 0x0000, 0x0000 }, /* R1567 */
- { 0x0003, 0x0003 }, /* R1568 - Oversampling */
- { 0x03C3, 0x03C3 }, /* R1569 - Sidetone */
-};
-
-const u16 wm8994_reg_defaults[WM8994_CACHE_SIZE] = {
- 0x8994, /* R0 - Software Reset */
- 0x0000, /* R1 - Power Management (1) */
- 0x6000, /* R2 - Power Management (2) */
- 0x0000, /* R3 - Power Management (3) */
- 0x0000, /* R4 - Power Management (4) */
- 0x0000, /* R5 - Power Management (5) */
- 0x0000, /* R6 - Power Management (6) */
- 0x0000, /* R7 */
- 0x0000, /* R8 */
- 0x0000, /* R9 */
- 0x0000, /* R10 */
- 0x0000, /* R11 */
- 0x0000, /* R12 */
- 0x0000, /* R13 */
- 0x0000, /* R14 */
- 0x0000, /* R15 */
- 0x0000, /* R16 */
- 0x0000, /* R17 */
- 0x0000, /* R18 */
- 0x0000, /* R19 */
- 0x0000, /* R20 */
- 0x0000, /* R21 - Input Mixer (1) */
- 0x0000, /* R22 */
- 0x0000, /* R23 */
- 0x008B, /* R24 - Left Line Input 1&2 Volume */
- 0x008B, /* R25 - Left Line Input 3&4 Volume */
- 0x008B, /* R26 - Right Line Input 1&2 Volume */
- 0x008B, /* R27 - Right Line Input 3&4 Volume */
- 0x006D, /* R28 - Left Output Volume */
- 0x006D, /* R29 - Right Output Volume */
- 0x0066, /* R30 - Line Outputs Volume */
- 0x0020, /* R31 - HPOUT2 Volume */
- 0x0079, /* R32 - Left OPGA Volume */
- 0x0079, /* R33 - Right OPGA Volume */
- 0x0003, /* R34 - SPKMIXL Attenuation */
- 0x0003, /* R35 - SPKMIXR Attenuation */
- 0x0011, /* R36 - SPKOUT Mixers */
- 0x0140, /* R37 - ClassD */
- 0x0079, /* R38 - Speaker Volume Left */
- 0x0079, /* R39 - Speaker Volume Right */
- 0x0000, /* R40 - Input Mixer (2) */
- 0x0000, /* R41 - Input Mixer (3) */
- 0x0000, /* R42 - Input Mixer (4) */
- 0x0000, /* R43 - Input Mixer (5) */
- 0x0000, /* R44 - Input Mixer (6) */
- 0x0000, /* R45 - Output Mixer (1) */
- 0x0000, /* R46 - Output Mixer (2) */
- 0x0000, /* R47 - Output Mixer (3) */
- 0x0000, /* R48 - Output Mixer (4) */
- 0x0000, /* R49 - Output Mixer (5) */
- 0x0000, /* R50 - Output Mixer (6) */
- 0x0000, /* R51 - HPOUT2 Mixer */
- 0x0000, /* R52 - Line Mixer (1) */
- 0x0000, /* R53 - Line Mixer (2) */
- 0x0000, /* R54 - Speaker Mixer */
- 0x0000, /* R55 - Additional Control */
- 0x0000, /* R56 - AntiPOP (1) */
- 0x0000, /* R57 - AntiPOP (2) */
- 0x0000, /* R58 - MICBIAS */
- 0x000D, /* R59 - LDO 1 */
- 0x0003, /* R60 - LDO 2 */
- 0x0039, /* R61 - MICBIAS1 */
- 0x0039, /* R62 - MICBIAS2 */
- 0x0000, /* R63 */
- 0x0000, /* R64 */
- 0x0000, /* R65 */
- 0x0000, /* R66 */
- 0x0000, /* R67 */
- 0x0000, /* R68 */
- 0x0000, /* R69 */
- 0x0000, /* R70 */
- 0x0000, /* R71 */
- 0x0000, /* R72 */
- 0x0000, /* R73 */
- 0x0000, /* R74 */
- 0x0000, /* R75 */
- 0x1F25, /* R76 - Charge Pump (1) */
- 0x0000, /* R77 */
- 0x0000, /* R78 */
- 0x0000, /* R79 */
- 0x0000, /* R80 */
- 0x0004, /* R81 - Class W (1) */
- 0x0000, /* R82 */
- 0x0000, /* R83 */
- 0x0000, /* R84 - DC Servo (1) */
- 0x054A, /* R85 - DC Servo (2) */
- 0x0000, /* R86 */
- 0x0000, /* R87 - DC Servo (4) */
- 0x0000, /* R88 - DC Servo Readback */
- 0x0000, /* R89 */
- 0x0000, /* R90 */
- 0x0000, /* R91 */
- 0x0000, /* R92 */
- 0x0000, /* R93 */
- 0x0000, /* R94 */
- 0x0000, /* R95 */
- 0x0000, /* R96 - Analogue HP (1) */
- 0x0000, /* R97 */
- 0x0000, /* R98 */
- 0x0000, /* R99 */
- 0x0000, /* R100 */
- 0x0000, /* R101 */
- 0x0000, /* R102 */
- 0x0000, /* R103 */
- 0x0000, /* R104 */
- 0x0000, /* R105 */
- 0x0000, /* R106 */
- 0x0000, /* R107 */
- 0x0000, /* R108 */
- 0x0000, /* R109 */
- 0x0000, /* R110 */
- 0x0000, /* R111 */
- 0x0000, /* R112 */
- 0x0000, /* R113 */
- 0x0000, /* R114 */
- 0x0000, /* R115 */
- 0x0000, /* R116 */
- 0x0000, /* R117 */
- 0x0000, /* R118 */
- 0x0000, /* R119 */
- 0x0000, /* R120 */
- 0x0000, /* R121 */
- 0x0000, /* R122 */
- 0x0000, /* R123 */
- 0x0000, /* R124 */
- 0x0000, /* R125 */
- 0x0000, /* R126 */
- 0x0000, /* R127 */
- 0x0000, /* R128 */
- 0x0000, /* R129 */
- 0x0000, /* R130 */
- 0x0000, /* R131 */
- 0x0000, /* R132 */
- 0x0000, /* R133 */
- 0x0000, /* R134 */
- 0x0000, /* R135 */
- 0x0000, /* R136 */
- 0x0000, /* R137 */
- 0x0000, /* R138 */
- 0x0000, /* R139 */
- 0x0000, /* R140 */
- 0x0000, /* R141 */
- 0x0000, /* R142 */
- 0x0000, /* R143 */
- 0x0000, /* R144 */
- 0x0000, /* R145 */
- 0x0000, /* R146 */
- 0x0000, /* R147 */
- 0x0000, /* R148 */
- 0x0000, /* R149 */
- 0x0000, /* R150 */
- 0x0000, /* R151 */
- 0x0000, /* R152 */
- 0x0000, /* R153 */
- 0x0000, /* R154 */
- 0x0000, /* R155 */
- 0x0000, /* R156 */
- 0x0000, /* R157 */
- 0x0000, /* R158 */
- 0x0000, /* R159 */
- 0x0000, /* R160 */
- 0x0000, /* R161 */
- 0x0000, /* R162 */
- 0x0000, /* R163 */
- 0x0000, /* R164 */
- 0x0000, /* R165 */
- 0x0000, /* R166 */
- 0x0000, /* R167 */
- 0x0000, /* R168 */
- 0x0000, /* R169 */
- 0x0000, /* R170 */
- 0x0000, /* R171 */
- 0x0000, /* R172 */
- 0x0000, /* R173 */
- 0x0000, /* R174 */
- 0x0000, /* R175 */
- 0x0000, /* R176 */
- 0x0000, /* R177 */
- 0x0000, /* R178 */
- 0x0000, /* R179 */
- 0x0000, /* R180 */
- 0x0000, /* R181 */
- 0x0000, /* R182 */
- 0x0000, /* R183 */
- 0x0000, /* R184 */
- 0x0000, /* R185 */
- 0x0000, /* R186 */
- 0x0000, /* R187 */
- 0x0000, /* R188 */
- 0x0000, /* R189 */
- 0x0000, /* R190 */
- 0x0000, /* R191 */
- 0x0000, /* R192 */
- 0x0000, /* R193 */
- 0x0000, /* R194 */
- 0x0000, /* R195 */
- 0x0000, /* R196 */
- 0x0000, /* R197 */
- 0x0000, /* R198 */
- 0x0000, /* R199 */
- 0x0000, /* R200 */
- 0x0000, /* R201 */
- 0x0000, /* R202 */
- 0x0000, /* R203 */
- 0x0000, /* R204 */
- 0x0000, /* R205 */
- 0x0000, /* R206 */
- 0x0000, /* R207 */
- 0x0000, /* R208 */
- 0x0000, /* R209 */
- 0x0000, /* R210 */
- 0x0000, /* R211 */
- 0x0000, /* R212 */
- 0x0000, /* R213 */
- 0x0000, /* R214 */
- 0x0000, /* R215 */
- 0x0000, /* R216 */
- 0x0000, /* R217 */
- 0x0000, /* R218 */
- 0x0000, /* R219 */
- 0x0000, /* R220 */
- 0x0000, /* R221 */
- 0x0000, /* R222 */
- 0x0000, /* R223 */
- 0x0000, /* R224 */
- 0x0000, /* R225 */
- 0x0000, /* R226 */
- 0x0000, /* R227 */
- 0x0000, /* R228 */
- 0x0000, /* R229 */
- 0x0000, /* R230 */
- 0x0000, /* R231 */
- 0x0000, /* R232 */
- 0x0000, /* R233 */
- 0x0000, /* R234 */
- 0x0000, /* R235 */
- 0x0000, /* R236 */
- 0x0000, /* R237 */
- 0x0000, /* R238 */
- 0x0000, /* R239 */
- 0x0000, /* R240 */
- 0x0000, /* R241 */
- 0x0000, /* R242 */
- 0x0000, /* R243 */
- 0x0000, /* R244 */
- 0x0000, /* R245 */
- 0x0000, /* R246 */
- 0x0000, /* R247 */
- 0x0000, /* R248 */
- 0x0000, /* R249 */
- 0x0000, /* R250 */
- 0x0000, /* R251 */
- 0x0000, /* R252 */
- 0x0000, /* R253 */
- 0x0000, /* R254 */
- 0x0000, /* R255 */
- 0x0003, /* R256 - Chip Revision */
- 0x8004, /* R257 - Control Interface */
- 0x0000, /* R258 */
- 0x0000, /* R259 */
- 0x0000, /* R260 */
- 0x0000, /* R261 */
- 0x0000, /* R262 */
- 0x0000, /* R263 */
- 0x0000, /* R264 */
- 0x0000, /* R265 */
- 0x0000, /* R266 */
- 0x0000, /* R267 */
- 0x0000, /* R268 */
- 0x0000, /* R269 */
- 0x0000, /* R270 */
- 0x0000, /* R271 */
- 0x0000, /* R272 - Write Sequencer Ctrl (1) */
- 0x0000, /* R273 - Write Sequencer Ctrl (2) */
- 0x0000, /* R274 */
- 0x0000, /* R275 */
- 0x0000, /* R276 */
- 0x0000, /* R277 */
- 0x0000, /* R278 */
- 0x0000, /* R279 */
- 0x0000, /* R280 */
- 0x0000, /* R281 */
- 0x0000, /* R282 */
- 0x0000, /* R283 */
- 0x0000, /* R284 */
- 0x0000, /* R285 */
- 0x0000, /* R286 */
- 0x0000, /* R287 */
- 0x0000, /* R288 */
- 0x0000, /* R289 */
- 0x0000, /* R290 */
- 0x0000, /* R291 */
- 0x0000, /* R292 */
- 0x0000, /* R293 */
- 0x0000, /* R294 */
- 0x0000, /* R295 */
- 0x0000, /* R296 */
- 0x0000, /* R297 */
- 0x0000, /* R298 */
- 0x0000, /* R299 */
- 0x0000, /* R300 */
- 0x0000, /* R301 */
- 0x0000, /* R302 */
- 0x0000, /* R303 */
- 0x0000, /* R304 */
- 0x0000, /* R305 */
- 0x0000, /* R306 */
- 0x0000, /* R307 */
- 0x0000, /* R308 */
- 0x0000, /* R309 */
- 0x0000, /* R310 */
- 0x0000, /* R311 */
- 0x0000, /* R312 */
- 0x0000, /* R313 */
- 0x0000, /* R314 */
- 0x0000, /* R315 */
- 0x0000, /* R316 */
- 0x0000, /* R317 */
- 0x0000, /* R318 */
- 0x0000, /* R319 */
- 0x0000, /* R320 */
- 0x0000, /* R321 */
- 0x0000, /* R322 */
- 0x0000, /* R323 */
- 0x0000, /* R324 */
- 0x0000, /* R325 */
- 0x0000, /* R326 */
- 0x0000, /* R327 */
- 0x0000, /* R328 */
- 0x0000, /* R329 */
- 0x0000, /* R330 */
- 0x0000, /* R331 */
- 0x0000, /* R332 */
- 0x0000, /* R333 */
- 0x0000, /* R334 */
- 0x0000, /* R335 */
- 0x0000, /* R336 */
- 0x0000, /* R337 */
- 0x0000, /* R338 */
- 0x0000, /* R339 */
- 0x0000, /* R340 */
- 0x0000, /* R341 */
- 0x0000, /* R342 */
- 0x0000, /* R343 */
- 0x0000, /* R344 */
- 0x0000, /* R345 */
- 0x0000, /* R346 */
- 0x0000, /* R347 */
- 0x0000, /* R348 */
- 0x0000, /* R349 */
- 0x0000, /* R350 */
- 0x0000, /* R351 */
- 0x0000, /* R352 */
- 0x0000, /* R353 */
- 0x0000, /* R354 */
- 0x0000, /* R355 */
- 0x0000, /* R356 */
- 0x0000, /* R357 */
- 0x0000, /* R358 */
- 0x0000, /* R359 */
- 0x0000, /* R360 */
- 0x0000, /* R361 */
- 0x0000, /* R362 */
- 0x0000, /* R363 */
- 0x0000, /* R364 */
- 0x0000, /* R365 */
- 0x0000, /* R366 */
- 0x0000, /* R367 */
- 0x0000, /* R368 */
- 0x0000, /* R369 */
- 0x0000, /* R370 */
- 0x0000, /* R371 */
- 0x0000, /* R372 */
- 0x0000, /* R373 */
- 0x0000, /* R374 */
- 0x0000, /* R375 */
- 0x0000, /* R376 */
- 0x0000, /* R377 */
- 0x0000, /* R378 */
- 0x0000, /* R379 */
- 0x0000, /* R380 */
- 0x0000, /* R381 */
- 0x0000, /* R382 */
- 0x0000, /* R383 */
- 0x0000, /* R384 */
- 0x0000, /* R385 */
- 0x0000, /* R386 */
- 0x0000, /* R387 */
- 0x0000, /* R388 */
- 0x0000, /* R389 */
- 0x0000, /* R390 */
- 0x0000, /* R391 */
- 0x0000, /* R392 */
- 0x0000, /* R393 */
- 0x0000, /* R394 */
- 0x0000, /* R395 */
- 0x0000, /* R396 */
- 0x0000, /* R397 */
- 0x0000, /* R398 */
- 0x0000, /* R399 */
- 0x0000, /* R400 */
- 0x0000, /* R401 */
- 0x0000, /* R402 */
- 0x0000, /* R403 */
- 0x0000, /* R404 */
- 0x0000, /* R405 */
- 0x0000, /* R406 */
- 0x0000, /* R407 */
- 0x0000, /* R408 */
- 0x0000, /* R409 */
- 0x0000, /* R410 */
- 0x0000, /* R411 */
- 0x0000, /* R412 */
- 0x0000, /* R413 */
- 0x0000, /* R414 */
- 0x0000, /* R415 */
- 0x0000, /* R416 */
- 0x0000, /* R417 */
- 0x0000, /* R418 */
- 0x0000, /* R419 */
- 0x0000, /* R420 */
- 0x0000, /* R421 */
- 0x0000, /* R422 */
- 0x0000, /* R423 */
- 0x0000, /* R424 */
- 0x0000, /* R425 */
- 0x0000, /* R426 */
- 0x0000, /* R427 */
- 0x0000, /* R428 */
- 0x0000, /* R429 */
- 0x0000, /* R430 */
- 0x0000, /* R431 */
- 0x0000, /* R432 */
- 0x0000, /* R433 */
- 0x0000, /* R434 */
- 0x0000, /* R435 */
- 0x0000, /* R436 */
- 0x0000, /* R437 */
- 0x0000, /* R438 */
- 0x0000, /* R439 */
- 0x0000, /* R440 */
- 0x0000, /* R441 */
- 0x0000, /* R442 */
- 0x0000, /* R443 */
- 0x0000, /* R444 */
- 0x0000, /* R445 */
- 0x0000, /* R446 */
- 0x0000, /* R447 */
- 0x0000, /* R448 */
- 0x0000, /* R449 */
- 0x0000, /* R450 */
- 0x0000, /* R451 */
- 0x0000, /* R452 */
- 0x0000, /* R453 */
- 0x0000, /* R454 */
- 0x0000, /* R455 */
- 0x0000, /* R456 */
- 0x0000, /* R457 */
- 0x0000, /* R458 */
- 0x0000, /* R459 */
- 0x0000, /* R460 */
- 0x0000, /* R461 */
- 0x0000, /* R462 */
- 0x0000, /* R463 */
- 0x0000, /* R464 */
- 0x0000, /* R465 */
- 0x0000, /* R466 */
- 0x0000, /* R467 */
- 0x0000, /* R468 */
- 0x0000, /* R469 */
- 0x0000, /* R470 */
- 0x0000, /* R471 */
- 0x0000, /* R472 */
- 0x0000, /* R473 */
- 0x0000, /* R474 */
- 0x0000, /* R475 */
- 0x0000, /* R476 */
- 0x0000, /* R477 */
- 0x0000, /* R478 */
- 0x0000, /* R479 */
- 0x0000, /* R480 */
- 0x0000, /* R481 */
- 0x0000, /* R482 */
- 0x0000, /* R483 */
- 0x0000, /* R484 */
- 0x0000, /* R485 */
- 0x0000, /* R486 */
- 0x0000, /* R487 */
- 0x0000, /* R488 */
- 0x0000, /* R489 */
- 0x0000, /* R490 */
- 0x0000, /* R491 */
- 0x0000, /* R492 */
- 0x0000, /* R493 */
- 0x0000, /* R494 */
- 0x0000, /* R495 */
- 0x0000, /* R496 */
- 0x0000, /* R497 */
- 0x0000, /* R498 */
- 0x0000, /* R499 */
- 0x0000, /* R500 */
- 0x0000, /* R501 */
- 0x0000, /* R502 */
- 0x0000, /* R503 */
- 0x0000, /* R504 */
- 0x0000, /* R505 */
- 0x0000, /* R506 */
- 0x0000, /* R507 */
- 0x0000, /* R508 */
- 0x0000, /* R509 */
- 0x0000, /* R510 */
- 0x0000, /* R511 */
- 0x0000, /* R512 - AIF1 Clocking (1) */
- 0x0000, /* R513 - AIF1 Clocking (2) */
- 0x0000, /* R514 */
- 0x0000, /* R515 */
- 0x0000, /* R516 - AIF2 Clocking (1) */
- 0x0000, /* R517 - AIF2 Clocking (2) */
- 0x0000, /* R518 */
- 0x0000, /* R519 */
- 0x0000, /* R520 - Clocking (1) */
- 0x0000, /* R521 - Clocking (2) */
- 0x0000, /* R522 */
- 0x0000, /* R523 */
- 0x0000, /* R524 */
- 0x0000, /* R525 */
- 0x0000, /* R526 */
- 0x0000, /* R527 */
- 0x0083, /* R528 - AIF1 Rate */
- 0x0083, /* R529 - AIF2 Rate */
- 0x0000, /* R530 - Rate Status */
- 0x0000, /* R531 */
- 0x0000, /* R532 */
- 0x0000, /* R533 */
- 0x0000, /* R534 */
- 0x0000, /* R535 */
- 0x0000, /* R536 */
- 0x0000, /* R537 */
- 0x0000, /* R538 */
- 0x0000, /* R539 */
- 0x0000, /* R540 */
- 0x0000, /* R541 */
- 0x0000, /* R542 */
- 0x0000, /* R543 */
- 0x0000, /* R544 - FLL1 Control (1) */
- 0x0000, /* R545 - FLL1 Control (2) */
- 0x0000, /* R546 - FLL1 Control (3) */
- 0x0000, /* R547 - FLL1 Control (4) */
- 0x0C80, /* R548 - FLL1 Control (5) */
- 0x0000, /* R549 */
- 0x0000, /* R550 */
- 0x0000, /* R551 */
- 0x0000, /* R552 */
- 0x0000, /* R553 */
- 0x0000, /* R554 */
- 0x0000, /* R555 */
- 0x0000, /* R556 */
- 0x0000, /* R557 */
- 0x0000, /* R558 */
- 0x0000, /* R559 */
- 0x0000, /* R560 */
- 0x0000, /* R561 */
- 0x0000, /* R562 */
- 0x0000, /* R563 */
- 0x0000, /* R564 */
- 0x0000, /* R565 */
- 0x0000, /* R566 */
- 0x0000, /* R567 */
- 0x0000, /* R568 */
- 0x0000, /* R569 */
- 0x0000, /* R570 */
- 0x0000, /* R571 */
- 0x0000, /* R572 */
- 0x0000, /* R573 */
- 0x0000, /* R574 */
- 0x0000, /* R575 */
- 0x0000, /* R576 - FLL2 Control (1) */
- 0x0000, /* R577 - FLL2 Control (2) */
- 0x0000, /* R578 - FLL2 Control (3) */
- 0x0000, /* R579 - FLL2 Control (4) */
- 0x0C80, /* R580 - FLL2 Control (5) */
- 0x0000, /* R581 */
- 0x0000, /* R582 */
- 0x0000, /* R583 */
- 0x0000, /* R584 */
- 0x0000, /* R585 */
- 0x0000, /* R586 */
- 0x0000, /* R587 */
- 0x0000, /* R588 */
- 0x0000, /* R589 */
- 0x0000, /* R590 */
- 0x0000, /* R591 */
- 0x0000, /* R592 */
- 0x0000, /* R593 */
- 0x0000, /* R594 */
- 0x0000, /* R595 */
- 0x0000, /* R596 */
- 0x0000, /* R597 */
- 0x0000, /* R598 */
- 0x0000, /* R599 */
- 0x0000, /* R600 */
- 0x0000, /* R601 */
- 0x0000, /* R602 */
- 0x0000, /* R603 */
- 0x0000, /* R604 */
- 0x0000, /* R605 */
- 0x0000, /* R606 */
- 0x0000, /* R607 */
- 0x0000, /* R608 */
- 0x0000, /* R609 */
- 0x0000, /* R610 */
- 0x0000, /* R611 */
- 0x0000, /* R612 */
- 0x0000, /* R613 */
- 0x0000, /* R614 */
- 0x0000, /* R615 */
- 0x0000, /* R616 */
- 0x0000, /* R617 */
- 0x0000, /* R618 */
- 0x0000, /* R619 */
- 0x0000, /* R620 */
- 0x0000, /* R621 */
- 0x0000, /* R622 */
- 0x0000, /* R623 */
- 0x0000, /* R624 */
- 0x0000, /* R625 */
- 0x0000, /* R626 */
- 0x0000, /* R627 */
- 0x0000, /* R628 */
- 0x0000, /* R629 */
- 0x0000, /* R630 */
- 0x0000, /* R631 */
- 0x0000, /* R632 */
- 0x0000, /* R633 */
- 0x0000, /* R634 */
- 0x0000, /* R635 */
- 0x0000, /* R636 */
- 0x0000, /* R637 */
- 0x0000, /* R638 */
- 0x0000, /* R639 */
- 0x0000, /* R640 */
- 0x0000, /* R641 */
- 0x0000, /* R642 */
- 0x0000, /* R643 */
- 0x0000, /* R644 */
- 0x0000, /* R645 */
- 0x0000, /* R646 */
- 0x0000, /* R647 */
- 0x0000, /* R648 */
- 0x0000, /* R649 */
- 0x0000, /* R650 */
- 0x0000, /* R651 */
- 0x0000, /* R652 */
- 0x0000, /* R653 */
- 0x0000, /* R654 */
- 0x0000, /* R655 */
- 0x0000, /* R656 */
- 0x0000, /* R657 */
- 0x0000, /* R658 */
- 0x0000, /* R659 */
- 0x0000, /* R660 */
- 0x0000, /* R661 */
- 0x0000, /* R662 */
- 0x0000, /* R663 */
- 0x0000, /* R664 */
- 0x0000, /* R665 */
- 0x0000, /* R666 */
- 0x0000, /* R667 */
- 0x0000, /* R668 */
- 0x0000, /* R669 */
- 0x0000, /* R670 */
- 0x0000, /* R671 */
- 0x0000, /* R672 */
- 0x0000, /* R673 */
- 0x0000, /* R674 */
- 0x0000, /* R675 */
- 0x0000, /* R676 */
- 0x0000, /* R677 */
- 0x0000, /* R678 */
- 0x0000, /* R679 */
- 0x0000, /* R680 */
- 0x0000, /* R681 */
- 0x0000, /* R682 */
- 0x0000, /* R683 */
- 0x0000, /* R684 */
- 0x0000, /* R685 */
- 0x0000, /* R686 */
- 0x0000, /* R687 */
- 0x0000, /* R688 */
- 0x0000, /* R689 */
- 0x0000, /* R690 */
- 0x0000, /* R691 */
- 0x0000, /* R692 */
- 0x0000, /* R693 */
- 0x0000, /* R694 */
- 0x0000, /* R695 */
- 0x0000, /* R696 */
- 0x0000, /* R697 */
- 0x0000, /* R698 */
- 0x0000, /* R699 */
- 0x0000, /* R700 */
- 0x0000, /* R701 */
- 0x0000, /* R702 */
- 0x0000, /* R703 */
- 0x0000, /* R704 */
- 0x0000, /* R705 */
- 0x0000, /* R706 */
- 0x0000, /* R707 */
- 0x0000, /* R708 */
- 0x0000, /* R709 */
- 0x0000, /* R710 */
- 0x0000, /* R711 */
- 0x0000, /* R712 */
- 0x0000, /* R713 */
- 0x0000, /* R714 */
- 0x0000, /* R715 */
- 0x0000, /* R716 */
- 0x0000, /* R717 */
- 0x0000, /* R718 */
- 0x0000, /* R719 */
- 0x0000, /* R720 */
- 0x0000, /* R721 */
- 0x0000, /* R722 */
- 0x0000, /* R723 */
- 0x0000, /* R724 */
- 0x0000, /* R725 */
- 0x0000, /* R726 */
- 0x0000, /* R727 */
- 0x0000, /* R728 */
- 0x0000, /* R729 */
- 0x0000, /* R730 */
- 0x0000, /* R731 */
- 0x0000, /* R732 */
- 0x0000, /* R733 */
- 0x0000, /* R734 */
- 0x0000, /* R735 */
- 0x0000, /* R736 */
- 0x0000, /* R737 */
- 0x0000, /* R738 */
- 0x0000, /* R739 */
- 0x0000, /* R740 */
- 0x0000, /* R741 */
- 0x0000, /* R742 */
- 0x0000, /* R743 */
- 0x0000, /* R744 */
- 0x0000, /* R745 */
- 0x0000, /* R746 */
- 0x0000, /* R747 */
- 0x0000, /* R748 */
- 0x0000, /* R749 */
- 0x0000, /* R750 */
- 0x0000, /* R751 */
- 0x0000, /* R752 */
- 0x0000, /* R753 */
- 0x0000, /* R754 */
- 0x0000, /* R755 */
- 0x0000, /* R756 */
- 0x0000, /* R757 */
- 0x0000, /* R758 */
- 0x0000, /* R759 */
- 0x0000, /* R760 */
- 0x0000, /* R761 */
- 0x0000, /* R762 */
- 0x0000, /* R763 */
- 0x0000, /* R764 */
- 0x0000, /* R765 */
- 0x0000, /* R766 */
- 0x0000, /* R767 */
- 0x4050, /* R768 - AIF1 Control (1) */
- 0x4000, /* R769 - AIF1 Control (2) */
- 0x0000, /* R770 - AIF1 Master/Slave */
- 0x0040, /* R771 - AIF1 BCLK */
- 0x0040, /* R772 - AIF1ADC LRCLK */
- 0x0040, /* R773 - AIF1DAC LRCLK */
- 0x0004, /* R774 - AIF1DAC Data */
- 0x0100, /* R775 - AIF1ADC Data */
- 0x0000, /* R776 */
- 0x0000, /* R777 */
- 0x0000, /* R778 */
- 0x0000, /* R779 */
- 0x0000, /* R780 */
- 0x0000, /* R781 */
- 0x0000, /* R782 */
- 0x0000, /* R783 */
- 0x4050, /* R784 - AIF2 Control (1) */
- 0x4000, /* R785 - AIF2 Control (2) */
- 0x0000, /* R786 - AIF2 Master/Slave */
- 0x0040, /* R787 - AIF2 BCLK */
- 0x0040, /* R788 - AIF2ADC LRCLK */
- 0x0040, /* R789 - AIF2DAC LRCLK */
- 0x0000, /* R790 - AIF2DAC Data */
- 0x0000, /* R791 - AIF2ADC Data */
- 0x0000, /* R792 */
- 0x0000, /* R793 */
- 0x0000, /* R794 */
- 0x0000, /* R795 */
- 0x0000, /* R796 */
- 0x0000, /* R797 */
- 0x0000, /* R798 */
- 0x0000, /* R799 */
- 0x0000, /* R800 */
- 0x0000, /* R801 */
- 0x0000, /* R802 */
- 0x0000, /* R803 */
- 0x0000, /* R804 */
- 0x0000, /* R805 */
- 0x0000, /* R806 */
- 0x0000, /* R807 */
- 0x0000, /* R808 */
- 0x0000, /* R809 */
- 0x0000, /* R810 */
- 0x0000, /* R811 */
- 0x0000, /* R812 */
- 0x0000, /* R813 */
- 0x0000, /* R814 */
- 0x0000, /* R815 */
- 0x0000, /* R816 */
- 0x0000, /* R817 */
- 0x0000, /* R818 */
- 0x0000, /* R819 */
- 0x0000, /* R820 */
- 0x0000, /* R821 */
- 0x0000, /* R822 */
- 0x0000, /* R823 */
- 0x0000, /* R824 */
- 0x0000, /* R825 */
- 0x0000, /* R826 */
- 0x0000, /* R827 */
- 0x0000, /* R828 */
- 0x0000, /* R829 */
- 0x0000, /* R830 */
- 0x0000, /* R831 */
- 0x0000, /* R832 */
- 0x0000, /* R833 */
- 0x0000, /* R834 */
- 0x0000, /* R835 */
- 0x0000, /* R836 */
- 0x0000, /* R837 */
- 0x0000, /* R838 */
- 0x0000, /* R839 */
- 0x0000, /* R840 */
- 0x0000, /* R841 */
- 0x0000, /* R842 */
- 0x0000, /* R843 */
- 0x0000, /* R844 */
- 0x0000, /* R845 */
- 0x0000, /* R846 */
- 0x0000, /* R847 */
- 0x0000, /* R848 */
- 0x0000, /* R849 */
- 0x0000, /* R850 */
- 0x0000, /* R851 */
- 0x0000, /* R852 */
- 0x0000, /* R853 */
- 0x0000, /* R854 */
- 0x0000, /* R855 */
- 0x0000, /* R856 */
- 0x0000, /* R857 */
- 0x0000, /* R858 */
- 0x0000, /* R859 */
- 0x0000, /* R860 */
- 0x0000, /* R861 */
- 0x0000, /* R862 */
- 0x0000, /* R863 */
- 0x0000, /* R864 */
- 0x0000, /* R865 */
- 0x0000, /* R866 */
- 0x0000, /* R867 */
- 0x0000, /* R868 */
- 0x0000, /* R869 */
- 0x0000, /* R870 */
- 0x0000, /* R871 */
- 0x0000, /* R872 */
- 0x0000, /* R873 */
- 0x0000, /* R874 */
- 0x0000, /* R875 */
- 0x0000, /* R876 */
- 0x0000, /* R877 */
- 0x0000, /* R878 */
- 0x0000, /* R879 */
- 0x0000, /* R880 */
- 0x0000, /* R881 */
- 0x0000, /* R882 */
- 0x0000, /* R883 */
- 0x0000, /* R884 */
- 0x0000, /* R885 */
- 0x0000, /* R886 */
- 0x0000, /* R887 */
- 0x0000, /* R888 */
- 0x0000, /* R889 */
- 0x0000, /* R890 */
- 0x0000, /* R891 */
- 0x0000, /* R892 */
- 0x0000, /* R893 */
- 0x0000, /* R894 */
- 0x0000, /* R895 */
- 0x0000, /* R896 */
- 0x0000, /* R897 */
- 0x0000, /* R898 */
- 0x0000, /* R899 */
- 0x0000, /* R900 */
- 0x0000, /* R901 */
- 0x0000, /* R902 */
- 0x0000, /* R903 */
- 0x0000, /* R904 */
- 0x0000, /* R905 */
- 0x0000, /* R906 */
- 0x0000, /* R907 */
- 0x0000, /* R908 */
- 0x0000, /* R909 */
- 0x0000, /* R910 */
- 0x0000, /* R911 */
- 0x0000, /* R912 */
- 0x0000, /* R913 */
- 0x0000, /* R914 */
- 0x0000, /* R915 */
- 0x0000, /* R916 */
- 0x0000, /* R917 */
- 0x0000, /* R918 */
- 0x0000, /* R919 */
- 0x0000, /* R920 */
- 0x0000, /* R921 */
- 0x0000, /* R922 */
- 0x0000, /* R923 */
- 0x0000, /* R924 */
- 0x0000, /* R925 */
- 0x0000, /* R926 */
- 0x0000, /* R927 */
- 0x0000, /* R928 */
- 0x0000, /* R929 */
- 0x0000, /* R930 */
- 0x0000, /* R931 */
- 0x0000, /* R932 */
- 0x0000, /* R933 */
- 0x0000, /* R934 */
- 0x0000, /* R935 */
- 0x0000, /* R936 */
- 0x0000, /* R937 */
- 0x0000, /* R938 */
- 0x0000, /* R939 */
- 0x0000, /* R940 */
- 0x0000, /* R941 */
- 0x0000, /* R942 */
- 0x0000, /* R943 */
- 0x0000, /* R944 */
- 0x0000, /* R945 */
- 0x0000, /* R946 */
- 0x0000, /* R947 */
- 0x0000, /* R948 */
- 0x0000, /* R949 */
- 0x0000, /* R950 */
- 0x0000, /* R951 */
- 0x0000, /* R952 */
- 0x0000, /* R953 */
- 0x0000, /* R954 */
- 0x0000, /* R955 */
- 0x0000, /* R956 */
- 0x0000, /* R957 */
- 0x0000, /* R958 */
- 0x0000, /* R959 */
- 0x0000, /* R960 */
- 0x0000, /* R961 */
- 0x0000, /* R962 */
- 0x0000, /* R963 */
- 0x0000, /* R964 */
- 0x0000, /* R965 */
- 0x0000, /* R966 */
- 0x0000, /* R967 */
- 0x0000, /* R968 */
- 0x0000, /* R969 */
- 0x0000, /* R970 */
- 0x0000, /* R971 */
- 0x0000, /* R972 */
- 0x0000, /* R973 */
- 0x0000, /* R974 */
- 0x0000, /* R975 */
- 0x0000, /* R976 */
- 0x0000, /* R977 */
- 0x0000, /* R978 */
- 0x0000, /* R979 */
- 0x0000, /* R980 */
- 0x0000, /* R981 */
- 0x0000, /* R982 */
- 0x0000, /* R983 */
- 0x0000, /* R984 */
- 0x0000, /* R985 */
- 0x0000, /* R986 */
- 0x0000, /* R987 */
- 0x0000, /* R988 */
- 0x0000, /* R989 */
- 0x0000, /* R990 */
- 0x0000, /* R991 */
- 0x0000, /* R992 */
- 0x0000, /* R993 */
- 0x0000, /* R994 */
- 0x0000, /* R995 */
- 0x0000, /* R996 */
- 0x0000, /* R997 */
- 0x0000, /* R998 */
- 0x0000, /* R999 */
- 0x0000, /* R1000 */
- 0x0000, /* R1001 */
- 0x0000, /* R1002 */
- 0x0000, /* R1003 */
- 0x0000, /* R1004 */
- 0x0000, /* R1005 */
- 0x0000, /* R1006 */
- 0x0000, /* R1007 */
- 0x0000, /* R1008 */
- 0x0000, /* R1009 */
- 0x0000, /* R1010 */
- 0x0000, /* R1011 */
- 0x0000, /* R1012 */
- 0x0000, /* R1013 */
- 0x0000, /* R1014 */
- 0x0000, /* R1015 */
- 0x0000, /* R1016 */
- 0x0000, /* R1017 */
- 0x0000, /* R1018 */
- 0x0000, /* R1019 */
- 0x0000, /* R1020 */
- 0x0000, /* R1021 */
- 0x0000, /* R1022 */
- 0x0000, /* R1023 */
- 0x00C0, /* R1024 - AIF1 ADC1 Left Volume */
- 0x00C0, /* R1025 - AIF1 ADC1 Right Volume */
- 0x00C0, /* R1026 - AIF1 DAC1 Left Volume */
- 0x00C0, /* R1027 - AIF1 DAC1 Right Volume */
- 0x00C0, /* R1028 - AIF1 ADC2 Left Volume */
- 0x00C0, /* R1029 - AIF1 ADC2 Right Volume */
- 0x00C0, /* R1030 - AIF1 DAC2 Left Volume */
- 0x00C0, /* R1031 - AIF1 DAC2 Right Volume */
- 0x0000, /* R1032 */
- 0x0000, /* R1033 */
- 0x0000, /* R1034 */
- 0x0000, /* R1035 */
- 0x0000, /* R1036 */
- 0x0000, /* R1037 */
- 0x0000, /* R1038 */
- 0x0000, /* R1039 */
- 0x0000, /* R1040 - AIF1 ADC1 Filters */
- 0x0000, /* R1041 - AIF1 ADC2 Filters */
- 0x0000, /* R1042 */
- 0x0000, /* R1043 */
- 0x0000, /* R1044 */
- 0x0000, /* R1045 */
- 0x0000, /* R1046 */
- 0x0000, /* R1047 */
- 0x0000, /* R1048 */
- 0x0000, /* R1049 */
- 0x0000, /* R1050 */
- 0x0000, /* R1051 */
- 0x0000, /* R1052 */
- 0x0000, /* R1053 */
- 0x0000, /* R1054 */
- 0x0000, /* R1055 */
- 0x0200, /* R1056 - AIF1 DAC1 Filters (1) */
- 0x0010, /* R1057 - AIF1 DAC1 Filters (2) */
- 0x0200, /* R1058 - AIF1 DAC2 Filters (1) */
- 0x0010, /* R1059 - AIF1 DAC2 Filters (2) */
- 0x0000, /* R1060 */
- 0x0000, /* R1061 */
- 0x0000, /* R1062 */
- 0x0000, /* R1063 */
- 0x0000, /* R1064 */
- 0x0000, /* R1065 */
- 0x0000, /* R1066 */
- 0x0000, /* R1067 */
- 0x0000, /* R1068 */
- 0x0000, /* R1069 */
- 0x0000, /* R1070 */
- 0x0000, /* R1071 */
- 0x0068, /* R1072 - AIF1 DAC1 Noise Gate */
- 0x0068, /* R1073 - AIF1 DAC2 Noise Gate */
- 0x0000, /* R1074 */
- 0x0000, /* R1075 */
- 0x0000, /* R1076 */
- 0x0000, /* R1077 */
- 0x0000, /* R1078 */
- 0x0000, /* R1079 */
- 0x0000, /* R1080 */
- 0x0000, /* R1081 */
- 0x0000, /* R1082 */
- 0x0000, /* R1083 */
- 0x0000, /* R1084 */
- 0x0000, /* R1085 */
- 0x0000, /* R1086 */
- 0x0000, /* R1087 */
- 0x0098, /* R1088 - AIF1 DRC1 (1) */
- 0x0845, /* R1089 - AIF1 DRC1 (2) */
- 0x0000, /* R1090 - AIF1 DRC1 (3) */
- 0x0000, /* R1091 - AIF1 DRC1 (4) */
- 0x0000, /* R1092 - AIF1 DRC1 (5) */
- 0x0000, /* R1093 */
- 0x0000, /* R1094 */
- 0x0000, /* R1095 */
- 0x0000, /* R1096 */
- 0x0000, /* R1097 */
- 0x0000, /* R1098 */
- 0x0000, /* R1099 */
- 0x0000, /* R1100 */
- 0x0000, /* R1101 */
- 0x0000, /* R1102 */
- 0x0000, /* R1103 */
- 0x0098, /* R1104 - AIF1 DRC2 (1) */
- 0x0845, /* R1105 - AIF1 DRC2 (2) */
- 0x0000, /* R1106 - AIF1 DRC2 (3) */
- 0x0000, /* R1107 - AIF1 DRC2 (4) */
- 0x0000, /* R1108 - AIF1 DRC2 (5) */
- 0x0000, /* R1109 */
- 0x0000, /* R1110 */
- 0x0000, /* R1111 */
- 0x0000, /* R1112 */
- 0x0000, /* R1113 */
- 0x0000, /* R1114 */
- 0x0000, /* R1115 */
- 0x0000, /* R1116 */
- 0x0000, /* R1117 */
- 0x0000, /* R1118 */
- 0x0000, /* R1119 */
- 0x0000, /* R1120 */
- 0x0000, /* R1121 */
- 0x0000, /* R1122 */
- 0x0000, /* R1123 */
- 0x0000, /* R1124 */
- 0x0000, /* R1125 */
- 0x0000, /* R1126 */
- 0x0000, /* R1127 */
- 0x0000, /* R1128 */
- 0x0000, /* R1129 */
- 0x0000, /* R1130 */
- 0x0000, /* R1131 */
- 0x0000, /* R1132 */
- 0x0000, /* R1133 */
- 0x0000, /* R1134 */
- 0x0000, /* R1135 */
- 0x0000, /* R1136 */
- 0x0000, /* R1137 */
- 0x0000, /* R1138 */
- 0x0000, /* R1139 */
- 0x0000, /* R1140 */
- 0x0000, /* R1141 */
- 0x0000, /* R1142 */
- 0x0000, /* R1143 */
- 0x0000, /* R1144 */
- 0x0000, /* R1145 */
- 0x0000, /* R1146 */
- 0x0000, /* R1147 */
- 0x0000, /* R1148 */
- 0x0000, /* R1149 */
- 0x0000, /* R1150 */
- 0x0000, /* R1151 */
- 0x6318, /* R1152 - AIF1 DAC1 EQ Gains (1) */
- 0x6300, /* R1153 - AIF1 DAC1 EQ Gains (2) */
- 0x0FCA, /* R1154 - AIF1 DAC1 EQ Band 1 A */
- 0x0400, /* R1155 - AIF1 DAC1 EQ Band 1 B */
- 0x00D8, /* R1156 - AIF1 DAC1 EQ Band 1 PG */
- 0x1EB5, /* R1157 - AIF1 DAC1 EQ Band 2 A */
- 0xF145, /* R1158 - AIF1 DAC1 EQ Band 2 B */
- 0x0B75, /* R1159 - AIF1 DAC1 EQ Band 2 C */
- 0x01C5, /* R1160 - AIF1 DAC1 EQ Band 2 PG */
- 0x1C58, /* R1161 - AIF1 DAC1 EQ Band 3 A */
- 0xF373, /* R1162 - AIF1 DAC1 EQ Band 3 B */
- 0x0A54, /* R1163 - AIF1 DAC1 EQ Band 3 C */
- 0x0558, /* R1164 - AIF1 DAC1 EQ Band 3 PG */
- 0x168E, /* R1165 - AIF1 DAC1 EQ Band 4 A */
- 0xF829, /* R1166 - AIF1 DAC1 EQ Band 4 B */
- 0x07AD, /* R1167 - AIF1 DAC1 EQ Band 4 C */
- 0x1103, /* R1168 - AIF1 DAC1 EQ Band 4 PG */
- 0x0564, /* R1169 - AIF1 DAC1 EQ Band 5 A */
- 0x0559, /* R1170 - AIF1 DAC1 EQ Band 5 B */
- 0x4000, /* R1171 - AIF1 DAC1 EQ Band 5 PG */
- 0x0000, /* R1172 */
- 0x0000, /* R1173 */
- 0x0000, /* R1174 */
- 0x0000, /* R1175 */
- 0x0000, /* R1176 */
- 0x0000, /* R1177 */
- 0x0000, /* R1178 */
- 0x0000, /* R1179 */
- 0x0000, /* R1180 */
- 0x0000, /* R1181 */
- 0x0000, /* R1182 */
- 0x0000, /* R1183 */
- 0x6318, /* R1184 - AIF1 DAC2 EQ Gains (1) */
- 0x6300, /* R1185 - AIF1 DAC2 EQ Gains (2) */
- 0x0FCA, /* R1186 - AIF1 DAC2 EQ Band 1 A */
- 0x0400, /* R1187 - AIF1 DAC2 EQ Band 1 B */
- 0x00D8, /* R1188 - AIF1 DAC2 EQ Band 1 PG */
- 0x1EB5, /* R1189 - AIF1 DAC2 EQ Band 2 A */
- 0xF145, /* R1190 - AIF1 DAC2 EQ Band 2 B */
- 0x0B75, /* R1191 - AIF1 DAC2 EQ Band 2 C */
- 0x01C5, /* R1192 - AIF1 DAC2 EQ Band 2 PG */
- 0x1C58, /* R1193 - AIF1 DAC2 EQ Band 3 A */
- 0xF373, /* R1194 - AIF1 DAC2 EQ Band 3 B */
- 0x0A54, /* R1195 - AIF1 DAC2 EQ Band 3 C */
- 0x0558, /* R1196 - AIF1 DAC2 EQ Band 3 PG */
- 0x168E, /* R1197 - AIF1 DAC2 EQ Band 4 A */
- 0xF829, /* R1198 - AIF1 DAC2 EQ Band 4 B */
- 0x07AD, /* R1199 - AIF1 DAC2 EQ Band 4 C */
- 0x1103, /* R1200 - AIF1 DAC2 EQ Band 4 PG */
- 0x0564, /* R1201 - AIF1 DAC2 EQ Band 5 A */
- 0x0559, /* R1202 - AIF1 DAC2 EQ Band 5 B */
- 0x4000, /* R1203 - AIF1 DAC2 EQ Band 5 PG */
- 0x0000, /* R1204 */
- 0x0000, /* R1205 */
- 0x0000, /* R1206 */
- 0x0000, /* R1207 */
- 0x0000, /* R1208 */
- 0x0000, /* R1209 */
- 0x0000, /* R1210 */
- 0x0000, /* R1211 */
- 0x0000, /* R1212 */
- 0x0000, /* R1213 */
- 0x0000, /* R1214 */
- 0x0000, /* R1215 */
- 0x0000, /* R1216 */
- 0x0000, /* R1217 */
- 0x0000, /* R1218 */
- 0x0000, /* R1219 */
- 0x0000, /* R1220 */
- 0x0000, /* R1221 */
- 0x0000, /* R1222 */
- 0x0000, /* R1223 */
- 0x0000, /* R1224 */
- 0x0000, /* R1225 */
- 0x0000, /* R1226 */
- 0x0000, /* R1227 */
- 0x0000, /* R1228 */
- 0x0000, /* R1229 */
- 0x0000, /* R1230 */
- 0x0000, /* R1231 */
- 0x0000, /* R1232 */
- 0x0000, /* R1233 */
- 0x0000, /* R1234 */
- 0x0000, /* R1235 */
- 0x0000, /* R1236 */
- 0x0000, /* R1237 */
- 0x0000, /* R1238 */
- 0x0000, /* R1239 */
- 0x0000, /* R1240 */
- 0x0000, /* R1241 */
- 0x0000, /* R1242 */
- 0x0000, /* R1243 */
- 0x0000, /* R1244 */
- 0x0000, /* R1245 */
- 0x0000, /* R1246 */
- 0x0000, /* R1247 */
- 0x0000, /* R1248 */
- 0x0000, /* R1249 */
- 0x0000, /* R1250 */
- 0x0000, /* R1251 */
- 0x0000, /* R1252 */
- 0x0000, /* R1253 */
- 0x0000, /* R1254 */
- 0x0000, /* R1255 */
- 0x0000, /* R1256 */
- 0x0000, /* R1257 */
- 0x0000, /* R1258 */
- 0x0000, /* R1259 */
- 0x0000, /* R1260 */
- 0x0000, /* R1261 */
- 0x0000, /* R1262 */
- 0x0000, /* R1263 */
- 0x0000, /* R1264 */
- 0x0000, /* R1265 */
- 0x0000, /* R1266 */
- 0x0000, /* R1267 */
- 0x0000, /* R1268 */
- 0x0000, /* R1269 */
- 0x0000, /* R1270 */
- 0x0000, /* R1271 */
- 0x0000, /* R1272 */
- 0x0000, /* R1273 */
- 0x0000, /* R1274 */
- 0x0000, /* R1275 */
- 0x0000, /* R1276 */
- 0x0000, /* R1277 */
- 0x0000, /* R1278 */
- 0x0000, /* R1279 */
- 0x00C0, /* R1280 - AIF2 ADC Left Volume */
- 0x00C0, /* R1281 - AIF2 ADC Right Volume */
- 0x00C0, /* R1282 - AIF2 DAC Left Volume */
- 0x00C0, /* R1283 - AIF2 DAC Right Volume */
- 0x0000, /* R1284 */
- 0x0000, /* R1285 */
- 0x0000, /* R1286 */
- 0x0000, /* R1287 */
- 0x0000, /* R1288 */
- 0x0000, /* R1289 */
- 0x0000, /* R1290 */
- 0x0000, /* R1291 */
- 0x0000, /* R1292 */
- 0x0000, /* R1293 */
- 0x0000, /* R1294 */
- 0x0000, /* R1295 */
- 0x0000, /* R1296 - AIF2 ADC Filters */
- 0x0000, /* R1297 */
- 0x0000, /* R1298 */
- 0x0000, /* R1299 */
- 0x0000, /* R1300 */
- 0x0000, /* R1301 */
- 0x0000, /* R1302 */
- 0x0000, /* R1303 */
- 0x0000, /* R1304 */
- 0x0000, /* R1305 */
- 0x0000, /* R1306 */
- 0x0000, /* R1307 */
- 0x0000, /* R1308 */
- 0x0000, /* R1309 */
- 0x0000, /* R1310 */
- 0x0000, /* R1311 */
- 0x0200, /* R1312 - AIF2 DAC Filters (1) */
- 0x0010, /* R1313 - AIF2 DAC Filters (2) */
- 0x0000, /* R1314 */
- 0x0000, /* R1315 */
- 0x0000, /* R1316 */
- 0x0000, /* R1317 */
- 0x0000, /* R1318 */
- 0x0000, /* R1319 */
- 0x0000, /* R1320 */
- 0x0000, /* R1321 */
- 0x0000, /* R1322 */
- 0x0000, /* R1323 */
- 0x0000, /* R1324 */
- 0x0000, /* R1325 */
- 0x0000, /* R1326 */
- 0x0000, /* R1327 */
- 0x0068, /* R1328 - AIF2 DAC Noise Gate */
- 0x0000, /* R1329 */
- 0x0000, /* R1330 */
- 0x0000, /* R1331 */
- 0x0000, /* R1332 */
- 0x0000, /* R1333 */
- 0x0000, /* R1334 */
- 0x0000, /* R1335 */
- 0x0000, /* R1336 */
- 0x0000, /* R1337 */
- 0x0000, /* R1338 */
- 0x0000, /* R1339 */
- 0x0000, /* R1340 */
- 0x0000, /* R1341 */
- 0x0000, /* R1342 */
- 0x0000, /* R1343 */
- 0x0098, /* R1344 - AIF2 DRC (1) */
- 0x0845, /* R1345 - AIF2 DRC (2) */
- 0x0000, /* R1346 - AIF2 DRC (3) */
- 0x0000, /* R1347 - AIF2 DRC (4) */
- 0x0000, /* R1348 - AIF2 DRC (5) */
- 0x0000, /* R1349 */
- 0x0000, /* R1350 */
- 0x0000, /* R1351 */
- 0x0000, /* R1352 */
- 0x0000, /* R1353 */
- 0x0000, /* R1354 */
- 0x0000, /* R1355 */
- 0x0000, /* R1356 */
- 0x0000, /* R1357 */
- 0x0000, /* R1358 */
- 0x0000, /* R1359 */
- 0x0000, /* R1360 */
- 0x0000, /* R1361 */
- 0x0000, /* R1362 */
- 0x0000, /* R1363 */
- 0x0000, /* R1364 */
- 0x0000, /* R1365 */
- 0x0000, /* R1366 */
- 0x0000, /* R1367 */
- 0x0000, /* R1368 */
- 0x0000, /* R1369 */
- 0x0000, /* R1370 */
- 0x0000, /* R1371 */
- 0x0000, /* R1372 */
- 0x0000, /* R1373 */
- 0x0000, /* R1374 */
- 0x0000, /* R1375 */
- 0x0000, /* R1376 */
- 0x0000, /* R1377 */
- 0x0000, /* R1378 */
- 0x0000, /* R1379 */
- 0x0000, /* R1380 */
- 0x0000, /* R1381 */
- 0x0000, /* R1382 */
- 0x0000, /* R1383 */
- 0x0000, /* R1384 */
- 0x0000, /* R1385 */
- 0x0000, /* R1386 */
- 0x0000, /* R1387 */
- 0x0000, /* R1388 */
- 0x0000, /* R1389 */
- 0x0000, /* R1390 */
- 0x0000, /* R1391 */
- 0x0000, /* R1392 */
- 0x0000, /* R1393 */
- 0x0000, /* R1394 */
- 0x0000, /* R1395 */
- 0x0000, /* R1396 */
- 0x0000, /* R1397 */
- 0x0000, /* R1398 */
- 0x0000, /* R1399 */
- 0x0000, /* R1400 */
- 0x0000, /* R1401 */
- 0x0000, /* R1402 */
- 0x0000, /* R1403 */
- 0x0000, /* R1404 */
- 0x0000, /* R1405 */
- 0x0000, /* R1406 */
- 0x0000, /* R1407 */
- 0x6318, /* R1408 - AIF2 EQ Gains (1) */
- 0x6300, /* R1409 - AIF2 EQ Gains (2) */
- 0x0FCA, /* R1410 - AIF2 EQ Band 1 A */
- 0x0400, /* R1411 - AIF2 EQ Band 1 B */
- 0x00D8, /* R1412 - AIF2 EQ Band 1 PG */
- 0x1EB5, /* R1413 - AIF2 EQ Band 2 A */
- 0xF145, /* R1414 - AIF2 EQ Band 2 B */
- 0x0B75, /* R1415 - AIF2 EQ Band 2 C */
- 0x01C5, /* R1416 - AIF2 EQ Band 2 PG */
- 0x1C58, /* R1417 - AIF2 EQ Band 3 A */
- 0xF373, /* R1418 - AIF2 EQ Band 3 B */
- 0x0A54, /* R1419 - AIF2 EQ Band 3 C */
- 0x0558, /* R1420 - AIF2 EQ Band 3 PG */
- 0x168E, /* R1421 - AIF2 EQ Band 4 A */
- 0xF829, /* R1422 - AIF2 EQ Band 4 B */
- 0x07AD, /* R1423 - AIF2 EQ Band 4 C */
- 0x1103, /* R1424 - AIF2 EQ Band 4 PG */
- 0x0564, /* R1425 - AIF2 EQ Band 5 A */
- 0x0559, /* R1426 - AIF2 EQ Band 5 B */
- 0x4000, /* R1427 - AIF2 EQ Band 5 PG */
- 0x0000, /* R1428 */
- 0x0000, /* R1429 */
- 0x0000, /* R1430 */
- 0x0000, /* R1431 */
- 0x0000, /* R1432 */
- 0x0000, /* R1433 */
- 0x0000, /* R1434 */
- 0x0000, /* R1435 */
- 0x0000, /* R1436 */
- 0x0000, /* R1437 */
- 0x0000, /* R1438 */
- 0x0000, /* R1439 */
- 0x0000, /* R1440 */
- 0x0000, /* R1441 */
- 0x0000, /* R1442 */
- 0x0000, /* R1443 */
- 0x0000, /* R1444 */
- 0x0000, /* R1445 */
- 0x0000, /* R1446 */
- 0x0000, /* R1447 */
- 0x0000, /* R1448 */
- 0x0000, /* R1449 */
- 0x0000, /* R1450 */
- 0x0000, /* R1451 */
- 0x0000, /* R1452 */
- 0x0000, /* R1453 */
- 0x0000, /* R1454 */
- 0x0000, /* R1455 */
- 0x0000, /* R1456 */
- 0x0000, /* R1457 */
- 0x0000, /* R1458 */
- 0x0000, /* R1459 */
- 0x0000, /* R1460 */
- 0x0000, /* R1461 */
- 0x0000, /* R1462 */
- 0x0000, /* R1463 */
- 0x0000, /* R1464 */
- 0x0000, /* R1465 */
- 0x0000, /* R1466 */
- 0x0000, /* R1467 */
- 0x0000, /* R1468 */
- 0x0000, /* R1469 */
- 0x0000, /* R1470 */
- 0x0000, /* R1471 */
- 0x0000, /* R1472 */
- 0x0000, /* R1473 */
- 0x0000, /* R1474 */
- 0x0000, /* R1475 */
- 0x0000, /* R1476 */
- 0x0000, /* R1477 */
- 0x0000, /* R1478 */
- 0x0000, /* R1479 */
- 0x0000, /* R1480 */
- 0x0000, /* R1481 */
- 0x0000, /* R1482 */
- 0x0000, /* R1483 */
- 0x0000, /* R1484 */
- 0x0000, /* R1485 */
- 0x0000, /* R1486 */
- 0x0000, /* R1487 */
- 0x0000, /* R1488 */
- 0x0000, /* R1489 */
- 0x0000, /* R1490 */
- 0x0000, /* R1491 */
- 0x0000, /* R1492 */
- 0x0000, /* R1493 */
- 0x0000, /* R1494 */
- 0x0000, /* R1495 */
- 0x0000, /* R1496 */
- 0x0000, /* R1497 */
- 0x0000, /* R1498 */
- 0x0000, /* R1499 */
- 0x0000, /* R1500 */
- 0x0000, /* R1501 */
- 0x0000, /* R1502 */
- 0x0000, /* R1503 */
- 0x0000, /* R1504 */
- 0x0000, /* R1505 */
- 0x0000, /* R1506 */
- 0x0000, /* R1507 */
- 0x0000, /* R1508 */
- 0x0000, /* R1509 */
- 0x0000, /* R1510 */
- 0x0000, /* R1511 */
- 0x0000, /* R1512 */
- 0x0000, /* R1513 */
- 0x0000, /* R1514 */
- 0x0000, /* R1515 */
- 0x0000, /* R1516 */
- 0x0000, /* R1517 */
- 0x0000, /* R1518 */
- 0x0000, /* R1519 */
- 0x0000, /* R1520 */
- 0x0000, /* R1521 */
- 0x0000, /* R1522 */
- 0x0000, /* R1523 */
- 0x0000, /* R1524 */
- 0x0000, /* R1525 */
- 0x0000, /* R1526 */
- 0x0000, /* R1527 */
- 0x0000, /* R1528 */
- 0x0000, /* R1529 */
- 0x0000, /* R1530 */
- 0x0000, /* R1531 */
- 0x0000, /* R1532 */
- 0x0000, /* R1533 */
- 0x0000, /* R1534 */
- 0x0000, /* R1535 */
- 0x0000, /* R1536 - DAC1 Mixer Volumes */
- 0x0000, /* R1537 - DAC1 Left Mixer Routing */
- 0x0000, /* R1538 - DAC1 Right Mixer Routing */
- 0x0000, /* R1539 - DAC2 Mixer Volumes */
- 0x0000, /* R1540 - DAC2 Left Mixer Routing */
- 0x0000, /* R1541 - DAC2 Right Mixer Routing */
- 0x0000, /* R1542 - AIF1 ADC1 Left Mixer Routing */
- 0x0000, /* R1543 - AIF1 ADC1 Right Mixer Routing */
- 0x0000, /* R1544 - AIF1 ADC2 Left Mixer Routing */
- 0x0000, /* R1545 - AIF1 ADC2 Right mixer Routing */
- 0x0000, /* R1546 */
- 0x0000, /* R1547 */
- 0x0000, /* R1548 */
- 0x0000, /* R1549 */
- 0x0000, /* R1550 */
- 0x0000, /* R1551 */
- 0x02C0, /* R1552 - DAC1 Left Volume */
- 0x02C0, /* R1553 - DAC1 Right Volume */
- 0x02C0, /* R1554 - DAC2 Left Volume */
- 0x02C0, /* R1555 - DAC2 Right Volume */
- 0x0000, /* R1556 - DAC Softmute */
- 0x0000, /* R1557 */
- 0x0000, /* R1558 */
- 0x0000, /* R1559 */
- 0x0000, /* R1560 */
- 0x0000, /* R1561 */
- 0x0000, /* R1562 */
- 0x0000, /* R1563 */
- 0x0000, /* R1564 */
- 0x0000, /* R1565 */
- 0x0000, /* R1566 */
- 0x0000, /* R1567 */
- 0x0002, /* R1568 - Oversampling */
- 0x0000, /* R1569 - Sidetone */
-};
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c
index d0c545b..93d27b6 100644
--- a/sound/soc/codecs/wm8994.c
+++ b/sound/soc/codecs/wm8994.c
@@ -38,6 +38,11 @@
#include "wm8994.h"
#include "wm_hubs.h"
+#define WM1811_JACKDET_MODE_NONE 0x0000
+#define WM1811_JACKDET_MODE_JACK 0x0100
+#define WM1811_JACKDET_MODE_MIC 0x0080
+#define WM1811_JACKDET_MODE_AUDIO 0x0180
+
#define WM8994_NUM_DRC 3
#define WM8994_NUM_EQ 3
@@ -53,103 +58,69 @@
WM8994_AIF2_EQ_GAINS_1,
};
-static int wm8994_readable(struct snd_soc_codec *codec, unsigned int reg)
+static void wm8958_default_micdet(u16 status, void *data);
+
+static const struct wm8958_micd_rate micdet_rates[] = {
+ { 32768, true, 1, 4 },
+ { 32768, false, 1, 1 },
+ { 44100 * 256, true, 7, 10 },
+ { 44100 * 256, false, 7, 10 },
+};
+
+static const struct wm8958_micd_rate jackdet_rates[] = {
+ { 32768, true, 0, 1 },
+ { 32768, false, 0, 1 },
+ { 44100 * 256, true, 7, 10 },
+ { 44100 * 256, false, 7, 10 },
+};
+
+static void wm8958_micd_set_rate(struct snd_soc_codec *codec)
{
struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
- struct wm8994 *control = codec->control_data;
+ int best, i, sysclk, val;
+ bool idle;
+ const struct wm8958_micd_rate *rates;
+ int num_rates;
- switch (reg) {
- case WM8994_GPIO_1:
- case WM8994_GPIO_2:
- case WM8994_GPIO_3:
- case WM8994_GPIO_4:
- case WM8994_GPIO_5:
- case WM8994_GPIO_6:
- case WM8994_GPIO_7:
- case WM8994_GPIO_8:
- case WM8994_GPIO_9:
- case WM8994_GPIO_10:
- case WM8994_GPIO_11:
- case WM8994_INTERRUPT_STATUS_1:
- case WM8994_INTERRUPT_STATUS_2:
- case WM8994_INTERRUPT_RAW_STATUS_2:
- return 1;
+ if (wm8994->jack_cb != wm8958_default_micdet)
+ return;
- case WM8958_DSP2_PROGRAM:
- case WM8958_DSP2_CONFIG:
- case WM8958_DSP2_EXECCONTROL:
- if (control->type == WM8958)
- return 1;
- else
- return 0;
+ idle = !wm8994->jack_mic;
- default:
- break;
+ sysclk = snd_soc_read(codec, WM8994_CLOCKING_1);
+ if (sysclk & WM8994_SYSCLK_SRC)
+ sysclk = wm8994->aifclk[1];
+ else
+ sysclk = wm8994->aifclk[0];
+
+ if (wm8994->pdata && wm8994->pdata->micd_rates) {
+ rates = wm8994->pdata->micd_rates;
+ num_rates = wm8994->pdata->num_micd_rates;
+ } else if (wm8994->jackdet) {
+ rates = jackdet_rates;
+ num_rates = ARRAY_SIZE(jackdet_rates);
+ } else {
+ rates = micdet_rates;
+ num_rates = ARRAY_SIZE(micdet_rates);
}
- if (reg >= WM8994_CACHE_SIZE)
- return 0;
- return wm8994_access_masks[reg].readable != 0;
-}
-
-static int wm8994_volatile(struct snd_soc_codec *codec, unsigned int reg)
-{
- if (reg >= WM8994_CACHE_SIZE)
- return 1;
-
- switch (reg) {
- case WM8994_SOFTWARE_RESET:
- case WM8994_CHIP_REVISION:
- case WM8994_DC_SERVO_1:
- case WM8994_DC_SERVO_READBACK:
- case WM8994_RATE_STATUS:
- case WM8994_LDO_1:
- case WM8994_LDO_2:
- case WM8958_DSP2_EXECCONTROL:
- case WM8958_MIC_DETECT_3:
- case WM8994_DC_SERVO_4E:
- return 1;
- default:
- return 0;
- }
-}
-
-static int wm8994_write(struct snd_soc_codec *codec, unsigned int reg,
- unsigned int value)
-{
- int ret;
-
- BUG_ON(reg > WM8994_MAX_REGISTER);
-
- if (!wm8994_volatile(codec, reg)) {
- ret = snd_soc_cache_write(codec, reg, value);
- if (ret != 0)
- dev_err(codec->dev, "Cache write to %x failed: %d\n",
- reg, ret);
+ best = 0;
+ for (i = 0; i < num_rates; i++) {
+ if (rates[i].idle != idle)
+ continue;
+ if (abs(rates[i].sysclk - sysclk) <
+ abs(rates[best].sysclk - sysclk))
+ best = i;
+ else if (rates[best].idle != idle)
+ best = i;
}
- return wm8994_reg_write(codec->control_data, reg, value);
-}
+ val = rates[best].start << WM8958_MICD_BIAS_STARTTIME_SHIFT
+ | rates[best].rate << WM8958_MICD_RATE_SHIFT;
-static unsigned int wm8994_read(struct snd_soc_codec *codec,
- unsigned int reg)
-{
- unsigned int val;
- int ret;
-
- BUG_ON(reg > WM8994_MAX_REGISTER);
-
- if (!wm8994_volatile(codec, reg) && wm8994_readable(codec, reg) &&
- reg < codec->driver->reg_cache_size) {
- ret = snd_soc_cache_read(codec, reg, &val);
- if (ret >= 0)
- return val;
- else
- dev_err(codec->dev, "Cache read from %x failed: %d\n",
- reg, ret);
- }
-
- return wm8994_reg_read(codec->control_data, reg);
+ snd_soc_update_bits(codec, WM8958_MIC_DETECT_1,
+ WM8958_MICD_BIAS_STARTTIME_MASK |
+ WM8958_MICD_RATE_MASK, val);
}
static int configure_aif_clock(struct snd_soc_codec *codec, int aif)
@@ -221,8 +192,10 @@
*/
/* If they're equal it doesn't matter which is used */
- if (wm8994->aifclk[0] == wm8994->aifclk[1])
+ if (wm8994->aifclk[0] == wm8994->aifclk[1]) {
+ wm8958_micd_set_rate(codec);
return 0;
+ }
if (wm8994->aifclk[0] < wm8994->aifclk[1])
new = WM8994_SYSCLK_SRC;
@@ -231,10 +204,10 @@
change = snd_soc_update_bits(codec, WM8994_CLOCKING_1,
WM8994_SYSCLK_SRC, new);
- if (!change)
- return 0;
+ if (change)
+ snd_soc_dapm_sync(&codec->dapm);
- snd_soc_dapm_sync(&codec->dapm);
+ wm8958_micd_set_rate(codec);
return 0;
}
@@ -708,6 +681,74 @@
mixin_boost_tlv),
};
+/* We run all mode setting through a function to enforce audio mode */
+static void wm1811_jackdet_set_mode(struct snd_soc_codec *codec, u16 mode)
+{
+ struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+
+ if (wm8994->active_refcount)
+ mode = WM1811_JACKDET_MODE_AUDIO;
+
+ snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
+ WM1811_JACKDET_MODE_MASK, mode);
+
+ if (mode == WM1811_JACKDET_MODE_MIC)
+ msleep(2);
+}
+
+static void active_reference(struct snd_soc_codec *codec)
+{
+ struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+
+ mutex_lock(&wm8994->accdet_lock);
+
+ wm8994->active_refcount++;
+
+ dev_dbg(codec->dev, "Active refcount incremented, now %d\n",
+ wm8994->active_refcount);
+
+ if (wm8994->active_refcount == 1) {
+ /* If we're using jack detection go into audio mode */
+ if (wm8994->jackdet && wm8994->jack_cb) {
+ snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
+ WM1811_JACKDET_MODE_MASK,
+ WM1811_JACKDET_MODE_AUDIO);
+ msleep(2);
+ }
+ }
+
+ mutex_unlock(&wm8994->accdet_lock);
+}
+
+static void active_dereference(struct snd_soc_codec *codec)
+{
+ struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+ u16 mode;
+
+ mutex_lock(&wm8994->accdet_lock);
+
+ wm8994->active_refcount--;
+
+ dev_dbg(codec->dev, "Active refcount decremented, now %d\n",
+ wm8994->active_refcount);
+
+ if (wm8994->active_refcount == 0) {
+ /* Go into appropriate detection only mode */
+ if (wm8994->jackdet && wm8994->jack_cb) {
+ if (wm8994->jack_mic || wm8994->mic_detecting)
+ mode = WM1811_JACKDET_MODE_MIC;
+ else
+ mode = WM1811_JACKDET_MODE_JACK;
+
+ snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
+ WM1811_JACKDET_MODE_MASK,
+ mode);
+ }
+ }
+
+ mutex_unlock(&wm8994->accdet_lock);
+}
+
static int clk_sys_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
@@ -1768,7 +1809,7 @@
unsigned int freq_in, unsigned int freq_out)
{
struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
- struct wm8994 *control = codec->control_data;
+ struct wm8994 *control = wm8994->wm8994;
int reg_offset, ret;
struct fll_div fll;
u16 reg, aif1, aif2;
@@ -1865,6 +1906,8 @@
if (freq_out) {
/* Enable VMID if we need it */
if (!was_enabled) {
+ active_reference(codec);
+
switch (control->type) {
case WM8994:
vmid_reference(codec);
@@ -1908,6 +1951,8 @@
default:
break;
}
+
+ active_dereference(codec);
}
}
@@ -2017,20 +2062,33 @@
static int wm8994_set_bias_level(struct snd_soc_codec *codec,
enum snd_soc_bias_level level)
{
- struct wm8994 *control = codec->control_data;
struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+ struct wm8994 *control = wm8994->wm8994;
switch (level) {
case SND_SOC_BIAS_ON:
break;
case SND_SOC_BIAS_PREPARE:
+ /* MICBIAS into regulating mode */
+ switch (control->type) {
+ case WM8958:
+ case WM1811:
+ snd_soc_update_bits(codec, WM8958_MICBIAS1,
+ WM8958_MICB1_MODE, 0);
+ snd_soc_update_bits(codec, WM8958_MICBIAS2,
+ WM8958_MICB2_MODE, 0);
+ break;
+ default:
+ break;
+ }
+
+ if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY)
+ active_reference(codec);
break;
case SND_SOC_BIAS_STANDBY:
if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
- pm_runtime_get_sync(codec->dev);
-
switch (control->type) {
case WM8994:
if (wm8994->revision < 4) {
@@ -2077,25 +2135,40 @@
WM8994_LINEOUT2_DISCH);
}
+ if (codec->dapm.bias_level == SND_SOC_BIAS_PREPARE)
+ active_dereference(codec);
+ /* MICBIAS into bypass mode on newer devices */
+ switch (control->type) {
+ case WM8958:
+ case WM1811:
+ snd_soc_update_bits(codec, WM8958_MICBIAS1,
+ WM8958_MICB1_MODE,
+ WM8958_MICB1_MODE);
+ snd_soc_update_bits(codec, WM8958_MICBIAS2,
+ WM8958_MICB2_MODE,
+ WM8958_MICB2_MODE);
+ break;
+ default:
+ break;
+ }
break;
case SND_SOC_BIAS_OFF:
- if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY) {
+ if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY)
wm8994->cur_fw = NULL;
-
- pm_runtime_put(codec->dev);
- }
break;
}
codec->dapm.bias_level = level;
+
return 0;
}
static int wm8994_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
{
struct snd_soc_codec *codec = dai->codec;
- struct wm8994 *control = codec->control_data;
+ struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+ struct wm8994 *control = wm8994->wm8994;
int ms_reg;
int aif1_reg;
int ms = 0;
@@ -2395,7 +2468,8 @@
struct snd_soc_dai *dai)
{
struct snd_soc_codec *codec = dai->codec;
- struct wm8994 *control = codec->control_data;
+ struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+ struct wm8994 *control = wm8994->wm8994;
int aif1_reg;
int aif1 = 0;
@@ -2536,7 +2610,7 @@
#define WM8994_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
-static struct snd_soc_dai_ops wm8994_aif1_dai_ops = {
+static const struct snd_soc_dai_ops wm8994_aif1_dai_ops = {
.set_sysclk = wm8994_set_dai_sysclk,
.set_fmt = wm8994_set_dai_fmt,
.hw_params = wm8994_hw_params,
@@ -2546,7 +2620,7 @@
.set_tristate = wm8994_set_tristate,
};
-static struct snd_soc_dai_ops wm8994_aif2_dai_ops = {
+static const struct snd_soc_dai_ops wm8994_aif2_dai_ops = {
.set_sysclk = wm8994_set_dai_sysclk,
.set_fmt = wm8994_set_dai_fmt,
.hw_params = wm8994_hw_params,
@@ -2556,7 +2630,7 @@
.set_tristate = wm8994_set_tristate,
};
-static struct snd_soc_dai_ops wm8994_aif3_dai_ops = {
+static const struct snd_soc_dai_ops wm8994_aif3_dai_ops = {
.hw_params = wm8994_aif3_hw_params,
.set_tristate = wm8994_set_tristate,
};
@@ -2623,10 +2697,10 @@
};
#ifdef CONFIG_PM
-static int wm8994_suspend(struct snd_soc_codec *codec, pm_message_t state)
+static int wm8994_suspend(struct snd_soc_codec *codec)
{
struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
- struct wm8994 *control = codec->control_data;
+ struct wm8994 *control = wm8994->wm8994;
int i, ret;
switch (control->type) {
@@ -2634,6 +2708,9 @@
snd_soc_update_bits(codec, WM8994_MICBIAS, WM8994_MICD_ENA, 0);
break;
case WM1811:
+ snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
+ WM1811_JACKDET_MODE_MASK, 0);
+ /* Fall through */
case WM8958:
snd_soc_update_bits(codec, WM8958_MIC_DETECT_1,
WM8958_MICD_ENA, 0);
@@ -2657,14 +2734,14 @@
static int wm8994_resume(struct snd_soc_codec *codec)
{
struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
- struct wm8994 *control = codec->control_data;
+ struct wm8994 *control = wm8994->wm8994;
int i, ret;
unsigned int val, mask;
if (wm8994->revision < 4) {
/* force a HW read */
- val = wm8994_reg_read(codec->control_data,
- WM8994_POWER_MANAGEMENT_5);
+ ret = regmap_read(control->regmap,
+ WM8994_POWER_MANAGEMENT_5, &val);
/* modify the cache only */
codec->cache_only = 1;
@@ -2703,6 +2780,13 @@
WM8994_MICD_ENA, WM8994_MICD_ENA);
break;
case WM1811:
+ if (wm8994->jackdet && wm8994->jack_cb) {
+ /* Restart from idle */
+ snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
+ WM1811_JACKDET_MODE_MASK,
+ WM1811_JACKDET_MODE_JACK);
+ break;
+ }
case WM8958:
if (wm8994->jack_cb)
snd_soc_update_bits(codec, WM8958_MIC_DETECT_1,
@@ -2815,8 +2899,8 @@
};
/* We need an array of texts for the enum API */
- wm8994->drc_texts = kmalloc(sizeof(char *)
- * pdata->num_drc_cfgs, GFP_KERNEL);
+ wm8994->drc_texts = devm_kzalloc(wm8994->codec->dev,
+ sizeof(char *) * pdata->num_drc_cfgs, GFP_KERNEL);
if (!wm8994->drc_texts) {
dev_err(wm8994->codec->dev,
"Failed to allocate %d DRC config texts\n",
@@ -2879,7 +2963,7 @@
{
struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
struct wm8994_micdet *micdet;
- struct wm8994 *control = codec->control_data;
+ struct wm8994 *control = wm8994->wm8994;
int reg;
if (control->type != WM8994)
@@ -2962,21 +3046,136 @@
{
struct snd_soc_codec *codec = data;
struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
- int report = 0;
+ int report;
- /* If nothing present then clear our statuses */
- if (!(status & WM8958_MICD_STS))
- goto done;
+ dev_dbg(codec->dev, "MICDET %x\n", status);
- report = SND_JACK_MICROPHONE;
+ /* Either nothing present or just starting detection */
+ if (!(status & WM8958_MICD_STS)) {
+ if (!wm8994->jackdet) {
+ /* If nothing present then clear our statuses */
+ dev_dbg(codec->dev, "Detected open circuit\n");
+ wm8994->jack_mic = false;
+ wm8994->mic_detecting = true;
- /* Everything else is buttons; just assign slots */
- if (status & 0x1c)
- report |= SND_JACK_BTN_0;
+ wm8958_micd_set_rate(codec);
-done:
- snd_soc_jack_report(wm8994->micdet[0].jack, report,
- SND_JACK_BTN_0 | SND_JACK_MICROPHONE);
+ snd_soc_jack_report(wm8994->micdet[0].jack, 0,
+ wm8994->btn_mask |
+ SND_JACK_HEADSET);
+ }
+ return;
+ }
+
+ /* If the measurement is showing a high impedence we've got a
+ * microphone.
+ */
+ if (wm8994->mic_detecting && (status & 0x600)) {
+ dev_dbg(codec->dev, "Detected microphone\n");
+
+ wm8994->mic_detecting = false;
+ wm8994->jack_mic = true;
+
+ wm8958_micd_set_rate(codec);
+
+ snd_soc_jack_report(wm8994->micdet[0].jack, SND_JACK_HEADSET,
+ SND_JACK_HEADSET);
+ }
+
+
+ if (wm8994->mic_detecting && status & 0x4) {
+ dev_dbg(codec->dev, "Detected headphone\n");
+ wm8994->mic_detecting = false;
+
+ wm8958_micd_set_rate(codec);
+
+ snd_soc_jack_report(wm8994->micdet[0].jack, SND_JACK_HEADPHONE,
+ SND_JACK_HEADSET);
+
+ /* If we have jackdet that will detect removal */
+ if (wm8994->jackdet) {
+ snd_soc_update_bits(codec, WM8958_MIC_DETECT_1,
+ WM8958_MICD_ENA, 0);
+
+ wm1811_jackdet_set_mode(codec,
+ WM1811_JACKDET_MODE_JACK);
+ }
+ }
+
+ /* Report short circuit as a button */
+ if (wm8994->jack_mic) {
+ report = 0;
+ if (status & 0x4)
+ report |= SND_JACK_BTN_0;
+
+ if (status & 0x8)
+ report |= SND_JACK_BTN_1;
+
+ if (status & 0x10)
+ report |= SND_JACK_BTN_2;
+
+ if (status & 0x20)
+ report |= SND_JACK_BTN_3;
+
+ if (status & 0x40)
+ report |= SND_JACK_BTN_4;
+
+ if (status & 0x80)
+ report |= SND_JACK_BTN_5;
+
+ snd_soc_jack_report(wm8994->micdet[0].jack, report,
+ wm8994->btn_mask);
+ }
+}
+
+static irqreturn_t wm1811_jackdet_irq(int irq, void *data)
+{
+ struct wm8994_priv *wm8994 = data;
+ struct snd_soc_codec *codec = wm8994->codec;
+ int reg;
+
+ mutex_lock(&wm8994->accdet_lock);
+
+ reg = snd_soc_read(codec, WM1811_JACKDET_CTRL);
+ if (reg < 0) {
+ dev_err(codec->dev, "Failed to read jack status: %d\n", reg);
+ mutex_unlock(&wm8994->accdet_lock);
+ return IRQ_NONE;
+ }
+
+ dev_dbg(codec->dev, "JACKDET %x\n", reg);
+
+ if (reg & WM1811_JACKDET_LVL) {
+ dev_dbg(codec->dev, "Jack detected\n");
+
+ snd_soc_jack_report(wm8994->micdet[0].jack,
+ SND_JACK_MECHANICAL, SND_JACK_MECHANICAL);
+
+ /*
+ * Start off measument of microphone impedence to find
+ * out what's actually there.
+ */
+ wm8994->mic_detecting = true;
+ wm1811_jackdet_set_mode(codec, WM1811_JACKDET_MODE_MIC);
+ snd_soc_update_bits(codec, WM8958_MIC_DETECT_1,
+ WM8958_MICD_ENA, WM8958_MICD_ENA);
+ } else {
+ dev_dbg(codec->dev, "Jack not detected\n");
+
+ snd_soc_jack_report(wm8994->micdet[0].jack, 0,
+ SND_JACK_MECHANICAL | SND_JACK_HEADSET |
+ wm8994->btn_mask);
+
+ wm8994->mic_detecting = false;
+ wm8994->jack_mic = false;
+ snd_soc_update_bits(codec, WM8958_MIC_DETECT_1,
+ WM8958_MICD_ENA, 0);
+ wm1811_jackdet_set_mode(codec, WM1811_JACKDET_MODE_JACK);
+ }
+
+ mutex_unlock(&wm8994->accdet_lock);
+
+ return IRQ_HANDLED;
}
/**
@@ -2999,7 +3198,8 @@
wm8958_micdet_cb cb, void *cb_data)
{
struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
- struct wm8994 *control = codec->control_data;
+ struct wm8994 *control = wm8994->wm8994;
+ u16 micd_lvl_sel;
switch (control->type) {
case WM1811:
@@ -3016,15 +3216,50 @@
cb_data = codec;
}
+ snd_soc_dapm_force_enable_pin(&codec->dapm, "CLK_SYS");
+
wm8994->micdet[0].jack = jack;
wm8994->jack_cb = cb;
wm8994->jack_cb_data = cb_data;
- snd_soc_update_bits(codec, WM8958_MIC_DETECT_1,
- WM8958_MICD_ENA, WM8958_MICD_ENA);
+ wm8994->mic_detecting = true;
+ wm8994->jack_mic = false;
+
+ wm8958_micd_set_rate(codec);
+
+ /* Detect microphones and short circuits by default */
+ if (wm8994->pdata->micd_lvl_sel)
+ micd_lvl_sel = wm8994->pdata->micd_lvl_sel;
+ else
+ micd_lvl_sel = 0x41;
+
+ wm8994->btn_mask = SND_JACK_BTN_0 | SND_JACK_BTN_1 |
+ SND_JACK_BTN_2 | SND_JACK_BTN_3 |
+ SND_JACK_BTN_4 | SND_JACK_BTN_5;
+
+ snd_soc_update_bits(codec, WM8958_MIC_DETECT_2,
+ WM8958_MICD_LVL_SEL_MASK, micd_lvl_sel);
+
+ WARN_ON(codec->dapm.bias_level > SND_SOC_BIAS_STANDBY);
+
+ /*
+ * If we can use jack detection start off with that,
+ * otherwise jump straight to microphone detection.
+ */
+ if (wm8994->jackdet) {
+ snd_soc_update_bits(codec, WM8994_LDO_1,
+ WM8994_LDO1_DISCH, 0);
+ wm1811_jackdet_set_mode(codec,
+ WM1811_JACKDET_MODE_JACK);
+ } else {
+ snd_soc_update_bits(codec, WM8958_MIC_DETECT_1,
+ WM8958_MICD_ENA, WM8958_MICD_ENA);
+ }
+
} else {
snd_soc_update_bits(codec, WM8958_MIC_DETECT_1,
WM8958_MICD_ENA, 0);
+ snd_soc_dapm_disable_pin(&codec->dapm, "CLK_SYS");
}
return 0;
@@ -3037,6 +3272,18 @@
struct snd_soc_codec *codec = wm8994->codec;
int reg, count;
+ mutex_lock(&wm8994->accdet_lock);
+
+ /*
+ * Jack detection may have detected a removal simulataneously
+ * with an update of the MICDET status; if so it will have
+ * stopped detection and we can ignore this interrupt.
+ */
+ if (!(snd_soc_read(codec, WM8958_MIC_DETECT_1) & WM8958_MICD_ENA)) {
+ mutex_unlock(&wm8994->accdet_lock);
+ return IRQ_HANDLED;
+ }
+
/* We may occasionally read a detection without an impedence
* range being provided - if that happens loop again.
*/
@@ -3044,6 +3291,7 @@
do {
reg = snd_soc_read(codec, WM8958_MIC_DETECT_3);
if (reg < 0) {
+ mutex_unlock(&wm8994->accdet_lock);
dev_err(codec->dev,
"Failed to read mic detect status: %d\n",
reg);
@@ -3074,6 +3322,8 @@
dev_warn(codec->dev, "Accessory detection with no callback\n");
out:
+ mutex_unlock(&wm8994->accdet_lock);
+
return IRQ_HANDLED;
}
@@ -3106,22 +3356,28 @@
static int wm8994_codec_probe(struct snd_soc_codec *codec)
{
- struct wm8994 *control;
+ struct wm8994 *control = dev_get_drvdata(codec->dev->parent);
struct wm8994_priv *wm8994;
struct snd_soc_dapm_context *dapm = &codec->dapm;
+ unsigned int reg;
int ret, i;
- codec->control_data = dev_get_drvdata(codec->dev->parent);
- control = codec->control_data;
+ codec->control_data = control->regmap;
- wm8994 = kzalloc(sizeof(struct wm8994_priv), GFP_KERNEL);
+ wm8994 = devm_kzalloc(codec->dev, sizeof(struct wm8994_priv),
+ GFP_KERNEL);
if (wm8994 == NULL)
return -ENOMEM;
snd_soc_codec_set_drvdata(codec, wm8994);
+ snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_REGMAP);
+
+ wm8994->wm8994 = dev_get_drvdata(codec->dev->parent);
wm8994->pdata = dev_get_platdata(codec->dev->parent);
wm8994->codec = codec;
+ mutex_init(&wm8994->accdet_lock);
+
for (i = 0; i < ARRAY_SIZE(wm8994->fll_locked); i++)
init_completion(&wm8994->fll_locked[i]);
@@ -3134,25 +3390,6 @@
pm_runtime_enable(codec->dev);
pm_runtime_resume(codec->dev);
- /* Read our current status back from the chip - we don't want to
- * reset as this may interfere with the GPIO or LDO operation. */
- for (i = 0; i < WM8994_CACHE_SIZE; i++) {
- if (!wm8994_readable(codec, i) || wm8994_volatile(codec, i))
- continue;
-
- ret = wm8994_reg_read(codec->control_data, i);
- if (ret <= 0)
- continue;
-
- ret = snd_soc_cache_write(codec, i, ret);
- if (ret != 0) {
- dev_err(codec->dev,
- "Failed to initialise cache for 0x%x: %d\n",
- i, ret);
- goto err;
- }
- }
-
/* Set revision-specific configuration */
wm8994->revision = snd_soc_read(codec, WM8994_CHIP_REVISION);
switch (control->type) {
@@ -3200,14 +3437,14 @@
break;
}
- wm8994_request_irq(codec->control_data, WM8994_IRQ_FIFOS_ERR,
+ wm8994_request_irq(wm8994->wm8994, WM8994_IRQ_FIFOS_ERR,
wm8994_fifo_error, "FIFO error", codec);
- wm8994_request_irq(codec->control_data, WM8994_IRQ_TEMP_WARN,
+ wm8994_request_irq(wm8994->wm8994, WM8994_IRQ_TEMP_WARN,
wm8994_temp_warn, "Thermal warning", codec);
- wm8994_request_irq(codec->control_data, WM8994_IRQ_TEMP_SHUT,
+ wm8994_request_irq(wm8994->wm8994, WM8994_IRQ_TEMP_SHUT,
wm8994_temp_shut, "Thermal shutdown", codec);
- ret = wm8994_request_irq(codec->control_data, WM8994_IRQ_DCS_DONE,
+ ret = wm8994_request_irq(wm8994->wm8994, WM8994_IRQ_DCS_DONE,
wm_hubs_dcs_done, "DC servo done",
&wm8994->hubs);
if (ret == 0)
@@ -3227,7 +3464,7 @@
ret);
}
- ret = wm8994_request_irq(codec->control_data,
+ ret = wm8994_request_irq(wm8994->wm8994,
WM8994_IRQ_MIC1_SHRT,
wm8994_mic_irq, "Mic 1 short",
wm8994);
@@ -3236,7 +3473,7 @@
"Failed to request Mic1 short IRQ: %d\n",
ret);
- ret = wm8994_request_irq(codec->control_data,
+ ret = wm8994_request_irq(wm8994->wm8994,
WM8994_IRQ_MIC2_DET,
wm8994_mic_irq, "Mic 2 detect",
wm8994);
@@ -3245,7 +3482,7 @@
"Failed to request Mic2 detect IRQ: %d\n",
ret);
- ret = wm8994_request_irq(codec->control_data,
+ ret = wm8994_request_irq(wm8994->wm8994,
WM8994_IRQ_MIC2_SHRT,
wm8994_mic_irq, "Mic 2 short",
wm8994);
@@ -3270,9 +3507,24 @@
}
}
+ switch (control->type) {
+ case WM1811:
+ if (wm8994->revision > 1) {
+ ret = wm8994_request_irq(wm8994->wm8994,
+ WM8994_IRQ_GPIO(6),
+ wm1811_jackdet_irq, "JACKDET",
+ wm8994);
+ if (ret == 0)
+ wm8994->jackdet = true;
+ }
+ break;
+ default:
+ break;
+ }
+
wm8994->fll_locked_irq = true;
for (i = 0; i < ARRAY_SIZE(wm8994->fll_locked); i++) {
- ret = wm8994_request_irq(codec->control_data,
+ ret = wm8994_request_irq(wm8994->wm8994,
WM8994_IRQ_FLL1_LOCK + i,
wm8994_fll_locked_irq, "FLL lock",
&wm8994->fll_locked[i]);
@@ -3284,24 +3536,24 @@
* configured on init - if a system wants to do this dynamically
* at runtime we can deal with that then.
*/
- ret = wm8994_reg_read(codec->control_data, WM8994_GPIO_1);
+ ret = regmap_read(control->regmap, WM8994_GPIO_1, ®);
if (ret < 0) {
dev_err(codec->dev, "Failed to read GPIO1 state: %d\n", ret);
goto err_irq;
}
- if ((ret & WM8994_GPN_FN_MASK) != WM8994_GP_FN_PIN_SPECIFIC) {
+ if ((reg & WM8994_GPN_FN_MASK) != WM8994_GP_FN_PIN_SPECIFIC) {
wm8994->lrclk_shared[0] = 1;
wm8994_dai[0].symmetric_rates = 1;
} else {
wm8994->lrclk_shared[0] = 0;
}
- ret = wm8994_reg_read(codec->control_data, WM8994_GPIO_6);
+ ret = regmap_read(control->regmap, WM8994_GPIO_6, ®);
if (ret < 0) {
dev_err(codec->dev, "Failed to read GPIO6 state: %d\n", ret);
goto err_irq;
}
- if ((ret & WM8994_GPN_FN_MASK) != WM8994_GP_FN_PIN_SPECIFIC) {
+ if ((reg & WM8994_GPN_FN_MASK) != WM8994_GP_FN_PIN_SPECIFIC) {
wm8994->lrclk_shared[1] = 1;
wm8994_dai[1].symmetric_rates = 1;
} else {
@@ -3368,6 +3620,19 @@
break;
}
+ /* Put MICBIAS into bypass mode by default on newer devices */
+ switch (control->type) {
+ case WM8958:
+ case WM1811:
+ snd_soc_update_bits(codec, WM8958_MICBIAS1,
+ WM8958_MICB1_MODE, WM8958_MICB1_MODE);
+ snd_soc_update_bits(codec, WM8958_MICBIAS2,
+ WM8958_MICB2_MODE, WM8958_MICB2_MODE);
+ break;
+ default:
+ break;
+ }
+
wm8994_update_class_w(codec);
wm8994_handle_pdata(wm8994);
@@ -3479,28 +3744,29 @@
return 0;
err_irq:
- wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_SHRT, wm8994);
- wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_DET, wm8994);
- wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_SHRT, wm8994);
+ if (wm8994->jackdet)
+ wm8994_free_irq(wm8994->wm8994, WM8994_IRQ_GPIO(6), wm8994);
+ wm8994_free_irq(wm8994->wm8994, WM8994_IRQ_MIC2_SHRT, wm8994);
+ wm8994_free_irq(wm8994->wm8994, WM8994_IRQ_MIC2_DET, wm8994);
+ wm8994_free_irq(wm8994->wm8994, WM8994_IRQ_MIC1_SHRT, wm8994);
if (wm8994->micdet_irq)
free_irq(wm8994->micdet_irq, wm8994);
for (i = 0; i < ARRAY_SIZE(wm8994->fll_locked); i++)
- wm8994_free_irq(codec->control_data, WM8994_IRQ_FLL1_LOCK + i,
+ wm8994_free_irq(wm8994->wm8994, WM8994_IRQ_FLL1_LOCK + i,
&wm8994->fll_locked[i]);
- wm8994_free_irq(codec->control_data, WM8994_IRQ_DCS_DONE,
+ wm8994_free_irq(wm8994->wm8994, WM8994_IRQ_DCS_DONE,
&wm8994->hubs);
- wm8994_free_irq(codec->control_data, WM8994_IRQ_FIFOS_ERR, codec);
- wm8994_free_irq(codec->control_data, WM8994_IRQ_TEMP_SHUT, codec);
- wm8994_free_irq(codec->control_data, WM8994_IRQ_TEMP_WARN, codec);
-err:
- kfree(wm8994);
+ wm8994_free_irq(wm8994->wm8994, WM8994_IRQ_FIFOS_ERR, codec);
+ wm8994_free_irq(wm8994->wm8994, WM8994_IRQ_TEMP_SHUT, codec);
+ wm8994_free_irq(wm8994->wm8994, WM8994_IRQ_TEMP_WARN, codec);
+
return ret;
}
static int wm8994_codec_remove(struct snd_soc_codec *codec)
{
struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
- struct wm8994 *control = codec->control_data;
+ struct wm8994 *control = wm8994->wm8994;
int i;
wm8994_set_bias_level(codec, SND_SOC_BIAS_OFF);
@@ -3508,24 +3774,27 @@
pm_runtime_disable(codec->dev);
for (i = 0; i < ARRAY_SIZE(wm8994->fll_locked); i++)
- wm8994_free_irq(codec->control_data, WM8994_IRQ_FLL1_LOCK + i,
+ wm8994_free_irq(wm8994->wm8994, WM8994_IRQ_FLL1_LOCK + i,
&wm8994->fll_locked[i]);
- wm8994_free_irq(codec->control_data, WM8994_IRQ_DCS_DONE,
+ wm8994_free_irq(wm8994->wm8994, WM8994_IRQ_DCS_DONE,
&wm8994->hubs);
- wm8994_free_irq(codec->control_data, WM8994_IRQ_FIFOS_ERR, codec);
- wm8994_free_irq(codec->control_data, WM8994_IRQ_TEMP_SHUT, codec);
- wm8994_free_irq(codec->control_data, WM8994_IRQ_TEMP_WARN, codec);
+ wm8994_free_irq(wm8994->wm8994, WM8994_IRQ_FIFOS_ERR, codec);
+ wm8994_free_irq(wm8994->wm8994, WM8994_IRQ_TEMP_SHUT, codec);
+ wm8994_free_irq(wm8994->wm8994, WM8994_IRQ_TEMP_WARN, codec);
+
+ if (wm8994->jackdet)
+ wm8994_free_irq(wm8994->wm8994, WM8994_IRQ_GPIO(6), wm8994);
switch (control->type) {
case WM8994:
if (wm8994->micdet_irq)
free_irq(wm8994->micdet_irq, wm8994);
- wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_DET,
+ wm8994_free_irq(wm8994->wm8994, WM8994_IRQ_MIC2_DET,
wm8994);
- wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_SHRT,
+ wm8994_free_irq(wm8994->wm8994, WM8994_IRQ_MIC1_SHRT,
wm8994);
- wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_DET,
+ wm8994_free_irq(wm8994->wm8994, WM8994_IRQ_MIC1_DET,
wm8994);
break;
@@ -3542,27 +3811,24 @@
if (wm8994->enh_eq)
release_firmware(wm8994->enh_eq);
kfree(wm8994->retune_mobile_texts);
- kfree(wm8994->drc_texts);
- kfree(wm8994);
return 0;
}
+static int wm8994_soc_volatile(struct snd_soc_codec *codec,
+ unsigned int reg)
+{
+ return true;
+}
+
static struct snd_soc_codec_driver soc_codec_dev_wm8994 = {
.probe = wm8994_codec_probe,
.remove = wm8994_codec_remove,
.suspend = wm8994_suspend,
.resume = wm8994_resume,
- .read = wm8994_read,
- .write = wm8994_write,
- .readable_register = wm8994_readable,
- .volatile_register = wm8994_volatile,
.set_bias_level = wm8994_set_bias_level,
-
- .reg_cache_size = WM8994_CACHE_SIZE,
- .reg_cache_default = wm8994_reg_defaults,
- .reg_word_size = 2,
- .compress_type = SND_SOC_RBTREE_COMPRESSION,
+ .reg_cache_size = WM8994_MAX_REGISTER,
+ .volatile_register = wm8994_soc_volatile,
};
static int __devinit wm8994_probe(struct platform_device *pdev)
@@ -3586,18 +3852,7 @@
.remove = __devexit_p(wm8994_remove),
};
-static __init int wm8994_init(void)
-{
- return platform_driver_register(&wm8994_codec_driver);
-}
-module_init(wm8994_init);
-
-static __exit void wm8994_exit(void)
-{
- platform_driver_unregister(&wm8994_codec_driver);
-}
-module_exit(wm8994_exit);
-
+module_platform_driver(wm8994_codec_driver);
MODULE_DESCRIPTION("ASoC WM8994 driver");
MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
diff --git a/sound/soc/codecs/wm8994.h b/sound/soc/codecs/wm8994.h
index f4f1355..c3a4247 100644
--- a/sound/soc/codecs/wm8994.h
+++ b/sound/soc/codecs/wm8994.h
@@ -39,16 +39,6 @@
int wm8958_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
wm8958_micdet_cb cb, void *cb_data);
-#define WM8994_CACHE_SIZE 1570
-
-struct wm8994_access_mask {
- unsigned short readable; /* Mask of readable bits */
- unsigned short writable; /* Mask of writable bits */
-};
-
-extern const struct wm8994_access_mask wm8994_access_masks[WM8994_CACHE_SIZE];
-extern const u16 wm8994_reg_defaults[WM8994_CACHE_SIZE];
-
int wm8958_aif_ev(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event);
@@ -70,10 +60,11 @@
#define WM8994_NUM_DRC 3
#define WM8994_NUM_EQ 3
+struct wm8994;
+
struct wm8994_priv {
struct wm_hubs_data hubs;
- enum snd_soc_control_type control_type;
- void *control_data;
+ struct wm8994 *wm8994;
struct snd_soc_codec *codec;
int sysclk[2];
int sysclk_rate[2];
@@ -84,6 +75,7 @@
bool fll_locked_irq;
int vmid_refcount;
+ int active_refcount;
int dac_rates[2];
int lrclk_shared[2];
@@ -125,7 +117,12 @@
const char **enh_eq_texts;
struct soc_enum enh_eq_enum;
+ struct mutex accdet_lock;
struct wm8994_micdet micdet[2];
+ bool mic_detecting;
+ bool jack_mic;
+ int btn_mask;
+ bool jackdet;
wm8958_micdet_cb jack_cb;
void *jack_cb_data;
diff --git a/sound/soc/codecs/wm8995.c b/sound/soc/codecs/wm8995.c
index 78eeb21..c8aada5 100644
--- a/sound/soc/codecs/wm8995.c
+++ b/sound/soc/codecs/wm8995.c
@@ -18,6 +18,7 @@
#include <linux/delay.h>
#include <linux/pm.h>
#include <linux/i2c.h>
+#include <linux/regmap.h>
#include <linux/spi/spi.h>
#include <linux/regulator/consumer.h>
#include <linux/slab.h>
@@ -43,88 +44,331 @@
"MICVDD"
};
-static const u16 wm8995_reg_defs[WM8995_MAX_REGISTER + 1] = {
- [0] = 0x8995, [5] = 0x0100, [16] = 0x000b, [17] = 0x000b,
- [24] = 0x02c0, [25] = 0x02c0, [26] = 0x02c0, [27] = 0x02c0,
- [28] = 0x000f, [32] = 0x0005, [33] = 0x0005, [40] = 0x0003,
- [41] = 0x0013, [48] = 0x0004, [56] = 0x09f8, [64] = 0x1f25,
- [69] = 0x0004, [82] = 0xaaaa, [84] = 0x2a2a, [146] = 0x0060,
- [256] = 0x0002, [257] = 0x8004, [520] = 0x0010, [528] = 0x0083,
- [529] = 0x0083, [548] = 0x0c80, [580] = 0x0c80, [768] = 0x4050,
- [769] = 0x4000, [771] = 0x0040, [772] = 0x0040, [773] = 0x0040,
- [774] = 0x0004, [775] = 0x0100, [784] = 0x4050, [785] = 0x4000,
- [787] = 0x0040, [788] = 0x0040, [789] = 0x0040, [1024] = 0x00c0,
- [1025] = 0x00c0, [1026] = 0x00c0, [1027] = 0x00c0, [1028] = 0x00c0,
- [1029] = 0x00c0, [1030] = 0x00c0, [1031] = 0x00c0, [1056] = 0x0200,
- [1057] = 0x0010, [1058] = 0x0200, [1059] = 0x0010, [1088] = 0x0098,
- [1089] = 0x0845, [1104] = 0x0098, [1105] = 0x0845, [1152] = 0x6318,
- [1153] = 0x6300, [1154] = 0x0fca, [1155] = 0x0400, [1156] = 0x00d8,
- [1157] = 0x1eb5, [1158] = 0xf145, [1159] = 0x0b75, [1160] = 0x01c5,
- [1161] = 0x1c58, [1162] = 0xf373, [1163] = 0x0a54, [1164] = 0x0558,
- [1165] = 0x168e, [1166] = 0xf829, [1167] = 0x07ad, [1168] = 0x1103,
- [1169] = 0x0564, [1170] = 0x0559, [1171] = 0x4000, [1184] = 0x6318,
- [1185] = 0x6300, [1186] = 0x0fca, [1187] = 0x0400, [1188] = 0x00d8,
- [1189] = 0x1eb5, [1190] = 0xf145, [1191] = 0x0b75, [1192] = 0x01c5,
- [1193] = 0x1c58, [1194] = 0xf373, [1195] = 0x0a54, [1196] = 0x0558,
- [1197] = 0x168e, [1198] = 0xf829, [1199] = 0x07ad, [1200] = 0x1103,
- [1201] = 0x0564, [1202] = 0x0559, [1203] = 0x4000, [1280] = 0x00c0,
- [1281] = 0x00c0, [1282] = 0x00c0, [1283] = 0x00c0, [1312] = 0x0200,
- [1313] = 0x0010, [1344] = 0x0098, [1345] = 0x0845, [1408] = 0x6318,
- [1409] = 0x6300, [1410] = 0x0fca, [1411] = 0x0400, [1412] = 0x00d8,
- [1413] = 0x1eb5, [1414] = 0xf145, [1415] = 0x0b75, [1416] = 0x01c5,
- [1417] = 0x1c58, [1418] = 0xf373, [1419] = 0x0a54, [1420] = 0x0558,
- [1421] = 0x168e, [1422] = 0xf829, [1423] = 0x07ad, [1424] = 0x1103,
- [1425] = 0x0564, [1426] = 0x0559, [1427] = 0x4000, [1568] = 0x0002,
- [1792] = 0xa100, [1793] = 0xa101, [1794] = 0xa101, [1795] = 0xa101,
- [1796] = 0xa101, [1797] = 0xa101, [1798] = 0xa101, [1799] = 0xa101,
- [1800] = 0xa101, [1801] = 0xa101, [1802] = 0xa101, [1803] = 0xa101,
- [1804] = 0xa101, [1805] = 0xa101, [1825] = 0x0055, [1848] = 0x3fff,
- [1849] = 0x1fff, [2049] = 0x0001, [2050] = 0x0069, [2056] = 0x0002,
- [2057] = 0x0003, [2058] = 0x0069, [12288] = 0x0001, [12289] = 0x0001,
- [12291] = 0x0006, [12292] = 0x0040, [12293] = 0x0001, [12294] = 0x000f,
- [12295] = 0x0006, [12296] = 0x0001, [12297] = 0x0003, [12298] = 0x0104,
- [12300] = 0x0060, [12301] = 0x0011, [12302] = 0x0401, [12304] = 0x0050,
- [12305] = 0x0003, [12306] = 0x0100, [12308] = 0x0051, [12309] = 0x0003,
- [12310] = 0x0104, [12311] = 0x000a, [12312] = 0x0060, [12313] = 0x003b,
- [12314] = 0x0502, [12315] = 0x0100, [12316] = 0x2fff, [12320] = 0x2fff,
- [12324] = 0x2fff, [12328] = 0x2fff, [12332] = 0x2fff, [12336] = 0x2fff,
- [12340] = 0x2fff, [12344] = 0x2fff, [12348] = 0x2fff, [12352] = 0x0001,
- [12353] = 0x0001, [12355] = 0x0006, [12356] = 0x0040, [12357] = 0x0001,
- [12358] = 0x000f, [12359] = 0x0006, [12360] = 0x0001, [12361] = 0x0003,
- [12362] = 0x0104, [12364] = 0x0060, [12365] = 0x0011, [12366] = 0x0401,
- [12368] = 0x0050, [12369] = 0x0003, [12370] = 0x0100, [12372] = 0x0060,
- [12373] = 0x003b, [12374] = 0x0502, [12375] = 0x0100, [12376] = 0x2fff,
- [12380] = 0x2fff, [12384] = 0x2fff, [12388] = 0x2fff, [12392] = 0x2fff,
- [12396] = 0x2fff, [12400] = 0x2fff, [12404] = 0x2fff, [12408] = 0x2fff,
- [12412] = 0x2fff, [12416] = 0x0001, [12417] = 0x0001, [12419] = 0x0006,
- [12420] = 0x0040, [12421] = 0x0001, [12422] = 0x000f, [12423] = 0x0006,
- [12424] = 0x0001, [12425] = 0x0003, [12426] = 0x0106, [12428] = 0x0061,
- [12429] = 0x0011, [12430] = 0x0401, [12432] = 0x0050, [12433] = 0x0003,
- [12434] = 0x0102, [12436] = 0x0051, [12437] = 0x0003, [12438] = 0x0106,
- [12439] = 0x000a, [12440] = 0x0061, [12441] = 0x003b, [12442] = 0x0502,
- [12443] = 0x0100, [12444] = 0x2fff, [12448] = 0x2fff, [12452] = 0x2fff,
- [12456] = 0x2fff, [12460] = 0x2fff, [12464] = 0x2fff, [12468] = 0x2fff,
- [12472] = 0x2fff, [12476] = 0x2fff, [12480] = 0x0001, [12481] = 0x0001,
- [12483] = 0x0006, [12484] = 0x0040, [12485] = 0x0001, [12486] = 0x000f,
- [12487] = 0x0006, [12488] = 0x0001, [12489] = 0x0003, [12490] = 0x0106,
- [12492] = 0x0061, [12493] = 0x0011, [12494] = 0x0401, [12496] = 0x0050,
- [12497] = 0x0003, [12498] = 0x0102, [12500] = 0x0061, [12501] = 0x003b,
- [12502] = 0x0502, [12503] = 0x0100, [12504] = 0x2fff, [12508] = 0x2fff,
- [12512] = 0x2fff, [12516] = 0x2fff, [12520] = 0x2fff, [12524] = 0x2fff,
- [12528] = 0x2fff, [12532] = 0x2fff, [12536] = 0x2fff, [12540] = 0x2fff,
- [12544] = 0x0060, [12546] = 0x0601, [12548] = 0x0050, [12550] = 0x0100,
- [12552] = 0x0001, [12554] = 0x0104, [12555] = 0x0100, [12556] = 0x2fff,
- [12560] = 0x2fff, [12564] = 0x2fff, [12568] = 0x2fff, [12572] = 0x2fff,
- [12576] = 0x2fff, [12580] = 0x2fff, [12584] = 0x2fff, [12588] = 0x2fff,
- [12592] = 0x2fff, [12596] = 0x2fff, [12600] = 0x2fff, [12604] = 0x2fff,
- [12608] = 0x0061, [12610] = 0x0601, [12612] = 0x0050, [12614] = 0x0102,
- [12616] = 0x0001, [12618] = 0x0106, [12619] = 0x0100, [12620] = 0x2fff,
- [12624] = 0x2fff, [12628] = 0x2fff, [12632] = 0x2fff, [12636] = 0x2fff,
- [12640] = 0x2fff, [12644] = 0x2fff, [12648] = 0x2fff, [12652] = 0x2fff,
- [12656] = 0x2fff, [12660] = 0x2fff, [12664] = 0x2fff, [12668] = 0x2fff,
- [12672] = 0x0060, [12674] = 0x0601, [12676] = 0x0061, [12678] = 0x0601,
- [12680] = 0x0050, [12682] = 0x0300, [12684] = 0x0001, [12686] = 0x0304,
- [12688] = 0x0040, [12690] = 0x000f, [12692] = 0x0001, [12695] = 0x0100
+static struct reg_default wm8995_reg_defaults[] = {
+ { 0, 0x8995 },
+ { 5, 0x0100 },
+ { 16, 0x000b },
+ { 17, 0x000b },
+ { 24, 0x02c0 },
+ { 25, 0x02c0 },
+ { 26, 0x02c0 },
+ { 27, 0x02c0 },
+ { 28, 0x000f },
+ { 32, 0x0005 },
+ { 33, 0x0005 },
+ { 40, 0x0003 },
+ { 41, 0x0013 },
+ { 48, 0x0004 },
+ { 56, 0x09f8 },
+ { 64, 0x1f25 },
+ { 69, 0x0004 },
+ { 82, 0xaaaa },
+ { 84, 0x2a2a },
+ { 146, 0x0060 },
+ { 256, 0x0002 },
+ { 257, 0x8004 },
+ { 520, 0x0010 },
+ { 528, 0x0083 },
+ { 529, 0x0083 },
+ { 548, 0x0c80 },
+ { 580, 0x0c80 },
+ { 768, 0x4050 },
+ { 769, 0x4000 },
+ { 771, 0x0040 },
+ { 772, 0x0040 },
+ { 773, 0x0040 },
+ { 774, 0x0004 },
+ { 775, 0x0100 },
+ { 784, 0x4050 },
+ { 785, 0x4000 },
+ { 787, 0x0040 },
+ { 788, 0x0040 },
+ { 789, 0x0040 },
+ { 1024, 0x00c0 },
+ { 1025, 0x00c0 },
+ { 1026, 0x00c0 },
+ { 1027, 0x00c0 },
+ { 1028, 0x00c0 },
+ { 1029, 0x00c0 },
+ { 1030, 0x00c0 },
+ { 1031, 0x00c0 },
+ { 1056, 0x0200 },
+ { 1057, 0x0010 },
+ { 1058, 0x0200 },
+ { 1059, 0x0010 },
+ { 1088, 0x0098 },
+ { 1089, 0x0845 },
+ { 1104, 0x0098 },
+ { 1105, 0x0845 },
+ { 1152, 0x6318 },
+ { 1153, 0x6300 },
+ { 1154, 0x0fca },
+ { 1155, 0x0400 },
+ { 1156, 0x00d8 },
+ { 1157, 0x1eb5 },
+ { 1158, 0xf145 },
+ { 1159, 0x0b75 },
+ { 1160, 0x01c5 },
+ { 1161, 0x1c58 },
+ { 1162, 0xf373 },
+ { 1163, 0x0a54 },
+ { 1164, 0x0558 },
+ { 1165, 0x168e },
+ { 1166, 0xf829 },
+ { 1167, 0x07ad },
+ { 1168, 0x1103 },
+ { 1169, 0x0564 },
+ { 1170, 0x0559 },
+ { 1171, 0x4000 },
+ { 1184, 0x6318 },
+ { 1185, 0x6300 },
+ { 1186, 0x0fca },
+ { 1187, 0x0400 },
+ { 1188, 0x00d8 },
+ { 1189, 0x1eb5 },
+ { 1190, 0xf145 },
+ { 1191, 0x0b75 },
+ { 1192, 0x01c5 },
+ { 1193, 0x1c58 },
+ { 1194, 0xf373 },
+ { 1195, 0x0a54 },
+ { 1196, 0x0558 },
+ { 1197, 0x168e },
+ { 1198, 0xf829 },
+ { 1199, 0x07ad },
+ { 1200, 0x1103 },
+ { 1201, 0x0564 },
+ { 1202, 0x0559 },
+ { 1203, 0x4000 },
+ { 1280, 0x00c0 },
+ { 1281, 0x00c0 },
+ { 1282, 0x00c0 },
+ { 1283, 0x00c0 },
+ { 1312, 0x0200 },
+ { 1313, 0x0010 },
+ { 1344, 0x0098 },
+ { 1345, 0x0845 },
+ { 1408, 0x6318 },
+ { 1409, 0x6300 },
+ { 1410, 0x0fca },
+ { 1411, 0x0400 },
+ { 1412, 0x00d8 },
+ { 1413, 0x1eb5 },
+ { 1414, 0xf145 },
+ { 1415, 0x0b75 },
+ { 1416, 0x01c5 },
+ { 1417, 0x1c58 },
+ { 1418, 0xf373 },
+ { 1419, 0x0a54 },
+ { 1420, 0x0558 },
+ { 1421, 0x168e },
+ { 1422, 0xf829 },
+ { 1423, 0x07ad },
+ { 1424, 0x1103 },
+ { 1425, 0x0564 },
+ { 1426, 0x0559 },
+ { 1427, 0x4000 },
+ { 1568, 0x0002 },
+ { 1792, 0xa100 },
+ { 1793, 0xa101 },
+ { 1794, 0xa101 },
+ { 1795, 0xa101 },
+ { 1796, 0xa101 },
+ { 1797, 0xa101 },
+ { 1798, 0xa101 },
+ { 1799, 0xa101 },
+ { 1800, 0xa101 },
+ { 1801, 0xa101 },
+ { 1802, 0xa101 },
+ { 1803, 0xa101 },
+ { 1804, 0xa101 },
+ { 1805, 0xa101 },
+ { 1825, 0x0055 },
+ { 1848, 0x3fff },
+ { 1849, 0x1fff },
+ { 2049, 0x0001 },
+ { 2050, 0x0069 },
+ { 2056, 0x0002 },
+ { 2057, 0x0003 },
+ { 2058, 0x0069 },
+ { 12288, 0x0001 },
+ { 12289, 0x0001 },
+ { 12291, 0x0006 },
+ { 12292, 0x0040 },
+ { 12293, 0x0001 },
+ { 12294, 0x000f },
+ { 12295, 0x0006 },
+ { 12296, 0x0001 },
+ { 12297, 0x0003 },
+ { 12298, 0x0104 },
+ { 12300, 0x0060 },
+ { 12301, 0x0011 },
+ { 12302, 0x0401 },
+ { 12304, 0x0050 },
+ { 12305, 0x0003 },
+ { 12306, 0x0100 },
+ { 12308, 0x0051 },
+ { 12309, 0x0003 },
+ { 12310, 0x0104 },
+ { 12311, 0x000a },
+ { 12312, 0x0060 },
+ { 12313, 0x003b },
+ { 12314, 0x0502 },
+ { 12315, 0x0100 },
+ { 12316, 0x2fff },
+ { 12320, 0x2fff },
+ { 12324, 0x2fff },
+ { 12328, 0x2fff },
+ { 12332, 0x2fff },
+ { 12336, 0x2fff },
+ { 12340, 0x2fff },
+ { 12344, 0x2fff },
+ { 12348, 0x2fff },
+ { 12352, 0x0001 },
+ { 12353, 0x0001 },
+ { 12355, 0x0006 },
+ { 12356, 0x0040 },
+ { 12357, 0x0001 },
+ { 12358, 0x000f },
+ { 12359, 0x0006 },
+ { 12360, 0x0001 },
+ { 12361, 0x0003 },
+ { 12362, 0x0104 },
+ { 12364, 0x0060 },
+ { 12365, 0x0011 },
+ { 12366, 0x0401 },
+ { 12368, 0x0050 },
+ { 12369, 0x0003 },
+ { 12370, 0x0100 },
+ { 12372, 0x0060 },
+ { 12373, 0x003b },
+ { 12374, 0x0502 },
+ { 12375, 0x0100 },
+ { 12376, 0x2fff },
+ { 12380, 0x2fff },
+ { 12384, 0x2fff },
+ { 12388, 0x2fff },
+ { 12392, 0x2fff },
+ { 12396, 0x2fff },
+ { 12400, 0x2fff },
+ { 12404, 0x2fff },
+ { 12408, 0x2fff },
+ { 12412, 0x2fff },
+ { 12416, 0x0001 },
+ { 12417, 0x0001 },
+ { 12419, 0x0006 },
+ { 12420, 0x0040 },
+ { 12421, 0x0001 },
+ { 12422, 0x000f },
+ { 12423, 0x0006 },
+ { 12424, 0x0001 },
+ { 12425, 0x0003 },
+ { 12426, 0x0106 },
+ { 12428, 0x0061 },
+ { 12429, 0x0011 },
+ { 12430, 0x0401 },
+ { 12432, 0x0050 },
+ { 12433, 0x0003 },
+ { 12434, 0x0102 },
+ { 12436, 0x0051 },
+ { 12437, 0x0003 },
+ { 12438, 0x0106 },
+ { 12439, 0x000a },
+ { 12440, 0x0061 },
+ { 12441, 0x003b },
+ { 12442, 0x0502 },
+ { 12443, 0x0100 },
+ { 12444, 0x2fff },
+ { 12448, 0x2fff },
+ { 12452, 0x2fff },
+ { 12456, 0x2fff },
+ { 12460, 0x2fff },
+ { 12464, 0x2fff },
+ { 12468, 0x2fff },
+ { 12472, 0x2fff },
+ { 12476, 0x2fff },
+ { 12480, 0x0001 },
+ { 12481, 0x0001 },
+ { 12483, 0x0006 },
+ { 12484, 0x0040 },
+ { 12485, 0x0001 },
+ { 12486, 0x000f },
+ { 12487, 0x0006 },
+ { 12488, 0x0001 },
+ { 12489, 0x0003 },
+ { 12490, 0x0106 },
+ { 12492, 0x0061 },
+ { 12493, 0x0011 },
+ { 12494, 0x0401 },
+ { 12496, 0x0050 },
+ { 12497, 0x0003 },
+ { 12498, 0x0102 },
+ { 12500, 0x0061 },
+ { 12501, 0x003b },
+ { 12502, 0x0502 },
+ { 12503, 0x0100 },
+ { 12504, 0x2fff },
+ { 12508, 0x2fff },
+ { 12512, 0x2fff },
+ { 12516, 0x2fff },
+ { 12520, 0x2fff },
+ { 12524, 0x2fff },
+ { 12528, 0x2fff },
+ { 12532, 0x2fff },
+ { 12536, 0x2fff },
+ { 12540, 0x2fff },
+ { 12544, 0x0060 },
+ { 12546, 0x0601 },
+ { 12548, 0x0050 },
+ { 12550, 0x0100 },
+ { 12552, 0x0001 },
+ { 12554, 0x0104 },
+ { 12555, 0x0100 },
+ { 12556, 0x2fff },
+ { 12560, 0x2fff },
+ { 12564, 0x2fff },
+ { 12568, 0x2fff },
+ { 12572, 0x2fff },
+ { 12576, 0x2fff },
+ { 12580, 0x2fff },
+ { 12584, 0x2fff },
+ { 12588, 0x2fff },
+ { 12592, 0x2fff },
+ { 12596, 0x2fff },
+ { 12600, 0x2fff },
+ { 12604, 0x2fff },
+ { 12608, 0x0061 },
+ { 12610, 0x0601 },
+ { 12612, 0x0050 },
+ { 12614, 0x0102 },
+ { 12616, 0x0001 },
+ { 12618, 0x0106 },
+ { 12619, 0x0100 },
+ { 12620, 0x2fff },
+ { 12624, 0x2fff },
+ { 12628, 0x2fff },
+ { 12632, 0x2fff },
+ { 12636, 0x2fff },
+ { 12640, 0x2fff },
+ { 12644, 0x2fff },
+ { 12648, 0x2fff },
+ { 12652, 0x2fff },
+ { 12656, 0x2fff },
+ { 12660, 0x2fff },
+ { 12664, 0x2fff },
+ { 12668, 0x2fff },
+ { 12672, 0x0060 },
+ { 12674, 0x0601 },
+ { 12676, 0x0061 },
+ { 12678, 0x0601 },
+ { 12680, 0x0050 },
+ { 12682, 0x0300 },
+ { 12684, 0x0001 },
+ { 12686, 0x0304 },
+ { 12688, 0x0040 },
+ { 12690, 0x000f },
+ { 12692, 0x0001 },
+ { 12695, 0x0100 },
};
struct fll_config {
@@ -134,7 +378,7 @@
};
struct wm8995_priv {
- enum snd_soc_control_type control_type;
+ struct regmap *regmap;
int sysclk[2];
int mclk[2];
int aifclk[2];
@@ -156,7 +400,7 @@
struct wm8995_priv *wm8995 = container_of(nb, struct wm8995_priv, \
disable_nb[n]); \
if (event & REGULATOR_EVENT_DISABLE) { \
- wm8995->codec->cache_sync = 1; \
+ regcache_mark_dirty(wm8995->regmap); \
} \
return 0; \
}
@@ -688,8 +932,10 @@
SND_SOC_DAPM_MIXER("IN1R PGA", SND_SOC_NOPM, 0, 0,
&in1r_pga, 1),
- SND_SOC_DAPM_MICBIAS("MICBIAS1", WM8995_POWER_MANAGEMENT_1, 8, 0),
- SND_SOC_DAPM_MICBIAS("MICBIAS2", WM8995_POWER_MANAGEMENT_1, 9, 0),
+ SND_SOC_DAPM_SUPPLY("MICBIAS1", WM8995_POWER_MANAGEMENT_1, 8, 0,
+ NULL, 0),
+ SND_SOC_DAPM_SUPPLY("MICBIAS2", WM8995_POWER_MANAGEMENT_1, 9, 0,
+ NULL, 0),
SND_SOC_DAPM_SUPPLY("AIF1CLK", WM8995_AIF1_CLOCKING_1, 0, 0, NULL, 0),
SND_SOC_DAPM_SUPPLY("AIF2CLK", WM8995_AIF2_CLOCKING_1, 0, 0, NULL, 0),
@@ -947,31 +1193,244 @@
{ "SPK2R", NULL, "SPK2R Driver" }
};
-static int wm8995_volatile(struct snd_soc_codec *codec, unsigned int reg)
+static bool wm8995_readable(struct device *dev, unsigned int reg)
{
- /* out of bounds registers are generally considered
- * volatile to support register banks that are partially
- * owned by something else for e.g. a DSP
- */
- if (reg > WM8995_MAX_CACHED_REGISTER)
- return 1;
+ switch (reg) {
+ case WM8995_SOFTWARE_RESET:
+ case WM8995_POWER_MANAGEMENT_1:
+ case WM8995_POWER_MANAGEMENT_2:
+ case WM8995_POWER_MANAGEMENT_3:
+ case WM8995_POWER_MANAGEMENT_4:
+ case WM8995_POWER_MANAGEMENT_5:
+ case WM8995_LEFT_LINE_INPUT_1_VOLUME:
+ case WM8995_RIGHT_LINE_INPUT_1_VOLUME:
+ case WM8995_LEFT_LINE_INPUT_CONTROL:
+ case WM8995_DAC1_LEFT_VOLUME:
+ case WM8995_DAC1_RIGHT_VOLUME:
+ case WM8995_DAC2_LEFT_VOLUME:
+ case WM8995_DAC2_RIGHT_VOLUME:
+ case WM8995_OUTPUT_VOLUME_ZC_1:
+ case WM8995_MICBIAS_1:
+ case WM8995_MICBIAS_2:
+ case WM8995_LDO_1:
+ case WM8995_LDO_2:
+ case WM8995_ACCESSORY_DETECT_MODE1:
+ case WM8995_ACCESSORY_DETECT_MODE2:
+ case WM8995_HEADPHONE_DETECT1:
+ case WM8995_HEADPHONE_DETECT2:
+ case WM8995_MIC_DETECT_1:
+ case WM8995_MIC_DETECT_2:
+ case WM8995_CHARGE_PUMP_1:
+ case WM8995_CLASS_W_1:
+ case WM8995_DC_SERVO_1:
+ case WM8995_DC_SERVO_2:
+ case WM8995_DC_SERVO_3:
+ case WM8995_DC_SERVO_5:
+ case WM8995_DC_SERVO_6:
+ case WM8995_DC_SERVO_7:
+ case WM8995_DC_SERVO_READBACK_0:
+ case WM8995_ANALOGUE_HP_1:
+ case WM8995_ANALOGUE_HP_2:
+ case WM8995_CHIP_REVISION:
+ case WM8995_CONTROL_INTERFACE_1:
+ case WM8995_CONTROL_INTERFACE_2:
+ case WM8995_WRITE_SEQUENCER_CTRL_1:
+ case WM8995_WRITE_SEQUENCER_CTRL_2:
+ case WM8995_AIF1_CLOCKING_1:
+ case WM8995_AIF1_CLOCKING_2:
+ case WM8995_AIF2_CLOCKING_1:
+ case WM8995_AIF2_CLOCKING_2:
+ case WM8995_CLOCKING_1:
+ case WM8995_CLOCKING_2:
+ case WM8995_AIF1_RATE:
+ case WM8995_AIF2_RATE:
+ case WM8995_RATE_STATUS:
+ case WM8995_FLL1_CONTROL_1:
+ case WM8995_FLL1_CONTROL_2:
+ case WM8995_FLL1_CONTROL_3:
+ case WM8995_FLL1_CONTROL_4:
+ case WM8995_FLL1_CONTROL_5:
+ case WM8995_FLL2_CONTROL_1:
+ case WM8995_FLL2_CONTROL_2:
+ case WM8995_FLL2_CONTROL_3:
+ case WM8995_FLL2_CONTROL_4:
+ case WM8995_FLL2_CONTROL_5:
+ case WM8995_AIF1_CONTROL_1:
+ case WM8995_AIF1_CONTROL_2:
+ case WM8995_AIF1_MASTER_SLAVE:
+ case WM8995_AIF1_BCLK:
+ case WM8995_AIF1ADC_LRCLK:
+ case WM8995_AIF1DAC_LRCLK:
+ case WM8995_AIF1DAC_DATA:
+ case WM8995_AIF1ADC_DATA:
+ case WM8995_AIF2_CONTROL_1:
+ case WM8995_AIF2_CONTROL_2:
+ case WM8995_AIF2_MASTER_SLAVE:
+ case WM8995_AIF2_BCLK:
+ case WM8995_AIF2ADC_LRCLK:
+ case WM8995_AIF2DAC_LRCLK:
+ case WM8995_AIF2DAC_DATA:
+ case WM8995_AIF2ADC_DATA:
+ case WM8995_AIF1_ADC1_LEFT_VOLUME:
+ case WM8995_AIF1_ADC1_RIGHT_VOLUME:
+ case WM8995_AIF1_DAC1_LEFT_VOLUME:
+ case WM8995_AIF1_DAC1_RIGHT_VOLUME:
+ case WM8995_AIF1_ADC2_LEFT_VOLUME:
+ case WM8995_AIF1_ADC2_RIGHT_VOLUME:
+ case WM8995_AIF1_DAC2_LEFT_VOLUME:
+ case WM8995_AIF1_DAC2_RIGHT_VOLUME:
+ case WM8995_AIF1_ADC1_FILTERS:
+ case WM8995_AIF1_ADC2_FILTERS:
+ case WM8995_AIF1_DAC1_FILTERS_1:
+ case WM8995_AIF1_DAC1_FILTERS_2:
+ case WM8995_AIF1_DAC2_FILTERS_1:
+ case WM8995_AIF1_DAC2_FILTERS_2:
+ case WM8995_AIF1_DRC1_1:
+ case WM8995_AIF1_DRC1_2:
+ case WM8995_AIF1_DRC1_3:
+ case WM8995_AIF1_DRC1_4:
+ case WM8995_AIF1_DRC1_5:
+ case WM8995_AIF1_DRC2_1:
+ case WM8995_AIF1_DRC2_2:
+ case WM8995_AIF1_DRC2_3:
+ case WM8995_AIF1_DRC2_4:
+ case WM8995_AIF1_DRC2_5:
+ case WM8995_AIF1_DAC1_EQ_GAINS_1:
+ case WM8995_AIF1_DAC1_EQ_GAINS_2:
+ case WM8995_AIF1_DAC1_EQ_BAND_1_A:
+ case WM8995_AIF1_DAC1_EQ_BAND_1_B:
+ case WM8995_AIF1_DAC1_EQ_BAND_1_PG:
+ case WM8995_AIF1_DAC1_EQ_BAND_2_A:
+ case WM8995_AIF1_DAC1_EQ_BAND_2_B:
+ case WM8995_AIF1_DAC1_EQ_BAND_2_C:
+ case WM8995_AIF1_DAC1_EQ_BAND_2_PG:
+ case WM8995_AIF1_DAC1_EQ_BAND_3_A:
+ case WM8995_AIF1_DAC1_EQ_BAND_3_B:
+ case WM8995_AIF1_DAC1_EQ_BAND_3_C:
+ case WM8995_AIF1_DAC1_EQ_BAND_3_PG:
+ case WM8995_AIF1_DAC1_EQ_BAND_4_A:
+ case WM8995_AIF1_DAC1_EQ_BAND_4_B:
+ case WM8995_AIF1_DAC1_EQ_BAND_4_C:
+ case WM8995_AIF1_DAC1_EQ_BAND_4_PG:
+ case WM8995_AIF1_DAC1_EQ_BAND_5_A:
+ case WM8995_AIF1_DAC1_EQ_BAND_5_B:
+ case WM8995_AIF1_DAC1_EQ_BAND_5_PG:
+ case WM8995_AIF1_DAC2_EQ_GAINS_1:
+ case WM8995_AIF1_DAC2_EQ_GAINS_2:
+ case WM8995_AIF1_DAC2_EQ_BAND_1_A:
+ case WM8995_AIF1_DAC2_EQ_BAND_1_B:
+ case WM8995_AIF1_DAC2_EQ_BAND_1_PG:
+ case WM8995_AIF1_DAC2_EQ_BAND_2_A:
+ case WM8995_AIF1_DAC2_EQ_BAND_2_B:
+ case WM8995_AIF1_DAC2_EQ_BAND_2_C:
+ case WM8995_AIF1_DAC2_EQ_BAND_2_PG:
+ case WM8995_AIF1_DAC2_EQ_BAND_3_A:
+ case WM8995_AIF1_DAC2_EQ_BAND_3_B:
+ case WM8995_AIF1_DAC2_EQ_BAND_3_C:
+ case WM8995_AIF1_DAC2_EQ_BAND_3_PG:
+ case WM8995_AIF1_DAC2_EQ_BAND_4_A:
+ case WM8995_AIF1_DAC2_EQ_BAND_4_B:
+ case WM8995_AIF1_DAC2_EQ_BAND_4_C:
+ case WM8995_AIF1_DAC2_EQ_BAND_4_PG:
+ case WM8995_AIF1_DAC2_EQ_BAND_5_A:
+ case WM8995_AIF1_DAC2_EQ_BAND_5_B:
+ case WM8995_AIF1_DAC2_EQ_BAND_5_PG:
+ case WM8995_AIF2_ADC_LEFT_VOLUME:
+ case WM8995_AIF2_ADC_RIGHT_VOLUME:
+ case WM8995_AIF2_DAC_LEFT_VOLUME:
+ case WM8995_AIF2_DAC_RIGHT_VOLUME:
+ case WM8995_AIF2_ADC_FILTERS:
+ case WM8995_AIF2_DAC_FILTERS_1:
+ case WM8995_AIF2_DAC_FILTERS_2:
+ case WM8995_AIF2_DRC_1:
+ case WM8995_AIF2_DRC_2:
+ case WM8995_AIF2_DRC_3:
+ case WM8995_AIF2_DRC_4:
+ case WM8995_AIF2_DRC_5:
+ case WM8995_AIF2_EQ_GAINS_1:
+ case WM8995_AIF2_EQ_GAINS_2:
+ case WM8995_AIF2_EQ_BAND_1_A:
+ case WM8995_AIF2_EQ_BAND_1_B:
+ case WM8995_AIF2_EQ_BAND_1_PG:
+ case WM8995_AIF2_EQ_BAND_2_A:
+ case WM8995_AIF2_EQ_BAND_2_B:
+ case WM8995_AIF2_EQ_BAND_2_C:
+ case WM8995_AIF2_EQ_BAND_2_PG:
+ case WM8995_AIF2_EQ_BAND_3_A:
+ case WM8995_AIF2_EQ_BAND_3_B:
+ case WM8995_AIF2_EQ_BAND_3_C:
+ case WM8995_AIF2_EQ_BAND_3_PG:
+ case WM8995_AIF2_EQ_BAND_4_A:
+ case WM8995_AIF2_EQ_BAND_4_B:
+ case WM8995_AIF2_EQ_BAND_4_C:
+ case WM8995_AIF2_EQ_BAND_4_PG:
+ case WM8995_AIF2_EQ_BAND_5_A:
+ case WM8995_AIF2_EQ_BAND_5_B:
+ case WM8995_AIF2_EQ_BAND_5_PG:
+ case WM8995_DAC1_MIXER_VOLUMES:
+ case WM8995_DAC1_LEFT_MIXER_ROUTING:
+ case WM8995_DAC1_RIGHT_MIXER_ROUTING:
+ case WM8995_DAC2_MIXER_VOLUMES:
+ case WM8995_DAC2_LEFT_MIXER_ROUTING:
+ case WM8995_DAC2_RIGHT_MIXER_ROUTING:
+ case WM8995_AIF1_ADC1_LEFT_MIXER_ROUTING:
+ case WM8995_AIF1_ADC1_RIGHT_MIXER_ROUTING:
+ case WM8995_AIF1_ADC2_LEFT_MIXER_ROUTING:
+ case WM8995_AIF1_ADC2_RIGHT_MIXER_ROUTING:
+ case WM8995_DAC_SOFTMUTE:
+ case WM8995_OVERSAMPLING:
+ case WM8995_SIDETONE:
+ case WM8995_GPIO_1:
+ case WM8995_GPIO_2:
+ case WM8995_GPIO_3:
+ case WM8995_GPIO_4:
+ case WM8995_GPIO_5:
+ case WM8995_GPIO_6:
+ case WM8995_GPIO_7:
+ case WM8995_GPIO_8:
+ case WM8995_GPIO_9:
+ case WM8995_GPIO_10:
+ case WM8995_GPIO_11:
+ case WM8995_GPIO_12:
+ case WM8995_GPIO_13:
+ case WM8995_GPIO_14:
+ case WM8995_PULL_CONTROL_1:
+ case WM8995_PULL_CONTROL_2:
+ case WM8995_INTERRUPT_STATUS_1:
+ case WM8995_INTERRUPT_STATUS_2:
+ case WM8995_INTERRUPT_RAW_STATUS_2:
+ case WM8995_INTERRUPT_STATUS_1_MASK:
+ case WM8995_INTERRUPT_STATUS_2_MASK:
+ case WM8995_INTERRUPT_CONTROL:
+ case WM8995_LEFT_PDM_SPEAKER_1:
+ case WM8995_RIGHT_PDM_SPEAKER_1:
+ case WM8995_PDM_SPEAKER_1_MUTE_SEQUENCE:
+ case WM8995_LEFT_PDM_SPEAKER_2:
+ case WM8995_RIGHT_PDM_SPEAKER_2:
+ case WM8995_PDM_SPEAKER_2_MUTE_SEQUENCE:
+ return true;
+ default:
+ return false;
+ }
+}
+static bool wm8995_volatile(struct device *dev, unsigned int reg)
+{
switch (reg) {
case WM8995_SOFTWARE_RESET:
case WM8995_DC_SERVO_READBACK_0:
case WM8995_INTERRUPT_STATUS_1:
case WM8995_INTERRUPT_STATUS_2:
- case WM8995_INTERRUPT_STATUS_1_MASK:
- case WM8995_INTERRUPT_STATUS_2_MASK:
case WM8995_INTERRUPT_CONTROL:
case WM8995_ACCESSORY_DETECT_MODE1:
case WM8995_ACCESSORY_DETECT_MODE2:
case WM8995_HEADPHONE_DETECT1:
case WM8995_HEADPHONE_DETECT2:
- return 1;
+ case WM8995_RATE_STATUS:
+ return true;
+ default:
+ return false;
}
-
- return 0;
}
static int wm8995_aif_mute(struct snd_soc_dai *dai, int mute)
@@ -1526,7 +1985,7 @@
if (ret)
return ret;
- ret = snd_soc_cache_sync(codec);
+ ret = regcache_sync(wm8995->regmap);
if (ret) {
dev_err(codec->dev,
"Failed to sync cache: %d\n", ret);
@@ -1550,7 +2009,7 @@
}
#ifdef CONFIG_PM
-static int wm8995_suspend(struct snd_soc_codec *codec, pm_message_t state)
+static int wm8995_suspend(struct snd_soc_codec *codec)
{
wm8995_set_bias_level(codec, SND_SOC_BIAS_OFF);
return 0;
@@ -1592,7 +2051,8 @@
wm8995 = snd_soc_codec_get_drvdata(codec);
wm8995->codec = codec;
- ret = snd_soc_codec_set_cache_io(codec, 16, 16, wm8995->control_type);
+ codec->control_data = wm8995->regmap;
+ ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_REGMAP);
if (ret < 0) {
dev_err(codec->dev, "Failed to set cache i/o: %d\n", ret);
return ret;
@@ -1696,7 +2156,7 @@
#define WM8995_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
-static struct snd_soc_dai_ops wm8995_aif1_dai_ops = {
+static const struct snd_soc_dai_ops wm8995_aif1_dai_ops = {
.set_sysclk = wm8995_set_dai_sysclk,
.set_fmt = wm8995_set_dai_fmt,
.hw_params = wm8995_hw_params,
@@ -1705,7 +2165,7 @@
.set_tristate = wm8995_set_tristate,
};
-static struct snd_soc_dai_ops wm8995_aif2_dai_ops = {
+static const struct snd_soc_dai_ops wm8995_aif2_dai_ops = {
.set_sysclk = wm8995_set_dai_sysclk,
.set_fmt = wm8995_set_dai_fmt,
.hw_params = wm8995_hw_params,
@@ -1714,7 +2174,7 @@
.set_tristate = wm8995_set_tristate,
};
-static struct snd_soc_dai_ops wm8995_aif3_dai_ops = {
+static const struct snd_soc_dai_ops wm8995_aif3_dai_ops = {
.set_tristate = wm8995_set_tristate,
};
@@ -1781,11 +2241,18 @@
.suspend = wm8995_suspend,
.resume = wm8995_resume,
.set_bias_level = wm8995_set_bias_level,
- .reg_cache_size = ARRAY_SIZE(wm8995_reg_defs),
- .reg_word_size = sizeof(u16),
- .reg_cache_default = wm8995_reg_defs,
- .volatile_register = wm8995_volatile,
- .compress_type = SND_SOC_RBTREE_COMPRESSION
+};
+
+static struct regmap_config wm8995_regmap = {
+ .reg_bits = 16,
+ .val_bits = 16,
+
+ .max_register = WM8995_MAX_REGISTER,
+ .reg_defaults = wm8995_reg_defaults,
+ .num_reg_defaults = ARRAY_SIZE(wm8995_reg_defaults),
+ .volatile_reg = wm8995_volatile,
+ .readable_reg = wm8995_readable,
+ .cache_type = REGCACHE_RBTREE,
};
#if defined(CONFIG_SPI_MASTER)
@@ -1798,21 +2265,37 @@
if (!wm8995)
return -ENOMEM;
- wm8995->control_type = SND_SOC_SPI;
spi_set_drvdata(spi, wm8995);
+ wm8995->regmap = regmap_init_spi(spi, &wm8995_regmap);
+ if (IS_ERR(wm8995->regmap)) {
+ ret = PTR_ERR(wm8995->regmap);
+ dev_err(&spi->dev, "Failed to register regmap: %d\n", ret);
+ goto err_alloc;
+ }
+
ret = snd_soc_register_codec(&spi->dev,
&soc_codec_dev_wm8995, wm8995_dai,
ARRAY_SIZE(wm8995_dai));
if (ret < 0)
- kfree(wm8995);
+ goto err_regmap;
+
+ return ret;
+
+err_regmap:
+ regmap_exit(wm8995->regmap);
+err_alloc:
+ kfree(wm8995);
+
return ret;
}
static int __devexit wm8995_spi_remove(struct spi_device *spi)
{
+ struct wm8995_priv *wm8995 = spi_get_drvdata(spi);
snd_soc_unregister_codec(&spi->dev);
- kfree(spi_get_drvdata(spi));
+ regmap_exit(wm8995->regmap);
+ kfree(wm8995);
return 0;
}
@@ -1837,21 +2320,40 @@
if (!wm8995)
return -ENOMEM;
- wm8995->control_type = SND_SOC_I2C;
i2c_set_clientdata(i2c, wm8995);
+ wm8995->regmap = regmap_init_i2c(i2c, &wm8995_regmap);
+ if (IS_ERR(wm8995->regmap)) {
+ ret = PTR_ERR(wm8995->regmap);
+ dev_err(&i2c->dev, "Failed to register regmap: %d\n", ret);
+ goto err_alloc;
+ }
+
ret = snd_soc_register_codec(&i2c->dev,
&soc_codec_dev_wm8995, wm8995_dai,
ARRAY_SIZE(wm8995_dai));
- if (ret < 0)
- kfree(wm8995);
+ if (ret < 0) {
+ dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret);
+ goto err_regmap;
+ }
+
+ return ret;
+
+err_regmap:
+ regmap_exit(wm8995->regmap);
+err_alloc:
+ kfree(wm8995);
+
return ret;
}
static __devexit int wm8995_i2c_remove(struct i2c_client *client)
{
+ struct wm8995_priv *wm8995 = i2c_get_clientdata(client);
+
snd_soc_unregister_codec(&client->dev);
- kfree(i2c_get_clientdata(client));
+ regmap_exit(wm8995->regmap);
+ kfree(wm8995);
return 0;
}
diff --git a/sound/soc/codecs/wm8996.c b/sound/soc/codecs/wm8996.c
index a33b04d..d8da10f 100644
--- a/sound/soc/codecs/wm8996.c
+++ b/sound/soc/codecs/wm8996.c
@@ -19,6 +19,7 @@
#include <linux/gcd.h>
#include <linux/gpio.h>
#include <linux/i2c.h>
+#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
#include <linux/slab.h>
#include <linux/workqueue.h>
@@ -49,6 +50,8 @@
};
struct wm8996_priv {
+ struct device *dev;
+ struct regmap *regmap;
struct snd_soc_codec *codec;
int ldo1ena;
@@ -105,7 +108,7 @@
struct wm8996_priv *wm8996 = container_of(nb, struct wm8996_priv, \
disable_nb[n]); \
if (event & REGULATOR_EVENT_DISABLE) { \
- wm8996->codec->cache_sync = 1; \
+ regcache_cache_only(wm8996->regmap, true); \
} \
return 0; \
}
@@ -114,297 +117,365 @@
WM8996_REGULATOR_EVENT(1)
WM8996_REGULATOR_EVENT(2)
-static const u16 wm8996_reg[WM8996_MAX_REGISTER] = {
- [WM8996_SOFTWARE_RESET] = 0x8996,
- [WM8996_POWER_MANAGEMENT_7] = 0x10,
- [WM8996_DAC1_HPOUT1_VOLUME] = 0x88,
- [WM8996_DAC2_HPOUT2_VOLUME] = 0x88,
- [WM8996_DAC1_LEFT_VOLUME] = 0x2c0,
- [WM8996_DAC1_RIGHT_VOLUME] = 0x2c0,
- [WM8996_DAC2_LEFT_VOLUME] = 0x2c0,
- [WM8996_DAC2_RIGHT_VOLUME] = 0x2c0,
- [WM8996_OUTPUT1_LEFT_VOLUME] = 0x80,
- [WM8996_OUTPUT1_RIGHT_VOLUME] = 0x80,
- [WM8996_OUTPUT2_LEFT_VOLUME] = 0x80,
- [WM8996_OUTPUT2_RIGHT_VOLUME] = 0x80,
- [WM8996_MICBIAS_1] = 0x39,
- [WM8996_MICBIAS_2] = 0x39,
- [WM8996_LDO_1] = 0x3,
- [WM8996_LDO_2] = 0x13,
- [WM8996_ACCESSORY_DETECT_MODE_1] = 0x4,
- [WM8996_HEADPHONE_DETECT_1] = 0x20,
- [WM8996_MIC_DETECT_1] = 0x7600,
- [WM8996_MIC_DETECT_2] = 0xbf,
- [WM8996_CHARGE_PUMP_1] = 0x1f25,
- [WM8996_CHARGE_PUMP_2] = 0xab19,
- [WM8996_DC_SERVO_5] = 0x2a2a,
- [WM8996_CONTROL_INTERFACE_1] = 0x8004,
- [WM8996_CLOCKING_1] = 0x10,
- [WM8996_AIF_RATE] = 0x83,
- [WM8996_FLL_CONTROL_4] = 0x5dc0,
- [WM8996_FLL_CONTROL_5] = 0xc84,
- [WM8996_FLL_EFS_2] = 0x2,
- [WM8996_AIF1_TX_LRCLK_1] = 0x80,
- [WM8996_AIF1_TX_LRCLK_2] = 0x8,
- [WM8996_AIF1_RX_LRCLK_1] = 0x80,
- [WM8996_AIF1TX_DATA_CONFIGURATION_1] = 0x1818,
- [WM8996_AIF1RX_DATA_CONFIGURATION] = 0x1818,
- [WM8996_AIF1TX_TEST] = 0x7,
- [WM8996_AIF2_TX_LRCLK_1] = 0x80,
- [WM8996_AIF2_TX_LRCLK_2] = 0x8,
- [WM8996_AIF2_RX_LRCLK_1] = 0x80,
- [WM8996_AIF2TX_DATA_CONFIGURATION_1] = 0x1818,
- [WM8996_AIF2RX_DATA_CONFIGURATION] = 0x1818,
- [WM8996_AIF2TX_TEST] = 0x1,
- [WM8996_DSP1_TX_LEFT_VOLUME] = 0xc0,
- [WM8996_DSP1_TX_RIGHT_VOLUME] = 0xc0,
- [WM8996_DSP1_RX_LEFT_VOLUME] = 0xc0,
- [WM8996_DSP1_RX_RIGHT_VOLUME] = 0xc0,
- [WM8996_DSP1_TX_FILTERS] = 0x2000,
- [WM8996_DSP1_RX_FILTERS_1] = 0x200,
- [WM8996_DSP1_RX_FILTERS_2] = 0x10,
- [WM8996_DSP1_DRC_1] = 0x98,
- [WM8996_DSP1_DRC_2] = 0x845,
- [WM8996_DSP1_RX_EQ_GAINS_1] = 0x6318,
- [WM8996_DSP1_RX_EQ_GAINS_2] = 0x6300,
- [WM8996_DSP1_RX_EQ_BAND_1_A] = 0xfca,
- [WM8996_DSP1_RX_EQ_BAND_1_B] = 0x400,
- [WM8996_DSP1_RX_EQ_BAND_1_PG] = 0xd8,
- [WM8996_DSP1_RX_EQ_BAND_2_A] = 0x1eb5,
- [WM8996_DSP1_RX_EQ_BAND_2_B] = 0xf145,
- [WM8996_DSP1_RX_EQ_BAND_2_C] = 0xb75,
- [WM8996_DSP1_RX_EQ_BAND_2_PG] = 0x1c5,
- [WM8996_DSP1_RX_EQ_BAND_3_A] = 0x1c58,
- [WM8996_DSP1_RX_EQ_BAND_3_B] = 0xf373,
- [WM8996_DSP1_RX_EQ_BAND_3_C] = 0xa54,
- [WM8996_DSP1_RX_EQ_BAND_3_PG] = 0x558,
- [WM8996_DSP1_RX_EQ_BAND_4_A] = 0x168e,
- [WM8996_DSP1_RX_EQ_BAND_4_B] = 0xf829,
- [WM8996_DSP1_RX_EQ_BAND_4_C] = 0x7ad,
- [WM8996_DSP1_RX_EQ_BAND_4_PG] = 0x1103,
- [WM8996_DSP1_RX_EQ_BAND_5_A] = 0x564,
- [WM8996_DSP1_RX_EQ_BAND_5_B] = 0x559,
- [WM8996_DSP1_RX_EQ_BAND_5_PG] = 0x4000,
- [WM8996_DSP2_TX_LEFT_VOLUME] = 0xc0,
- [WM8996_DSP2_TX_RIGHT_VOLUME] = 0xc0,
- [WM8996_DSP2_RX_LEFT_VOLUME] = 0xc0,
- [WM8996_DSP2_RX_RIGHT_VOLUME] = 0xc0,
- [WM8996_DSP2_TX_FILTERS] = 0x2000,
- [WM8996_DSP2_RX_FILTERS_1] = 0x200,
- [WM8996_DSP2_RX_FILTERS_2] = 0x10,
- [WM8996_DSP2_DRC_1] = 0x98,
- [WM8996_DSP2_DRC_2] = 0x845,
- [WM8996_DSP2_RX_EQ_GAINS_1] = 0x6318,
- [WM8996_DSP2_RX_EQ_GAINS_2] = 0x6300,
- [WM8996_DSP2_RX_EQ_BAND_1_A] = 0xfca,
- [WM8996_DSP2_RX_EQ_BAND_1_B] = 0x400,
- [WM8996_DSP2_RX_EQ_BAND_1_PG] = 0xd8,
- [WM8996_DSP2_RX_EQ_BAND_2_A] = 0x1eb5,
- [WM8996_DSP2_RX_EQ_BAND_2_B] = 0xf145,
- [WM8996_DSP2_RX_EQ_BAND_2_C] = 0xb75,
- [WM8996_DSP2_RX_EQ_BAND_2_PG] = 0x1c5,
- [WM8996_DSP2_RX_EQ_BAND_3_A] = 0x1c58,
- [WM8996_DSP2_RX_EQ_BAND_3_B] = 0xf373,
- [WM8996_DSP2_RX_EQ_BAND_3_C] = 0xa54,
- [WM8996_DSP2_RX_EQ_BAND_3_PG] = 0x558,
- [WM8996_DSP2_RX_EQ_BAND_4_A] = 0x168e,
- [WM8996_DSP2_RX_EQ_BAND_4_B] = 0xf829,
- [WM8996_DSP2_RX_EQ_BAND_4_C] = 0x7ad,
- [WM8996_DSP2_RX_EQ_BAND_4_PG] = 0x1103,
- [WM8996_DSP2_RX_EQ_BAND_5_A] = 0x564,
- [WM8996_DSP2_RX_EQ_BAND_5_B] = 0x559,
- [WM8996_DSP2_RX_EQ_BAND_5_PG] = 0x4000,
- [WM8996_OVERSAMPLING] = 0xd,
- [WM8996_SIDETONE] = 0x1040,
- [WM8996_GPIO_1] = 0xa101,
- [WM8996_GPIO_2] = 0xa101,
- [WM8996_GPIO_3] = 0xa101,
- [WM8996_GPIO_4] = 0xa101,
- [WM8996_GPIO_5] = 0xa101,
- [WM8996_PULL_CONTROL_2] = 0x140,
- [WM8996_INTERRUPT_STATUS_1_MASK] = 0x1f,
- [WM8996_INTERRUPT_STATUS_2_MASK] = 0x1ecf,
- [WM8996_RIGHT_PDM_SPEAKER] = 0x1,
- [WM8996_PDM_SPEAKER_MUTE_SEQUENCE] = 0x69,
- [WM8996_PDM_SPEAKER_VOLUME] = 0x66,
- [WM8996_WRITE_SEQUENCER_0] = 0x1,
- [WM8996_WRITE_SEQUENCER_1] = 0x1,
- [WM8996_WRITE_SEQUENCER_3] = 0x6,
- [WM8996_WRITE_SEQUENCER_4] = 0x40,
- [WM8996_WRITE_SEQUENCER_5] = 0x1,
- [WM8996_WRITE_SEQUENCER_6] = 0xf,
- [WM8996_WRITE_SEQUENCER_7] = 0x6,
- [WM8996_WRITE_SEQUENCER_8] = 0x1,
- [WM8996_WRITE_SEQUENCER_9] = 0x3,
- [WM8996_WRITE_SEQUENCER_10] = 0x104,
- [WM8996_WRITE_SEQUENCER_12] = 0x60,
- [WM8996_WRITE_SEQUENCER_13] = 0x11,
- [WM8996_WRITE_SEQUENCER_14] = 0x401,
- [WM8996_WRITE_SEQUENCER_16] = 0x50,
- [WM8996_WRITE_SEQUENCER_17] = 0x3,
- [WM8996_WRITE_SEQUENCER_18] = 0x100,
- [WM8996_WRITE_SEQUENCER_20] = 0x51,
- [WM8996_WRITE_SEQUENCER_21] = 0x3,
- [WM8996_WRITE_SEQUENCER_22] = 0x104,
- [WM8996_WRITE_SEQUENCER_23] = 0xa,
- [WM8996_WRITE_SEQUENCER_24] = 0x60,
- [WM8996_WRITE_SEQUENCER_25] = 0x3b,
- [WM8996_WRITE_SEQUENCER_26] = 0x502,
- [WM8996_WRITE_SEQUENCER_27] = 0x100,
- [WM8996_WRITE_SEQUENCER_28] = 0x2fff,
- [WM8996_WRITE_SEQUENCER_32] = 0x2fff,
- [WM8996_WRITE_SEQUENCER_36] = 0x2fff,
- [WM8996_WRITE_SEQUENCER_40] = 0x2fff,
- [WM8996_WRITE_SEQUENCER_44] = 0x2fff,
- [WM8996_WRITE_SEQUENCER_48] = 0x2fff,
- [WM8996_WRITE_SEQUENCER_52] = 0x2fff,
- [WM8996_WRITE_SEQUENCER_56] = 0x2fff,
- [WM8996_WRITE_SEQUENCER_60] = 0x2fff,
- [WM8996_WRITE_SEQUENCER_64] = 0x1,
- [WM8996_WRITE_SEQUENCER_65] = 0x1,
- [WM8996_WRITE_SEQUENCER_67] = 0x6,
- [WM8996_WRITE_SEQUENCER_68] = 0x40,
- [WM8996_WRITE_SEQUENCER_69] = 0x1,
- [WM8996_WRITE_SEQUENCER_70] = 0xf,
- [WM8996_WRITE_SEQUENCER_71] = 0x6,
- [WM8996_WRITE_SEQUENCER_72] = 0x1,
- [WM8996_WRITE_SEQUENCER_73] = 0x3,
- [WM8996_WRITE_SEQUENCER_74] = 0x104,
- [WM8996_WRITE_SEQUENCER_76] = 0x60,
- [WM8996_WRITE_SEQUENCER_77] = 0x11,
- [WM8996_WRITE_SEQUENCER_78] = 0x401,
- [WM8996_WRITE_SEQUENCER_80] = 0x50,
- [WM8996_WRITE_SEQUENCER_81] = 0x3,
- [WM8996_WRITE_SEQUENCER_82] = 0x100,
- [WM8996_WRITE_SEQUENCER_84] = 0x60,
- [WM8996_WRITE_SEQUENCER_85] = 0x3b,
- [WM8996_WRITE_SEQUENCER_86] = 0x502,
- [WM8996_WRITE_SEQUENCER_87] = 0x100,
- [WM8996_WRITE_SEQUENCER_88] = 0x2fff,
- [WM8996_WRITE_SEQUENCER_92] = 0x2fff,
- [WM8996_WRITE_SEQUENCER_96] = 0x2fff,
- [WM8996_WRITE_SEQUENCER_100] = 0x2fff,
- [WM8996_WRITE_SEQUENCER_104] = 0x2fff,
- [WM8996_WRITE_SEQUENCER_108] = 0x2fff,
- [WM8996_WRITE_SEQUENCER_112] = 0x2fff,
- [WM8996_WRITE_SEQUENCER_116] = 0x2fff,
- [WM8996_WRITE_SEQUENCER_120] = 0x2fff,
- [WM8996_WRITE_SEQUENCER_124] = 0x2fff,
- [WM8996_WRITE_SEQUENCER_128] = 0x1,
- [WM8996_WRITE_SEQUENCER_129] = 0x1,
- [WM8996_WRITE_SEQUENCER_131] = 0x6,
- [WM8996_WRITE_SEQUENCER_132] = 0x40,
- [WM8996_WRITE_SEQUENCER_133] = 0x1,
- [WM8996_WRITE_SEQUENCER_134] = 0xf,
- [WM8996_WRITE_SEQUENCER_135] = 0x6,
- [WM8996_WRITE_SEQUENCER_136] = 0x1,
- [WM8996_WRITE_SEQUENCER_137] = 0x3,
- [WM8996_WRITE_SEQUENCER_138] = 0x106,
- [WM8996_WRITE_SEQUENCER_140] = 0x61,
- [WM8996_WRITE_SEQUENCER_141] = 0x11,
- [WM8996_WRITE_SEQUENCER_142] = 0x401,
- [WM8996_WRITE_SEQUENCER_144] = 0x50,
- [WM8996_WRITE_SEQUENCER_145] = 0x3,
- [WM8996_WRITE_SEQUENCER_146] = 0x102,
- [WM8996_WRITE_SEQUENCER_148] = 0x51,
- [WM8996_WRITE_SEQUENCER_149] = 0x3,
- [WM8996_WRITE_SEQUENCER_150] = 0x106,
- [WM8996_WRITE_SEQUENCER_151] = 0xa,
- [WM8996_WRITE_SEQUENCER_152] = 0x61,
- [WM8996_WRITE_SEQUENCER_153] = 0x3b,
- [WM8996_WRITE_SEQUENCER_154] = 0x502,
- [WM8996_WRITE_SEQUENCER_155] = 0x100,
- [WM8996_WRITE_SEQUENCER_156] = 0x2fff,
- [WM8996_WRITE_SEQUENCER_160] = 0x2fff,
- [WM8996_WRITE_SEQUENCER_164] = 0x2fff,
- [WM8996_WRITE_SEQUENCER_168] = 0x2fff,
- [WM8996_WRITE_SEQUENCER_172] = 0x2fff,
- [WM8996_WRITE_SEQUENCER_176] = 0x2fff,
- [WM8996_WRITE_SEQUENCER_180] = 0x2fff,
- [WM8996_WRITE_SEQUENCER_184] = 0x2fff,
- [WM8996_WRITE_SEQUENCER_188] = 0x2fff,
- [WM8996_WRITE_SEQUENCER_192] = 0x1,
- [WM8996_WRITE_SEQUENCER_193] = 0x1,
- [WM8996_WRITE_SEQUENCER_195] = 0x6,
- [WM8996_WRITE_SEQUENCER_196] = 0x40,
- [WM8996_WRITE_SEQUENCER_197] = 0x1,
- [WM8996_WRITE_SEQUENCER_198] = 0xf,
- [WM8996_WRITE_SEQUENCER_199] = 0x6,
- [WM8996_WRITE_SEQUENCER_200] = 0x1,
- [WM8996_WRITE_SEQUENCER_201] = 0x3,
- [WM8996_WRITE_SEQUENCER_202] = 0x106,
- [WM8996_WRITE_SEQUENCER_204] = 0x61,
- [WM8996_WRITE_SEQUENCER_205] = 0x11,
- [WM8996_WRITE_SEQUENCER_206] = 0x401,
- [WM8996_WRITE_SEQUENCER_208] = 0x50,
- [WM8996_WRITE_SEQUENCER_209] = 0x3,
- [WM8996_WRITE_SEQUENCER_210] = 0x102,
- [WM8996_WRITE_SEQUENCER_212] = 0x61,
- [WM8996_WRITE_SEQUENCER_213] = 0x3b,
- [WM8996_WRITE_SEQUENCER_214] = 0x502,
- [WM8996_WRITE_SEQUENCER_215] = 0x100,
- [WM8996_WRITE_SEQUENCER_216] = 0x2fff,
- [WM8996_WRITE_SEQUENCER_220] = 0x2fff,
- [WM8996_WRITE_SEQUENCER_224] = 0x2fff,
- [WM8996_WRITE_SEQUENCER_228] = 0x2fff,
- [WM8996_WRITE_SEQUENCER_232] = 0x2fff,
- [WM8996_WRITE_SEQUENCER_236] = 0x2fff,
- [WM8996_WRITE_SEQUENCER_240] = 0x2fff,
- [WM8996_WRITE_SEQUENCER_244] = 0x2fff,
- [WM8996_WRITE_SEQUENCER_248] = 0x2fff,
- [WM8996_WRITE_SEQUENCER_252] = 0x2fff,
- [WM8996_WRITE_SEQUENCER_256] = 0x60,
- [WM8996_WRITE_SEQUENCER_258] = 0x601,
- [WM8996_WRITE_SEQUENCER_260] = 0x50,
- [WM8996_WRITE_SEQUENCER_262] = 0x100,
- [WM8996_WRITE_SEQUENCER_264] = 0x1,
- [WM8996_WRITE_SEQUENCER_266] = 0x104,
- [WM8996_WRITE_SEQUENCER_267] = 0x100,
- [WM8996_WRITE_SEQUENCER_268] = 0x2fff,
- [WM8996_WRITE_SEQUENCER_272] = 0x2fff,
- [WM8996_WRITE_SEQUENCER_276] = 0x2fff,
- [WM8996_WRITE_SEQUENCER_280] = 0x2fff,
- [WM8996_WRITE_SEQUENCER_284] = 0x2fff,
- [WM8996_WRITE_SEQUENCER_288] = 0x2fff,
- [WM8996_WRITE_SEQUENCER_292] = 0x2fff,
- [WM8996_WRITE_SEQUENCER_296] = 0x2fff,
- [WM8996_WRITE_SEQUENCER_300] = 0x2fff,
- [WM8996_WRITE_SEQUENCER_304] = 0x2fff,
- [WM8996_WRITE_SEQUENCER_308] = 0x2fff,
- [WM8996_WRITE_SEQUENCER_312] = 0x2fff,
- [WM8996_WRITE_SEQUENCER_316] = 0x2fff,
- [WM8996_WRITE_SEQUENCER_320] = 0x61,
- [WM8996_WRITE_SEQUENCER_322] = 0x601,
- [WM8996_WRITE_SEQUENCER_324] = 0x50,
- [WM8996_WRITE_SEQUENCER_326] = 0x102,
- [WM8996_WRITE_SEQUENCER_328] = 0x1,
- [WM8996_WRITE_SEQUENCER_330] = 0x106,
- [WM8996_WRITE_SEQUENCER_331] = 0x100,
- [WM8996_WRITE_SEQUENCER_332] = 0x2fff,
- [WM8996_WRITE_SEQUENCER_336] = 0x2fff,
- [WM8996_WRITE_SEQUENCER_340] = 0x2fff,
- [WM8996_WRITE_SEQUENCER_344] = 0x2fff,
- [WM8996_WRITE_SEQUENCER_348] = 0x2fff,
- [WM8996_WRITE_SEQUENCER_352] = 0x2fff,
- [WM8996_WRITE_SEQUENCER_356] = 0x2fff,
- [WM8996_WRITE_SEQUENCER_360] = 0x2fff,
- [WM8996_WRITE_SEQUENCER_364] = 0x2fff,
- [WM8996_WRITE_SEQUENCER_368] = 0x2fff,
- [WM8996_WRITE_SEQUENCER_372] = 0x2fff,
- [WM8996_WRITE_SEQUENCER_376] = 0x2fff,
- [WM8996_WRITE_SEQUENCER_380] = 0x2fff,
- [WM8996_WRITE_SEQUENCER_384] = 0x60,
- [WM8996_WRITE_SEQUENCER_386] = 0x601,
- [WM8996_WRITE_SEQUENCER_388] = 0x61,
- [WM8996_WRITE_SEQUENCER_390] = 0x601,
- [WM8996_WRITE_SEQUENCER_392] = 0x50,
- [WM8996_WRITE_SEQUENCER_394] = 0x300,
- [WM8996_WRITE_SEQUENCER_396] = 0x1,
- [WM8996_WRITE_SEQUENCER_398] = 0x304,
- [WM8996_WRITE_SEQUENCER_400] = 0x40,
- [WM8996_WRITE_SEQUENCER_402] = 0xf,
- [WM8996_WRITE_SEQUENCER_404] = 0x1,
- [WM8996_WRITE_SEQUENCER_407] = 0x100,
+static struct reg_default wm8996_reg[] = {
+ { WM8996_SOFTWARE_RESET, 0x8996 },
+ { WM8996_POWER_MANAGEMENT_1, 0x0 },
+ { WM8996_POWER_MANAGEMENT_2, 0x0 },
+ { WM8996_POWER_MANAGEMENT_3, 0x0 },
+ { WM8996_POWER_MANAGEMENT_4, 0x0 },
+ { WM8996_POWER_MANAGEMENT_5, 0x0 },
+ { WM8996_POWER_MANAGEMENT_6, 0x0 },
+ { WM8996_POWER_MANAGEMENT_7, 0x10 },
+ { WM8996_POWER_MANAGEMENT_8, 0x0 },
+ { WM8996_LEFT_LINE_INPUT_VOLUME, 0x0 },
+ { WM8996_RIGHT_LINE_INPUT_VOLUME, 0x0 },
+ { WM8996_LINE_INPUT_CONTROL, 0x0 },
+ { WM8996_DAC1_HPOUT1_VOLUME, 0x88 },
+ { WM8996_DAC2_HPOUT2_VOLUME, 0x88 },
+ { WM8996_DAC1_LEFT_VOLUME, 0x2c0 },
+ { WM8996_DAC1_RIGHT_VOLUME, 0x2c0 },
+ { WM8996_DAC2_LEFT_VOLUME, 0x2c0 },
+ { WM8996_DAC2_RIGHT_VOLUME, 0x2c0 },
+ { WM8996_OUTPUT1_LEFT_VOLUME, 0x80 },
+ { WM8996_OUTPUT1_RIGHT_VOLUME, 0x80 },
+ { WM8996_OUTPUT2_LEFT_VOLUME, 0x80 },
+ { WM8996_OUTPUT2_RIGHT_VOLUME, 0x80 },
+ { WM8996_MICBIAS_1, 0x39 },
+ { WM8996_MICBIAS_2, 0x39 },
+ { WM8996_LDO_1, 0x3 },
+ { WM8996_LDO_2, 0x13 },
+ { WM8996_ACCESSORY_DETECT_MODE_1, 0x4 },
+ { WM8996_ACCESSORY_DETECT_MODE_2, 0x0 },
+ { WM8996_HEADPHONE_DETECT_1, 0x20 },
+ { WM8996_HEADPHONE_DETECT_2, 0x0 },
+ { WM8996_MIC_DETECT_1, 0x7600 },
+ { WM8996_MIC_DETECT_2, 0xbf },
+ { WM8996_CHARGE_PUMP_1, 0x1f25 },
+ { WM8996_CHARGE_PUMP_2, 0xab19 },
+ { WM8996_DC_SERVO_1, 0x0 },
+ { WM8996_DC_SERVO_2, 0x0 },
+ { WM8996_DC_SERVO_3, 0x0 },
+ { WM8996_DC_SERVO_5, 0x2a2a },
+ { WM8996_DC_SERVO_6, 0x0 },
+ { WM8996_DC_SERVO_7, 0x0 },
+ { WM8996_ANALOGUE_HP_1, 0x0 },
+ { WM8996_ANALOGUE_HP_2, 0x0 },
+ { WM8996_CONTROL_INTERFACE_1, 0x8004 },
+ { WM8996_WRITE_SEQUENCER_CTRL_1, 0x0 },
+ { WM8996_WRITE_SEQUENCER_CTRL_2, 0x0 },
+ { WM8996_AIF_CLOCKING_1, 0x0 },
+ { WM8996_AIF_CLOCKING_2, 0x0 },
+ { WM8996_CLOCKING_1, 0x10 },
+ { WM8996_CLOCKING_2, 0x0 },
+ { WM8996_AIF_RATE, 0x83 },
+ { WM8996_FLL_CONTROL_1, 0x0 },
+ { WM8996_FLL_CONTROL_2, 0x0 },
+ { WM8996_FLL_CONTROL_3, 0x0 },
+ { WM8996_FLL_CONTROL_4, 0x5dc0 },
+ { WM8996_FLL_CONTROL_5, 0xc84 },
+ { WM8996_FLL_EFS_1, 0x0 },
+ { WM8996_FLL_EFS_2, 0x2 },
+ { WM8996_AIF1_CONTROL, 0x0 },
+ { WM8996_AIF1_BCLK, 0x0 },
+ { WM8996_AIF1_TX_LRCLK_1, 0x80 },
+ { WM8996_AIF1_TX_LRCLK_2, 0x8 },
+ { WM8996_AIF1_RX_LRCLK_1, 0x80 },
+ { WM8996_AIF1_RX_LRCLK_2, 0x0 },
+ { WM8996_AIF1TX_DATA_CONFIGURATION_1, 0x1818 },
+ { WM8996_AIF1TX_DATA_CONFIGURATION_2, 0 },
+ { WM8996_AIF1RX_DATA_CONFIGURATION, 0x1818 },
+ { WM8996_AIF1TX_CHANNEL_0_CONFIGURATION, 0x0 },
+ { WM8996_AIF1TX_CHANNEL_1_CONFIGURATION, 0x0 },
+ { WM8996_AIF1TX_CHANNEL_2_CONFIGURATION, 0x0 },
+ { WM8996_AIF1TX_CHANNEL_3_CONFIGURATION, 0x0 },
+ { WM8996_AIF1TX_CHANNEL_4_CONFIGURATION, 0x0 },
+ { WM8996_AIF1TX_CHANNEL_5_CONFIGURATION, 0x0 },
+ { WM8996_AIF1RX_CHANNEL_0_CONFIGURATION, 0x0 },
+ { WM8996_AIF1RX_CHANNEL_1_CONFIGURATION, 0x0 },
+ { WM8996_AIF1RX_CHANNEL_2_CONFIGURATION, 0x0 },
+ { WM8996_AIF1RX_CHANNEL_3_CONFIGURATION, 0x0 },
+ { WM8996_AIF1RX_CHANNEL_4_CONFIGURATION, 0x0 },
+ { WM8996_AIF1RX_CHANNEL_5_CONFIGURATION, 0x0 },
+ { WM8996_AIF1RX_MONO_CONFIGURATION, 0x0 },
+ { WM8996_AIF1TX_TEST, 0x7 },
+ { WM8996_AIF2_CONTROL, 0x0 },
+ { WM8996_AIF2_BCLK, 0x0 },
+ { WM8996_AIF2_TX_LRCLK_1, 0x80 },
+ { WM8996_AIF2_TX_LRCLK_2, 0x8 },
+ { WM8996_AIF2_RX_LRCLK_1, 0x80 },
+ { WM8996_AIF2_RX_LRCLK_2, 0x0 },
+ { WM8996_AIF2TX_DATA_CONFIGURATION_1, 0x1818 },
+ { WM8996_AIF2RX_DATA_CONFIGURATION, 0x1818 },
+ { WM8996_AIF2RX_DATA_CONFIGURATION, 0x0 },
+ { WM8996_AIF2TX_CHANNEL_0_CONFIGURATION, 0x0 },
+ { WM8996_AIF2TX_CHANNEL_1_CONFIGURATION, 0x0 },
+ { WM8996_AIF2RX_CHANNEL_0_CONFIGURATION, 0x0 },
+ { WM8996_AIF2RX_CHANNEL_1_CONFIGURATION, 0x0 },
+ { WM8996_AIF2RX_MONO_CONFIGURATION, 0x0 },
+ { WM8996_AIF2TX_TEST, 0x1 },
+ { WM8996_DSP1_TX_LEFT_VOLUME, 0xc0 },
+ { WM8996_DSP1_TX_RIGHT_VOLUME, 0xc0 },
+ { WM8996_DSP1_RX_LEFT_VOLUME, 0xc0 },
+ { WM8996_DSP1_RX_RIGHT_VOLUME, 0xc0 },
+ { WM8996_DSP1_TX_FILTERS, 0x2000 },
+ { WM8996_DSP1_RX_FILTERS_1, 0x200 },
+ { WM8996_DSP1_RX_FILTERS_2, 0x10 },
+ { WM8996_DSP1_DRC_1, 0x98 },
+ { WM8996_DSP1_DRC_2, 0x845 },
+ { WM8996_DSP1_RX_EQ_GAINS_1, 0x6318 },
+ { WM8996_DSP1_RX_EQ_GAINS_2, 0x6300 },
+ { WM8996_DSP1_RX_EQ_BAND_1_A, 0xfca },
+ { WM8996_DSP1_RX_EQ_BAND_1_B, 0x400 },
+ { WM8996_DSP1_RX_EQ_BAND_1_PG, 0xd8 },
+ { WM8996_DSP1_RX_EQ_BAND_2_A, 0x1eb5 },
+ { WM8996_DSP1_RX_EQ_BAND_2_B, 0xf145 },
+ { WM8996_DSP1_RX_EQ_BAND_2_C, 0xb75 },
+ { WM8996_DSP1_RX_EQ_BAND_2_PG, 0x1c5 },
+ { WM8996_DSP1_RX_EQ_BAND_3_A, 0x1c58 },
+ { WM8996_DSP1_RX_EQ_BAND_3_B, 0xf373 },
+ { WM8996_DSP1_RX_EQ_BAND_3_C, 0xa54 },
+ { WM8996_DSP1_RX_EQ_BAND_3_PG, 0x558 },
+ { WM8996_DSP1_RX_EQ_BAND_4_A, 0x168e },
+ { WM8996_DSP1_RX_EQ_BAND_4_B, 0xf829 },
+ { WM8996_DSP1_RX_EQ_BAND_4_C, 0x7ad },
+ { WM8996_DSP1_RX_EQ_BAND_4_PG, 0x1103 },
+ { WM8996_DSP1_RX_EQ_BAND_5_A, 0x564 },
+ { WM8996_DSP1_RX_EQ_BAND_5_B, 0x559 },
+ { WM8996_DSP1_RX_EQ_BAND_5_PG, 0x4000 },
+ { WM8996_DSP2_TX_LEFT_VOLUME, 0xc0 },
+ { WM8996_DSP2_TX_RIGHT_VOLUME, 0xc0 },
+ { WM8996_DSP2_RX_LEFT_VOLUME, 0xc0 },
+ { WM8996_DSP2_RX_RIGHT_VOLUME, 0xc0 },
+ { WM8996_DSP2_TX_FILTERS, 0x2000 },
+ { WM8996_DSP2_RX_FILTERS_1, 0x200 },
+ { WM8996_DSP2_RX_FILTERS_2, 0x10 },
+ { WM8996_DSP2_DRC_1, 0x98 },
+ { WM8996_DSP2_DRC_2, 0x845 },
+ { WM8996_DSP2_RX_EQ_GAINS_1, 0x6318 },
+ { WM8996_DSP2_RX_EQ_GAINS_2, 0x6300 },
+ { WM8996_DSP2_RX_EQ_BAND_1_A, 0xfca },
+ { WM8996_DSP2_RX_EQ_BAND_1_B, 0x400 },
+ { WM8996_DSP2_RX_EQ_BAND_1_PG, 0xd8 },
+ { WM8996_DSP2_RX_EQ_BAND_2_A, 0x1eb5 },
+ { WM8996_DSP2_RX_EQ_BAND_2_B, 0xf145 },
+ { WM8996_DSP2_RX_EQ_BAND_2_C, 0xb75 },
+ { WM8996_DSP2_RX_EQ_BAND_2_PG, 0x1c5 },
+ { WM8996_DSP2_RX_EQ_BAND_3_A, 0x1c58 },
+ { WM8996_DSP2_RX_EQ_BAND_3_B, 0xf373 },
+ { WM8996_DSP2_RX_EQ_BAND_3_C, 0xa54 },
+ { WM8996_DSP2_RX_EQ_BAND_3_PG, 0x558 },
+ { WM8996_DSP2_RX_EQ_BAND_4_A, 0x168e },
+ { WM8996_DSP2_RX_EQ_BAND_4_B, 0xf829 },
+ { WM8996_DSP2_RX_EQ_BAND_4_C, 0x7ad },
+ { WM8996_DSP2_RX_EQ_BAND_4_PG, 0x1103 },
+ { WM8996_DSP2_RX_EQ_BAND_5_A, 0x564 },
+ { WM8996_DSP2_RX_EQ_BAND_5_B, 0x559 },
+ { WM8996_DSP2_RX_EQ_BAND_5_PG, 0x4000 },
+ { WM8996_DAC1_MIXER_VOLUMES, 0x0 },
+ { WM8996_DAC1_LEFT_MIXER_ROUTING, 0x0 },
+ { WM8996_DAC1_RIGHT_MIXER_ROUTING, 0x0 },
+ { WM8996_DAC2_MIXER_VOLUMES, 0x0 },
+ { WM8996_DAC2_LEFT_MIXER_ROUTING, 0x0 },
+ { WM8996_DAC2_RIGHT_MIXER_ROUTING, 0x0 },
+ { WM8996_DSP1_TX_LEFT_MIXER_ROUTING, 0x0 },
+ { WM8996_DSP1_TX_RIGHT_MIXER_ROUTING, 0x0 },
+ { WM8996_DSP2_TX_LEFT_MIXER_ROUTING, 0x0 },
+ { WM8996_DSP2_TX_RIGHT_MIXER_ROUTING, 0x0 },
+ { WM8996_DSP_TX_MIXER_SELECT, 0x0 },
+ { WM8996_DAC_SOFTMUTE, 0x0 },
+ { WM8996_OVERSAMPLING, 0xd },
+ { WM8996_SIDETONE, 0x1040 },
+ { WM8996_GPIO_1, 0xa101 },
+ { WM8996_GPIO_2, 0xa101 },
+ { WM8996_GPIO_3, 0xa101 },
+ { WM8996_GPIO_4, 0xa101 },
+ { WM8996_GPIO_5, 0xa101 },
+ { WM8996_PULL_CONTROL_1, 0x0 },
+ { WM8996_PULL_CONTROL_2, 0x140 },
+ { WM8996_INTERRUPT_STATUS_1_MASK, 0x1f },
+ { WM8996_INTERRUPT_STATUS_2_MASK, 0x1ecf },
+ { WM8996_LEFT_PDM_SPEAKER, 0x0 },
+ { WM8996_RIGHT_PDM_SPEAKER, 0x1 },
+ { WM8996_PDM_SPEAKER_MUTE_SEQUENCE, 0x69 },
+ { WM8996_PDM_SPEAKER_VOLUME, 0x66 },
+ { WM8996_WRITE_SEQUENCER_0, 0x1 },
+ { WM8996_WRITE_SEQUENCER_1, 0x1 },
+ { WM8996_WRITE_SEQUENCER_3, 0x6 },
+ { WM8996_WRITE_SEQUENCER_4, 0x40 },
+ { WM8996_WRITE_SEQUENCER_5, 0x1 },
+ { WM8996_WRITE_SEQUENCER_6, 0xf },
+ { WM8996_WRITE_SEQUENCER_7, 0x6 },
+ { WM8996_WRITE_SEQUENCER_8, 0x1 },
+ { WM8996_WRITE_SEQUENCER_9, 0x3 },
+ { WM8996_WRITE_SEQUENCER_10, 0x104 },
+ { WM8996_WRITE_SEQUENCER_12, 0x60 },
+ { WM8996_WRITE_SEQUENCER_13, 0x11 },
+ { WM8996_WRITE_SEQUENCER_14, 0x401 },
+ { WM8996_WRITE_SEQUENCER_16, 0x50 },
+ { WM8996_WRITE_SEQUENCER_17, 0x3 },
+ { WM8996_WRITE_SEQUENCER_18, 0x100 },
+ { WM8996_WRITE_SEQUENCER_20, 0x51 },
+ { WM8996_WRITE_SEQUENCER_21, 0x3 },
+ { WM8996_WRITE_SEQUENCER_22, 0x104 },
+ { WM8996_WRITE_SEQUENCER_23, 0xa },
+ { WM8996_WRITE_SEQUENCER_24, 0x60 },
+ { WM8996_WRITE_SEQUENCER_25, 0x3b },
+ { WM8996_WRITE_SEQUENCER_26, 0x502 },
+ { WM8996_WRITE_SEQUENCER_27, 0x100 },
+ { WM8996_WRITE_SEQUENCER_28, 0x2fff },
+ { WM8996_WRITE_SEQUENCER_32, 0x2fff },
+ { WM8996_WRITE_SEQUENCER_36, 0x2fff },
+ { WM8996_WRITE_SEQUENCER_40, 0x2fff },
+ { WM8996_WRITE_SEQUENCER_44, 0x2fff },
+ { WM8996_WRITE_SEQUENCER_48, 0x2fff },
+ { WM8996_WRITE_SEQUENCER_52, 0x2fff },
+ { WM8996_WRITE_SEQUENCER_56, 0x2fff },
+ { WM8996_WRITE_SEQUENCER_60, 0x2fff },
+ { WM8996_WRITE_SEQUENCER_64, 0x1 },
+ { WM8996_WRITE_SEQUENCER_65, 0x1 },
+ { WM8996_WRITE_SEQUENCER_67, 0x6 },
+ { WM8996_WRITE_SEQUENCER_68, 0x40 },
+ { WM8996_WRITE_SEQUENCER_69, 0x1 },
+ { WM8996_WRITE_SEQUENCER_70, 0xf },
+ { WM8996_WRITE_SEQUENCER_71, 0x6 },
+ { WM8996_WRITE_SEQUENCER_72, 0x1 },
+ { WM8996_WRITE_SEQUENCER_73, 0x3 },
+ { WM8996_WRITE_SEQUENCER_74, 0x104 },
+ { WM8996_WRITE_SEQUENCER_76, 0x60 },
+ { WM8996_WRITE_SEQUENCER_77, 0x11 },
+ { WM8996_WRITE_SEQUENCER_78, 0x401 },
+ { WM8996_WRITE_SEQUENCER_80, 0x50 },
+ { WM8996_WRITE_SEQUENCER_81, 0x3 },
+ { WM8996_WRITE_SEQUENCER_82, 0x100 },
+ { WM8996_WRITE_SEQUENCER_84, 0x60 },
+ { WM8996_WRITE_SEQUENCER_85, 0x3b },
+ { WM8996_WRITE_SEQUENCER_86, 0x502 },
+ { WM8996_WRITE_SEQUENCER_87, 0x100 },
+ { WM8996_WRITE_SEQUENCER_88, 0x2fff },
+ { WM8996_WRITE_SEQUENCER_92, 0x2fff },
+ { WM8996_WRITE_SEQUENCER_96, 0x2fff },
+ { WM8996_WRITE_SEQUENCER_100, 0x2fff },
+ { WM8996_WRITE_SEQUENCER_104, 0x2fff },
+ { WM8996_WRITE_SEQUENCER_108, 0x2fff },
+ { WM8996_WRITE_SEQUENCER_112, 0x2fff },
+ { WM8996_WRITE_SEQUENCER_116, 0x2fff },
+ { WM8996_WRITE_SEQUENCER_120, 0x2fff },
+ { WM8996_WRITE_SEQUENCER_124, 0x2fff },
+ { WM8996_WRITE_SEQUENCER_128, 0x1 },
+ { WM8996_WRITE_SEQUENCER_129, 0x1 },
+ { WM8996_WRITE_SEQUENCER_131, 0x6 },
+ { WM8996_WRITE_SEQUENCER_132, 0x40 },
+ { WM8996_WRITE_SEQUENCER_133, 0x1 },
+ { WM8996_WRITE_SEQUENCER_134, 0xf },
+ { WM8996_WRITE_SEQUENCER_135, 0x6 },
+ { WM8996_WRITE_SEQUENCER_136, 0x1 },
+ { WM8996_WRITE_SEQUENCER_137, 0x3 },
+ { WM8996_WRITE_SEQUENCER_138, 0x106 },
+ { WM8996_WRITE_SEQUENCER_140, 0x61 },
+ { WM8996_WRITE_SEQUENCER_141, 0x11 },
+ { WM8996_WRITE_SEQUENCER_142, 0x401 },
+ { WM8996_WRITE_SEQUENCER_144, 0x50 },
+ { WM8996_WRITE_SEQUENCER_145, 0x3 },
+ { WM8996_WRITE_SEQUENCER_146, 0x102 },
+ { WM8996_WRITE_SEQUENCER_148, 0x51 },
+ { WM8996_WRITE_SEQUENCER_149, 0x3 },
+ { WM8996_WRITE_SEQUENCER_150, 0x106 },
+ { WM8996_WRITE_SEQUENCER_151, 0xa },
+ { WM8996_WRITE_SEQUENCER_152, 0x61 },
+ { WM8996_WRITE_SEQUENCER_153, 0x3b },
+ { WM8996_WRITE_SEQUENCER_154, 0x502 },
+ { WM8996_WRITE_SEQUENCER_155, 0x100 },
+ { WM8996_WRITE_SEQUENCER_156, 0x2fff },
+ { WM8996_WRITE_SEQUENCER_160, 0x2fff },
+ { WM8996_WRITE_SEQUENCER_164, 0x2fff },
+ { WM8996_WRITE_SEQUENCER_168, 0x2fff },
+ { WM8996_WRITE_SEQUENCER_172, 0x2fff },
+ { WM8996_WRITE_SEQUENCER_176, 0x2fff },
+ { WM8996_WRITE_SEQUENCER_180, 0x2fff },
+ { WM8996_WRITE_SEQUENCER_184, 0x2fff },
+ { WM8996_WRITE_SEQUENCER_188, 0x2fff },
+ { WM8996_WRITE_SEQUENCER_192, 0x1 },
+ { WM8996_WRITE_SEQUENCER_193, 0x1 },
+ { WM8996_WRITE_SEQUENCER_195, 0x6 },
+ { WM8996_WRITE_SEQUENCER_196, 0x40 },
+ { WM8996_WRITE_SEQUENCER_197, 0x1 },
+ { WM8996_WRITE_SEQUENCER_198, 0xf },
+ { WM8996_WRITE_SEQUENCER_199, 0x6 },
+ { WM8996_WRITE_SEQUENCER_200, 0x1 },
+ { WM8996_WRITE_SEQUENCER_201, 0x3 },
+ { WM8996_WRITE_SEQUENCER_202, 0x106 },
+ { WM8996_WRITE_SEQUENCER_204, 0x61 },
+ { WM8996_WRITE_SEQUENCER_205, 0x11 },
+ { WM8996_WRITE_SEQUENCER_206, 0x401 },
+ { WM8996_WRITE_SEQUENCER_208, 0x50 },
+ { WM8996_WRITE_SEQUENCER_209, 0x3 },
+ { WM8996_WRITE_SEQUENCER_210, 0x102 },
+ { WM8996_WRITE_SEQUENCER_212, 0x61 },
+ { WM8996_WRITE_SEQUENCER_213, 0x3b },
+ { WM8996_WRITE_SEQUENCER_214, 0x502 },
+ { WM8996_WRITE_SEQUENCER_215, 0x100 },
+ { WM8996_WRITE_SEQUENCER_216, 0x2fff },
+ { WM8996_WRITE_SEQUENCER_220, 0x2fff },
+ { WM8996_WRITE_SEQUENCER_224, 0x2fff },
+ { WM8996_WRITE_SEQUENCER_228, 0x2fff },
+ { WM8996_WRITE_SEQUENCER_232, 0x2fff },
+ { WM8996_WRITE_SEQUENCER_236, 0x2fff },
+ { WM8996_WRITE_SEQUENCER_240, 0x2fff },
+ { WM8996_WRITE_SEQUENCER_244, 0x2fff },
+ { WM8996_WRITE_SEQUENCER_248, 0x2fff },
+ { WM8996_WRITE_SEQUENCER_252, 0x2fff },
+ { WM8996_WRITE_SEQUENCER_256, 0x60 },
+ { WM8996_WRITE_SEQUENCER_258, 0x601 },
+ { WM8996_WRITE_SEQUENCER_260, 0x50 },
+ { WM8996_WRITE_SEQUENCER_262, 0x100 },
+ { WM8996_WRITE_SEQUENCER_264, 0x1 },
+ { WM8996_WRITE_SEQUENCER_266, 0x104 },
+ { WM8996_WRITE_SEQUENCER_267, 0x100 },
+ { WM8996_WRITE_SEQUENCER_268, 0x2fff },
+ { WM8996_WRITE_SEQUENCER_272, 0x2fff },
+ { WM8996_WRITE_SEQUENCER_276, 0x2fff },
+ { WM8996_WRITE_SEQUENCER_280, 0x2fff },
+ { WM8996_WRITE_SEQUENCER_284, 0x2fff },
+ { WM8996_WRITE_SEQUENCER_288, 0x2fff },
+ { WM8996_WRITE_SEQUENCER_292, 0x2fff },
+ { WM8996_WRITE_SEQUENCER_296, 0x2fff },
+ { WM8996_WRITE_SEQUENCER_300, 0x2fff },
+ { WM8996_WRITE_SEQUENCER_304, 0x2fff },
+ { WM8996_WRITE_SEQUENCER_308, 0x2fff },
+ { WM8996_WRITE_SEQUENCER_312, 0x2fff },
+ { WM8996_WRITE_SEQUENCER_316, 0x2fff },
+ { WM8996_WRITE_SEQUENCER_320, 0x61 },
+ { WM8996_WRITE_SEQUENCER_322, 0x601 },
+ { WM8996_WRITE_SEQUENCER_324, 0x50 },
+ { WM8996_WRITE_SEQUENCER_326, 0x102 },
+ { WM8996_WRITE_SEQUENCER_328, 0x1 },
+ { WM8996_WRITE_SEQUENCER_330, 0x106 },
+ { WM8996_WRITE_SEQUENCER_331, 0x100 },
+ { WM8996_WRITE_SEQUENCER_332, 0x2fff },
+ { WM8996_WRITE_SEQUENCER_336, 0x2fff },
+ { WM8996_WRITE_SEQUENCER_340, 0x2fff },
+ { WM8996_WRITE_SEQUENCER_344, 0x2fff },
+ { WM8996_WRITE_SEQUENCER_348, 0x2fff },
+ { WM8996_WRITE_SEQUENCER_352, 0x2fff },
+ { WM8996_WRITE_SEQUENCER_356, 0x2fff },
+ { WM8996_WRITE_SEQUENCER_360, 0x2fff },
+ { WM8996_WRITE_SEQUENCER_364, 0x2fff },
+ { WM8996_WRITE_SEQUENCER_368, 0x2fff },
+ { WM8996_WRITE_SEQUENCER_372, 0x2fff },
+ { WM8996_WRITE_SEQUENCER_376, 0x2fff },
+ { WM8996_WRITE_SEQUENCER_380, 0x2fff },
+ { WM8996_WRITE_SEQUENCER_384, 0x60 },
+ { WM8996_WRITE_SEQUENCER_386, 0x601 },
+ { WM8996_WRITE_SEQUENCER_388, 0x61 },
+ { WM8996_WRITE_SEQUENCER_390, 0x601 },
+ { WM8996_WRITE_SEQUENCER_392, 0x50 },
+ { WM8996_WRITE_SEQUENCER_394, 0x300 },
+ { WM8996_WRITE_SEQUENCER_396, 0x1 },
+ { WM8996_WRITE_SEQUENCER_398, 0x304 },
+ { WM8996_WRITE_SEQUENCER_400, 0x40 },
+ { WM8996_WRITE_SEQUENCER_402, 0xf },
+ { WM8996_WRITE_SEQUENCER_404, 0x1 },
+ { WM8996_WRITE_SEQUENCER_407, 0x100 },
};
static const DECLARE_TLV_DB_SCALE(inpga_tlv, 0, 100, 0);
@@ -1413,8 +1484,7 @@
{ "SPKDAT", NULL, "SPKR PGA" },
};
-static int wm8996_readable_register(struct snd_soc_codec *codec,
- unsigned int reg)
+static bool wm8996_readable_register(struct device *dev, unsigned int reg)
{
/* Due to the sparseness of the register map the compiler
* output from an explicit switch statement ends up being much
@@ -1621,8 +1691,7 @@
}
}
-static int wm8996_volatile_register(struct snd_soc_codec *codec,
- unsigned int reg)
+static bool wm8996_volatile_register(struct device *dev, unsigned int reg)
{
switch (reg) {
case WM8996_SOFTWARE_RESET:
@@ -1646,9 +1715,15 @@
}
}
-static int wm8996_reset(struct snd_soc_codec *codec)
+static int wm8996_reset(struct wm8996_priv *wm8996)
{
- return snd_soc_write(codec, WM8996_SOFTWARE_RESET, 0x8915);
+ if (wm8996->pdata.ldo_ena > 0) {
+ gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0);
+ return 0;
+ } else {
+ return regmap_write(wm8996->regmap, WM8996_SOFTWARE_RESET,
+ 0x8915);
+ }
}
static const int bclk_divs[] = {
@@ -1723,13 +1798,13 @@
msleep(5);
}
- codec->cache_only = false;
- snd_soc_cache_sync(codec);
+ regcache_cache_only(codec->control_data, false);
+ regcache_sync(codec->control_data);
}
break;
case SND_SOC_BIAS_OFF:
- codec->cache_only = true;
+ regcache_cache_only(codec->control_data, true);
if (wm8996->pdata.ldo_ena >= 0)
gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0);
regulator_bulk_disable(ARRAY_SIZE(wm8996->supplies),
@@ -2252,48 +2327,45 @@
static void wm8996_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
{
struct wm8996_priv *wm8996 = gpio_to_wm8996(chip);
- struct snd_soc_codec *codec = wm8996->codec;
- snd_soc_update_bits(codec, WM8996_GPIO_1 + offset,
- WM8996_GP1_LVL, !!value << WM8996_GP1_LVL_SHIFT);
+ regmap_update_bits(wm8996->regmap, WM8996_GPIO_1 + offset,
+ WM8996_GP1_LVL, !!value << WM8996_GP1_LVL_SHIFT);
}
static int wm8996_gpio_direction_out(struct gpio_chip *chip,
unsigned offset, int value)
{
struct wm8996_priv *wm8996 = gpio_to_wm8996(chip);
- struct snd_soc_codec *codec = wm8996->codec;
int val;
val = (1 << WM8996_GP1_FN_SHIFT) | (!!value << WM8996_GP1_LVL_SHIFT);
- return snd_soc_update_bits(codec, WM8996_GPIO_1 + offset,
- WM8996_GP1_FN_MASK | WM8996_GP1_DIR |
- WM8996_GP1_LVL, val);
+ return regmap_update_bits(wm8996->regmap, WM8996_GPIO_1 + offset,
+ WM8996_GP1_FN_MASK | WM8996_GP1_DIR |
+ WM8996_GP1_LVL, val);
}
static int wm8996_gpio_get(struct gpio_chip *chip, unsigned offset)
{
struct wm8996_priv *wm8996 = gpio_to_wm8996(chip);
- struct snd_soc_codec *codec = wm8996->codec;
+ unsigned int reg;
int ret;
- ret = snd_soc_read(codec, WM8996_GPIO_1 + offset);
+ ret = regmap_read(wm8996->regmap, WM8996_GPIO_1 + offset, ®);
if (ret < 0)
return ret;
- return (ret & WM8996_GP1_LVL) != 0;
+ return (reg & WM8996_GP1_LVL) != 0;
}
static int wm8996_gpio_direction_in(struct gpio_chip *chip, unsigned offset)
{
struct wm8996_priv *wm8996 = gpio_to_wm8996(chip);
- struct snd_soc_codec *codec = wm8996->codec;
- return snd_soc_update_bits(codec, WM8996_GPIO_1 + offset,
- WM8996_GP1_FN_MASK | WM8996_GP1_DIR,
- (1 << WM8996_GP1_FN_SHIFT) |
- (1 << WM8996_GP1_DIR_SHIFT));
+ return regmap_update_bits(wm8996->regmap, WM8996_GPIO_1 + offset,
+ WM8996_GP1_FN_MASK | WM8996_GP1_DIR,
+ (1 << WM8996_GP1_FN_SHIFT) |
+ (1 << WM8996_GP1_DIR_SHIFT));
}
static struct gpio_chip wm8996_template_chip = {
@@ -2306,14 +2378,13 @@
.can_sleep = 1,
};
-static void wm8996_init_gpio(struct snd_soc_codec *codec)
+static void wm8996_init_gpio(struct wm8996_priv *wm8996)
{
- struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
int ret;
wm8996->gpio_chip = wm8996_template_chip;
wm8996->gpio_chip.ngpio = 5;
- wm8996->gpio_chip.dev = codec->dev;
+ wm8996->gpio_chip.dev = wm8996->dev;
if (wm8996->pdata.gpio_base)
wm8996->gpio_chip.base = wm8996->pdata.gpio_base;
@@ -2322,24 +2393,23 @@
ret = gpiochip_add(&wm8996->gpio_chip);
if (ret != 0)
- dev_err(codec->dev, "Failed to add GPIOs: %d\n", ret);
+ dev_err(wm8996->dev, "Failed to add GPIOs: %d\n", ret);
}
-static void wm8996_free_gpio(struct snd_soc_codec *codec)
+static void wm8996_free_gpio(struct wm8996_priv *wm8996)
{
- struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
int ret;
ret = gpiochip_remove(&wm8996->gpio_chip);
if (ret != 0)
- dev_err(codec->dev, "Failed to remove GPIOs: %d\n", ret);
+ dev_err(wm8996->dev, "Failed to remove GPIOs: %d\n", ret);
}
#else
-static void wm8996_init_gpio(struct snd_soc_codec *codec)
+static void wm8996_init_gpio(struct wm8996_priv *wm8996)
{
}
-static void wm8996_free_gpio(struct snd_soc_codec *codec)
+static void wm8996_free_gpio(struct wm8996_priv *wm8996)
{
}
#endif
@@ -2502,8 +2572,10 @@
SND_JACK_BTN_0);
snd_soc_update_bits(codec, WM8996_MIC_DETECT_1,
- WM8996_MICD_RATE_MASK,
- WM8996_MICD_RATE_MASK);
+ WM8996_MICD_RATE_MASK |
+ WM8996_MICD_BIAS_STARTTIME_MASK,
+ WM8996_MICD_RATE_MASK |
+ 9 << WM8996_MICD_BIAS_STARTTIME_SHIFT);
return;
}
@@ -2520,8 +2592,10 @@
/* Increase poll rate to give better responsiveness
* for buttons */
snd_soc_update_bits(codec, WM8996_MIC_DETECT_1,
- WM8996_MICD_RATE_MASK,
- 5 << WM8996_MICD_RATE_SHIFT);
+ WM8996_MICD_RATE_MASK |
+ WM8996_MICD_BIAS_STARTTIME_MASK,
+ 5 << WM8996_MICD_RATE_SHIFT |
+ 7 << WM8996_MICD_BIAS_STARTTIME_SHIFT);
} else {
dev_dbg(codec->dev, "Mic button up\n");
snd_soc_jack_report(wm8996->jack, 0, SND_JACK_BTN_0);
@@ -2569,8 +2643,10 @@
* responsiveness.
*/
snd_soc_update_bits(codec, WM8996_MIC_DETECT_1,
- WM8996_MICD_RATE_MASK,
- 7 << WM8996_MICD_RATE_SHIFT);
+ WM8996_MICD_RATE_MASK |
+ WM8996_MICD_BIAS_STARTTIME_MASK,
+ 7 << WM8996_MICD_RATE_SHIFT |
+ 7 << WM8996_MICD_BIAS_STARTTIME_SHIFT);
}
}
}
@@ -2693,6 +2769,18 @@
"Failed to add ReTune Mobile controls: %d\n", ret);
}
+static const struct regmap_config wm8996_regmap = {
+ .reg_bits = 16,
+ .val_bits = 16,
+
+ .max_register = WM8996_MAX_REGISTER,
+ .reg_defaults = wm8996_reg,
+ .num_reg_defaults = ARRAY_SIZE(wm8996_reg),
+ .volatile_reg = wm8996_volatile_register,
+ .readable_reg = wm8996_readable_register,
+ .cache_type = REGCACHE_RBTREE,
+};
+
static int wm8996_probe(struct snd_soc_codec *codec)
{
int ret;
@@ -2708,33 +2796,18 @@
dapm->idle_bias_off = true;
- ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_I2C);
+ codec->control_data = wm8996->regmap;
+
+ ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_REGMAP);
if (ret != 0) {
dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
goto err;
}
- for (i = 0; i < ARRAY_SIZE(wm8996->supplies); i++)
- wm8996->supplies[i].supply = wm8996_supply_names[i];
-
- ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8996->supplies),
- wm8996->supplies);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
- goto err;
- }
-
wm8996->disable_nb[0].notifier_call = wm8996_regulator_event_0;
wm8996->disable_nb[1].notifier_call = wm8996_regulator_event_1;
wm8996->disable_nb[2].notifier_call = wm8996_regulator_event_2;
- wm8996->cpvdd = regulator_get(&i2c->dev, "CPVDD");
- if (IS_ERR(wm8996->cpvdd)) {
- ret = PTR_ERR(wm8996->cpvdd);
- dev_err(&i2c->dev, "Failed to get CPVDD: %d\n", ret);
- goto err_get;
- }
-
/* This should really be moved into the regulator core */
for (i = 0; i < ARRAY_SIZE(wm8996->supplies); i++) {
ret = regulator_register_notifier(wm8996->supplies[i].consumer,
@@ -2746,50 +2819,7 @@
}
}
- ret = regulator_bulk_enable(ARRAY_SIZE(wm8996->supplies),
- wm8996->supplies);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
- goto err_cpvdd;
- }
-
- if (wm8996->pdata.ldo_ena >= 0) {
- gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 1);
- msleep(5);
- }
-
- ret = snd_soc_read(codec, WM8996_SOFTWARE_RESET);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to read ID register: %d\n", ret);
- goto err_enable;
- }
- if (ret != 0x8915) {
- dev_err(codec->dev, "Device is not a WM8996, ID %x\n", ret);
- ret = -EINVAL;
- goto err_enable;
- }
-
- ret = snd_soc_read(codec, WM8996_CHIP_REVISION);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to read device revision: %d\n",
- ret);
- goto err_enable;
- }
-
- dev_info(codec->dev, "revision %c\n",
- (ret & WM8996_CHIP_REV_MASK) + 'A');
-
- if (wm8996->pdata.ldo_ena >= 0) {
- gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0);
- } else {
- ret = wm8996_reset(codec);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to issue reset\n");
- goto err_enable;
- }
- }
-
- codec->cache_only = true;
+ regcache_cache_only(codec->control_data, true);
/* Apply platform data settings */
snd_soc_update_bits(codec, WM8996_LINE_INPUT_CONTROL,
@@ -2947,10 +2977,6 @@
WM8996_AIF2TX_LRCLK_MODE,
WM8996_AIF2TX_LRCLK_MODE);
- regulator_bulk_disable(ARRAY_SIZE(wm8996->supplies), wm8996->supplies);
-
- wm8996_init_gpio(codec);
-
if (i2c->irq) {
if (wm8996->pdata.irq_flags)
irq_flags = wm8996->pdata.irq_flags;
@@ -2988,15 +3014,6 @@
return 0;
-err_enable:
- if (wm8996->pdata.ldo_ena >= 0)
- gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0);
-
- regulator_bulk_disable(ARRAY_SIZE(wm8996->supplies), wm8996->supplies);
-err_cpvdd:
- regulator_put(wm8996->cpvdd);
-err_get:
- regulator_bulk_free(ARRAY_SIZE(wm8996->supplies), wm8996->supplies);
err:
return ret;
}
@@ -3013,8 +3030,6 @@
if (i2c->irq)
free_irq(i2c->irq, codec);
- wm8996_free_gpio(codec);
-
for (i = 0; i < ARRAY_SIZE(wm8996->supplies); i++)
regulator_unregister_notifier(wm8996->supplies[i].consumer,
&wm8996->disable_nb[i]);
@@ -3024,17 +3039,17 @@
return 0;
}
+static int wm8996_soc_volatile_register(struct snd_soc_codec *codec,
+ unsigned int reg)
+{
+ return true;
+}
+
static struct snd_soc_codec_driver soc_codec_dev_wm8996 = {
.probe = wm8996_probe,
.remove = wm8996_remove,
.set_bias_level = wm8996_set_bias_level,
.seq_notifier = wm8996_seq_notifier,
- .reg_cache_size = WM8996_MAX_REGISTER + 1,
- .reg_word_size = sizeof(u16),
- .reg_cache_default = wm8996_reg,
- .volatile_register = wm8996_volatile_register,
- .readable_register = wm8996_readable_register,
- .compress_type = SND_SOC_RBTREE_COMPRESSION,
.controls = wm8996_snd_controls,
.num_controls = ARRAY_SIZE(wm8996_snd_controls),
.dapm_widgets = wm8996_dapm_widgets,
@@ -3042,6 +3057,8 @@
.dapm_routes = wm8996_dapm_routes,
.num_dapm_routes = ARRAY_SIZE(wm8996_dapm_routes),
.set_pll = wm8996_set_fll,
+ .reg_cache_size = WM8996_MAX_REGISTER,
+ .volatile_register = wm8996_soc_volatile_register,
};
#define WM8996_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\
@@ -3050,7 +3067,7 @@
SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE |\
SNDRV_PCM_FMTBIT_S32_LE)
-static struct snd_soc_dai_ops wm8996_dai_ops = {
+static const struct snd_soc_dai_ops wm8996_dai_ops = {
.set_fmt = wm8996_set_fmt,
.hw_params = wm8996_hw_params,
.set_sysclk = wm8996_set_sysclk,
@@ -3099,13 +3116,16 @@
const struct i2c_device_id *id)
{
struct wm8996_priv *wm8996;
- int ret;
+ int ret, i;
+ unsigned int reg;
- wm8996 = kzalloc(sizeof(struct wm8996_priv), GFP_KERNEL);
+ wm8996 = devm_kzalloc(&i2c->dev, sizeof(struct wm8996_priv),
+ GFP_KERNEL);
if (wm8996 == NULL)
return -ENOMEM;
i2c_set_clientdata(i2c, wm8996);
+ wm8996->dev = &i2c->dev;
if (dev_get_platdata(&i2c->dev))
memcpy(&wm8996->pdata, dev_get_platdata(&i2c->dev),
@@ -3121,19 +3141,97 @@
}
}
+ for (i = 0; i < ARRAY_SIZE(wm8996->supplies); i++)
+ wm8996->supplies[i].supply = wm8996_supply_names[i];
+
+ ret = regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm8996->supplies),
+ wm8996->supplies);
+ if (ret != 0) {
+ dev_err(&i2c->dev, "Failed to request supplies: %d\n", ret);
+ goto err_gpio;
+ }
+
+ wm8996->cpvdd = regulator_get(&i2c->dev, "CPVDD");
+ if (IS_ERR(wm8996->cpvdd)) {
+ ret = PTR_ERR(wm8996->cpvdd);
+ dev_err(&i2c->dev, "Failed to get CPVDD: %d\n", ret);
+ goto err_get;
+ }
+
+ ret = regulator_bulk_enable(ARRAY_SIZE(wm8996->supplies),
+ wm8996->supplies);
+ if (ret != 0) {
+ dev_err(&i2c->dev, "Failed to enable supplies: %d\n", ret);
+ goto err_cpvdd;
+ }
+
+ if (wm8996->pdata.ldo_ena > 0) {
+ gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 1);
+ msleep(5);
+ }
+
+ wm8996->regmap = regmap_init_i2c(i2c, &wm8996_regmap);
+ if (IS_ERR(wm8996->regmap)) {
+ ret = PTR_ERR(wm8996->regmap);
+ dev_err(&i2c->dev, "regmap_init() failed: %d\n", ret);
+ goto err_enable;
+ }
+
+ ret = regmap_read(wm8996->regmap, WM8996_SOFTWARE_RESET, ®);
+ if (ret < 0) {
+ dev_err(&i2c->dev, "Failed to read ID register: %d\n", ret);
+ goto err_regmap;
+ }
+ if (reg != 0x8915) {
+ dev_err(&i2c->dev, "Device is not a WM8996, ID %x\n", ret);
+ ret = -EINVAL;
+ goto err_regmap;
+ }
+
+ ret = regmap_read(wm8996->regmap, WM8996_CHIP_REVISION, ®);
+ if (ret < 0) {
+ dev_err(&i2c->dev, "Failed to read device revision: %d\n",
+ ret);
+ goto err_regmap;
+ }
+
+ dev_info(&i2c->dev, "revision %c\n",
+ (reg & WM8996_CHIP_REV_MASK) + 'A');
+
+ regulator_bulk_disable(ARRAY_SIZE(wm8996->supplies), wm8996->supplies);
+
+ ret = wm8996_reset(wm8996);
+ if (ret < 0) {
+ dev_err(&i2c->dev, "Failed to issue reset\n");
+ goto err_regmap;
+ }
+
+ wm8996_init_gpio(wm8996);
+
ret = snd_soc_register_codec(&i2c->dev,
&soc_codec_dev_wm8996, wm8996_dai,
ARRAY_SIZE(wm8996_dai));
if (ret < 0)
- goto err_gpio;
+ goto err_gpiolib;
return ret;
+err_gpiolib:
+ wm8996_free_gpio(wm8996);
+err_regmap:
+ regmap_exit(wm8996->regmap);
+err_enable:
+ if (wm8996->pdata.ldo_ena > 0)
+ gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0);
+ regulator_bulk_disable(ARRAY_SIZE(wm8996->supplies), wm8996->supplies);
+err_cpvdd:
+ regulator_put(wm8996->cpvdd);
+err_get:
+ regulator_bulk_free(ARRAY_SIZE(wm8996->supplies), wm8996->supplies);
err_gpio:
if (wm8996->pdata.ldo_ena > 0)
gpio_free(wm8996->pdata.ldo_ena);
err:
- kfree(wm8996);
return ret;
}
@@ -3143,9 +3241,14 @@
struct wm8996_priv *wm8996 = i2c_get_clientdata(client);
snd_soc_unregister_codec(&client->dev);
- if (wm8996->pdata.ldo_ena > 0)
+ wm8996_free_gpio(wm8996);
+ regulator_put(wm8996->cpvdd);
+ regulator_bulk_free(ARRAY_SIZE(wm8996->supplies), wm8996->supplies);
+ regmap_exit(wm8996->regmap);
+ if (wm8996->pdata.ldo_ena > 0) {
+ gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0);
gpio_free(wm8996->pdata.ldo_ena);
- kfree(i2c_get_clientdata(client));
+ }
return 0;
}
diff --git a/sound/soc/codecs/wm9081.c b/sound/soc/codecs/wm9081.c
index 4a398c3..a6bab39 100644
--- a/sound/soc/codecs/wm9081.c
+++ b/sound/soc/codecs/wm9081.c
@@ -18,7 +18,7 @@
#include <linux/device.h>
#include <linux/pm.h>
#include <linux/i2c.h>
-#include <linux/platform_device.h>
+#include <linux/regmap.h>
#include <linux/slab.h>
#include <sound/core.h>
#include <sound/pcm.h>
@@ -30,69 +30,60 @@
#include <sound/wm9081.h>
#include "wm9081.h"
-static u16 wm9081_reg_defaults[] = {
- 0x0000, /* R0 - Software Reset */
- 0x0000, /* R1 */
- 0x00B9, /* R2 - Analogue Lineout */
- 0x00B9, /* R3 - Analogue Speaker PGA */
- 0x0001, /* R4 - VMID Control */
- 0x0068, /* R5 - Bias Control 1 */
- 0x0000, /* R6 */
- 0x0000, /* R7 - Analogue Mixer */
- 0x0000, /* R8 - Anti Pop Control */
- 0x01DB, /* R9 - Analogue Speaker 1 */
- 0x0018, /* R10 - Analogue Speaker 2 */
- 0x0180, /* R11 - Power Management */
- 0x0000, /* R12 - Clock Control 1 */
- 0x0038, /* R13 - Clock Control 2 */
- 0x4000, /* R14 - Clock Control 3 */
- 0x0000, /* R15 */
- 0x0000, /* R16 - FLL Control 1 */
- 0x0200, /* R17 - FLL Control 2 */
- 0x0000, /* R18 - FLL Control 3 */
- 0x0204, /* R19 - FLL Control 4 */
- 0x0000, /* R20 - FLL Control 5 */
- 0x0000, /* R21 */
- 0x0000, /* R22 - Audio Interface 1 */
- 0x0002, /* R23 - Audio Interface 2 */
- 0x0008, /* R24 - Audio Interface 3 */
- 0x0022, /* R25 - Audio Interface 4 */
- 0x0000, /* R26 - Interrupt Status */
- 0x0006, /* R27 - Interrupt Status Mask */
- 0x0000, /* R28 - Interrupt Polarity */
- 0x0000, /* R29 - Interrupt Control */
- 0x00C0, /* R30 - DAC Digital 1 */
- 0x0008, /* R31 - DAC Digital 2 */
- 0x09AF, /* R32 - DRC 1 */
- 0x4201, /* R33 - DRC 2 */
- 0x0000, /* R34 - DRC 3 */
- 0x0000, /* R35 - DRC 4 */
- 0x0000, /* R36 */
- 0x0000, /* R37 */
- 0x0000, /* R38 - Write Sequencer 1 */
- 0x0000, /* R39 - Write Sequencer 2 */
- 0x0002, /* R40 - MW Slave 1 */
- 0x0000, /* R41 */
- 0x0000, /* R42 - EQ 1 */
- 0x0000, /* R43 - EQ 2 */
- 0x0FCA, /* R44 - EQ 3 */
- 0x0400, /* R45 - EQ 4 */
- 0x00B8, /* R46 - EQ 5 */
- 0x1EB5, /* R47 - EQ 6 */
- 0xF145, /* R48 - EQ 7 */
- 0x0B75, /* R49 - EQ 8 */
- 0x01C5, /* R50 - EQ 9 */
- 0x169E, /* R51 - EQ 10 */
- 0xF829, /* R52 - EQ 11 */
- 0x07AD, /* R53 - EQ 12 */
- 0x1103, /* R54 - EQ 13 */
- 0x1C58, /* R55 - EQ 14 */
- 0xF373, /* R56 - EQ 15 */
- 0x0A54, /* R57 - EQ 16 */
- 0x0558, /* R58 - EQ 17 */
- 0x0564, /* R59 - EQ 18 */
- 0x0559, /* R60 - EQ 19 */
- 0x4000, /* R61 - EQ 20 */
+static struct reg_default wm9081_reg[] = {
+ { 2, 0x00B9 }, /* R2 - Analogue Lineout */
+ { 3, 0x00B9 }, /* R3 - Analogue Speaker PGA */
+ { 4, 0x0001 }, /* R4 - VMID Control */
+ { 5, 0x0068 }, /* R5 - Bias Control 1 */
+ { 7, 0x0000 }, /* R7 - Analogue Mixer */
+ { 8, 0x0000 }, /* R8 - Anti Pop Control */
+ { 9, 0x01DB }, /* R9 - Analogue Speaker 1 */
+ { 10, 0x0018 }, /* R10 - Analogue Speaker 2 */
+ { 11, 0x0180 }, /* R11 - Power Management */
+ { 12, 0x0000 }, /* R12 - Clock Control 1 */
+ { 13, 0x0038 }, /* R13 - Clock Control 2 */
+ { 14, 0x4000 }, /* R14 - Clock Control 3 */
+ { 16, 0x0000 }, /* R16 - FLL Control 1 */
+ { 17, 0x0200 }, /* R17 - FLL Control 2 */
+ { 18, 0x0000 }, /* R18 - FLL Control 3 */
+ { 19, 0x0204 }, /* R19 - FLL Control 4 */
+ { 20, 0x0000 }, /* R20 - FLL Control 5 */
+ { 22, 0x0000 }, /* R22 - Audio Interface 1 */
+ { 23, 0x0002 }, /* R23 - Audio Interface 2 */
+ { 24, 0x0008 }, /* R24 - Audio Interface 3 */
+ { 25, 0x0022 }, /* R25 - Audio Interface 4 */
+ { 27, 0x0006 }, /* R27 - Interrupt Status Mask */
+ { 28, 0x0000 }, /* R28 - Interrupt Polarity */
+ { 29, 0x0000 }, /* R29 - Interrupt Control */
+ { 30, 0x00C0 }, /* R30 - DAC Digital 1 */
+ { 31, 0x0008 }, /* R31 - DAC Digital 2 */
+ { 32, 0x09AF }, /* R32 - DRC 1 */
+ { 33, 0x4201 }, /* R33 - DRC 2 */
+ { 34, 0x0000 }, /* R34 - DRC 3 */
+ { 35, 0x0000 }, /* R35 - DRC 4 */
+ { 38, 0x0000 }, /* R38 - Write Sequencer 1 */
+ { 39, 0x0000 }, /* R39 - Write Sequencer 2 */
+ { 40, 0x0002 }, /* R40 - MW Slave 1 */
+ { 42, 0x0000 }, /* R42 - EQ 1 */
+ { 43, 0x0000 }, /* R43 - EQ 2 */
+ { 44, 0x0FCA }, /* R44 - EQ 3 */
+ { 45, 0x0400 }, /* R45 - EQ 4 */
+ { 46, 0x00B8 }, /* R46 - EQ 5 */
+ { 47, 0x1EB5 }, /* R47 - EQ 6 */
+ { 48, 0xF145 }, /* R48 - EQ 7 */
+ { 49, 0x0B75 }, /* R49 - EQ 8 */
+ { 50, 0x01C5 }, /* R50 - EQ 9 */
+ { 51, 0x169E }, /* R51 - EQ 10 */
+ { 52, 0xF829 }, /* R52 - EQ 11 */
+ { 53, 0x07AD }, /* R53 - EQ 12 */
+ { 54, 0x1103 }, /* R54 - EQ 13 */
+ { 55, 0x1C58 }, /* R55 - EQ 14 */
+ { 56, 0xF373 }, /* R56 - EQ 15 */
+ { 57, 0x0A54 }, /* R57 - EQ 16 */
+ { 58, 0x0558 }, /* R58 - EQ 17 */
+ { 59, 0x0564 }, /* R59 - EQ 18 */
+ { 60, 0x0559 }, /* R60 - EQ 19 */
+ { 61, 0x4000 }, /* R61 - EQ 20 */
};
static struct {
@@ -156,7 +147,7 @@
};
struct wm9081_priv {
- enum snd_soc_control_type control_type;
+ struct regmap *regmap;
int sysclk_source;
int mclk_rate;
int sysclk_rate;
@@ -169,20 +160,84 @@
struct wm9081_pdata pdata;
};
-static int wm9081_volatile_register(struct snd_soc_codec *codec, unsigned int reg)
+static bool wm9081_volatile_register(struct device *dev, unsigned int reg)
{
switch (reg) {
case WM9081_SOFTWARE_RESET:
case WM9081_INTERRUPT_STATUS:
- return 1;
+ return true;
default:
- return 0;
+ return false;
}
}
-static int wm9081_reset(struct snd_soc_codec *codec)
+static bool wm9081_readable_register(struct device *dev, unsigned int reg)
{
- return snd_soc_write(codec, WM9081_SOFTWARE_RESET, 0);
+ switch (reg) {
+ case WM9081_SOFTWARE_RESET:
+ case WM9081_ANALOGUE_LINEOUT:
+ case WM9081_ANALOGUE_SPEAKER_PGA:
+ case WM9081_VMID_CONTROL:
+ case WM9081_BIAS_CONTROL_1:
+ case WM9081_ANALOGUE_MIXER:
+ case WM9081_ANTI_POP_CONTROL:
+ case WM9081_ANALOGUE_SPEAKER_1:
+ case WM9081_ANALOGUE_SPEAKER_2:
+ case WM9081_POWER_MANAGEMENT:
+ case WM9081_CLOCK_CONTROL_1:
+ case WM9081_CLOCK_CONTROL_2:
+ case WM9081_CLOCK_CONTROL_3:
+ case WM9081_FLL_CONTROL_1:
+ case WM9081_FLL_CONTROL_2:
+ case WM9081_FLL_CONTROL_3:
+ case WM9081_FLL_CONTROL_4:
+ case WM9081_FLL_CONTROL_5:
+ case WM9081_AUDIO_INTERFACE_1:
+ case WM9081_AUDIO_INTERFACE_2:
+ case WM9081_AUDIO_INTERFACE_3:
+ case WM9081_AUDIO_INTERFACE_4:
+ case WM9081_INTERRUPT_STATUS:
+ case WM9081_INTERRUPT_STATUS_MASK:
+ case WM9081_INTERRUPT_POLARITY:
+ case WM9081_INTERRUPT_CONTROL:
+ case WM9081_DAC_DIGITAL_1:
+ case WM9081_DAC_DIGITAL_2:
+ case WM9081_DRC_1:
+ case WM9081_DRC_2:
+ case WM9081_DRC_3:
+ case WM9081_DRC_4:
+ case WM9081_WRITE_SEQUENCER_1:
+ case WM9081_WRITE_SEQUENCER_2:
+ case WM9081_MW_SLAVE_1:
+ case WM9081_EQ_1:
+ case WM9081_EQ_2:
+ case WM9081_EQ_3:
+ case WM9081_EQ_4:
+ case WM9081_EQ_5:
+ case WM9081_EQ_6:
+ case WM9081_EQ_7:
+ case WM9081_EQ_8:
+ case WM9081_EQ_9:
+ case WM9081_EQ_10:
+ case WM9081_EQ_11:
+ case WM9081_EQ_12:
+ case WM9081_EQ_13:
+ case WM9081_EQ_14:
+ case WM9081_EQ_15:
+ case WM9081_EQ_16:
+ case WM9081_EQ_17:
+ case WM9081_EQ_18:
+ case WM9081_EQ_19:
+ case WM9081_EQ_20:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static int wm9081_reset(struct regmap *map)
+{
+ return regmap_write(map, WM9081_SOFTWARE_RESET, 0x9081);
}
static const DECLARE_TLV_DB_SCALE(drc_in_tlv, -4500, 75, 0);
@@ -737,6 +792,7 @@
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
SND_SOC_DAPM_SUPPLY("CLK_DSP", WM9081_CLOCK_CONTROL_3, 1, 0, NULL, 0),
SND_SOC_DAPM_SUPPLY("TOCLK", WM9081_CLOCK_CONTROL_3, 2, 0, NULL, 0),
+SND_SOC_DAPM_SUPPLY("TSENSE", WM9081_POWER_MANAGEMENT, 7, 0, NULL, 0),
};
@@ -759,6 +815,7 @@
{ "Speaker PGA", NULL, "CLK_SYS" },
{ "Speaker", NULL, "Speaker PGA" },
+ { "Speaker", NULL, "TSENSE" },
{ "SPKN", NULL, "Speaker" },
{ "SPKP", NULL, "Speaker" },
@@ -767,84 +824,74 @@
static int wm9081_set_bias_level(struct snd_soc_codec *codec,
enum snd_soc_bias_level level)
{
- u16 reg;
-
switch (level) {
case SND_SOC_BIAS_ON:
break;
case SND_SOC_BIAS_PREPARE:
/* VMID=2*40k */
- reg = snd_soc_read(codec, WM9081_VMID_CONTROL);
- reg &= ~WM9081_VMID_SEL_MASK;
- reg |= 0x2;
- snd_soc_write(codec, WM9081_VMID_CONTROL, reg);
+ snd_soc_update_bits(codec, WM9081_VMID_CONTROL,
+ WM9081_VMID_SEL_MASK, 0x2);
/* Normal bias current */
- reg = snd_soc_read(codec, WM9081_BIAS_CONTROL_1);
- reg &= ~WM9081_STBY_BIAS_ENA;
- snd_soc_write(codec, WM9081_BIAS_CONTROL_1, reg);
+ snd_soc_update_bits(codec, WM9081_BIAS_CONTROL_1,
+ WM9081_STBY_BIAS_ENA, 0);
break;
case SND_SOC_BIAS_STANDBY:
/* Initial cold start */
if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
/* Disable LINEOUT discharge */
- reg = snd_soc_read(codec, WM9081_ANTI_POP_CONTROL);
- reg &= ~WM9081_LINEOUT_DISCH;
- snd_soc_write(codec, WM9081_ANTI_POP_CONTROL, reg);
+ snd_soc_update_bits(codec, WM9081_ANTI_POP_CONTROL,
+ WM9081_LINEOUT_DISCH, 0);
/* Select startup bias source */
- reg = snd_soc_read(codec, WM9081_BIAS_CONTROL_1);
- reg |= WM9081_BIAS_SRC | WM9081_BIAS_ENA;
- snd_soc_write(codec, WM9081_BIAS_CONTROL_1, reg);
+ snd_soc_update_bits(codec, WM9081_BIAS_CONTROL_1,
+ WM9081_BIAS_SRC | WM9081_BIAS_ENA,
+ WM9081_BIAS_SRC | WM9081_BIAS_ENA);
/* VMID 2*4k; Soft VMID ramp enable */
- reg = snd_soc_read(codec, WM9081_VMID_CONTROL);
- reg |= WM9081_VMID_RAMP | 0x6;
- snd_soc_write(codec, WM9081_VMID_CONTROL, reg);
+ snd_soc_update_bits(codec, WM9081_VMID_CONTROL,
+ WM9081_VMID_RAMP |
+ WM9081_VMID_SEL_MASK,
+ WM9081_VMID_RAMP | 0x6);
mdelay(100);
/* Normal bias enable & soft start off */
- reg &= ~WM9081_VMID_RAMP;
- snd_soc_write(codec, WM9081_VMID_CONTROL, reg);
+ snd_soc_update_bits(codec, WM9081_VMID_CONTROL,
+ WM9081_VMID_RAMP, 0);
/* Standard bias source */
- reg = snd_soc_read(codec, WM9081_BIAS_CONTROL_1);
- reg &= ~WM9081_BIAS_SRC;
- snd_soc_write(codec, WM9081_BIAS_CONTROL_1, reg);
+ snd_soc_update_bits(codec, WM9081_BIAS_CONTROL_1,
+ WM9081_BIAS_SRC, 0);
}
/* VMID 2*240k */
- reg = snd_soc_read(codec, WM9081_VMID_CONTROL);
- reg &= ~WM9081_VMID_SEL_MASK;
- reg |= 0x04;
- snd_soc_write(codec, WM9081_VMID_CONTROL, reg);
+ snd_soc_update_bits(codec, WM9081_VMID_CONTROL,
+ WM9081_VMID_SEL_MASK, 0x04);
/* Standby bias current on */
- reg = snd_soc_read(codec, WM9081_BIAS_CONTROL_1);
- reg |= WM9081_STBY_BIAS_ENA;
- snd_soc_write(codec, WM9081_BIAS_CONTROL_1, reg);
+ snd_soc_update_bits(codec, WM9081_BIAS_CONTROL_1,
+ WM9081_STBY_BIAS_ENA,
+ WM9081_STBY_BIAS_ENA);
break;
case SND_SOC_BIAS_OFF:
/* Startup bias source and disable bias */
- reg = snd_soc_read(codec, WM9081_BIAS_CONTROL_1);
- reg |= WM9081_BIAS_SRC;
- reg &= ~WM9081_BIAS_ENA;
- snd_soc_write(codec, WM9081_BIAS_CONTROL_1, reg);
+ snd_soc_update_bits(codec, WM9081_BIAS_CONTROL_1,
+ WM9081_BIAS_SRC | WM9081_BIAS_ENA,
+ WM9081_BIAS_SRC);
/* Disable VMID with soft ramping */
- reg = snd_soc_read(codec, WM9081_VMID_CONTROL);
- reg &= ~WM9081_VMID_SEL_MASK;
- reg |= WM9081_VMID_RAMP;
- snd_soc_write(codec, WM9081_VMID_CONTROL, reg);
+ snd_soc_update_bits(codec, WM9081_VMID_CONTROL,
+ WM9081_VMID_RAMP | WM9081_VMID_SEL_MASK,
+ WM9081_VMID_RAMP);
/* Actively discharge LINEOUT */
- reg = snd_soc_read(codec, WM9081_ANTI_POP_CONTROL);
- reg |= WM9081_LINEOUT_DISCH;
- snd_soc_write(codec, WM9081_ANTI_POP_CONTROL, reg);
+ snd_soc_update_bits(codec, WM9081_ANTI_POP_CONTROL,
+ WM9081_LINEOUT_DISCH,
+ WM9081_LINEOUT_DISCH);
break;
}
@@ -1185,7 +1232,7 @@
(SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
-static struct snd_soc_dai_ops wm9081_dai_ops = {
+static const struct snd_soc_dai_ops wm9081_dai_ops = {
.hw_params = wm9081_hw_params,
.set_fmt = wm9081_set_dai_fmt,
.digital_mute = wm9081_digital_mute,
@@ -1213,25 +1260,14 @@
int ret;
u16 reg;
- ret = snd_soc_codec_set_cache_io(codec, 8, 16, wm9081->control_type);
+ codec->control_data = wm9081->regmap;
+
+ ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP);
if (ret != 0) {
dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
return ret;
}
- reg = snd_soc_read(codec, WM9081_SOFTWARE_RESET);
- if (reg != 0x9081) {
- dev_err(codec->dev, "Device is not a WM9081: ID=0x%x\n", reg);
- ret = -EINVAL;
- return ret;
- }
-
- ret = wm9081_reset(codec);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to issue reset\n");
- return ret;
- }
-
reg = 0;
if (wm9081->pdata.irq_high)
reg |= WM9081_IRQ_POL;
@@ -1243,11 +1279,10 @@
wm9081_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
/* Enable zero cross by default */
- reg = snd_soc_read(codec, WM9081_ANALOGUE_LINEOUT);
- snd_soc_write(codec, WM9081_ANALOGUE_LINEOUT, reg | WM9081_LINEOUTZC);
- reg = snd_soc_read(codec, WM9081_ANALOGUE_SPEAKER_PGA);
- snd_soc_write(codec, WM9081_ANALOGUE_SPEAKER_PGA,
- reg | WM9081_SPKPGAZC);
+ snd_soc_update_bits(codec, WM9081_ANALOGUE_LINEOUT,
+ WM9081_LINEOUTZC, WM9081_LINEOUTZC);
+ snd_soc_update_bits(codec, WM9081_ANALOGUE_SPEAKER_PGA,
+ WM9081_SPKPGAZC, WM9081_SPKPGAZC);
if (!wm9081->pdata.num_retune_configs) {
dev_dbg(codec->dev,
@@ -1266,7 +1301,7 @@
}
#ifdef CONFIG_PM
-static int wm9081_suspend(struct snd_soc_codec *codec, pm_message_t state)
+static int wm9081_suspend(struct snd_soc_codec *codec)
{
wm9081_set_bias_level(codec, SND_SOC_BIAS_OFF);
@@ -1275,15 +1310,9 @@
static int wm9081_resume(struct snd_soc_codec *codec)
{
- u16 *reg_cache = codec->reg_cache;
- int i;
+ struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec);
- for (i = 0; i < codec->driver->reg_cache_size; i++) {
- if (i == WM9081_SOFTWARE_RESET)
- continue;
-
- snd_soc_write(codec, i, reg_cache[i]);
- }
+ regcache_sync(wm9081->regmap);
wm9081_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
@@ -1303,11 +1332,6 @@
.set_sysclk = wm9081_set_sysclk,
.set_bias_level = wm9081_set_bias_level,
- .reg_cache_size = ARRAY_SIZE(wm9081_reg_defaults),
- .reg_word_size = sizeof(u16),
- .reg_cache_default = wm9081_reg_defaults,
- .volatile_register = wm9081_volatile_register,
-
.controls = wm9081_snd_controls,
.num_controls = ARRAY_SIZE(wm9081_snd_controls),
.dapm_widgets = wm9081_dapm_widgets,
@@ -1316,19 +1340,56 @@
.num_dapm_routes = ARRAY_SIZE(wm9081_audio_paths),
};
+static const struct regmap_config wm9081_regmap = {
+ .reg_bits = 8,
+ .val_bits = 16,
+
+ .max_register = WM9081_MAX_REGISTER,
+ .reg_defaults = wm9081_reg,
+ .num_reg_defaults = ARRAY_SIZE(wm9081_reg),
+ .volatile_reg = wm9081_volatile_register,
+ .readable_reg = wm9081_readable_register,
+ .cache_type = REGCACHE_RBTREE,
+};
+
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
static __devinit int wm9081_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
struct wm9081_priv *wm9081;
+ unsigned int reg;
int ret;
- wm9081 = kzalloc(sizeof(struct wm9081_priv), GFP_KERNEL);
+ wm9081 = devm_kzalloc(&i2c->dev, sizeof(struct wm9081_priv),
+ GFP_KERNEL);
if (wm9081 == NULL)
return -ENOMEM;
i2c_set_clientdata(i2c, wm9081);
- wm9081->control_type = SND_SOC_I2C;
+
+ wm9081->regmap = regmap_init_i2c(i2c, &wm9081_regmap);
+ if (IS_ERR(wm9081->regmap)) {
+ ret = PTR_ERR(wm9081->regmap);
+ dev_err(&i2c->dev, "regmap_init() failed: %d\n", ret);
+ goto err;
+ }
+
+ ret = regmap_read(wm9081->regmap, WM9081_SOFTWARE_RESET, ®);
+ if (ret != 0) {
+ dev_err(&i2c->dev, "Failed to read chip ID: %d\n", ret);
+ goto err_regmap;
+ }
+ if (reg != 0x9081) {
+ dev_err(&i2c->dev, "Device is not a WM9081: ID=0x%x\n", reg);
+ ret = -EINVAL;
+ goto err_regmap;
+ }
+
+ ret = wm9081_reset(wm9081->regmap);
+ if (ret < 0) {
+ dev_err(&i2c->dev, "Failed to issue reset\n");
+ goto err_regmap;
+ }
if (dev_get_platdata(&i2c->dev))
memcpy(&wm9081->pdata, dev_get_platdata(&i2c->dev),
@@ -1337,14 +1398,23 @@
ret = snd_soc_register_codec(&i2c->dev,
&soc_codec_dev_wm9081, &wm9081_dai, 1);
if (ret < 0)
- kfree(wm9081);
+ goto err_regmap;
+
+ return 0;
+
+err_regmap:
+ regmap_exit(wm9081->regmap);
+err:
+
return ret;
}
static __devexit int wm9081_i2c_remove(struct i2c_client *client)
{
+ struct wm9081_priv *wm9081 = i2c_get_clientdata(client);
+
snd_soc_unregister_codec(&client->dev);
- kfree(i2c_get_clientdata(client));
+ regmap_exit(wm9081->regmap);
return 0;
}
diff --git a/sound/soc/codecs/wm9090.c b/sound/soc/codecs/wm9090.c
index f94c060..41ebe0dc 100644
--- a/sound/soc/codecs/wm9090.c
+++ b/sound/soc/codecs/wm9090.c
@@ -513,18 +513,7 @@
case SND_SOC_BIAS_STANDBY:
if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
/* Restore the register cache */
- for (i = 1; i < codec->driver->reg_cache_size; i++) {
- if (reg_cache[i] == wm9090_reg_defaults[i])
- continue;
- if (wm9090_volatile(codec, i))
- continue;
-
- ret = snd_soc_write(codec, i, reg_cache[i]);
- if (ret != 0)
- dev_warn(codec->dev,
- "Failed to restore register %d: %d\n",
- i, ret);
- }
+ snd_soc_cache_sync(codec);
}
/* We keep VMID off during standby since the combination of
@@ -604,7 +593,7 @@
}
#ifdef CONFIG_PM
-static int wm9090_suspend(struct snd_soc_codec *codec, pm_message_t state)
+static int wm9090_suspend(struct snd_soc_codec *codec)
{
wm9090_set_bias_level(codec, SND_SOC_BIAS_OFF);
@@ -647,7 +636,7 @@
struct wm9090_priv *wm9090;
int ret;
- wm9090 = kzalloc(sizeof(*wm9090), GFP_KERNEL);
+ wm9090 = devm_kzalloc(&i2c->dev, sizeof(*wm9090), GFP_KERNEL);
if (wm9090 == NULL) {
dev_err(&i2c->dev, "Can not allocate memory\n");
return -ENOMEM;
@@ -661,8 +650,6 @@
ret = snd_soc_register_codec(&i2c->dev,
&soc_codec_dev_wm9090, NULL, 0);
- if (ret < 0)
- kfree(wm9090);
return ret;
}
@@ -671,7 +658,6 @@
struct wm9090_priv *wm9090 = i2c_get_clientdata(i2c);
snd_soc_unregister_codec(&i2c->dev);
- kfree(wm9090);
return 0;
}
@@ -685,7 +671,7 @@
static struct i2c_driver wm9090_i2c_driver = {
.driver = {
- .name = "wm9090-codec",
+ .name = "wm9090",
.owner = THIS_MODULE,
},
.probe = wm9090_i2c_probe,
diff --git a/sound/soc/codecs/wm9705.c b/sound/soc/codecs/wm9705.c
index 646b58d..40c92ea 100644
--- a/sound/soc/codecs/wm9705.c
+++ b/sound/soc/codecs/wm9705.c
@@ -258,7 +258,7 @@
SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \
SNDRV_PCM_RATE_48000)
-static struct snd_soc_dai_ops wm9705_dai_ops = {
+static const struct snd_soc_dai_ops wm9705_dai_ops = {
.prepare = ac97_prepare,
};
@@ -306,7 +306,7 @@
}
#ifdef CONFIG_PM
-static int wm9705_soc_suspend(struct snd_soc_codec *codec, pm_message_t msg)
+static int wm9705_soc_suspend(struct snd_soc_codec *codec)
{
soc_ac97_ops.write(codec->ac97, AC97_POWERDOWN, 0xffff);
@@ -406,17 +406,7 @@
.remove = __devexit_p(wm9705_remove),
};
-static int __init wm9705_init(void)
-{
- return platform_driver_register(&wm9705_codec_driver);
-}
-module_init(wm9705_init);
-
-static void __exit wm9705_exit(void)
-{
- platform_driver_unregister(&wm9705_codec_driver);
-}
-module_exit(wm9705_exit);
+module_platform_driver(wm9705_codec_driver);
MODULE_DESCRIPTION("ASoC WM9705 driver");
MODULE_AUTHOR("Ian Molton");
diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c
index 90117f8..b7b31f8 100644
--- a/sound/soc/codecs/wm9712.c
+++ b/sound/soc/codecs/wm9712.c
@@ -505,11 +505,11 @@
SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_44100 |\
SNDRV_PCM_RATE_48000)
-static struct snd_soc_dai_ops wm9712_dai_ops_hifi = {
+static const struct snd_soc_dai_ops wm9712_dai_ops_hifi = {
.prepare = ac97_prepare,
};
-static struct snd_soc_dai_ops wm9712_dai_ops_aux = {
+static const struct snd_soc_dai_ops wm9712_dai_ops_aux = {
.prepare = ac97_aux_prepare,
};
@@ -583,8 +583,7 @@
return -EIO;
}
-static int wm9712_soc_suspend(struct snd_soc_codec *codec,
- pm_message_t state)
+static int wm9712_soc_suspend(struct snd_soc_codec *codec)
{
wm9712_set_bias_level(codec, SND_SOC_BIAS_OFF);
return 0;
@@ -694,17 +693,7 @@
.remove = __devexit_p(wm9712_remove),
};
-static int __init wm9712_init(void)
-{
- return platform_driver_register(&wm9712_codec_driver);
-}
-module_init(wm9712_init);
-
-static void __exit wm9712_exit(void)
-{
- platform_driver_unregister(&wm9712_codec_driver);
-}
-module_exit(wm9712_exit);
+module_platform_driver(wm9712_codec_driver);
MODULE_DESCRIPTION("ASoC WM9711/WM9712 driver");
MODULE_AUTHOR("Liam Girdwood");
diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c
index 7167cb6..2b8479b 100644
--- a/sound/soc/codecs/wm9713.c
+++ b/sound/soc/codecs/wm9713.c
@@ -1026,19 +1026,19 @@
(SNDRV_PCM_FORMAT_S16_LE | SNDRV_PCM_FORMAT_S20_3LE | \
SNDRV_PCM_FORMAT_S24_LE)
-static struct snd_soc_dai_ops wm9713_dai_ops_hifi = {
+static const struct snd_soc_dai_ops wm9713_dai_ops_hifi = {
.prepare = ac97_hifi_prepare,
.set_clkdiv = wm9713_set_dai_clkdiv,
.set_pll = wm9713_set_dai_pll,
};
-static struct snd_soc_dai_ops wm9713_dai_ops_aux = {
+static const struct snd_soc_dai_ops wm9713_dai_ops_aux = {
.prepare = ac97_aux_prepare,
.set_clkdiv = wm9713_set_dai_clkdiv,
.set_pll = wm9713_set_dai_pll,
};
-static struct snd_soc_dai_ops wm9713_dai_ops_voice = {
+static const struct snd_soc_dai_ops wm9713_dai_ops_voice = {
.hw_params = wm9713_pcm_hw_params,
.set_clkdiv = wm9713_set_dai_clkdiv,
.set_pll = wm9713_set_dai_pll,
@@ -1140,8 +1140,7 @@
return 0;
}
-static int wm9713_soc_suspend(struct snd_soc_codec *codec,
- pm_message_t state)
+static int wm9713_soc_suspend(struct snd_soc_codec *codec)
{
u16 reg;
@@ -1277,17 +1276,7 @@
.remove = __devexit_p(wm9713_remove),
};
-static int __init wm9713_init(void)
-{
- return platform_driver_register(&wm9713_codec_driver);
-}
-module_init(wm9713_init);
-
-static void __exit wm9713_exit(void)
-{
- platform_driver_unregister(&wm9713_codec_driver);
-}
-module_exit(wm9713_exit);
+module_platform_driver(wm9713_codec_driver);
MODULE_DESCRIPTION("ASoC WM9713/WM9714 driver");
MODULE_AUTHOR("Liam Girdwood");
diff --git a/sound/soc/codecs/wm_hubs.c b/sound/soc/codecs/wm_hubs.c
index 48e61e9..2a61094 100644
--- a/sound/soc/codecs/wm_hubs.c
+++ b/sound/soc/codecs/wm_hubs.c
@@ -17,7 +17,6 @@
#include <linux/delay.h>
#include <linux/pm.h>
#include <linux/i2c.h>
-#include <linux/platform_device.h>
#include <linux/mfd/wm8994/registers.h>
#include <sound/core.h>
#include <sound/pcm.h>
@@ -611,8 +610,8 @@
SND_SOC_DAPM_INPUT("IN2RN"),
SND_SOC_DAPM_INPUT("IN2RP:VXRP"),
-SND_SOC_DAPM_MICBIAS("MICBIAS2", WM8993_POWER_MANAGEMENT_1, 5, 0),
-SND_SOC_DAPM_MICBIAS("MICBIAS1", WM8993_POWER_MANAGEMENT_1, 4, 0),
+SND_SOC_DAPM_SUPPLY("MICBIAS2", WM8993_POWER_MANAGEMENT_1, 5, 0, NULL, 0),
+SND_SOC_DAPM_SUPPLY("MICBIAS1", WM8993_POWER_MANAGEMENT_1, 4, 0, NULL, 0),
SND_SOC_DAPM_MIXER("IN1L PGA", WM8993_POWER_MANAGEMENT_2, 6, 0,
in1l_pga, ARRAY_SIZE(in1l_pga)),
@@ -654,6 +653,7 @@
SND_SOC_DAPM_MIXER("SPKR Boost", SND_SOC_NOPM, 0, 0,
right_speaker_boost, ARRAY_SIZE(right_speaker_boost)),
+SND_SOC_DAPM_SUPPLY("TSHUT", WM8993_POWER_MANAGEMENT_2, 14, 0, NULL, 0),
SND_SOC_DAPM_PGA("SPKL Driver", WM8993_POWER_MANAGEMENT_1, 12, 0,
NULL, 0),
SND_SOC_DAPM_PGA("SPKR Driver", WM8993_POWER_MANAGEMENT_1, 13, 0,
@@ -789,10 +789,12 @@
{ "SPKL Driver", NULL, "VMID" },
{ "SPKL Driver", NULL, "SPKL Boost" },
{ "SPKL Driver", NULL, "CLK_SYS" },
+ { "SPKL Driver", NULL, "TSHUT" },
{ "SPKR Driver", NULL, "VMID" },
{ "SPKR Driver", NULL, "SPKR Boost" },
{ "SPKR Driver", NULL, "CLK_SYS" },
+ { "SPKR Driver", NULL, "TSHUT" },
{ "SPKOUTLP", NULL, "SPKL Driver" },
{ "SPKOUTLN", NULL, "SPKL Driver" },
diff --git a/sound/soc/davinci/davinci-evm.c b/sound/soc/davinci/davinci-evm.c
index f78c3f0..10a2d8c 100644
--- a/sound/soc/davinci/davinci-evm.c
+++ b/sound/soc/davinci/davinci-evm.c
@@ -242,6 +242,7 @@
/* davinci dm6446 evm audio machine driver */
static struct snd_soc_card dm6446_snd_soc_card_evm = {
.name = "DaVinci DM6446 EVM",
+ .owner = THIS_MODULE,
.dai_link = &dm6446_evm_dai,
.num_links = 1,
};
@@ -249,6 +250,7 @@
/* davinci dm355 evm audio machine driver */
static struct snd_soc_card dm355_snd_soc_card_evm = {
.name = "DaVinci DM355 EVM",
+ .owner = THIS_MODULE,
.dai_link = &dm355_evm_dai,
.num_links = 1,
};
@@ -256,6 +258,7 @@
/* davinci dm365 evm audio machine driver */
static struct snd_soc_card dm365_snd_soc_card_evm = {
.name = "DaVinci DM365 EVM",
+ .owner = THIS_MODULE,
.dai_link = &dm365_evm_dai,
.num_links = 1,
};
@@ -263,18 +266,21 @@
/* davinci dm6467 evm audio machine driver */
static struct snd_soc_card dm6467_snd_soc_card_evm = {
.name = "DaVinci DM6467 EVM",
+ .owner = THIS_MODULE,
.dai_link = dm6467_evm_dai,
.num_links = ARRAY_SIZE(dm6467_evm_dai),
};
static struct snd_soc_card da830_snd_soc_card = {
.name = "DA830/OMAP-L137 EVM",
+ .owner = THIS_MODULE,
.dai_link = &da830_evm_dai,
.num_links = 1,
};
static struct snd_soc_card da850_snd_soc_card = {
.name = "DA850/OMAP-L138 EVM",
+ .owner = THIS_MODULE,
.dai_link = &da850_evm_dai,
.num_links = 1,
};
diff --git a/sound/soc/davinci/davinci-i2s.c b/sound/soc/davinci/davinci-i2s.c
index 300e121..0a74b95 100644
--- a/sound/soc/davinci/davinci-i2s.c
+++ b/sound/soc/davinci/davinci-i2s.c
@@ -620,7 +620,7 @@
#define DAVINCI_I2S_RATES SNDRV_PCM_RATE_8000_96000
-static struct snd_soc_dai_ops davinci_i2s_dai_ops = {
+static const struct snd_soc_dai_ops davinci_i2s_dai_ops = {
.startup = davinci_i2s_startup,
.shutdown = davinci_i2s_shutdown,
.prepare = davinci_i2s_prepare,
@@ -661,18 +661,18 @@
return -ENODEV;
}
- ioarea = request_mem_region(mem->start, resource_size(mem),
- pdev->name);
+ ioarea = devm_request_mem_region(&pdev->dev, mem->start,
+ resource_size(mem),
+ pdev->name);
if (!ioarea) {
dev_err(&pdev->dev, "McBSP region already claimed\n");
return -EBUSY;
}
- dev = kzalloc(sizeof(struct davinci_mcbsp_dev), GFP_KERNEL);
- if (!dev) {
- ret = -ENOMEM;
- goto err_release_region;
- }
+ dev = devm_kzalloc(&pdev->dev, sizeof(struct davinci_mcbsp_dev),
+ GFP_KERNEL);
+ if (!dev)
+ return -ENOMEM;
if (pdata) {
dev->enable_channel_combine = pdata->enable_channel_combine;
dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK].sram_size =
@@ -691,13 +691,11 @@
dev->dma_params[SNDRV_PCM_STREAM_CAPTURE].ram_chan_q = ram_chan_q;
dev->clk = clk_get(&pdev->dev, NULL);
- if (IS_ERR(dev->clk)) {
- ret = -ENODEV;
- goto err_free_mem;
- }
+ if (IS_ERR(dev->clk))
+ return -ENODEV;
clk_enable(dev->clk);
- dev->base = ioremap(mem->start, resource_size(mem));
+ dev->base = devm_ioremap(&pdev->dev, mem->start, resource_size(mem));
if (!dev->base) {
dev_err(&pdev->dev, "ioremap failed\n");
ret = -ENOMEM;
@@ -715,7 +713,7 @@
if (!res) {
dev_err(&pdev->dev, "no DMA resource\n");
ret = -ENXIO;
- goto err_iounmap;
+ goto err_release_clk;
}
dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK].channel = res->start;
@@ -723,7 +721,7 @@
if (!res) {
dev_err(&pdev->dev, "no DMA resource\n");
ret = -ENXIO;
- goto err_iounmap;
+ goto err_release_clk;
}
dev->dma_params[SNDRV_PCM_STREAM_CAPTURE].channel = res->start;
dev->dev = &pdev->dev;
@@ -732,35 +730,24 @@
ret = snd_soc_register_dai(&pdev->dev, &davinci_i2s_dai);
if (ret != 0)
- goto err_iounmap;
+ goto err_release_clk;
return 0;
-err_iounmap:
- iounmap(dev->base);
err_release_clk:
clk_disable(dev->clk);
clk_put(dev->clk);
-err_free_mem:
- kfree(dev);
-err_release_region:
- release_mem_region(mem->start, resource_size(mem));
-
return ret;
}
static int davinci_i2s_remove(struct platform_device *pdev)
{
struct davinci_mcbsp_dev *dev = dev_get_drvdata(&pdev->dev);
- struct resource *mem;
snd_soc_unregister_dai(&pdev->dev);
clk_disable(dev->clk);
clk_put(dev->clk);
dev->clk = NULL;
- kfree(dev);
- mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- release_mem_region(mem->start, resource_size(mem));
return 0;
}
@@ -774,17 +761,7 @@
},
};
-static int __init davinci_i2s_init(void)
-{
- return platform_driver_register(&davinci_mcbsp_driver);
-}
-module_init(davinci_i2s_init);
-
-static void __exit davinci_i2s_exit(void)
-{
- platform_driver_unregister(&davinci_mcbsp_driver);
-}
-module_exit(davinci_i2s_exit);
+module_platform_driver(davinci_mcbsp_driver);
MODULE_AUTHOR("Vladimir Barinov");
MODULE_DESCRIPTION("TI DAVINCI I2S (McBSP) SoC Interface");
diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c
index 7173df25..95441bf 100644
--- a/sound/soc/davinci/davinci-mcasp.c
+++ b/sound/soc/davinci/davinci-mcasp.c
@@ -813,7 +813,7 @@
return 0;
}
-static struct snd_soc_dai_ops davinci_mcasp_dai_ops = {
+static const struct snd_soc_dai_ops davinci_mcasp_dai_ops = {
.startup = davinci_mcasp_startup,
.trigger = davinci_mcasp_trigger,
.hw_params = davinci_mcasp_hw_params,
@@ -865,38 +865,35 @@
struct resource *mem, *ioarea, *res;
struct snd_platform_data *pdata;
struct davinci_audio_dev *dev;
- int ret = 0;
+ int ret;
- dev = kzalloc(sizeof(struct davinci_audio_dev), GFP_KERNEL);
+ dev = devm_kzalloc(&pdev->dev, sizeof(struct davinci_audio_dev),
+ GFP_KERNEL);
if (!dev)
return -ENOMEM;
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!mem) {
dev_err(&pdev->dev, "no mem resource?\n");
- ret = -ENODEV;
- goto err_release_data;
+ return -ENODEV;
}
- ioarea = request_mem_region(mem->start,
+ ioarea = devm_request_mem_region(&pdev->dev, mem->start,
resource_size(mem), pdev->name);
if (!ioarea) {
dev_err(&pdev->dev, "Audio region already claimed\n");
- ret = -EBUSY;
- goto err_release_data;
+ return -EBUSY;
}
pdata = pdev->dev.platform_data;
dev->clk = clk_get(&pdev->dev, NULL);
- if (IS_ERR(dev->clk)) {
- ret = -ENODEV;
- goto err_release_region;
- }
+ if (IS_ERR(dev->clk))
+ return -ENODEV;
clk_enable(dev->clk);
dev->clk_active = 1;
- dev->base = ioremap(mem->start, resource_size(mem));
+ dev->base = devm_ioremap(&pdev->dev, mem->start, resource_size(mem));
if (!dev->base) {
dev_err(&pdev->dev, "ioremap failed\n");
ret = -ENOMEM;
@@ -924,7 +921,7 @@
if (!res) {
dev_err(&pdev->dev, "no DMA resource\n");
ret = -ENODEV;
- goto err_iounmap;
+ goto err_release_clk;
}
dma_data->channel = res->start;
@@ -940,7 +937,7 @@
if (!res) {
dev_err(&pdev->dev, "no DMA resource\n");
ret = -ENODEV;
- goto err_iounmap;
+ goto err_release_clk;
}
dma_data->channel = res->start;
@@ -948,37 +945,24 @@
ret = snd_soc_register_dai(&pdev->dev, &davinci_mcasp_dai[pdata->op_mode]);
if (ret != 0)
- goto err_iounmap;
+ goto err_release_clk;
return 0;
-err_iounmap:
- iounmap(dev->base);
err_release_clk:
clk_disable(dev->clk);
clk_put(dev->clk);
-err_release_region:
- release_mem_region(mem->start, resource_size(mem));
-err_release_data:
- kfree(dev);
-
return ret;
}
static int davinci_mcasp_remove(struct platform_device *pdev)
{
struct davinci_audio_dev *dev = dev_get_drvdata(&pdev->dev);
- struct resource *mem;
snd_soc_unregister_dai(&pdev->dev);
clk_disable(dev->clk);
clk_put(dev->clk);
dev->clk = NULL;
- mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- release_mem_region(mem->start, resource_size(mem));
-
- kfree(dev);
-
return 0;
}
@@ -991,17 +975,7 @@
},
};
-static int __init davinci_mcasp_init(void)
-{
- return platform_driver_register(&davinci_mcasp_driver);
-}
-module_init(davinci_mcasp_init);
-
-static void __exit davinci_mcasp_exit(void)
-{
- platform_driver_unregister(&davinci_mcasp_driver);
-}
-module_exit(davinci_mcasp_exit);
+module_platform_driver(davinci_mcasp_driver);
MODULE_AUTHOR("Steve Chen");
MODULE_DESCRIPTION("TI DAVINCI McASP SoC Interface");
diff --git a/sound/soc/davinci/davinci-pcm.c b/sound/soc/davinci/davinci-pcm.c
index d5fe08c..b26401f 100644
--- a/sound/soc/davinci/davinci-pcm.c
+++ b/sound/soc/davinci/davinci-pcm.c
@@ -831,7 +831,6 @@
static int davinci_pcm_new(struct snd_soc_pcm_runtime *rtd)
{
struct snd_card *card = rtd->card->snd_card;
- struct snd_soc_dai *dai = rtd->cpu_dai;
struct snd_pcm *pcm = rtd->pcm;
int ret;
@@ -840,7 +839,7 @@
if (!card->dev->coherent_dma_mask)
card->dev->coherent_dma_mask = 0xffffffff;
- if (dai->driver->playback.channels_min) {
+ if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
ret = davinci_pcm_preallocate_dma_buffer(pcm,
SNDRV_PCM_STREAM_PLAYBACK,
pcm_hardware_playback.buffer_bytes_max);
@@ -848,7 +847,7 @@
return ret;
}
- if (dai->driver->capture.channels_min) {
+ if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
ret = davinci_pcm_preallocate_dma_buffer(pcm,
SNDRV_PCM_STREAM_CAPTURE,
pcm_hardware_capture.buffer_bytes_max);
@@ -886,17 +885,7 @@
.remove = __devexit_p(davinci_soc_platform_remove),
};
-static int __init snd_davinci_pcm_init(void)
-{
- return platform_driver_register(&davinci_pcm_driver);
-}
-module_init(snd_davinci_pcm_init);
-
-static void __exit snd_davinci_pcm_exit(void)
-{
- platform_driver_unregister(&davinci_pcm_driver);
-}
-module_exit(snd_davinci_pcm_exit);
+module_platform_driver(davinci_pcm_driver);
MODULE_AUTHOR("Vladimir Barinov");
MODULE_DESCRIPTION("TI DAVINCI PCM DMA module");
diff --git a/sound/soc/davinci/davinci-sffsdr.c b/sound/soc/davinci/davinci-sffsdr.c
index 0fe558c..f71175b 100644
--- a/sound/soc/davinci/davinci-sffsdr.c
+++ b/sound/soc/davinci/davinci-sffsdr.c
@@ -93,6 +93,7 @@
/* davinci-sffsdr audio machine driver */
static struct snd_soc_card snd_soc_sffsdr = {
.name = "DaVinci SFFSDR",
+ .owner = THIS_MODULE,
.dai_link = &sffsdr_dai,
.num_links = 1,
};
diff --git a/sound/soc/davinci/davinci-vcif.c b/sound/soc/davinci/davinci-vcif.c
index 1f11525..da030ff 100644
--- a/sound/soc/davinci/davinci-vcif.c
+++ b/sound/soc/davinci/davinci-vcif.c
@@ -183,7 +183,7 @@
#define DAVINCI_VCIF_RATES SNDRV_PCM_RATE_8000_48000
-static struct snd_soc_dai_ops davinci_vcif_dai_ops = {
+static const struct snd_soc_dai_ops davinci_vcif_dai_ops = {
.startup = davinci_vcif_startup,
.trigger = davinci_vcif_trigger,
.hw_params = davinci_vcif_hw_params,
@@ -210,7 +210,9 @@
struct davinci_vcif_dev *davinci_vcif_dev;
int ret;
- davinci_vcif_dev = kzalloc(sizeof(struct davinci_vcif_dev), GFP_KERNEL);
+ davinci_vcif_dev = devm_kzalloc(&pdev->dev,
+ sizeof(struct davinci_vcif_dev),
+ GFP_KERNEL);
if (!davinci_vcif_dev) {
dev_dbg(&pdev->dev,
"could not allocate memory for private data\n");
@@ -235,23 +237,15 @@
ret = snd_soc_register_dai(&pdev->dev, &davinci_vcif_dai);
if (ret != 0) {
dev_err(&pdev->dev, "could not register dai\n");
- goto fail;
+ return ret;
}
return 0;
-
-fail:
- kfree(davinci_vcif_dev);
-
- return ret;
}
static int davinci_vcif_remove(struct platform_device *pdev)
{
- struct davinci_vcif_dev *davinci_vcif_dev = dev_get_drvdata(&pdev->dev);
-
snd_soc_unregister_dai(&pdev->dev);
- kfree(davinci_vcif_dev);
return 0;
}
@@ -265,17 +259,7 @@
},
};
-static int __init davinci_vcif_init(void)
-{
- return platform_driver_probe(&davinci_vcif_driver, davinci_vcif_probe);
-}
-module_init(davinci_vcif_init);
-
-static void __exit davinci_vcif_exit(void)
-{
- platform_driver_unregister(&davinci_vcif_driver);
-}
-module_exit(davinci_vcif_exit);
+module_platform_driver(davinci_vcif_driver);
MODULE_AUTHOR("Miguel Aguilar");
MODULE_DESCRIPTION("Texas Instruments DaVinci ASoC Voice Codec Interface");
diff --git a/sound/soc/ep93xx/edb93xx.c b/sound/soc/ep93xx/edb93xx.c
index 51930b6..bae5cbb 100644
--- a/sound/soc/ep93xx/edb93xx.c
+++ b/sound/soc/ep93xx/edb93xx.c
@@ -48,18 +48,6 @@
else
mclk_rate = rate * 64 * 2;
- err = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
- SND_SOC_DAIFMT_NB_IF |
- SND_SOC_DAIFMT_CBS_CFS);
- if (err)
- return err;
-
- err = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
- SND_SOC_DAIFMT_NB_IF |
- SND_SOC_DAIFMT_CBS_CFS);
- if (err)
- return err;
-
err = snd_soc_dai_set_sysclk(codec_dai, 0, mclk_rate,
SND_SOC_CLOCK_IN);
if (err)
@@ -80,11 +68,14 @@
.cpu_dai_name = "ep93xx-i2s",
.codec_name = "spi0.0",
.codec_dai_name = "cs4271-hifi",
+ .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_IF |
+ SND_SOC_DAIFMT_CBS_CFS,
.ops = &edb93xx_ops,
};
static struct snd_soc_card snd_soc_edb93xx = {
.name = "EDB93XX",
+ .owner = THIS_MODULE,
.dai_link = &edb93xx_dai,
.num_links = 1,
};
@@ -131,17 +122,7 @@
.remove = __devexit_p(edb93xx_remove),
};
-static int __init edb93xx_init(void)
-{
- return platform_driver_register(&edb93xx_driver);
-}
-module_init(edb93xx_init);
-
-static void __exit edb93xx_exit(void)
-{
- platform_driver_unregister(&edb93xx_driver);
-}
-module_exit(edb93xx_exit);
+module_platform_driver(edb93xx_driver);
MODULE_AUTHOR("Alexander Sverdlin <subaparts@yandex.ru>");
MODULE_DESCRIPTION("ALSA SoC EDB93xx");
diff --git a/sound/soc/ep93xx/ep93xx-ac97.c b/sound/soc/ep93xx/ep93xx-ac97.c
index 3cd6158..0678637 100644
--- a/sound/soc/ep93xx/ep93xx-ac97.c
+++ b/sound/soc/ep93xx/ep93xx-ac97.c
@@ -330,7 +330,7 @@
return 0;
}
-static struct snd_soc_dai_ops ep93xx_ac97_dai_ops = {
+static const struct snd_soc_dai_ops ep93xx_ac97_dai_ops = {
.startup = ep93xx_ac97_startup,
.trigger = ep93xx_ac97_trigger,
};
@@ -449,17 +449,7 @@
},
};
-static int __init ep93xx_ac97_init(void)
-{
- return platform_driver_register(&ep93xx_ac97_driver);
-}
-module_init(ep93xx_ac97_init);
-
-static void __exit ep93xx_ac97_exit(void)
-{
- platform_driver_unregister(&ep93xx_ac97_driver);
-}
-module_exit(ep93xx_ac97_exit);
+module_platform_driver(ep93xx_ac97_driver);
MODULE_DESCRIPTION("EP93xx AC97 ASoC Driver");
MODULE_AUTHOR("Mika Westerberg <mika.westerberg@iki.fi>");
diff --git a/sound/soc/ep93xx/ep93xx-i2s.c b/sound/soc/ep93xx/ep93xx-i2s.c
index 099614e..f7a6234 100644
--- a/sound/soc/ep93xx/ep93xx-i2s.c
+++ b/sound/soc/ep93xx/ep93xx-i2s.c
@@ -338,7 +338,7 @@
#define ep93xx_i2s_resume NULL
#endif
-static struct snd_soc_dai_ops ep93xx_i2s_dai_ops = {
+static const struct snd_soc_dai_ops ep93xx_i2s_dai_ops = {
.startup = ep93xx_i2s_startup,
.shutdown = ep93xx_i2s_shutdown,
.hw_params = ep93xx_i2s_hw_params,
@@ -464,18 +464,7 @@
},
};
-static int __init ep93xx_i2s_init(void)
-{
- return platform_driver_register(&ep93xx_i2s_driver);
-}
-
-static void __exit ep93xx_i2s_exit(void)
-{
- platform_driver_unregister(&ep93xx_i2s_driver);
-}
-
-module_init(ep93xx_i2s_init);
-module_exit(ep93xx_i2s_exit);
+module_platform_driver(ep93xx_i2s_driver);
MODULE_ALIAS("platform:ep93xx-i2s");
MODULE_AUTHOR("Ryan Mallon");
diff --git a/sound/soc/ep93xx/ep93xx-pcm.c b/sound/soc/ep93xx/ep93xx-pcm.c
index d00230a..3fc9613 100644
--- a/sound/soc/ep93xx/ep93xx-pcm.c
+++ b/sound/soc/ep93xx/ep93xx-pcm.c
@@ -286,7 +286,6 @@
static int ep93xx_pcm_new(struct snd_soc_pcm_runtime *rtd)
{
struct snd_card *card = rtd->card->snd_card;
- struct snd_soc_dai *dai = rtd->cpu_dai;
struct snd_pcm *pcm = rtd->pcm;
int ret = 0;
@@ -295,14 +294,14 @@
if (!card->dev->coherent_dma_mask)
card->dev->coherent_dma_mask = 0xffffffff;
- if (dai->driver->playback.channels_min) {
+ if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
ret = ep93xx_pcm_preallocate_dma_buffer(pcm,
SNDRV_PCM_STREAM_PLAYBACK);
if (ret)
return ret;
}
- if (dai->driver->capture.channels_min) {
+ if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
ret = ep93xx_pcm_preallocate_dma_buffer(pcm,
SNDRV_PCM_STREAM_CAPTURE);
if (ret)
@@ -339,18 +338,7 @@
.remove = __devexit_p(ep93xx_soc_platform_remove),
};
-static int __init ep93xx_soc_platform_init(void)
-{
- return platform_driver_register(&ep93xx_pcm_driver);
-}
-
-static void __exit ep93xx_soc_platform_exit(void)
-{
- platform_driver_unregister(&ep93xx_pcm_driver);
-}
-
-module_init(ep93xx_soc_platform_init);
-module_exit(ep93xx_soc_platform_exit);
+module_platform_driver(ep93xx_pcm_driver);
MODULE_AUTHOR("Ryan Mallon");
MODULE_DESCRIPTION("EP93xx ALSA PCM interface");
diff --git a/sound/soc/ep93xx/simone.c b/sound/soc/ep93xx/simone.c
index 968cb31..dd99709 100644
--- a/sound/soc/ep93xx/simone.c
+++ b/sound/soc/ep93xx/simone.c
@@ -34,6 +34,7 @@
static struct snd_soc_card snd_soc_simone = {
.name = "Sim.One",
+ .owner = THIS_MODULE,
.dai_link = &simone_dai,
.num_links = 1,
};
@@ -81,17 +82,7 @@
.remove = __devexit_p(simone_remove),
};
-static int __init simone_init(void)
-{
- return platform_driver_register(&simone_driver);
-}
-module_init(simone_init);
-
-static void __exit simone_exit(void)
-{
- platform_driver_unregister(&simone_driver);
-}
-module_exit(simone_exit);
+module_platform_driver(simone_driver);
MODULE_DESCRIPTION("ALSA SoC Simplemachines Sim.One");
MODULE_AUTHOR("Mika Westerberg <mika.westerberg@iki.fi>");
diff --git a/sound/soc/ep93xx/snappercl15.c b/sound/soc/ep93xx/snappercl15.c
index 2cde433..ccae34a 100644
--- a/sound/soc/ep93xx/snappercl15.c
+++ b/sound/soc/ep93xx/snappercl15.c
@@ -33,16 +33,6 @@
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
int err;
- err = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
- SND_SOC_DAIFMT_NB_IF |
- SND_SOC_DAIFMT_CBS_CFS);
-
- err = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
- SND_SOC_DAIFMT_NB_IF |
- SND_SOC_DAIFMT_CBS_CFS);
- if (err)
- return err;
-
err = snd_soc_dai_set_sysclk(codec_dai, 0, CODEC_CLOCK,
SND_SOC_CLOCK_IN);
if (err)
@@ -96,11 +86,14 @@
.codec_name = "tlv320aic23-codec.0-001a",
.platform_name = "ep93xx-pcm-audio",
.init = snappercl15_tlv320aic23_init,
+ .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_IF |
+ SND_SOC_DAIFMT_CBS_CFS,
.ops = &snappercl15_ops,
};
static struct snd_soc_card snd_soc_snappercl15 = {
.name = "Snapper CL15",
+ .owner = THIS_MODULE,
.dai_link = &snappercl15_dai,
.num_links = 1,
};
@@ -147,18 +140,7 @@
.remove = __devexit_p(snappercl15_remove),
};
-static int __init snappercl15_init(void)
-{
- return platform_driver_register(&snappercl15_driver);
-}
-
-static void __exit snappercl15_exit(void)
-{
- platform_driver_unregister(&snappercl15_driver);
-}
-
-module_init(snappercl15_init);
-module_exit(snappercl15_exit);
+module_platform_driver(snappercl15_driver);
MODULE_AUTHOR("Ryan Mallon");
MODULE_DESCRIPTION("ALSA SoC Snapper CL15");
diff --git a/sound/soc/fsl/efika-audio-fabric.c b/sound/soc/fsl/efika-audio-fabric.c
index 108b5d8..b2acd329 100644
--- a/sound/soc/fsl/efika-audio-fabric.c
+++ b/sound/soc/fsl/efika-audio-fabric.c
@@ -31,8 +31,6 @@
#define DRV_NAME "efika-audio-fabric"
-static struct snd_soc_card card;
-
static struct snd_soc_dai_link efika_fabric_dai[] = {
{
.name = "AC97",
@@ -52,6 +50,13 @@
},
};
+static struct snd_soc_card card = {
+ .name = "Efika",
+ .owner = THIS_MODULE,
+ .dai_link = efika_fabric_dai,
+ .num_links = ARRAY_SIZE(efika_fabric_dai),
+};
+
static __init int efika_fabric_init(void)
{
struct platform_device *pdev;
@@ -60,11 +65,6 @@
if (!of_machine_is_compatible("bplan,efika"))
return -ENODEV;
- card.name = "Efika";
- card.dai_link = efika_fabric_dai;
- card.num_links = ARRAY_SIZE(efika_fabric_dai);
-
-
pdev = platform_device_alloc("soc-audio", 1);
if (!pdev) {
pr_err("efika_fabric_init: platform_device_alloc() failed\n");
diff --git a/sound/soc/fsl/fsl_dma.c b/sound/soc/fsl/fsl_dma.c
index ef15402..4f59bba 100644
--- a/sound/soc/fsl/fsl_dma.c
+++ b/sound/soc/fsl/fsl_dma.c
@@ -992,20 +992,7 @@
.remove = __devexit_p(fsl_soc_dma_remove),
};
-static int __init fsl_soc_dma_init(void)
-{
- pr_info("Freescale Elo DMA ASoC PCM Driver\n");
-
- return platform_driver_register(&fsl_soc_dma_driver);
-}
-
-static void __exit fsl_soc_dma_exit(void)
-{
- platform_driver_unregister(&fsl_soc_dma_driver);
-}
-
-module_init(fsl_soc_dma_init);
-module_exit(fsl_soc_dma_exit);
+module_platform_driver(fsl_soc_dma_driver);
MODULE_AUTHOR("Timur Tabi <timur@freescale.com>");
MODULE_DESCRIPTION("Freescale Elo DMA ASoC PCM Driver");
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index 83c4bd5..3e06696 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -514,7 +514,7 @@
}
}
-static struct snd_soc_dai_ops fsl_ssi_dai_ops = {
+static const struct snd_soc_dai_ops fsl_ssi_dai_ops = {
.startup = fsl_ssi_startup,
.hw_params = fsl_ssi_hw_params,
.shutdown = fsl_ssi_shutdown,
@@ -793,20 +793,7 @@
.remove = fsl_ssi_remove,
};
-static int __init fsl_ssi_init(void)
-{
- printk(KERN_INFO "Freescale Synchronous Serial Interface (SSI) ASoC Driver\n");
-
- return platform_driver_register(&fsl_ssi_driver);
-}
-
-static void __exit fsl_ssi_exit(void)
-{
- platform_driver_unregister(&fsl_ssi_driver);
-}
-
-module_init(fsl_ssi_init);
-module_exit(fsl_ssi_exit);
+module_platform_driver(fsl_ssi_driver);
MODULE_AUTHOR("Timur Tabi <timur@freescale.com>");
MODULE_DESCRIPTION("Freescale Synchronous Serial Interface (SSI) ASoC Driver");
diff --git a/sound/soc/fsl/mpc5200_dma.c b/sound/soc/fsl/mpc5200_dma.c
index 5c6c245..e7803d3 100644
--- a/sound/soc/fsl/mpc5200_dma.c
+++ b/sound/soc/fsl/mpc5200_dma.c
@@ -526,17 +526,7 @@
}
};
-static int __init mpc5200_hpcd_init(void)
-{
- return platform_driver_register(&mpc5200_hpcd_of_driver);
-}
-module_init(mpc5200_hpcd_init);
-
-static void __exit mpc5200_hpcd_exit(void)
-{
- platform_driver_unregister(&mpc5200_hpcd_of_driver);
-}
-module_exit(mpc5200_hpcd_exit);
+module_platform_driver(mpc5200_hpcd_of_driver);
MODULE_AUTHOR("Grant Likely <grant.likely@secretlab.ca>");
MODULE_DESCRIPTION("Freescale MPC5200 PSC in DMA mode ASoC Driver");
diff --git a/sound/soc/fsl/mpc5200_psc_ac97.c b/sound/soc/fsl/mpc5200_psc_ac97.c
index ad36b09..ffa00a2 100644
--- a/sound/soc/fsl/mpc5200_psc_ac97.c
+++ b/sound/soc/fsl/mpc5200_psc_ac97.c
@@ -226,12 +226,12 @@
/**
* psc_ac97_dai_template: template CPU Digital Audio Interface
*/
-static struct snd_soc_dai_ops psc_ac97_analog_ops = {
+static const struct snd_soc_dai_ops psc_ac97_analog_ops = {
.hw_params = psc_ac97_hw_analog_params,
.trigger = psc_ac97_trigger,
};
-static struct snd_soc_dai_ops psc_ac97_digital_ops = {
+static const struct snd_soc_dai_ops psc_ac97_digital_ops = {
.hw_params = psc_ac97_hw_digital_params,
};
@@ -325,21 +325,7 @@
},
};
-/* ---------------------------------------------------------------------
- * Module setup and teardown; simply register the of_platform driver
- * for the PSC in AC97 mode.
- */
-static int __init psc_ac97_init(void)
-{
- return platform_driver_register(&psc_ac97_driver);
-}
-module_init(psc_ac97_init);
-
-static void __exit psc_ac97_exit(void)
-{
- platform_driver_unregister(&psc_ac97_driver);
-}
-module_exit(psc_ac97_exit);
+module_platform_driver(psc_ac97_driver);
MODULE_AUTHOR("Jon Smirl <jonsmirl@gmail.com>");
MODULE_DESCRIPTION("mpc5200 AC97 module");
diff --git a/sound/soc/fsl/mpc5200_psc_i2s.c b/sound/soc/fsl/mpc5200_psc_i2s.c
index 87cf2a5..7b53032 100644
--- a/sound/soc/fsl/mpc5200_psc_i2s.c
+++ b/sound/soc/fsl/mpc5200_psc_i2s.c
@@ -123,7 +123,7 @@
/**
* psc_i2s_dai_template: template CPU Digital Audio Interface
*/
-static struct snd_soc_dai_ops psc_i2s_dai_ops = {
+static const struct snd_soc_dai_ops psc_i2s_dai_ops = {
.hw_params = psc_i2s_hw_params,
.set_sysclk = psc_i2s_set_sysclk,
.set_fmt = psc_i2s_set_fmt,
@@ -222,21 +222,7 @@
},
};
-/* ---------------------------------------------------------------------
- * Module setup and teardown; simply register the of_platform driver
- * for the PSC in I2S mode.
- */
-static int __init psc_i2s_init(void)
-{
- return platform_driver_register(&psc_i2s_driver);
-}
-module_init(psc_i2s_init);
-
-static void __exit psc_i2s_exit(void)
-{
- platform_driver_unregister(&psc_i2s_driver);
-}
-module_exit(psc_i2s_exit);
+module_platform_driver(psc_i2s_driver);
MODULE_AUTHOR("Grant Likely <grant.likely@secretlab.ca>");
MODULE_DESCRIPTION("Freescale MPC5200 PSC in I2S mode ASoC Driver");
diff --git a/sound/soc/fsl/mpc8610_hpcd.c b/sound/soc/fsl/mpc8610_hpcd.c
index ae49f1c..0ea4a5a 100644
--- a/sound/soc/fsl/mpc8610_hpcd.c
+++ b/sound/soc/fsl/mpc8610_hpcd.c
@@ -14,6 +14,7 @@
#include <linux/interrupt.h>
#include <linux/of_device.h>
#include <linux/slab.h>
+#include <linux/of_i2c.h>
#include <sound/soc.h>
#include <asm/fsl_guts.h>
@@ -249,8 +250,9 @@
static int codec_node_dev_name(struct device_node *np, char *buf, size_t len)
{
const u32 *iprop;
- int bus, addr;
+ int addr;
char temp[DAI_NAME_SIZE];
+ struct i2c_client *i2c;
of_modalias_node(np, temp, DAI_NAME_SIZE);
@@ -260,11 +262,12 @@
addr = be32_to_cpup(iprop);
- bus = get_parent_cell_index(np);
- if (bus < 0)
- return bus;
+ /* We need the adapter number */
+ i2c = of_find_i2c_device_by_node(np);
+ if (!i2c)
+ return -ENODEV;
- snprintf(buf, len, "%s-codec.%u-%04x", temp, bus, addr);
+ snprintf(buf, len, "%s-codec.%u-%04x", temp, i2c->adapter->nr, addr);
return 0;
}
diff --git a/sound/soc/fsl/p1022_ds.c b/sound/soc/fsl/p1022_ds.c
index 2c064a9..a5d4e80 100644
--- a/sound/soc/fsl/p1022_ds.c
+++ b/sound/soc/fsl/p1022_ds.c
@@ -14,6 +14,7 @@
#include <linux/interrupt.h>
#include <linux/of_device.h>
#include <linux/slab.h>
+#include <linux/of_i2c.h>
#include <sound/soc.h>
#include <asm/fsl_guts.h>
@@ -252,8 +253,9 @@
static int codec_node_dev_name(struct device_node *np, char *buf, size_t len)
{
const u32 *iprop;
- int bus, addr;
+ int addr;
char temp[DAI_NAME_SIZE];
+ struct i2c_client *i2c;
of_modalias_node(np, temp, DAI_NAME_SIZE);
@@ -263,11 +265,12 @@
addr = be32_to_cpup(iprop);
- bus = get_parent_cell_index(np);
- if (bus < 0)
- return bus;
+ /* We need the adapter number */
+ i2c = of_find_i2c_device_by_node(np);
+ if (!i2c)
+ return -ENODEV;
- snprintf(buf, len, "%s.%u-%04x", temp, bus, addr);
+ snprintf(buf, len, "%s.%u-%04x", temp, i2c->adapter->nr, addr);
return 0;
}
@@ -540,12 +543,6 @@
.probe = p1022_ds_probe,
.remove = __devexit_p(p1022_ds_remove),
.driver = {
- /* The name must match the 'model' property in the device tree,
- * in lowercase letters, but only the part after that last
- * comma. This is because some model properties have a "fsl,"
- * prefix.
- */
- .name = "snd-soc-p1022",
.owner = THIS_MODULE,
},
};
@@ -559,13 +556,39 @@
{
struct device_node *guts_np;
struct resource res;
+ const char *sprop;
- pr_info("Freescale P1022 DS ALSA SoC machine driver\n");
+ /*
+ * Check if we're actually running on a P1022DS. Older device trees
+ * have a model of "fsl,P1022" and newer ones use "fsl,P1022DS", so we
+ * need to support both. The SSI driver uses that property to link to
+ * the machine driver, so have to match it.
+ */
+ sprop = of_get_property(of_find_node_by_path("/"), "model", NULL);
+ if (!sprop) {
+ pr_err("snd-soc-p1022ds: missing /model node");
+ return -ENODEV;
+ }
+
+ pr_debug("snd-soc-p1022ds: board model name is %s\n", sprop);
+
+ /*
+ * The name of this board, taken from the device tree. Normally, this is a*
+ * fixed string, but some P1022DS device trees have a /model property of
+ * "fsl,P1022", and others have "fsl,P1022DS".
+ */
+ if (strcasecmp(sprop, "fsl,p1022ds") == 0)
+ p1022_ds_driver.driver.name = "snd-soc-p1022ds";
+ else if (strcasecmp(sprop, "fsl,p1022") == 0)
+ p1022_ds_driver.driver.name = "snd-soc-p1022";
+ else
+ return -ENODEV;
/* Get the physical address of the global utilities registers */
guts_np = of_find_compatible_node(NULL, NULL, "fsl,p1022-guts");
if (of_address_to_resource(guts_np, 0, &res)) {
- pr_err("p1022-ds: missing/invalid global utilities node\n");
+ pr_err("snd-soc-p1022ds: missing/invalid global utils node\n");
+ of_node_put(guts_np);
return -EINVAL;
}
guts_phys = res.start;
diff --git a/sound/soc/fsl/pcm030-audio-fabric.c b/sound/soc/fsl/pcm030-audio-fabric.c
index ba4d85e..b3af55d 100644
--- a/sound/soc/fsl/pcm030-audio-fabric.c
+++ b/sound/soc/fsl/pcm030-audio-fabric.c
@@ -31,8 +31,6 @@
#define DRV_NAME "pcm030-audio-fabric"
-static struct snd_soc_card card;
-
static struct snd_soc_dai_link pcm030_fabric_dai[] = {
{
.name = "AC97",
@@ -52,6 +50,13 @@
},
};
+static struct snd_soc_card card = {
+ .name = "pcm030",
+ .owner = THIS_MODULE,
+ .dai_link = pcm030_fabric_dai,
+ .num_links = ARRAY_SIZE(pcm030_fabric_dai),
+};
+
static __init int pcm030_fabric_init(void)
{
struct platform_device *pdev;
@@ -60,11 +65,6 @@
if (!of_machine_is_compatible("phytec,pcm030"))
return -ENODEV;
-
- card.name = "pcm030";
- card.dai_link = pcm030_fabric_dai;
- card.num_links = ARRAY_SIZE(pcm030_fabric_dai);
-
pdev = platform_device_alloc("soc-audio", 1);
if (!pdev) {
pr_err("pcm030_fabric_init: platform_device_alloc() failed\n");
diff --git a/sound/soc/imx/eukrea-tlv320.c b/sound/soc/imx/eukrea-tlv320.c
index 75fb4b8..1c1fdd1 100644
--- a/sound/soc/imx/eukrea-tlv320.c
+++ b/sound/soc/imx/eukrea-tlv320.c
@@ -87,6 +87,7 @@
static struct snd_soc_card eukrea_tlv320 = {
.name = "cpuimx-audio",
+ .owner = THIS_MODULE,
.dai_link = &eukrea_tlv320_dai,
.num_links = 1,
};
diff --git a/sound/soc/imx/imx-pcm-dma-mx2.c b/sound/soc/imx/imx-pcm-dma-mx2.c
index 43fdc24f..1cf2fe8 100644
--- a/sound/soc/imx/imx-pcm-dma-mx2.c
+++ b/sound/soc/imx/imx-pcm-dma-mx2.c
@@ -326,16 +326,6 @@
.remove = __devexit_p(imx_soc_platform_remove),
};
-static int __init snd_imx_pcm_init(void)
-{
- return platform_driver_register(&imx_pcm_driver);
-}
-module_init(snd_imx_pcm_init);
-
-static void __exit snd_imx_pcm_exit(void)
-{
- platform_driver_unregister(&imx_pcm_driver);
-}
-module_exit(snd_imx_pcm_exit);
+module_platform_driver(imx_pcm_driver);
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:imx-pcm-audio");
diff --git a/sound/soc/imx/imx-pcm-fiq.c b/sound/soc/imx/imx-pcm-fiq.c
index 8df0fae2..456b7d7 100644
--- a/sound/soc/imx/imx-pcm-fiq.c
+++ b/sound/soc/imx/imx-pcm-fiq.c
@@ -331,14 +331,6 @@
.remove = __devexit_p(imx_soc_platform_remove),
};
-static int __init snd_imx_pcm_init(void)
-{
- return platform_driver_register(&imx_pcm_driver);
-}
-module_init(snd_imx_pcm_init);
+module_platform_driver(imx_pcm_driver);
-static void __exit snd_imx_pcm_exit(void)
-{
- platform_driver_unregister(&imx_pcm_driver);
-}
-module_exit(snd_imx_pcm_exit);
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/imx/imx-ssi.c b/sound/soc/imx/imx-ssi.c
index 4c05e2b..01d1f74 100644
--- a/sound/soc/imx/imx-ssi.c
+++ b/sound/soc/imx/imx-ssi.c
@@ -342,7 +342,7 @@
return 0;
}
-static struct snd_soc_dai_ops imx_ssi_pcm_dai_ops = {
+static const struct snd_soc_dai_ops imx_ssi_pcm_dai_ops = {
.hw_params = imx_ssi_hw_params,
.set_fmt = imx_ssi_set_dai_fmt,
.set_clkdiv = imx_ssi_set_dai_clkdiv,
@@ -757,18 +757,7 @@
},
};
-static int __init imx_ssi_init(void)
-{
- return platform_driver_register(&imx_ssi_driver);
-}
-
-static void __exit imx_ssi_exit(void)
-{
- platform_driver_unregister(&imx_ssi_driver);
-}
-
-module_init(imx_ssi_init);
-module_exit(imx_ssi_exit);
+module_platform_driver(imx_ssi_driver);
/* Module information */
MODULE_AUTHOR("Sascha Hauer, <s.hauer@pengutronix.de>");
diff --git a/sound/soc/imx/mx27vis-aic32x4.c b/sound/soc/imx/mx27vis-aic32x4.c
index 054110b..3c2eed9 100644
--- a/sound/soc/imx/mx27vis-aic32x4.c
+++ b/sound/soc/imx/mx27vis-aic32x4.c
@@ -86,6 +86,7 @@
static struct snd_soc_card mx27vis_aic32x4 = {
.name = "visstrim_m10-audio",
+ .owner = THIS_MODULE,
.dai_link = &mx27vis_aic32x4_dai,
.num_links = 1,
};
diff --git a/sound/soc/imx/phycore-ac97.c b/sound/soc/imx/phycore-ac97.c
index a7deb5c..6ac1211 100644
--- a/sound/soc/imx/phycore-ac97.c
+++ b/sound/soc/imx/phycore-ac97.c
@@ -38,6 +38,7 @@
static struct snd_soc_card imx_phycore = {
.name = "PhyCORE-ac97-audio",
+ .owner = THIS_MODULE,
.dai_link = imx_phycore_dai_ac97,
.num_links = ARRAY_SIZE(imx_phycore_dai_ac97),
};
diff --git a/sound/soc/imx/wm1133-ev1.c b/sound/soc/imx/wm1133-ev1.c
index 490a126..37480c9 100644
--- a/sound/soc/imx/wm1133-ev1.c
+++ b/sound/soc/imx/wm1133-ev1.c
@@ -255,6 +255,7 @@
static struct snd_soc_card wm1133_ev1 = {
.name = "WM1133-EV1",
+ .owner = THIS_MODULE,
.dai_link = &wm1133_ev1_dai,
.num_links = 1,
};
diff --git a/sound/soc/jz4740/jz4740-i2s.c b/sound/soc/jz4740/jz4740-i2s.c
index cd22a54..a5af7c4 100644
--- a/sound/soc/jz4740/jz4740-i2s.c
+++ b/sound/soc/jz4740/jz4740-i2s.c
@@ -392,7 +392,7 @@
return 0;
}
-static struct snd_soc_dai_ops jz4740_i2s_dai_ops = {
+static const struct snd_soc_dai_ops jz4740_i2s_dai_ops = {
.startup = jz4740_i2s_startup,
.shutdown = jz4740_i2s_shutdown,
.trigger = jz4740_i2s_trigger,
@@ -519,17 +519,7 @@
},
};
-static int __init jz4740_i2s_init(void)
-{
- return platform_driver_register(&jz4740_i2s_driver);
-}
-module_init(jz4740_i2s_init);
-
-static void __exit jz4740_i2s_exit(void)
-{
- platform_driver_unregister(&jz4740_i2s_driver);
-}
-module_exit(jz4740_i2s_exit);
+module_platform_driver(jz4740_i2s_driver);
MODULE_AUTHOR("Lars-Peter Clausen, <lars@metafoo.de>");
MODULE_DESCRIPTION("Ingenic JZ4740 SoC I2S driver");
diff --git a/sound/soc/jz4740/jz4740-pcm.c b/sound/soc/jz4740/jz4740-pcm.c
index d1989cd..9b8cf25 100644
--- a/sound/soc/jz4740/jz4740-pcm.c
+++ b/sound/soc/jz4740/jz4740-pcm.c
@@ -302,7 +302,6 @@
static int jz4740_pcm_new(struct snd_soc_pcm_runtime *rtd)
{
struct snd_card *card = rtd->card->snd_card;
- struct snd_soc_dai *dai = rtd->cpu_dai;
struct snd_pcm *pcm = rtd->pcm;
int ret = 0;
@@ -312,14 +311,14 @@
if (!card->dev->coherent_dma_mask)
card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
- if (dai->driver->playback.channels_min) {
+ if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
ret = jz4740_pcm_preallocate_dma_buffer(pcm,
SNDRV_PCM_STREAM_PLAYBACK);
if (ret)
goto err;
}
- if (dai->driver->capture.channels_min) {
+ if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
ret = jz4740_pcm_preallocate_dma_buffer(pcm,
SNDRV_PCM_STREAM_CAPTURE);
if (ret)
@@ -356,17 +355,7 @@
},
};
-static int __init jz4740_soc_platform_init(void)
-{
- return platform_driver_register(&jz4740_pcm_driver);
-}
-module_init(jz4740_soc_platform_init);
-
-static void __exit jz4740_soc_platform_exit(void)
-{
- return platform_driver_unregister(&jz4740_pcm_driver);
-}
-module_exit(jz4740_soc_platform_exit);
+module_platform_driver(jz4740_pcm_driver);
MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
MODULE_DESCRIPTION("Ingenic SoC JZ4740 PCM driver");
diff --git a/sound/soc/jz4740/qi_lb60.c b/sound/soc/jz4740/qi_lb60.c
index c5fc339..0097c3b 100644
--- a/sound/soc/jz4740/qi_lb60.c
+++ b/sound/soc/jz4740/qi_lb60.c
@@ -81,6 +81,7 @@
static struct snd_soc_card qi_lb60 = {
.name = "QI LB60",
+ .owner = THIS_MODULE,
.dai_link = &qi_lb60_dai,
.num_links = 1,
diff --git a/sound/soc/kirkwood/kirkwood-dma.c b/sound/soc/kirkwood/kirkwood-dma.c
index df12e09..d038540 100644
--- a/sound/soc/kirkwood/kirkwood-dma.c
+++ b/sound/soc/kirkwood/kirkwood-dma.c
@@ -318,7 +318,6 @@
static int kirkwood_dma_new(struct snd_soc_pcm_runtime *rtd)
{
struct snd_card *card = rtd->card->snd_card;
- struct snd_soc_dai *dai = rtd->cpu_dai;
struct snd_pcm *pcm = rtd->pcm;
int ret;
@@ -327,14 +326,14 @@
if (!card->dev->coherent_dma_mask)
card->dev->coherent_dma_mask = 0xffffffff;
- if (dai->driver->playback.channels_min) {
+ if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
ret = kirkwood_dma_preallocate_dma_buffer(pcm,
SNDRV_PCM_STREAM_PLAYBACK);
if (ret)
return ret;
}
- if (dai->driver->capture.channels_min) {
+ if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
ret = kirkwood_dma_preallocate_dma_buffer(pcm,
SNDRV_PCM_STREAM_CAPTURE);
if (ret)
@@ -391,17 +390,7 @@
.remove = __devexit_p(kirkwood_soc_platform_remove),
};
-static int __init kirkwood_pcm_init(void)
-{
- return platform_driver_register(&kirkwood_pcm_driver);
-}
-module_init(kirkwood_pcm_init);
-
-static void __exit kirkwood_pcm_exit(void)
-{
- platform_driver_unregister(&kirkwood_pcm_driver);
-}
-module_exit(kirkwood_pcm_exit);
+module_platform_driver(kirkwood_pcm_driver);
MODULE_AUTHOR("Arnaud Patard <arnaud.patard@rtp-net.org>");
MODULE_DESCRIPTION("Marvell Kirkwood Audio DMA module");
diff --git a/sound/soc/kirkwood/kirkwood-i2s.c b/sound/soc/kirkwood/kirkwood-i2s.c
index 715e841..3cb9aa4 100644
--- a/sound/soc/kirkwood/kirkwood-i2s.c
+++ b/sound/soc/kirkwood/kirkwood-i2s.c
@@ -373,7 +373,7 @@
return 0;
}
-static struct snd_soc_dai_ops kirkwood_i2s_dai_ops = {
+static const struct snd_soc_dai_ops kirkwood_i2s_dai_ops = {
.startup = kirkwood_i2s_startup,
.trigger = kirkwood_i2s_trigger,
.hw_params = kirkwood_i2s_hw_params,
@@ -441,13 +441,12 @@
goto err_ioremap;
}
- if (!data || !data->dram) {
+ if (!data) {
dev_err(&pdev->dev, "no platform data ?!\n");
err = -EINVAL;
goto err_ioremap;
}
- priv->dram = data->dram;
priv->burst = data->burst;
return snd_soc_register_dai(&pdev->dev, &kirkwood_i2s_dai);
@@ -483,17 +482,7 @@
},
};
-static int __init kirkwood_i2s_init(void)
-{
- return platform_driver_register(&kirkwood_i2s_driver);
-}
-module_init(kirkwood_i2s_init);
-
-static void __exit kirkwood_i2s_exit(void)
-{
- platform_driver_unregister(&kirkwood_i2s_driver);
-}
-module_exit(kirkwood_i2s_exit);
+module_platform_driver(kirkwood_i2s_driver);
/* Module information */
MODULE_AUTHOR("Arnaud Patard, <arnaud.patard@rtp-net.org>");
diff --git a/sound/soc/kirkwood/kirkwood-openrd.c b/sound/soc/kirkwood/kirkwood-openrd.c
index d863afb..55d2ed3 100644
--- a/sound/soc/kirkwood/kirkwood-openrd.c
+++ b/sound/soc/kirkwood/kirkwood-openrd.c
@@ -26,18 +26,7 @@
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_dai *codec_dai = rtd->codec_dai;
- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- int ret;
- unsigned int freq, fmt;
-
- fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS;
- ret = snd_soc_dai_set_fmt(cpu_dai, fmt);
- if (ret < 0)
- return ret;
-
- ret = snd_soc_dai_set_fmt(codec_dai, fmt);
- if (ret < 0)
- return ret;
+ unsigned int freq;
switch (params_rate(params)) {
default:
@@ -69,6 +58,7 @@
.platform_name = "kirkwood-pcm-audio",
.codec_dai_name = "cs42l51-hifi",
.codec_name = "cs42l51-codec.0-004a",
+ .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS,
.ops = &openrd_client_ops,
},
};
@@ -76,6 +66,7 @@
static struct snd_soc_card openrd_client = {
.name = "OpenRD Client",
+ .owner = THIS_MODULE,
.dai_link = openrd_client_dai,
.num_links = ARRAY_SIZE(openrd_client_dai),
};
diff --git a/sound/soc/kirkwood/kirkwood-t5325.c b/sound/soc/kirkwood/kirkwood-t5325.c
index c772b3c..b47cc4e 100644
--- a/sound/soc/kirkwood/kirkwood-t5325.c
+++ b/sound/soc/kirkwood/kirkwood-t5325.c
@@ -25,18 +25,7 @@
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_dai *codec_dai = rtd->codec_dai;
- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- int ret;
- unsigned int freq, fmt;
-
- fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS;
- ret = snd_soc_dai_set_fmt(cpu_dai, fmt);
- if (ret < 0)
- return ret;
-
- ret = snd_soc_dai_set_fmt(codec_dai, fmt);
- if (ret < 0)
- return ret;
+ unsigned int freq;
freq = params_rate(params) * 256;
@@ -70,11 +59,6 @@
struct snd_soc_codec *codec = rtd->codec;
struct snd_soc_dapm_context *dapm = &codec->dapm;
- snd_soc_dapm_new_controls(dapm, t5325_dapm_widgets,
- ARRAY_SIZE(t5325_dapm_widgets));
-
- snd_soc_dapm_add_routes(dapm, t5325_route, ARRAY_SIZE(t5325_route));
-
snd_soc_dapm_enable_pin(dapm, "Mic Jack");
snd_soc_dapm_enable_pin(dapm, "Headphone Jack");
snd_soc_dapm_enable_pin(dapm, "Speaker");
@@ -90,6 +74,7 @@
.platform_name = "kirkwood-pcm-audio",
.codec_dai_name = "alc5621-hifi",
.codec_name = "alc562x-codec.0-001a",
+ .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS,
.ops = &t5325_ops,
.init = t5325_dai_init,
},
@@ -98,8 +83,14 @@
static struct snd_soc_card t5325 = {
.name = "t5325",
+ .owner = THIS_MODULE,
.dai_link = t5325_dai,
.num_links = ARRAY_SIZE(t5325_dai),
+
+ .dapm_widgets = t5325_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(t5325_dapm_widgets),
+ .dapm_routes = t5325_route,
+ .num_dapm_routes = ARRAY_SIZE(t5325_route),
};
static struct platform_device *t5325_snd_device;
diff --git a/sound/soc/kirkwood/kirkwood.h b/sound/soc/kirkwood/kirkwood.h
index bb6e6a5..9047436 100644
--- a/sound/soc/kirkwood/kirkwood.h
+++ b/sound/soc/kirkwood/kirkwood.h
@@ -123,7 +123,6 @@
void __iomem *io;
int irq;
int burst;
- struct mbus_dram_target_info *dram;
};
#endif
diff --git a/sound/soc/mid-x86/Kconfig b/sound/soc/mid-x86/Kconfig
index 2935042..61c10bf 100644
--- a/sound/soc/mid-x86/Kconfig
+++ b/sound/soc/mid-x86/Kconfig
@@ -1,7 +1,6 @@
config SND_MFLD_MACHINE
tristate "SOC Machine Audio driver for Intel Medfield MID platform"
depends on INTEL_SCU_IPC
- depends on SND_INTEL_SST
select SND_SOC_SN95031
select SND_SST_PLATFORM
help
diff --git a/sound/soc/mid-x86/mfld_machine.c b/sound/soc/mid-x86/mfld_machine.c
index cca693a..6f77eef 100644
--- a/sound/soc/mid-x86/mfld_machine.c
+++ b/sound/soc/mid-x86/mfld_machine.c
@@ -281,7 +281,7 @@
return ret_val;
}
-struct snd_soc_dai_link mfld_msic_dailink[] = {
+static struct snd_soc_dai_link mfld_msic_dailink[] = {
{
.name = "Medfield Headset",
.stream_name = "Headset",
@@ -323,6 +323,7 @@
/* SoC card */
static struct snd_soc_card snd_soc_card_mfld = {
.name = "medfield_audio",
+ .owner = THIS_MODULE,
.dai_link = mfld_msic_dailink,
.num_links = ARRAY_SIZE(mfld_msic_dailink),
};
@@ -428,19 +429,7 @@
.remove = __devexit_p(snd_mfld_mc_remove),
};
-static int __init snd_mfld_driver_init(void)
-{
- pr_debug("snd_mfld_driver_init called\n");
- return platform_driver_register(&snd_mfld_mc_driver);
-}
-module_init(snd_mfld_driver_init);
-
-static void __exit snd_mfld_driver_exit(void)
-{
- pr_debug("snd_mfld_driver_exit called\n");
- platform_driver_unregister(&snd_mfld_mc_driver);
-}
-module_exit(snd_mfld_driver_exit);
+module_platform_driver(snd_mfld_mc_driver);
MODULE_DESCRIPTION("ASoC Intel(R) MID Machine driver");
MODULE_AUTHOR("Vinod Koul <vinod.koul@intel.com>");
diff --git a/sound/soc/mid-x86/sst_platform.c b/sound/soc/mid-x86/sst_platform.c
index 2305702..d34563b 100644
--- a/sound/soc/mid-x86/sst_platform.c
+++ b/sound/soc/mid-x86/sst_platform.c
@@ -32,10 +32,51 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include "../../../drivers/staging/intel_sst/intel_sst_ioctl.h"
-#include "../../../drivers/staging/intel_sst/intel_sst.h"
#include "sst_platform.h"
+static struct sst_device *sst;
+static DEFINE_MUTEX(sst_lock);
+
+int sst_register_dsp(struct sst_device *dev)
+{
+ BUG_ON(!dev);
+ if (!try_module_get(dev->dev->driver->owner))
+ return -ENODEV;
+ mutex_lock(&sst_lock);
+ if (sst) {
+ pr_err("we already have a device %s\n", sst->name);
+ module_put(dev->dev->driver->owner);
+ mutex_unlock(&sst_lock);
+ return -EEXIST;
+ }
+ pr_debug("registering device %s\n", dev->name);
+ sst = dev;
+ mutex_unlock(&sst_lock);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(sst_register_dsp);
+
+int sst_unregister_dsp(struct sst_device *dev)
+{
+ BUG_ON(!dev);
+ if (dev != sst)
+ return -EINVAL;
+
+ mutex_lock(&sst_lock);
+
+ if (!sst) {
+ mutex_unlock(&sst_lock);
+ return -EIO;
+ }
+
+ module_put(sst->dev->driver->owner);
+ pr_debug("unreg %s\n", sst->name);
+ sst = NULL;
+ mutex_unlock(&sst_lock);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(sst_unregister_dsp);
+
static struct snd_pcm_hardware sst_platform_pcm_hw = {
.info = (SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_DOUBLE |
@@ -135,37 +176,34 @@
}
static void sst_fill_pcm_params(struct snd_pcm_substream *substream,
- struct snd_sst_stream_params *param)
+ struct sst_pcm_params *param)
{
- param->uc.pcm_params.codec = SST_CODEC_TYPE_PCM;
- param->uc.pcm_params.num_chan = (u8) substream->runtime->channels;
- param->uc.pcm_params.pcm_wd_sz = substream->runtime->sample_bits;
- param->uc.pcm_params.reserved = 0;
- param->uc.pcm_params.sfreq = substream->runtime->rate;
- param->uc.pcm_params.ring_buffer_size =
- snd_pcm_lib_buffer_bytes(substream);
- param->uc.pcm_params.period_count = substream->runtime->period_size;
- param->uc.pcm_params.ring_buffer_addr =
- virt_to_phys(substream->dma_buffer.area);
- pr_debug("period_cnt = %d\n", param->uc.pcm_params.period_count);
- pr_debug("sfreq= %d, wd_sz = %d\n",
- param->uc.pcm_params.sfreq, param->uc.pcm_params.pcm_wd_sz);
+ param->codec = SST_CODEC_TYPE_PCM;
+ param->num_chan = (u8) substream->runtime->channels;
+ param->pcm_wd_sz = substream->runtime->sample_bits;
+ param->reserved = 0;
+ param->sfreq = substream->runtime->rate;
+ param->ring_buffer_size = snd_pcm_lib_buffer_bytes(substream);
+ param->period_count = substream->runtime->period_size;
+ param->ring_buffer_addr = virt_to_phys(substream->dma_buffer.area);
+ pr_debug("period_cnt = %d\n", param->period_count);
+ pr_debug("sfreq= %d, wd_sz = %d\n", param->sfreq, param->pcm_wd_sz);
}
static int sst_platform_alloc_stream(struct snd_pcm_substream *substream)
{
struct sst_runtime_stream *stream =
substream->runtime->private_data;
- struct snd_sst_stream_params param = {{{0,},},};
- struct snd_sst_params str_params = {0};
+ struct sst_pcm_params param = {0};
+ struct sst_stream_params str_params = {0};
int ret_val;
/* set codec params and inform SST driver the same */
sst_fill_pcm_params(substream, ¶m);
substream->runtime->dma_area = substream->dma_buffer.area;
str_params.sparams = param;
- str_params.codec = param.uc.pcm_params.codec;
+ str_params.codec = param.codec;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
str_params.ops = STREAM_OPS_PLAYBACK;
str_params.device_type = substream->pcm->device + 1;
@@ -177,7 +215,7 @@
pr_debug("Capture stream,Device %d\n",
substream->pcm->device);
}
- ret_val = stream->sstdrv_ops->pcm_control->open(&str_params);
+ ret_val = stream->ops->open(&str_params);
pr_debug("SST_SND_PLAY/CAPTURE ret_val = %x\n", ret_val);
if (ret_val < 0)
return ret_val;
@@ -216,7 +254,7 @@
stream->stream_info.mad_substream = substream;
stream->stream_info.buffer_ptr = 0;
stream->stream_info.sfreq = substream->runtime->rate;
- ret_val = stream->sstdrv_ops->pcm_control->device_control(
+ ret_val = stream->ops->device_control(
SST_SND_STREAM_INIT, &stream->stream_info);
if (ret_val)
pr_err("control_set ret error %d\n", ret_val);
@@ -229,7 +267,7 @@
{
struct snd_pcm_runtime *runtime = substream->runtime;
struct sst_runtime_stream *stream;
- int ret_val = 0;
+ int ret_val;
pr_debug("sst_platform_open called\n");
@@ -243,27 +281,27 @@
if (!stream)
return -ENOMEM;
spin_lock_init(&stream->status_lock);
+
+ /* get the sst ops */
+ mutex_lock(&sst_lock);
+ if (!sst) {
+ pr_err("no device available to run\n");
+ mutex_unlock(&sst_lock);
+ kfree(stream);
+ return -ENODEV;
+ }
+ if (!try_module_get(sst->dev->driver->owner)) {
+ mutex_unlock(&sst_lock);
+ kfree(stream);
+ return -ENODEV;
+ }
+ stream->ops = sst->ops;
+ mutex_unlock(&sst_lock);
+
stream->stream_info.str_id = 0;
sst_set_stream_status(stream, SST_PLATFORM_INIT);
stream->stream_info.mad_substream = substream;
/* allocate memory for SST API set */
- stream->sstdrv_ops = kzalloc(sizeof(*stream->sstdrv_ops),
- GFP_KERNEL);
- if (!stream->sstdrv_ops) {
- pr_err("sst: mem allocation for ops fail\n");
- kfree(stream);
- return -ENOMEM;
- }
- stream->sstdrv_ops->vendor_id = MSIC_VENDOR_ID;
- stream->sstdrv_ops->module_name = SST_CARD_NAMES;
- /* registering with SST driver to get access to SST APIs to use */
- ret_val = register_sst_card(stream->sstdrv_ops);
- if (ret_val) {
- pr_err("sst: sst card registration failed\n");
- kfree(stream->sstdrv_ops);
- kfree(stream);
- return ret_val;
- }
runtime->private_data = stream;
return 0;
@@ -278,9 +316,8 @@
stream = substream->runtime->private_data;
str_id = stream->stream_info.str_id;
if (str_id)
- ret_val = stream->sstdrv_ops->pcm_control->close(str_id);
- unregister_sst_card(stream->sstdrv_ops);
- kfree(stream->sstdrv_ops);
+ ret_val = stream->ops->close(str_id);
+ module_put(sst->dev->driver->owner);
kfree(stream);
return ret_val;
}
@@ -294,8 +331,8 @@
stream = substream->runtime->private_data;
str_id = stream->stream_info.str_id;
if (stream->stream_info.str_id) {
- ret_val = stream->sstdrv_ops->pcm_control->device_control(
- SST_SND_DROP, &str_id);
+ ret_val = stream->ops->device_control(
+ SST_SND_DROP, &str_id);
return ret_val;
}
@@ -347,8 +384,7 @@
default:
return -EINVAL;
}
- ret_val = stream->sstdrv_ops->pcm_control->device_control(str_cmd,
- &str_id);
+ ret_val = stream->ops->device_control(str_cmd, &str_id);
if (!ret_val)
sst_set_stream_status(stream, status);
@@ -368,7 +404,7 @@
if (status == SST_PLATFORM_INIT)
return 0;
str_info = &stream->stream_info;
- ret_val = stream->sstdrv_ops->pcm_control->device_control(
+ ret_val = stream->ops->device_control(
SST_SND_BUFFER_POINTER, str_info);
if (ret_val) {
pr_err("sst: error code = %d\n", ret_val);
@@ -408,15 +444,14 @@
snd_pcm_lib_preallocate_free_for_all(pcm);
}
-int sst_pcm_new(struct snd_soc_pcm_runtime *rtd)
+static int sst_pcm_new(struct snd_soc_pcm_runtime *rtd)
{
- struct snd_soc_dai *dai = rtd->cpu_dai;
struct snd_pcm *pcm = rtd->pcm;
int retval = 0;
pr_debug("sst_pcm_new called\n");
- if (dai->driver->playback.channels_min ||
- dai->driver->capture.channels_min) {
+ if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream ||
+ pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
retval = snd_pcm_lib_preallocate_pages_for_all(pcm,
SNDRV_DMA_TYPE_CONTINUOUS,
snd_dma_continuous_data(GFP_KERNEL),
@@ -428,7 +463,7 @@
}
return retval;
}
-struct snd_soc_platform_driver sst_soc_platform_drv = {
+static struct snd_soc_platform_driver sst_soc_platform_drv = {
.ops = &sst_platform_ops,
.pcm_new = sst_pcm_new,
.pcm_free = sst_pcm_free,
@@ -439,6 +474,7 @@
int ret;
pr_debug("sst_platform_probe called\n");
+ sst = NULL;
ret = snd_soc_register_platform(&pdev->dev, &sst_soc_platform_drv);
if (ret) {
pr_err("registering soc platform failed\n");
@@ -472,19 +508,7 @@
.remove = sst_platform_remove,
};
-static int __init sst_soc_platform_init(void)
-{
- pr_debug("sst_soc_platform_init called\n");
- return platform_driver_register(&sst_platform_driver);
-}
-module_init(sst_soc_platform_init);
-
-static void __exit sst_soc_platform_exit(void)
-{
- platform_driver_unregister(&sst_platform_driver);
- pr_debug("sst_soc_platform_exit success\n");
-}
-module_exit(sst_soc_platform_exit);
+module_platform_driver(sst_platform_driver);
MODULE_DESCRIPTION("ASoC Intel(R) MID Platform driver");
MODULE_AUTHOR("Vinod Koul <vinod.koul@intel.com>");
diff --git a/sound/soc/mid-x86/sst_platform.h b/sound/soc/mid-x86/sst_platform.h
index df37028..f04f4f7 100644
--- a/sound/soc/mid-x86/sst_platform.h
+++ b/sound/soc/mid-x86/sst_platform.h
@@ -42,14 +42,14 @@
#define SST_MIN_PERIODS 2
#define SST_MAX_PERIODS (1024*2)
#define SST_FIFO_SIZE 0
-#define SST_CARD_NAMES "intel_mid_card"
-#define MSIC_VENDOR_ID 3
+#define SST_CODEC_TYPE_PCM 1
-struct sst_runtime_stream {
- int stream_status;
- struct pcm_stream_info stream_info;
- struct intel_sst_card_ops *sstdrv_ops;
- spinlock_t status_lock;
+struct pcm_stream_info {
+ int str_id;
+ void *mad_substream;
+ void (*period_elapsed) (void *mad_substream);
+ unsigned long long buffer_ptr;
+ int sfreq;
};
enum sst_drv_status {
@@ -60,4 +60,72 @@
SST_PLATFORM_DROPPED,
};
+enum sst_controls {
+ SST_SND_ALLOC = 0x00,
+ SST_SND_PAUSE = 0x01,
+ SST_SND_RESUME = 0x02,
+ SST_SND_DROP = 0x03,
+ SST_SND_FREE = 0x04,
+ SST_SND_BUFFER_POINTER = 0x05,
+ SST_SND_STREAM_INIT = 0x06,
+ SST_SND_START = 0x07,
+ SST_MAX_CONTROLS = 0x07,
+};
+
+enum sst_stream_ops {
+ STREAM_OPS_PLAYBACK = 0,
+ STREAM_OPS_CAPTURE,
+};
+
+enum sst_audio_device_type {
+ SND_SST_DEVICE_HEADSET = 1,
+ SND_SST_DEVICE_IHF,
+ SND_SST_DEVICE_VIBRA,
+ SND_SST_DEVICE_HAPTIC,
+ SND_SST_DEVICE_CAPTURE,
+};
+
+/* PCM Parameters */
+struct sst_pcm_params {
+ u16 codec; /* codec type */
+ u8 num_chan; /* 1=Mono, 2=Stereo */
+ u8 pcm_wd_sz; /* 16/24 - bit*/
+ u32 reserved; /* Bitrate in bits per second */
+ u32 sfreq; /* Sampling rate in Hz */
+ u32 ring_buffer_size;
+ u32 period_count; /* period elapsed in samples*/
+ u32 ring_buffer_addr;
+};
+
+struct sst_stream_params {
+ u32 result;
+ u32 stream_id;
+ u8 codec;
+ u8 ops;
+ u8 stream_type;
+ u8 device_type;
+ struct sst_pcm_params sparams;
+};
+
+struct sst_ops {
+ int (*open) (struct sst_stream_params *str_param);
+ int (*device_control) (int cmd, void *arg);
+ int (*close) (unsigned int str_id);
+};
+
+struct sst_runtime_stream {
+ int stream_status;
+ struct pcm_stream_info stream_info;
+ struct sst_ops *ops;
+ spinlock_t status_lock;
+};
+
+struct sst_device {
+ char *name;
+ struct device *dev;
+ struct sst_ops *ops;
+};
+
+int sst_register_dsp(struct sst_device *sst);
+int sst_unregister_dsp(struct sst_device *sst);
#endif
diff --git a/sound/soc/mxs/mxs-pcm.c b/sound/soc/mxs/mxs-pcm.c
index f39d7dd..0e12f4e 100644
--- a/sound/soc/mxs/mxs-pcm.c
+++ b/sound/soc/mxs/mxs-pcm.c
@@ -346,17 +346,7 @@
.remove = __devexit_p(mxs_soc_platform_remove),
};
-static int __init snd_mxs_pcm_init(void)
-{
- return platform_driver_register(&mxs_pcm_driver);
-}
-module_init(snd_mxs_pcm_init);
-
-static void __exit snd_mxs_pcm_exit(void)
-{
- platform_driver_unregister(&mxs_pcm_driver);
-}
-module_exit(snd_mxs_pcm_exit);
+module_platform_driver(mxs_pcm_driver);
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:mxs-pcm-audio");
diff --git a/sound/soc/mxs/mxs-saif.c b/sound/soc/mxs/mxs-saif.c
index d775b07..dccfb37 100644
--- a/sound/soc/mxs/mxs-saif.c
+++ b/sound/soc/mxs/mxs-saif.c
@@ -550,7 +550,7 @@
(SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
SNDRV_PCM_FMTBIT_S24_LE)
-static struct snd_soc_dai_ops mxs_saif_dai_ops = {
+static const struct snd_soc_dai_ops mxs_saif_dai_ops = {
.startup = mxs_saif_startup,
.trigger = mxs_saif_trigger,
.prepare = mxs_saif_prepare,
@@ -779,18 +779,8 @@
},
};
-static int __init mxs_saif_init(void)
-{
- return platform_driver_register(&mxs_saif_driver);
-}
+module_platform_driver(mxs_saif_driver);
-static void __exit mxs_saif_exit(void)
-{
- platform_driver_unregister(&mxs_saif_driver);
-}
-
-module_init(mxs_saif_init);
-module_exit(mxs_saif_exit);
MODULE_AUTHOR("Freescale Semiconductor, Inc.");
MODULE_DESCRIPTION("MXS ASoC SAIF driver");
MODULE_LICENSE("GPL");
diff --git a/sound/soc/mxs/mxs-sgtl5000.c b/sound/soc/mxs/mxs-sgtl5000.c
index 1c57f66..60f052b 100644
--- a/sound/soc/mxs/mxs-sgtl5000.c
+++ b/sound/soc/mxs/mxs-sgtl5000.c
@@ -105,6 +105,7 @@
static struct snd_soc_card mxs_sgtl5000 = {
.name = "mxs_sgtl5000",
+ .owner = THIS_MODULE,
.dai_link = mxs_sgtl5000_dai,
.num_links = ARRAY_SIZE(mxs_sgtl5000_dai),
};
@@ -156,17 +157,7 @@
.remove = __devexit_p(mxs_sgtl5000_remove),
};
-static int __init mxs_sgtl5000_init(void)
-{
- return platform_driver_register(&mxs_sgtl5000_audio_driver);
-}
-module_init(mxs_sgtl5000_init);
-
-static void __exit mxs_sgtl5000_exit(void)
-{
- platform_driver_unregister(&mxs_sgtl5000_audio_driver);
-}
-module_exit(mxs_sgtl5000_exit);
+module_platform_driver(mxs_sgtl5000_audio_driver);
MODULE_AUTHOR("Freescale Semiconductor, Inc.");
MODULE_DESCRIPTION("MXS ALSA SoC Machine driver");
diff --git a/sound/soc/nuc900/nuc900-ac97.c b/sound/soc/nuc900/nuc900-ac97.c
index a4e3237..45d11dd 100644
--- a/sound/soc/nuc900/nuc900-ac97.c
+++ b/sound/soc/nuc900/nuc900-ac97.c
@@ -291,7 +291,7 @@
return 0;
}
-static struct snd_soc_dai_ops nuc900_ac97_dai_ops = {
+static const struct snd_soc_dai_ops nuc900_ac97_dai_ops = {
.trigger = nuc900_ac97_trigger,
};
@@ -406,18 +406,7 @@
.remove = __devexit_p(nuc900_ac97_drvremove),
};
-static int __init nuc900_ac97_init(void)
-{
- return platform_driver_register(&nuc900_ac97_driver);
-}
-
-static void __exit nuc900_ac97_exit(void)
-{
- platform_driver_unregister(&nuc900_ac97_driver);
-}
-
-module_init(nuc900_ac97_init);
-module_exit(nuc900_ac97_exit);
+module_platform_driver(nuc900_ac97_driver);
MODULE_AUTHOR("Wan ZongShun <mcuos.com@gmail.com>");
MODULE_DESCRIPTION("NUC900 AC97 SoC driver!");
diff --git a/sound/soc/nuc900/nuc900-audio.c b/sound/soc/nuc900/nuc900-audio.c
index 38a2d0d8..2f6e6fd 100644
--- a/sound/soc/nuc900/nuc900-audio.c
+++ b/sound/soc/nuc900/nuc900-audio.c
@@ -32,6 +32,7 @@
static struct snd_soc_card nuc900evb_audio_machine = {
.name = "NUC900EVB_AC97",
+ .owner = THIS_MODULE,
.dai_link = &nuc900evb_ac97_dai,
.num_links = 1,
};
diff --git a/sound/soc/nuc900/nuc900-pcm.c b/sound/soc/nuc900/nuc900-pcm.c
index ae8d680..37585b4 100644
--- a/sound/soc/nuc900/nuc900-pcm.c
+++ b/sound/soc/nuc900/nuc900-pcm.c
@@ -358,17 +358,7 @@
.remove = __devexit_p(nuc900_soc_platform_remove),
};
-static int __init nuc900_pcm_init(void)
-{
- return platform_driver_register(&nuc900_pcm_driver);
-}
-module_init(nuc900_pcm_init);
-
-static void __exit nuc900_pcm_exit(void)
-{
- platform_driver_unregister(&nuc900_pcm_driver);
-}
-module_exit(nuc900_pcm_exit);
+module_platform_driver(nuc900_pcm_driver);
MODULE_AUTHOR("Wan ZongShun, <mcuos.com@gmail.com>");
MODULE_DESCRIPTION("nuc900 Audio DMA module");
diff --git a/sound/soc/omap/Kconfig b/sound/soc/omap/Kconfig
index fe83d0d..fb1bf258 100644
--- a/sound/soc/omap/Kconfig
+++ b/sound/soc/omap/Kconfig
@@ -2,6 +2,9 @@
tristate "SoC Audio for the Texas Instruments OMAP chips"
depends on ARCH_OMAP
+config SND_OMAP_SOC_DMIC
+ tristate
+
config SND_OMAP_SOC_MCBSP
tristate
select OMAP_MCBSP
@@ -97,8 +100,10 @@
config SND_OMAP_SOC_SDP4430
tristate "SoC Audio support for Texas Instruments SDP4430"
depends on TWL4030_CORE && SND_OMAP_SOC && MACH_OMAP_4430SDP
+ select SND_OMAP_SOC_DMIC
select SND_OMAP_SOC_MCPDM
select SND_SOC_TWL6040
+ select SND_SOC_DMIC
help
Say Y if you want to add support for SoC audio on Texas Instruments
SDP4430.
diff --git a/sound/soc/omap/Makefile b/sound/soc/omap/Makefile
index 052fd75..1fd723f 100644
--- a/sound/soc/omap/Makefile
+++ b/sound/soc/omap/Makefile
@@ -1,10 +1,12 @@
# OMAP Platform Support
snd-soc-omap-objs := omap-pcm.o
+snd-soc-omap-dmic-objs := omap-dmic.o
snd-soc-omap-mcbsp-objs := omap-mcbsp.o
snd-soc-omap-mcpdm-objs := omap-mcpdm.o
snd-soc-omap-hdmi-objs := omap-hdmi.o
obj-$(CONFIG_SND_OMAP_SOC) += snd-soc-omap.o
+obj-$(CONFIG_SND_OMAP_SOC_DMIC) += snd-soc-omap-dmic.o
obj-$(CONFIG_SND_OMAP_SOC_MCBSP) += snd-soc-omap-mcbsp.o
obj-$(CONFIG_SND_OMAP_SOC_MCPDM) += snd-soc-omap-mcpdm.o
obj-$(CONFIG_SND_OMAP_SOC_HDMI) += snd-soc-omap-hdmi.o
diff --git a/sound/soc/omap/am3517evm.c b/sound/soc/omap/am3517evm.c
index c1cd4a0..add4866 100644
--- a/sound/soc/omap/am3517evm.c
+++ b/sound/soc/omap/am3517evm.c
@@ -107,6 +107,7 @@
/* Audio machine driver */
static struct snd_soc_card snd_soc_am3517evm = {
.name = "am3517evm",
+ .owner = THIS_MODULE,
.dai_link = &am3517evm_dai,
.num_links = 1,
diff --git a/sound/soc/omap/ams-delta.c b/sound/soc/omap/ams-delta.c
index ccb8a6a..a67f437 100644
--- a/sound/soc/omap/ams-delta.c
+++ b/sound/soc/omap/ams-delta.c
@@ -431,22 +431,20 @@
struct snd_soc_dapm_context *dapm,
enum snd_soc_bias_level level)
{
- struct snd_soc_codec *codec = card->rtd->codec;
-
switch (level) {
case SND_SOC_BIAS_ON:
case SND_SOC_BIAS_PREPARE:
case SND_SOC_BIAS_STANDBY:
- if (codec->dapm.bias_level == SND_SOC_BIAS_OFF)
+ if (card->dapm.bias_level == SND_SOC_BIAS_OFF)
ams_delta_latch2_write(AMS_DELTA_LATCH2_MODEM_NRESET,
AMS_DELTA_LATCH2_MODEM_NRESET);
break;
case SND_SOC_BIAS_OFF:
- if (codec->dapm.bias_level != SND_SOC_BIAS_OFF)
+ if (card->dapm.bias_level != SND_SOC_BIAS_OFF)
ams_delta_latch2_write(AMS_DELTA_LATCH2_MODEM_NRESET,
0);
}
- codec->dapm.bias_level = level;
+ card->dapm.bias_level = level;
return 0;
}
@@ -474,7 +472,7 @@
}
/* Our codec DAI probably doesn't have its own .ops structure */
-static struct snd_soc_dai_ops ams_delta_dai_ops = {
+static const struct snd_soc_dai_ops ams_delta_dai_ops = {
.digital_mute = ams_delta_digital_mute,
};
@@ -597,6 +595,7 @@
/* Audio card driver */
static struct snd_soc_card ams_delta_audio_card = {
.name = "AMS_DELTA",
+ .owner = THIS_MODULE,
.dai_link = &ams_delta_dai_link,
.num_links = 1,
.set_bias_level = ams_delta_set_bias_level,
diff --git a/sound/soc/omap/igep0020.c b/sound/soc/omap/igep0020.c
index 591fbf8..ccae58a 100644
--- a/sound/soc/omap/igep0020.c
+++ b/sound/soc/omap/igep0020.c
@@ -72,6 +72,7 @@
/* Audio machine driver */
static struct snd_soc_card snd_soc_card_igep2 = {
.name = "igep2",
+ .owner = THIS_MODULE,
.dai_link = &igep2_dai,
.num_links = 1,
};
diff --git a/sound/soc/omap/n810.c b/sound/soc/omap/n810.c
index fc6209b..597be41 100644
--- a/sound/soc/omap/n810.c
+++ b/sound/soc/omap/n810.c
@@ -289,6 +289,7 @@
/* Audio machine driver */
static struct snd_soc_card snd_soc_n810 = {
.name = "N810",
+ .owner = THIS_MODULE,
.dai_link = &n810_dai,
.num_links = 1,
diff --git a/sound/soc/omap/omap-dmic.c b/sound/soc/omap/omap-dmic.c
new file mode 100644
index 0000000..0855c1c
--- /dev/null
+++ b/sound/soc/omap/omap-dmic.c
@@ -0,0 +1,546 @@
+/*
+ * omap-dmic.c -- OMAP ASoC DMIC DAI driver
+ *
+ * Copyright (C) 2010 - 2011 Texas Instruments
+ *
+ * Author: David Lambert <dlambert@ti.com>
+ * Misael Lopez Cruz <misael.lopez@ti.com>
+ * Liam Girdwood <lrg@ti.com>
+ * Peter Ujfalusi <peter.ujfalusi@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * 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 <linux/init.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/pm_runtime.h>
+#include <plat/dma.h>
+
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/initval.h>
+#include <sound/soc.h>
+
+#include "omap-pcm.h"
+#include "omap-dmic.h"
+
+struct omap_dmic {
+ struct device *dev;
+ void __iomem *io_base;
+ struct clk *fclk;
+ int fclk_freq;
+ int out_freq;
+ int clk_div;
+ int sysclk;
+ int threshold;
+ u32 ch_enabled;
+ bool active;
+ struct mutex mutex;
+};
+
+/*
+ * Stream DMA parameters
+ */
+static struct omap_pcm_dma_data omap_dmic_dai_dma_params = {
+ .name = "DMIC capture",
+ .data_type = OMAP_DMA_DATA_TYPE_S32,
+ .sync_mode = OMAP_DMA_SYNC_PACKET,
+};
+
+static inline void omap_dmic_write(struct omap_dmic *dmic, u16 reg, u32 val)
+{
+ __raw_writel(val, dmic->io_base + reg);
+}
+
+static inline int omap_dmic_read(struct omap_dmic *dmic, u16 reg)
+{
+ return __raw_readl(dmic->io_base + reg);
+}
+
+static inline void omap_dmic_start(struct omap_dmic *dmic)
+{
+ u32 ctrl = omap_dmic_read(dmic, OMAP_DMIC_CTRL_REG);
+
+ /* Configure DMA controller */
+ omap_dmic_write(dmic, OMAP_DMIC_DMAENABLE_SET_REG,
+ OMAP_DMIC_DMA_ENABLE);
+
+ omap_dmic_write(dmic, OMAP_DMIC_CTRL_REG, ctrl | dmic->ch_enabled);
+}
+
+static inline void omap_dmic_stop(struct omap_dmic *dmic)
+{
+ u32 ctrl = omap_dmic_read(dmic, OMAP_DMIC_CTRL_REG);
+ omap_dmic_write(dmic, OMAP_DMIC_CTRL_REG,
+ ctrl & ~OMAP_DMIC_UP_ENABLE_MASK);
+
+ /* Disable DMA request generation */
+ omap_dmic_write(dmic, OMAP_DMIC_DMAENABLE_CLR_REG,
+ OMAP_DMIC_DMA_ENABLE);
+
+}
+
+static inline int dmic_is_enabled(struct omap_dmic *dmic)
+{
+ return omap_dmic_read(dmic, OMAP_DMIC_CTRL_REG) &
+ OMAP_DMIC_UP_ENABLE_MASK;
+}
+
+static int omap_dmic_dai_startup(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ struct omap_dmic *dmic = snd_soc_dai_get_drvdata(dai);
+ int ret = 0;
+
+ mutex_lock(&dmic->mutex);
+
+ if (!dai->active) {
+ snd_pcm_hw_constraint_msbits(substream->runtime, 0, 32, 24);
+ dmic->active = 1;
+ } else {
+ ret = -EBUSY;
+ }
+
+ mutex_unlock(&dmic->mutex);
+
+ return ret;
+}
+
+static void omap_dmic_dai_shutdown(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ struct omap_dmic *dmic = snd_soc_dai_get_drvdata(dai);
+
+ mutex_lock(&dmic->mutex);
+
+ if (!dai->active)
+ dmic->active = 0;
+
+ mutex_unlock(&dmic->mutex);
+}
+
+static int omap_dmic_select_divider(struct omap_dmic *dmic, int sample_rate)
+{
+ int divider = -EINVAL;
+
+ /*
+ * 192KHz rate is only supported with 19.2MHz/3.84MHz clock
+ * configuration.
+ */
+ if (sample_rate == 192000) {
+ if (dmic->fclk_freq == 19200000 && dmic->out_freq == 3840000)
+ divider = 0x6; /* Divider: 5 (192KHz sampling rate) */
+ else
+ dev_err(dmic->dev,
+ "invalid clock configuration for 192KHz\n");
+
+ return divider;
+ }
+
+ switch (dmic->out_freq) {
+ case 1536000:
+ if (dmic->fclk_freq != 24576000)
+ goto div_err;
+ divider = 0x4; /* Divider: 16 */
+ break;
+ case 2400000:
+ switch (dmic->fclk_freq) {
+ case 12000000:
+ divider = 0x5; /* Divider: 5 */
+ break;
+ case 19200000:
+ divider = 0x0; /* Divider: 8 */
+ break;
+ case 24000000:
+ divider = 0x2; /* Divider: 10 */
+ break;
+ default:
+ goto div_err;
+ }
+ break;
+ case 3072000:
+ if (dmic->fclk_freq != 24576000)
+ goto div_err;
+ divider = 0x3; /* Divider: 8 */
+ break;
+ case 3840000:
+ if (dmic->fclk_freq != 19200000)
+ goto div_err;
+ divider = 0x1; /* Divider: 5 (96KHz sampling rate) */
+ break;
+ default:
+ dev_err(dmic->dev, "invalid out frequency: %dHz\n",
+ dmic->out_freq);
+ break;
+ }
+
+ return divider;
+
+div_err:
+ dev_err(dmic->dev, "invalid out frequency %dHz for %dHz input\n",
+ dmic->out_freq, dmic->fclk_freq);
+ return -EINVAL;
+}
+
+static int omap_dmic_dai_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params,
+ struct snd_soc_dai *dai)
+{
+ struct omap_dmic *dmic = snd_soc_dai_get_drvdata(dai);
+ int channels;
+
+ dmic->clk_div = omap_dmic_select_divider(dmic, params_rate(params));
+ if (dmic->clk_div < 0) {
+ dev_err(dmic->dev, "no valid divider for %dHz from %dHz\n",
+ dmic->out_freq, dmic->fclk_freq);
+ return -EINVAL;
+ }
+
+ dmic->ch_enabled = 0;
+ channels = params_channels(params);
+ switch (channels) {
+ case 6:
+ dmic->ch_enabled |= OMAP_DMIC_UP3_ENABLE;
+ case 4:
+ dmic->ch_enabled |= OMAP_DMIC_UP2_ENABLE;
+ case 2:
+ dmic->ch_enabled |= OMAP_DMIC_UP1_ENABLE;
+ break;
+ default:
+ dev_err(dmic->dev, "invalid number of legacy channels\n");
+ return -EINVAL;
+ }
+
+ /* packet size is threshold * channels */
+ omap_dmic_dai_dma_params.packet_size = dmic->threshold * channels;
+ snd_soc_dai_set_dma_data(dai, substream, &omap_dmic_dai_dma_params);
+
+ return 0;
+}
+
+static int omap_dmic_dai_prepare(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ struct omap_dmic *dmic = snd_soc_dai_get_drvdata(dai);
+ u32 ctrl;
+
+ /* Configure uplink threshold */
+ omap_dmic_write(dmic, OMAP_DMIC_FIFO_CTRL_REG, dmic->threshold);
+
+ ctrl = omap_dmic_read(dmic, OMAP_DMIC_CTRL_REG);
+
+ /* Set dmic out format */
+ ctrl &= ~(OMAP_DMIC_FORMAT | OMAP_DMIC_POLAR_MASK);
+ ctrl |= (OMAP_DMICOUTFORMAT_LJUST | OMAP_DMIC_POLAR1 |
+ OMAP_DMIC_POLAR2 | OMAP_DMIC_POLAR3);
+
+ /* Configure dmic clock divider */
+ ctrl &= ~OMAP_DMIC_CLK_DIV_MASK;
+ ctrl |= OMAP_DMIC_CLK_DIV(dmic->clk_div);
+
+ omap_dmic_write(dmic, OMAP_DMIC_CTRL_REG, ctrl);
+
+ omap_dmic_write(dmic, OMAP_DMIC_CTRL_REG,
+ ctrl | OMAP_DMICOUTFORMAT_LJUST | OMAP_DMIC_POLAR1 |
+ OMAP_DMIC_POLAR2 | OMAP_DMIC_POLAR3);
+
+ return 0;
+}
+
+static int omap_dmic_dai_trigger(struct snd_pcm_substream *substream,
+ int cmd, struct snd_soc_dai *dai)
+{
+ struct omap_dmic *dmic = snd_soc_dai_get_drvdata(dai);
+
+ switch (cmd) {
+ case SNDRV_PCM_TRIGGER_START:
+ omap_dmic_start(dmic);
+ break;
+ case SNDRV_PCM_TRIGGER_STOP:
+ omap_dmic_stop(dmic);
+ break;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+static int omap_dmic_select_fclk(struct omap_dmic *dmic, int clk_id,
+ unsigned int freq)
+{
+ struct clk *parent_clk;
+ char *parent_clk_name;
+ int ret = 0;
+
+ switch (freq) {
+ case 12000000:
+ case 19200000:
+ case 24000000:
+ case 24576000:
+ break;
+ default:
+ dev_err(dmic->dev, "invalid input frequency: %dHz\n", freq);
+ dmic->fclk_freq = 0;
+ return -EINVAL;
+ }
+
+ if (dmic->sysclk == clk_id) {
+ dmic->fclk_freq = freq;
+ return 0;
+ }
+
+ /* re-parent not allowed if a stream is ongoing */
+ if (dmic->active && dmic_is_enabled(dmic)) {
+ dev_err(dmic->dev, "can't re-parent when DMIC active\n");
+ return -EBUSY;
+ }
+
+ switch (clk_id) {
+ case OMAP_DMIC_SYSCLK_PAD_CLKS:
+ parent_clk_name = "pad_clks_ck";
+ break;
+ case OMAP_DMIC_SYSCLK_SLIMBLUS_CLKS:
+ parent_clk_name = "slimbus_clk";
+ break;
+ case OMAP_DMIC_SYSCLK_SYNC_MUX_CLKS:
+ parent_clk_name = "dmic_sync_mux_ck";
+ break;
+ default:
+ dev_err(dmic->dev, "fclk clk_id (%d) not supported\n", clk_id);
+ return -EINVAL;
+ }
+
+ parent_clk = clk_get(dmic->dev, parent_clk_name);
+ if (IS_ERR(parent_clk)) {
+ dev_err(dmic->dev, "can't get %s\n", parent_clk_name);
+ return -ENODEV;
+ }
+
+ mutex_lock(&dmic->mutex);
+ if (dmic->active) {
+ /* disable clock while reparenting */
+ pm_runtime_put_sync(dmic->dev);
+ ret = clk_set_parent(dmic->fclk, parent_clk);
+ pm_runtime_get_sync(dmic->dev);
+ } else {
+ ret = clk_set_parent(dmic->fclk, parent_clk);
+ }
+ mutex_unlock(&dmic->mutex);
+
+ if (ret < 0) {
+ dev_err(dmic->dev, "re-parent failed\n");
+ goto err_busy;
+ }
+
+ dmic->sysclk = clk_id;
+ dmic->fclk_freq = freq;
+
+err_busy:
+ clk_put(parent_clk);
+
+ return ret;
+}
+
+static int omap_dmic_select_outclk(struct omap_dmic *dmic, int clk_id,
+ unsigned int freq)
+{
+ int ret = 0;
+
+ if (clk_id != OMAP_DMIC_ABE_DMIC_CLK) {
+ dev_err(dmic->dev, "output clk_id (%d) not supported\n",
+ clk_id);
+ return -EINVAL;
+ }
+
+ switch (freq) {
+ case 1536000:
+ case 2400000:
+ case 3072000:
+ case 3840000:
+ dmic->out_freq = freq;
+ break;
+ default:
+ dev_err(dmic->dev, "invalid out frequency: %dHz\n", freq);
+ dmic->out_freq = 0;
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+
+static int omap_dmic_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
+ unsigned int freq, int dir)
+{
+ struct omap_dmic *dmic = snd_soc_dai_get_drvdata(dai);
+
+ if (dir == SND_SOC_CLOCK_IN)
+ return omap_dmic_select_fclk(dmic, clk_id, freq);
+ else if (dir == SND_SOC_CLOCK_OUT)
+ return omap_dmic_select_outclk(dmic, clk_id, freq);
+
+ dev_err(dmic->dev, "invalid clock direction (%d)\n", dir);
+ return -EINVAL;
+}
+
+static const struct snd_soc_dai_ops omap_dmic_dai_ops = {
+ .startup = omap_dmic_dai_startup,
+ .shutdown = omap_dmic_dai_shutdown,
+ .hw_params = omap_dmic_dai_hw_params,
+ .prepare = omap_dmic_dai_prepare,
+ .trigger = omap_dmic_dai_trigger,
+ .set_sysclk = omap_dmic_set_dai_sysclk,
+};
+
+static int omap_dmic_probe(struct snd_soc_dai *dai)
+{
+ struct omap_dmic *dmic = snd_soc_dai_get_drvdata(dai);
+
+ pm_runtime_enable(dmic->dev);
+
+ /* Disable lines while request is ongoing */
+ pm_runtime_get_sync(dmic->dev);
+ omap_dmic_write(dmic, OMAP_DMIC_CTRL_REG, 0x00);
+ pm_runtime_put_sync(dmic->dev);
+
+ /* Configure DMIC threshold value */
+ dmic->threshold = OMAP_DMIC_THRES_MAX - 3;
+ return 0;
+}
+
+static int omap_dmic_remove(struct snd_soc_dai *dai)
+{
+ struct omap_dmic *dmic = snd_soc_dai_get_drvdata(dai);
+
+ pm_runtime_disable(dmic->dev);
+
+ return 0;
+}
+
+static struct snd_soc_dai_driver omap_dmic_dai = {
+ .name = "omap-dmic",
+ .probe = omap_dmic_probe,
+ .remove = omap_dmic_remove,
+ .capture = {
+ .channels_min = 2,
+ .channels_max = 6,
+ .rates = SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000,
+ .formats = SNDRV_PCM_FMTBIT_S32_LE,
+ },
+ .ops = &omap_dmic_dai_ops,
+};
+
+static __devinit int asoc_dmic_probe(struct platform_device *pdev)
+{
+ struct omap_dmic *dmic;
+ struct resource *res;
+ int ret;
+
+ dmic = devm_kzalloc(&pdev->dev, sizeof(struct omap_dmic), GFP_KERNEL);
+ if (!dmic)
+ return -ENOMEM;
+
+ platform_set_drvdata(pdev, dmic);
+ dmic->dev = &pdev->dev;
+ dmic->sysclk = OMAP_DMIC_SYSCLK_SYNC_MUX_CLKS;
+
+ mutex_init(&dmic->mutex);
+
+ dmic->fclk = clk_get(dmic->dev, "dmic_fck");
+ if (IS_ERR(dmic->fclk)) {
+ dev_err(dmic->dev, "cant get dmic_fck\n");
+ return -ENODEV;
+ }
+
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dma");
+ if (!res) {
+ dev_err(dmic->dev, "invalid dma memory resource\n");
+ ret = -ENODEV;
+ goto err_put_clk;
+ }
+ omap_dmic_dai_dma_params.port_addr = res->start + OMAP_DMIC_DATA_REG;
+
+ res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
+ if (!res) {
+ dev_err(dmic->dev, "invalid dma resource\n");
+ ret = -ENODEV;
+ goto err_put_clk;
+ }
+ omap_dmic_dai_dma_params.dma_req = res->start;
+
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mpu");
+ if (!res) {
+ dev_err(dmic->dev, "invalid memory resource\n");
+ ret = -ENODEV;
+ goto err_put_clk;
+ }
+
+ if (!devm_request_mem_region(&pdev->dev, res->start,
+ resource_size(res), pdev->name)) {
+ dev_err(dmic->dev, "memory region already claimed\n");
+ ret = -ENODEV;
+ goto err_put_clk;
+ }
+
+ dmic->io_base = devm_ioremap(&pdev->dev, res->start,
+ resource_size(res));
+ if (!dmic->io_base) {
+ ret = -ENOMEM;
+ goto err_put_clk;
+ }
+
+ ret = snd_soc_register_dai(&pdev->dev, &omap_dmic_dai);
+ if (ret)
+ goto err_put_clk;
+
+ return 0;
+
+err_put_clk:
+ clk_put(dmic->fclk);
+ return ret;
+}
+
+static int __devexit asoc_dmic_remove(struct platform_device *pdev)
+{
+ struct omap_dmic *dmic = platform_get_drvdata(pdev);
+
+ snd_soc_unregister_dai(&pdev->dev);
+ clk_put(dmic->fclk);
+
+ return 0;
+}
+
+static struct platform_driver asoc_dmic_driver = {
+ .driver = {
+ .name = "omap-dmic",
+ .owner = THIS_MODULE,
+ },
+ .probe = asoc_dmic_probe,
+ .remove = __devexit_p(asoc_dmic_remove),
+};
+
+module_platform_driver(asoc_dmic_driver);
+
+MODULE_ALIAS("platform:omap-dmic");
+MODULE_AUTHOR("Peter Ujfalusi <peter.ujfalusi@ti.com>");
+MODULE_DESCRIPTION("OMAP DMIC ASoC Interface");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/omap/omap-dmic.h b/sound/soc/omap/omap-dmic.h
new file mode 100644
index 0000000..231e728
--- /dev/null
+++ b/sound/soc/omap/omap-dmic.h
@@ -0,0 +1,69 @@
+/*
+ * omap-dmic.h -- OMAP Digital Microphone Controller
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef _OMAP_DMIC_H
+#define _OMAP_DMIC_H
+
+#define OMAP_DMIC_REVISION_REG 0x00
+#define OMAP_DMIC_SYSCONFIG_REG 0x10
+#define OMAP_DMIC_IRQSTATUS_RAW_REG 0x24
+#define OMAP_DMIC_IRQSTATUS_REG 0x28
+#define OMAP_DMIC_IRQENABLE_SET_REG 0x2C
+#define OMAP_DMIC_IRQENABLE_CLR_REG 0x30
+#define OMAP_DMIC_IRQWAKE_EN_REG 0x34
+#define OMAP_DMIC_DMAENABLE_SET_REG 0x38
+#define OMAP_DMIC_DMAENABLE_CLR_REG 0x3C
+#define OMAP_DMIC_DMAWAKEEN_REG 0x40
+#define OMAP_DMIC_CTRL_REG 0x44
+#define OMAP_DMIC_DATA_REG 0x48
+#define OMAP_DMIC_FIFO_CTRL_REG 0x4C
+#define OMAP_DMIC_FIFO_DMIC1R_DATA_REG 0x50
+#define OMAP_DMIC_FIFO_DMIC1L_DATA_REG 0x54
+#define OMAP_DMIC_FIFO_DMIC2R_DATA_REG 0x58
+#define OMAP_DMIC_FIFO_DMIC2L_DATA_REG 0x5C
+#define OMAP_DMIC_FIFO_DMIC3R_DATA_REG 0x60
+#define OMAP_DMIC_FIFO_DMIC3L_DATA_REG 0x64
+
+/* IRQSTATUS_RAW, IRQSTATUS, IRQENABLE_SET, IRQENABLE_CLR bit fields */
+#define OMAP_DMIC_IRQ (1 << 0)
+#define OMAP_DMIC_IRQ_FULL (1 << 1)
+#define OMAP_DMIC_IRQ_ALMST_EMPTY (1 << 2)
+#define OMAP_DMIC_IRQ_EMPTY (1 << 3)
+#define OMAP_DMIC_IRQ_MASK 0x07
+
+/* DMIC_DMAENABLE bit fields */
+#define OMAP_DMIC_DMA_ENABLE 0x1
+
+/* DMIC_CTRL bit fields */
+#define OMAP_DMIC_UP1_ENABLE (1 << 0)
+#define OMAP_DMIC_UP2_ENABLE (1 << 1)
+#define OMAP_DMIC_UP3_ENABLE (1 << 2)
+#define OMAP_DMIC_UP_ENABLE_MASK 0x7
+#define OMAP_DMIC_FORMAT (1 << 3)
+#define OMAP_DMIC_POLAR1 (1 << 4)
+#define OMAP_DMIC_POLAR2 (1 << 5)
+#define OMAP_DMIC_POLAR3 (1 << 6)
+#define OMAP_DMIC_POLAR_MASK (0x7 << 4)
+#define OMAP_DMIC_CLK_DIV(x) (((x) & 0x7) << 7)
+#define OMAP_DMIC_CLK_DIV_MASK (0x7 << 7)
+#define OMAP_DMIC_RESET (1 << 10)
+
+#define OMAP_DMICOUTFORMAT_LJUST (0 << 3)
+#define OMAP_DMICOUTFORMAT_RJUST (1 << 3)
+
+/* DMIC_FIFO_CTRL bit fields */
+#define OMAP_DMIC_THRES_MAX 0xF
+
+enum omap_dmic_clk {
+ OMAP_DMIC_SYSCLK_PAD_CLKS, /* PAD_CLKS */
+ OMAP_DMIC_SYSCLK_SLIMBLUS_CLKS, /* SLIMBUS_CLK */
+ OMAP_DMIC_SYSCLK_SYNC_MUX_CLKS, /* DMIC_SYNC_MUX_CLK */
+ OMAP_DMIC_ABE_DMIC_CLK, /* abe_dmic_clk */
+};
+
+#endif
diff --git a/sound/soc/omap/omap-hdmi.c b/sound/soc/omap/omap-hdmi.c
index 36c6eae..38e0def 100644
--- a/sound/soc/omap/omap-hdmi.c
+++ b/sound/soc/omap/omap-hdmi.c
@@ -83,7 +83,7 @@
return err;
}
-static struct snd_soc_dai_ops omap_hdmi_dai_ops = {
+static const struct snd_soc_dai_ops omap_hdmi_dai_ops = {
.startup = omap_hdmi_dai_startup,
.hw_params = omap_hdmi_dai_hw_params,
};
@@ -139,17 +139,7 @@
.remove = __devexit_p(omap_hdmi_remove),
};
-static int __init hdmi_dai_init(void)
-{
- return platform_driver_register(&hdmi_dai_driver);
-}
-module_init(hdmi_dai_init);
-
-static void __exit hdmi_dai_exit(void)
-{
- platform_driver_unregister(&hdmi_dai_driver);
-}
-module_exit(hdmi_dai_exit);
+module_platform_driver(hdmi_dai_driver);
MODULE_AUTHOR("Jorge Candelaria <jorge.candelaria@ti.com>");
MODULE_AUTHOR("Ricardo Neri <ricardo.neri@ti.com>");
diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c
index 4314647..0173719 100644
--- a/sound/soc/omap/omap-mcbsp.c
+++ b/sound/soc/omap/omap-mcbsp.c
@@ -258,7 +258,7 @@
default:
return -EINVAL;
}
- if (cpu_is_omap34xx()) {
+ if (cpu_is_omap34xx() || cpu_is_omap44xx()) {
dma_data->set_threshold = omap_mcbsp_set_threshold;
/* TODO: Currently, MODE_ELEMENT == MODE_FRAME */
if (omap_mcbsp_get_dma_op_mode(bus_id) ==
@@ -599,7 +599,7 @@
return err;
}
-static struct snd_soc_dai_ops mcbsp_dai_ops = {
+static const struct snd_soc_dai_ops mcbsp_dai_ops = {
.startup = omap_mcbsp_dai_startup,
.shutdown = omap_mcbsp_dai_shutdown,
.trigger = omap_mcbsp_dai_trigger,
@@ -785,17 +785,7 @@
.remove = __devexit_p(asoc_mcbsp_remove),
};
-static int __init snd_omap_mcbsp_init(void)
-{
- return platform_driver_register(&asoc_mcbsp_driver);
-}
-module_init(snd_omap_mcbsp_init);
-
-static void __exit snd_omap_mcbsp_exit(void)
-{
- platform_driver_unregister(&asoc_mcbsp_driver);
-}
-module_exit(snd_omap_mcbsp_exit);
+module_platform_driver(asoc_mcbsp_driver);
MODULE_AUTHOR("Jarkko Nikula <jarkko.nikula@bitmer.com>");
MODULE_DESCRIPTION("OMAP I2S SoC Interface");
diff --git a/sound/soc/omap/omap-mcpdm.c b/sound/soc/omap/omap-mcpdm.c
index 41d1706..0e25df4 100644
--- a/sound/soc/omap/omap-mcpdm.c
+++ b/sound/soc/omap/omap-mcpdm.c
@@ -266,8 +266,6 @@
mutex_lock(&mcpdm->mutex);
if (!dai->active) {
- pm_runtime_get_sync(mcpdm->dev);
-
/* Enable watch dog for ES above ES 1.0 to avoid saturation */
if (omap_rev() != OMAP4430_REV_ES1_0) {
u32 ctrl = omap_mcpdm_read(mcpdm, MCPDM_REG_CTRL);
@@ -295,9 +293,6 @@
omap_mcpdm_stop(mcpdm);
omap_mcpdm_close_streams(mcpdm);
}
-
- if (!omap_mcpdm_active(mcpdm))
- pm_runtime_put_sync(mcpdm->dev);
}
mutex_unlock(&mcpdm->mutex);
@@ -367,7 +362,7 @@
return 0;
}
-static struct snd_soc_dai_ops omap_mcpdm_dai_ops = {
+static const struct snd_soc_dai_ops omap_mcpdm_dai_ops = {
.startup = omap_mcpdm_dai_startup,
.shutdown = omap_mcpdm_dai_shutdown,
.hw_params = omap_mcpdm_dai_hw_params,
@@ -520,17 +515,7 @@
.remove = __devexit_p(asoc_mcpdm_remove),
};
-static int __init snd_omap_mcpdm_init(void)
-{
- return platform_driver_register(&asoc_mcpdm_driver);
-}
-module_init(snd_omap_mcpdm_init);
-
-static void __exit snd_omap_mcpdm_exit(void)
-{
- platform_driver_unregister(&asoc_mcpdm_driver);
-}
-module_exit(snd_omap_mcpdm_exit);
+module_platform_driver(asoc_mcpdm_driver);
MODULE_AUTHOR("Misael Lopez Cruz <misael.lopez@ti.com>");
MODULE_DESCRIPTION("OMAP PDM SoC Interface");
diff --git a/sound/soc/omap/omap-pcm.c b/sound/soc/omap/omap-pcm.c
index 6ede7dc..a59bd35 100644
--- a/sound/soc/omap/omap-pcm.c
+++ b/sound/soc/omap/omap-pcm.c
@@ -378,7 +378,6 @@
static int omap_pcm_new(struct snd_soc_pcm_runtime *rtd)
{
struct snd_card *card = rtd->card->snd_card;
- struct snd_soc_dai *dai = rtd->cpu_dai;
struct snd_pcm *pcm = rtd->pcm;
int ret = 0;
@@ -387,14 +386,14 @@
if (!card->dev->coherent_dma_mask)
card->dev->coherent_dma_mask = DMA_BIT_MASK(64);
- if (dai->driver->playback.channels_min) {
+ if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
ret = omap_pcm_preallocate_dma_buffer(pcm,
SNDRV_PCM_STREAM_PLAYBACK);
if (ret)
goto out;
}
- if (dai->driver->capture.channels_min) {
+ if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
ret = omap_pcm_preallocate_dma_buffer(pcm,
SNDRV_PCM_STREAM_CAPTURE);
if (ret)
@@ -433,17 +432,7 @@
.remove = __devexit_p(omap_pcm_remove),
};
-static int __init snd_omap_pcm_init(void)
-{
- return platform_driver_register(&omap_pcm_driver);
-}
-module_init(snd_omap_pcm_init);
-
-static void __exit snd_omap_pcm_exit(void)
-{
- platform_driver_unregister(&omap_pcm_driver);
-}
-module_exit(snd_omap_pcm_exit);
+module_platform_driver(omap_pcm_driver);
MODULE_AUTHOR("Jarkko Nikula <jarkko.nikula@bitmer.com>");
MODULE_DESCRIPTION("OMAP PCM DMA module");
diff --git a/sound/soc/omap/omap3evm.c b/sound/soc/omap/omap3evm.c
index 6857895..071fcb0 100644
--- a/sound/soc/omap/omap3evm.c
+++ b/sound/soc/omap/omap3evm.c
@@ -70,6 +70,7 @@
/* Audio machine driver */
static struct snd_soc_card snd_soc_omap3evm = {
.name = "omap3evm",
+ .owner = THIS_MODULE,
.dai_link = &omap3evm_dai,
.num_links = 1,
};
diff --git a/sound/soc/omap/omap3pandora.c b/sound/soc/omap/omap3pandora.c
index 7605c37..07794bd 100644
--- a/sound/soc/omap/omap3pandora.c
+++ b/sound/soc/omap/omap3pandora.c
@@ -233,6 +233,7 @@
/* SoC card */
static struct snd_soc_card snd_soc_card_omap3pandora = {
.name = "omap3pandora",
+ .owner = THIS_MODULE,
.dai_link = omap3pandora_dai,
.num_links = ARRAY_SIZE(omap3pandora_dai),
};
diff --git a/sound/soc/omap/omap4-hdmi-card.c b/sound/soc/omap/omap4-hdmi-card.c
index 8671261..28d689b 100644
--- a/sound/soc/omap/omap4-hdmi-card.c
+++ b/sound/soc/omap/omap4-hdmi-card.c
@@ -74,6 +74,7 @@
static struct snd_soc_card snd_soc_omap4_hdmi = {
.name = "OMAP4HDMI",
+ .owner = THIS_MODULE,
.dai_link = &omap4_hdmi_dai,
.num_links = 1,
};
@@ -112,17 +113,7 @@
.remove = __devexit_p(omap4_hdmi_remove),
};
-static int __init omap4_hdmi_init(void)
-{
- return platform_driver_register(&omap4_hdmi_driver);
-}
-module_init(omap4_hdmi_init);
-
-static void __exit omap4_hdmi_exit(void)
-{
- platform_driver_unregister(&omap4_hdmi_driver);
-}
-module_exit(omap4_hdmi_exit);
+module_platform_driver(omap4_hdmi_driver);
MODULE_AUTHOR("Ricardo Neri <ricardo.neri@ti.com>");
MODULE_DESCRIPTION("OMAP4 HDMI machine ASoC driver");
diff --git a/sound/soc/omap/osk5912.c b/sound/soc/omap/osk5912.c
index 351ec9d..d859b59 100644
--- a/sound/soc/omap/osk5912.c
+++ b/sound/soc/omap/osk5912.c
@@ -108,6 +108,7 @@
/* Audio machine driver */
static struct snd_soc_card snd_soc_card_osk = {
.name = "OSK5912",
+ .owner = THIS_MODULE,
.dai_link = &osk_dai,
.num_links = 1,
diff --git a/sound/soc/omap/overo.c b/sound/soc/omap/overo.c
index c3550ae..2ee889c 100644
--- a/sound/soc/omap/overo.c
+++ b/sound/soc/omap/overo.c
@@ -72,6 +72,7 @@
/* Audio machine driver */
static struct snd_soc_card snd_soc_card_overo = {
.name = "overo",
+ .owner = THIS_MODULE,
.dai_link = &overo_dai,
.num_links = 1,
};
diff --git a/sound/soc/omap/rx51.c b/sound/soc/omap/rx51.c
index 4cabb74..fada6ef 100644
--- a/sound/soc/omap/rx51.c
+++ b/sound/soc/omap/rx51.c
@@ -365,7 +365,7 @@
},
};
-struct snd_soc_aux_dev rx51_aux_dev[] = {
+static struct snd_soc_aux_dev rx51_aux_dev[] = {
{
.name = "TLV320AIC34b",
.codec_name = "tlv320aic3x-codec.2-0019",
@@ -383,6 +383,7 @@
/* Audio card */
static struct snd_soc_card rx51_sound_card = {
.name = "RX-51",
+ .owner = THIS_MODULE,
.dai_link = rx51_dai,
.num_links = ARRAY_SIZE(rx51_dai),
.aux_dev = rx51_aux_dev,
diff --git a/sound/soc/omap/sdp3430.c b/sound/soc/omap/sdp3430.c
index e8fbf8e..2c85066 100644
--- a/sound/soc/omap/sdp3430.c
+++ b/sound/soc/omap/sdp3430.c
@@ -213,6 +213,7 @@
/* Audio machine driver */
static struct snd_soc_card snd_soc_sdp3430 = {
.name = "SDP3430",
+ .owner = THIS_MODULE,
.dai_link = sdp3430_dai,
.num_links = ARRAY_SIZE(sdp3430_dai),
diff --git a/sound/soc/omap/sdp4430.c b/sound/soc/omap/sdp4430.c
index 03d9fa4..175ba9a 100644
--- a/sound/soc/omap/sdp4430.c
+++ b/sound/soc/omap/sdp4430.c
@@ -33,6 +33,7 @@
#include <plat/hardware.h>
#include <plat/mux.h>
+#include "omap-dmic.h"
#include "omap-mcpdm.h"
#include "omap-pcm.h"
#include "../codecs/twl6040.h"
@@ -67,6 +68,32 @@
.hw_params = sdp4430_hw_params,
};
+static int sdp4430_dmic_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ int ret = 0;
+
+ ret = snd_soc_dai_set_sysclk(cpu_dai, OMAP_DMIC_SYSCLK_PAD_CLKS,
+ 19200000, SND_SOC_CLOCK_IN);
+ if (ret < 0) {
+ printk(KERN_ERR "can't set DMIC cpu system clock\n");
+ return ret;
+ }
+ ret = snd_soc_dai_set_sysclk(cpu_dai, OMAP_DMIC_ABE_DMIC_CLK, 2400000,
+ SND_SOC_CLOCK_OUT);
+ if (ret < 0) {
+ printk(KERN_ERR "can't set DMIC output clock\n");
+ return ret;
+ }
+ return 0;
+}
+
+static struct snd_soc_ops sdp4430_dmic_ops = {
+ .hw_params = sdp4430_dmic_hw_params,
+};
+
/* Headset jack */
static struct snd_soc_jack hs_jack;
@@ -148,23 +175,60 @@
return ret;
}
+static const struct snd_soc_dapm_widget sdp4430_dmic_dapm_widgets[] = {
+ SND_SOC_DAPM_MIC("Digital Mic", NULL),
+};
+
+static const struct snd_soc_dapm_route dmic_audio_map[] = {
+ {"DMic", NULL, "Digital Mic1 Bias"},
+ {"Digital Mic1 Bias", NULL, "Digital Mic"},
+};
+
+static int sdp4430_dmic_init(struct snd_soc_pcm_runtime *rtd)
+{
+ struct snd_soc_codec *codec = rtd->codec;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
+ int ret;
+
+ ret = snd_soc_dapm_new_controls(dapm, sdp4430_dmic_dapm_widgets,
+ ARRAY_SIZE(sdp4430_dmic_dapm_widgets));
+ if (ret)
+ return ret;
+
+ return snd_soc_dapm_add_routes(dapm, dmic_audio_map,
+ ARRAY_SIZE(dmic_audio_map));
+}
+
/* Digital audio interface glue - connects codec <--> CPU */
-static struct snd_soc_dai_link sdp4430_dai = {
- .name = "TWL6040",
- .stream_name = "TWL6040",
- .cpu_dai_name = "omap-mcpdm",
- .codec_dai_name = "twl6040-legacy",
- .platform_name = "omap-pcm-audio",
- .codec_name = "twl6040-codec",
- .init = sdp4430_twl6040_init,
- .ops = &sdp4430_ops,
+static struct snd_soc_dai_link sdp4430_dai[] = {
+ {
+ .name = "TWL6040",
+ .stream_name = "TWL6040",
+ .cpu_dai_name = "omap-mcpdm",
+ .codec_dai_name = "twl6040-legacy",
+ .platform_name = "omap-pcm-audio",
+ .codec_name = "twl6040-codec",
+ .init = sdp4430_twl6040_init,
+ .ops = &sdp4430_ops,
+ },
+ {
+ .name = "DMIC",
+ .stream_name = "DMIC Capture",
+ .cpu_dai_name = "omap-dmic",
+ .codec_dai_name = "dmic-hifi",
+ .platform_name = "omap-pcm-audio",
+ .codec_name = "dmic-codec",
+ .init = sdp4430_dmic_init,
+ .ops = &sdp4430_dmic_ops,
+ },
};
/* Audio machine driver */
static struct snd_soc_card snd_soc_sdp4430 = {
.name = "SDP4430",
- .dai_link = &sdp4430_dai,
- .num_links = 1,
+ .owner = THIS_MODULE,
+ .dai_link = sdp4430_dai,
+ .num_links = ARRAY_SIZE(sdp4430_dai),
.dapm_widgets = sdp4430_twl6040_dapm_widgets,
.num_dapm_widgets = ARRAY_SIZE(sdp4430_twl6040_dapm_widgets),
diff --git a/sound/soc/omap/zoom2.c b/sound/soc/omap/zoom2.c
index 7641a7f..981616d 100644
--- a/sound/soc/omap/zoom2.c
+++ b/sound/soc/omap/zoom2.c
@@ -157,6 +157,7 @@
/* Audio machine driver */
static struct snd_soc_card snd_soc_zoom2 = {
.name = "Zoom2",
+ .owner = THIS_MODULE,
.dai_link = zoom2_dai,
.num_links = ARRAY_SIZE(zoom2_dai),
diff --git a/sound/soc/pxa/corgi.c b/sound/soc/pxa/corgi.c
index b0e2fb7..bc21944 100644
--- a/sound/soc/pxa/corgi.c
+++ b/sound/soc/pxa/corgi.c
@@ -142,18 +142,6 @@
break;
}
- /* set codec DAI configuration */
- ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
- SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
- if (ret < 0)
- return ret;
-
- /* set cpu DAI configuration */
- ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
- SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
- if (ret < 0)
- return ret;
-
/* set the codec system clock for DAC and ADC */
ret = snd_soc_dai_set_sysclk(codec_dai, WM8731_SYSCLK_XTAL, clk,
SND_SOC_CLOCK_IN);
@@ -239,7 +227,7 @@
};
/* Corgi machine audio map (connections to the codec pins) */
-static const struct snd_soc_dapm_route audio_map[] = {
+static const struct snd_soc_dapm_route corgi_audio_map[] = {
/* headset Jack - in = micin, out = LHPOUT*/
{"Headset Jack", NULL, "LHPOUT"},
@@ -281,24 +269,10 @@
{
struct snd_soc_codec *codec = rtd->codec;
struct snd_soc_dapm_context *dapm = &codec->dapm;
- int err;
snd_soc_dapm_nc_pin(dapm, "LLINEIN");
snd_soc_dapm_nc_pin(dapm, "RLINEIN");
- /* Add corgi specific controls */
- err = snd_soc_add_controls(codec, wm8731_corgi_controls,
- ARRAY_SIZE(wm8731_corgi_controls));
- if (err < 0)
- return err;
-
- /* Add corgi specific widgets */
- snd_soc_dapm_new_controls(dapm, wm8731_dapm_widgets,
- ARRAY_SIZE(wm8731_dapm_widgets));
-
- /* Set up corgi specific audio path audio_map */
- snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
-
return 0;
}
@@ -311,48 +285,61 @@
.platform_name = "pxa-pcm-audio",
.codec_name = "wm8731.0-001b",
.init = corgi_wm8731_init,
+ .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
+ SND_SOC_DAIFMT_CBS_CFS,
.ops = &corgi_ops,
};
/* corgi audio machine driver */
-static struct snd_soc_card snd_soc_corgi = {
+static struct snd_soc_card corgi = {
.name = "Corgi",
+ .owner = THIS_MODULE,
.dai_link = &corgi_dai,
.num_links = 1,
+
+ .controls = wm8731_corgi_controls,
+ .num_controls = ARRAY_SIZE(wm8731_corgi_controls),
+ .dapm_widgets = wm8731_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(wm8731_dapm_widgets),
+ .dapm_routes = corgi_audio_map,
+ .num_dapm_routes = ARRAY_SIZE(corgi_audio_map),
};
-static struct platform_device *corgi_snd_device;
-
-static int __init corgi_init(void)
+static int __devinit corgi_probe(struct platform_device *pdev)
{
+ struct snd_soc_card *card = &corgi;
int ret;
- if (!(machine_is_corgi() || machine_is_shepherd() ||
- machine_is_husky()))
- return -ENODEV;
+ card->dev = &pdev->dev;
- corgi_snd_device = platform_device_alloc("soc-audio", -1);
- if (!corgi_snd_device)
- return -ENOMEM;
-
- platform_set_drvdata(corgi_snd_device, &snd_soc_corgi);
- ret = platform_device_add(corgi_snd_device);
-
+ ret = snd_soc_register_card(card);
if (ret)
- platform_device_put(corgi_snd_device);
-
+ dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
+ ret);
return ret;
}
-static void __exit corgi_exit(void)
+static int __devexit corgi_remove(struct platform_device *pdev)
{
- platform_device_unregister(corgi_snd_device);
+ struct snd_soc_card *card = platform_get_drvdata(pdev);
+
+ snd_soc_unregister_card(card);
+ return 0;
}
-module_init(corgi_init);
-module_exit(corgi_exit);
+static struct platform_driver corgi_driver = {
+ .driver = {
+ .name = "corgi-audio",
+ .owner = THIS_MODULE,
+ },
+ .probe = corgi_probe,
+ .remove = __devexit_p(corgi_remove),
+};
+
+module_platform_driver(corgi_driver);
/* Module information */
MODULE_AUTHOR("Richard Purdie");
MODULE_DESCRIPTION("ALSA SoC Corgi");
MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:corgi-audio");
diff --git a/sound/soc/pxa/e740_wm9705.c b/sound/soc/pxa/e740_wm9705.c
index 35ed7eb..7b1bc23 100644
--- a/sound/soc/pxa/e740_wm9705.c
+++ b/sound/soc/pxa/e740_wm9705.c
@@ -133,78 +133,60 @@
static struct snd_soc_card e740 = {
.name = "Toshiba e740",
+ .owner = THIS_MODULE,
.dai_link = e740_dai,
.num_links = ARRAY_SIZE(e740_dai),
};
-static struct platform_device *e740_snd_device;
+static struct gpio e740_audio_gpios[] = {
+ { GPIO_E740_MIC_ON, GPIOF_OUT_INIT_LOW, "Mic amp" },
+ { GPIO_E740_AMP_ON, GPIOF_OUT_INIT_LOW, "Output amp" },
+ { GPIO_E740_WM9705_nAVDD2, GPIOF_OUT_INIT_HIGH, "Audio power" },
+};
-static int __init e740_init(void)
+static int __devinit e740_probe(struct platform_device *pdev)
{
+ struct snd_soc_card *card = &e740;
int ret;
- if (!machine_is_e740())
- return -ENODEV;
-
- ret = gpio_request(GPIO_E740_MIC_ON, "Mic amp");
+ ret = gpio_request_array(e740_audio_gpios,
+ ARRAY_SIZE(e740_audio_gpios));
if (ret)
return ret;
- ret = gpio_request(GPIO_E740_AMP_ON, "Output amp");
- if (ret)
- goto free_mic_amp_gpio;
+ card->dev = &pdev->dev;
- ret = gpio_request(GPIO_E740_WM9705_nAVDD2, "Audio power");
- if (ret)
- goto free_op_amp_gpio;
-
- /* Disable audio */
- ret = gpio_direction_output(GPIO_E740_MIC_ON, 0);
- if (ret)
- goto free_apwr_gpio;
- ret = gpio_direction_output(GPIO_E740_AMP_ON, 0);
- if (ret)
- goto free_apwr_gpio;
- ret = gpio_direction_output(GPIO_E740_WM9705_nAVDD2, 1);
- if (ret)
- goto free_apwr_gpio;
-
- e740_snd_device = platform_device_alloc("soc-audio", -1);
- if (!e740_snd_device) {
- ret = -ENOMEM;
- goto free_apwr_gpio;
+ ret = snd_soc_register_card(card);
+ if (ret) {
+ dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
+ ret);
+ gpio_free_array(e740_audio_gpios, ARRAY_SIZE(e740_audio_gpios));
}
-
- platform_set_drvdata(e740_snd_device, &e740);
- ret = platform_device_add(e740_snd_device);
-
- if (!ret)
- return 0;
-
-/* Fail gracefully */
- platform_device_put(e740_snd_device);
-free_apwr_gpio:
- gpio_free(GPIO_E740_WM9705_nAVDD2);
-free_op_amp_gpio:
- gpio_free(GPIO_E740_AMP_ON);
-free_mic_amp_gpio:
- gpio_free(GPIO_E740_MIC_ON);
-
return ret;
}
-static void __exit e740_exit(void)
+static int __devexit e740_remove(struct platform_device *pdev)
{
- platform_device_unregister(e740_snd_device);
- gpio_free(GPIO_E740_WM9705_nAVDD2);
- gpio_free(GPIO_E740_AMP_ON);
- gpio_free(GPIO_E740_MIC_ON);
+ struct snd_soc_card *card = platform_get_drvdata(pdev);
+
+ gpio_free_array(e740_audio_gpios, ARRAY_SIZE(e740_audio_gpios));
+ snd_soc_unregister_card(card);
+ return 0;
}
-module_init(e740_init);
-module_exit(e740_exit);
+static struct platform_driver e740_driver = {
+ .driver = {
+ .name = "e740-audio",
+ .owner = THIS_MODULE,
+ },
+ .probe = e740_probe,
+ .remove = __devexit_p(e740_remove),
+};
+
+module_platform_driver(e740_driver);
/* Module information */
MODULE_AUTHOR("Ian Molton <spyro@f2s.com>");
MODULE_DESCRIPTION("ALSA SoC driver for e740");
MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:e740-audio");
diff --git a/sound/soc/pxa/e750_wm9705.c b/sound/soc/pxa/e750_wm9705.c
index ce5f0560..47b89d7 100644
--- a/sound/soc/pxa/e750_wm9705.c
+++ b/sound/soc/pxa/e750_wm9705.c
@@ -116,68 +116,59 @@
static struct snd_soc_card e750 = {
.name = "Toshiba e750",
+ .owner = THIS_MODULE,
.dai_link = e750_dai,
.num_links = ARRAY_SIZE(e750_dai),
};
-static struct platform_device *e750_snd_device;
+static struct gpio e750_audio_gpios[] = {
+ { GPIO_E750_HP_AMP_OFF, GPIOF_OUT_INIT_HIGH, "Headphone amp" },
+ { GPIO_E750_SPK_AMP_OFF, GPIOF_OUT_INIT_HIGH, "Speaker amp" },
+};
-static int __init e750_init(void)
+static int __devinit e750_probe(struct platform_device *pdev)
{
+ struct snd_soc_card *card = &e750;
int ret;
- if (!machine_is_e750())
- return -ENODEV;
-
- ret = gpio_request(GPIO_E750_HP_AMP_OFF, "Headphone amp");
+ ret = gpio_request_array(e750_audio_gpios,
+ ARRAY_SIZE(e750_audio_gpios));
if (ret)
return ret;
- ret = gpio_request(GPIO_E750_SPK_AMP_OFF, "Speaker amp");
- if (ret)
- goto free_hp_amp_gpio;
+ card->dev = &pdev->dev;
- ret = gpio_direction_output(GPIO_E750_HP_AMP_OFF, 1);
- if (ret)
- goto free_spk_amp_gpio;
-
- ret = gpio_direction_output(GPIO_E750_SPK_AMP_OFF, 1);
- if (ret)
- goto free_spk_amp_gpio;
-
- e750_snd_device = platform_device_alloc("soc-audio", -1);
- if (!e750_snd_device) {
- ret = -ENOMEM;
- goto free_spk_amp_gpio;
+ ret = snd_soc_register_card(card);
+ if (ret) {
+ dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
+ ret);
+ gpio_free_array(e750_audio_gpios, ARRAY_SIZE(e750_audio_gpios));
}
-
- platform_set_drvdata(e750_snd_device, &e750);
- ret = platform_device_add(e750_snd_device);
-
- if (!ret)
- return 0;
-
-/* Fail gracefully */
- platform_device_put(e750_snd_device);
-free_spk_amp_gpio:
- gpio_free(GPIO_E750_SPK_AMP_OFF);
-free_hp_amp_gpio:
- gpio_free(GPIO_E750_HP_AMP_OFF);
-
return ret;
}
-static void __exit e750_exit(void)
+static int __devexit e750_remove(struct platform_device *pdev)
{
- platform_device_unregister(e750_snd_device);
- gpio_free(GPIO_E750_SPK_AMP_OFF);
- gpio_free(GPIO_E750_HP_AMP_OFF);
+ struct snd_soc_card *card = platform_get_drvdata(pdev);
+
+ gpio_free_array(e750_audio_gpios, ARRAY_SIZE(e750_audio_gpios));
+ snd_soc_unregister_card(card);
+ return 0;
}
-module_init(e750_init);
-module_exit(e750_exit);
+static struct platform_driver e750_driver = {
+ .driver = {
+ .name = "e750-audio",
+ .owner = THIS_MODULE,
+ },
+ .probe = e750_probe,
+ .remove = __devexit_p(e750_remove),
+};
+
+module_platform_driver(e750_driver);
/* Module information */
MODULE_AUTHOR("Ian Molton <spyro@f2s.com>");
MODULE_DESCRIPTION("ALSA SoC driver for e750");
MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:e750-audio");
diff --git a/sound/soc/pxa/e800_wm9712.c b/sound/soc/pxa/e800_wm9712.c
index 6a8f38b..ea9707e 100644
--- a/sound/soc/pxa/e800_wm9712.c
+++ b/sound/soc/pxa/e800_wm9712.c
@@ -106,66 +106,59 @@
static struct snd_soc_card e800 = {
.name = "Toshiba e800",
+ .owner = THIS_MODULE,
.dai_link = e800_dai,
.num_links = ARRAY_SIZE(e800_dai),
};
-static struct platform_device *e800_snd_device;
+static struct gpio e800_audio_gpios[] = {
+ { GPIO_E800_SPK_AMP_ON, GPIOF_OUT_INIT_HIGH, "Headphone amp" },
+ { GPIO_E800_HP_AMP_OFF, GPIOF_OUT_INIT_HIGH, "Speaker amp" },
+};
-static int __init e800_init(void)
+static int __devinit e800_probe(struct platform_device *pdev)
{
+ struct snd_soc_card *card = &e800;
int ret;
- if (!machine_is_e800())
- return -ENODEV;
-
- ret = gpio_request(GPIO_E800_HP_AMP_OFF, "Headphone amp");
+ ret = gpio_request_array(e800_audio_gpios,
+ ARRAY_SIZE(e800_audio_gpios));
if (ret)
return ret;
- ret = gpio_request(GPIO_E800_SPK_AMP_ON, "Speaker amp");
- if (ret)
- goto free_hp_amp_gpio;
+ card->dev = &pdev->dev;
- ret = gpio_direction_output(GPIO_E800_HP_AMP_OFF, 1);
- if (ret)
- goto free_spk_amp_gpio;
-
- ret = gpio_direction_output(GPIO_E800_SPK_AMP_ON, 1);
- if (ret)
- goto free_spk_amp_gpio;
-
- e800_snd_device = platform_device_alloc("soc-audio", -1);
- if (!e800_snd_device)
- return -ENOMEM;
-
- platform_set_drvdata(e800_snd_device, &e800);
- ret = platform_device_add(e800_snd_device);
-
- if (!ret)
- return 0;
-
-/* Fail gracefully */
- platform_device_put(e800_snd_device);
-free_spk_amp_gpio:
- gpio_free(GPIO_E800_SPK_AMP_ON);
-free_hp_amp_gpio:
- gpio_free(GPIO_E800_HP_AMP_OFF);
-
+ ret = snd_soc_register_card(card);
+ if (ret) {
+ dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
+ ret);
+ gpio_free_array(e800_audio_gpios, ARRAY_SIZE(e800_audio_gpios));
+ }
return ret;
}
-static void __exit e800_exit(void)
+static int __devexit e800_remove(struct platform_device *pdev)
{
- platform_device_unregister(e800_snd_device);
- gpio_free(GPIO_E800_SPK_AMP_ON);
- gpio_free(GPIO_E800_HP_AMP_OFF);
+ struct snd_soc_card *card = platform_get_drvdata(pdev);
+
+ gpio_free_array(e800_audio_gpios, ARRAY_SIZE(e800_audio_gpios));
+ snd_soc_unregister_card(card);
+ return 0;
}
-module_init(e800_init);
-module_exit(e800_exit);
+static struct platform_driver e800_driver = {
+ .driver = {
+ .name = "e800-audio",
+ .owner = THIS_MODULE,
+ },
+ .probe = e800_probe,
+ .remove = __devexit_p(e800_remove),
+};
+
+module_platform_driver(e800_driver);
/* Module information */
MODULE_AUTHOR("Ian Molton <spyro@f2s.com>");
MODULE_DESCRIPTION("ALSA SoC driver for e800");
MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:e800-audio");
diff --git a/sound/soc/pxa/em-x270.c b/sound/soc/pxa/em-x270.c
index b13a425..64743a0 100644
--- a/sound/soc/pxa/em-x270.c
+++ b/sound/soc/pxa/em-x270.c
@@ -54,6 +54,7 @@
static struct snd_soc_card em_x270 = {
.name = "EM-X270",
+ .owner = THIS_MODULE,
.dai_link = em_x270_dai,
.num_links = ARRAY_SIZE(em_x270_dai),
};
diff --git a/sound/soc/pxa/hx4700.c b/sound/soc/pxa/hx4700.c
index c664e33..2a342c9 100644
--- a/sound/soc/pxa/hx4700.c
+++ b/sound/soc/pxa/hx4700.c
@@ -65,20 +65,6 @@
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
int ret = 0;
- /* set codec DAI configuration */
- ret = snd_soc_dai_set_fmt(codec_dai,
- SND_SOC_DAIFMT_MSB | SND_SOC_DAIFMT_NB_NF |
- SND_SOC_DAIFMT_CBS_CFS);
- if (ret < 0)
- return ret;
-
- /* set cpu DAI configuration */
- ret = snd_soc_dai_set_fmt(cpu_dai,
- SND_SOC_DAIFMT_MSB | SND_SOC_DAIFMT_NB_NF |
- SND_SOC_DAIFMT_CBS_CFS);
- if (ret < 0)
- return ret;
-
/* set the I2S system clock as output */
ret = snd_soc_dai_set_sysclk(cpu_dai, PXA2XX_I2S_SYSCLK, 0,
SND_SOC_CLOCK_OUT);
@@ -175,12 +161,15 @@
.platform_name = "pxa-pcm-audio",
.codec_name = "ak4641.0-0012",
.init = hx4700_ak4641_init,
+ .dai_fmt = SND_SOC_DAIFMT_MSB | SND_SOC_DAIFMT_NB_NF |
+ SND_SOC_DAIFMT_CBS_CFS,
.ops = &hx4700_ops,
};
/* hx4700 audio machine driver */
static struct snd_soc_card snd_soc_card_hx4700 = {
.name = "iPAQ hx4700",
+ .owner = THIS_MODULE,
.dai_link = &hx4700_dai,
.num_links = 1,
.dapm_widgets = hx4700_dapm_widgets,
@@ -237,18 +226,7 @@
.remove = __devexit_p(hx4700_audio_remove),
};
-static int __init hx4700_modinit(void)
-{
- return platform_driver_register(&hx4700_audio_driver);
-}
-module_init(hx4700_modinit);
-
-static void __exit hx4700_modexit(void)
-{
- platform_driver_unregister(&hx4700_audio_driver);
-}
-
-module_exit(hx4700_modexit);
+module_platform_driver(hx4700_audio_driver);
MODULE_AUTHOR("Philipp Zabel");
MODULE_DESCRIPTION("ALSA SoC iPAQ hx4700");
diff --git a/sound/soc/pxa/imote2.c b/sound/soc/pxa/imote2.c
index 154fc6f..b93dafd 100644
--- a/sound/soc/pxa/imote2.c
+++ b/sound/soc/pxa/imote2.c
@@ -30,20 +30,6 @@
break;
}
- /* set codec DAI configuration */
- ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S
- | SND_SOC_DAIFMT_NB_NF
- | SND_SOC_DAIFMT_CBS_CFS);
- if (ret < 0)
- return ret;
-
- /* CPU should be clock master */
- ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S
- | SND_SOC_DAIFMT_NB_NF
- | SND_SOC_DAIFMT_CBS_CFS);
- if (ret < 0)
- return ret;
-
ret = snd_soc_dai_set_sysclk(codec_dai, 0, clk,
SND_SOC_CLOCK_IN);
if (ret < 0)
@@ -67,42 +53,52 @@
.codec_dai_name = "wm8940-hifi",
.platform_name = "pxa-pcm-audio",
.codec_name = "wm8940-codec.0-0034",
+ .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
+ SND_SOC_DAIFMT_CBS_CFS,
.ops = &imote2_asoc_ops,
};
-static struct snd_soc_card snd_soc_imote2 = {
+static struct snd_soc_card imote2 = {
.name = "Imote2",
+ .owner = THIS_MODULE,
.dai_link = &imote2_dai,
.num_links = 1,
};
-static struct platform_device *imote2_snd_device;
-
-static int __init imote2_asoc_init(void)
+static int __devinit imote2_probe(struct platform_device *pdev)
{
+ struct snd_soc_card *card = &imote2;
int ret;
- if (!machine_is_intelmote2())
- return -ENODEV;
- imote2_snd_device = platform_device_alloc("soc-audio", -1);
- if (!imote2_snd_device)
- return -ENOMEM;
+ card->dev = &pdev->dev;
- platform_set_drvdata(imote2_snd_device, &snd_soc_imote2);
- ret = platform_device_add(imote2_snd_device);
+ ret = snd_soc_register_card(card);
if (ret)
- platform_device_put(imote2_snd_device);
-
+ dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
+ ret);
return ret;
}
-module_init(imote2_asoc_init);
-static void __exit imote2_asoc_exit(void)
+static int __devexit imote2_remove(struct platform_device *pdev)
{
- platform_device_unregister(imote2_snd_device);
+ struct snd_soc_card *card = platform_get_drvdata(pdev);
+
+ snd_soc_unregister_card(card);
+ return 0;
}
-module_exit(imote2_asoc_exit);
+
+static struct platform_driver imote2_driver = {
+ .driver = {
+ .name = "imote2-audio",
+ .owner = THIS_MODULE,
+ },
+ .probe = imote2_probe,
+ .remove = __devexit_p(imote2_remove),
+};
+
+module_platform_driver(imote2_driver);
MODULE_AUTHOR("Jonathan Cameron");
MODULE_DESCRIPTION("ALSA SoC Imote 2");
MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:imote2-audio");
diff --git a/sound/soc/pxa/magician.c b/sound/soc/pxa/magician.c
index e79f516..3f7a8ec 100644
--- a/sound/soc/pxa/magician.c
+++ b/sound/soc/pxa/magician.c
@@ -452,6 +452,7 @@
/* magician audio machine driver */
static struct snd_soc_card snd_soc_card_magician = {
.name = "Magician",
+ .owner = THIS_MODULE,
.dai_link = magician_dai,
.num_links = ARRAY_SIZE(magician_dai),
diff --git a/sound/soc/pxa/mioa701_wm9713.c b/sound/soc/pxa/mioa701_wm9713.c
index 0b8d1ee..9c585af 100644
--- a/sound/soc/pxa/mioa701_wm9713.c
+++ b/sound/soc/pxa/mioa701_wm9713.c
@@ -181,6 +181,7 @@
static struct snd_soc_card mioa701 = {
.name = "MioA701",
+ .owner = THIS_MODULE,
.dai_link = mioa701_dai,
.num_links = ARRAY_SIZE(mioa701_dai),
};
@@ -227,18 +228,7 @@
},
};
-static int __init mioa701_asoc_init(void)
-{
- return platform_driver_register(&mioa701_wm9713_driver);
-}
-
-static void __exit mioa701_asoc_exit(void)
-{
- platform_driver_unregister(&mioa701_wm9713_driver);
-}
-
-module_init(mioa701_asoc_init);
-module_exit(mioa701_asoc_exit);
+module_platform_driver(mioa701_wm9713_driver);
/* Module information */
MODULE_AUTHOR("Robert Jarzmik (rjarzmik@free.fr)");
diff --git a/sound/soc/pxa/palm27x.c b/sound/soc/pxa/palm27x.c
index 7edc1fb..db24bc6 100644
--- a/sound/soc/pxa/palm27x.c
+++ b/sound/soc/pxa/palm27x.c
@@ -146,6 +146,7 @@
static struct snd_soc_card palm27x_asoc = {
.name = "Palm/PXA27x",
+ .owner = THIS_MODULE,
.dai_link = palm27x_dai,
.num_links = ARRAY_SIZE(palm27x_dai),
};
@@ -201,18 +202,7 @@
},
};
-static int __init palm27x_asoc_init(void)
-{
- return platform_driver_register(&palm27x_wm9712_driver);
-}
-
-static void __exit palm27x_asoc_exit(void)
-{
- platform_driver_unregister(&palm27x_wm9712_driver);
-}
-
-module_init(palm27x_asoc_init);
-module_exit(palm27x_asoc_exit);
+module_platform_driver(palm27x_wm9712_driver);
/* Module information */
MODULE_AUTHOR("Marek Vasut <marek.vasut@gmail.com>");
diff --git a/sound/soc/pxa/poodle.c b/sound/soc/pxa/poodle.c
index 4c29bc1..fd0ed10 100644
--- a/sound/soc/pxa/poodle.c
+++ b/sound/soc/pxa/poodle.c
@@ -121,18 +121,6 @@
break;
}
- /* set codec DAI configuration */
- ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
- SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
- if (ret < 0)
- return ret;
-
- /* set cpu DAI configuration */
- ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
- SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
- if (ret < 0)
- return ret;
-
/* set the codec system clock for DAC and ADC */
ret = snd_soc_dai_set_sysclk(codec_dai, WM8731_SYSCLK_XTAL, clk,
SND_SOC_CLOCK_IN);
@@ -214,7 +202,7 @@
};
/* Corgi machine connections to the codec pins */
-static const struct snd_soc_dapm_route audio_map[] = {
+static const struct snd_soc_dapm_route poodle_audio_map[] = {
/* headphone connected to LHPOUT1, RHPOUT1 */
{"Headphone Jack", NULL, "LHPOUT"},
@@ -246,25 +234,11 @@
{
struct snd_soc_codec *codec = rtd->codec;
struct snd_soc_dapm_context *dapm = &codec->dapm;
- int err;
snd_soc_dapm_nc_pin(dapm, "LLINEIN");
snd_soc_dapm_nc_pin(dapm, "RLINEIN");
snd_soc_dapm_enable_pin(dapm, "MICIN");
- /* Add poodle specific controls */
- err = snd_soc_add_controls(codec, wm8731_poodle_controls,
- ARRAY_SIZE(wm8731_poodle_controls));
- if (err < 0)
- return err;
-
- /* Add poodle specific widgets */
- snd_soc_dapm_new_controls(dapm, wm8731_dapm_widgets,
- ARRAY_SIZE(wm8731_dapm_widgets));
-
- /* Set up poodle specific audio path audio_map */
- snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
-
return 0;
}
@@ -277,26 +251,31 @@
.platform_name = "pxa-pcm-audio",
.codec_name = "wm8731.0-001b",
.init = poodle_wm8731_init,
+ .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
+ SND_SOC_DAIFMT_CBS_CFS,
.ops = &poodle_ops,
};
/* poodle audio machine driver */
-static struct snd_soc_card snd_soc_poodle = {
+static struct snd_soc_card poodle = {
.name = "Poodle",
.dai_link = &poodle_dai,
.num_links = 1,
.owner = THIS_MODULE,
+
+ .controls = wm8731_poodle_controls,
+ .num_controls = ARRAY_SIZE(wm8731_poodle_controls),
+ .dapm_widgets = wm8731_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(wm8731_dapm_widgets),
+ .dapm_routes = poodle_audio_map,
+ .num_dapm_routes = ARRAY_SIZE(poodle_audio_map),
};
-static struct platform_device *poodle_snd_device;
-
-static int __init poodle_init(void)
+static int __devinit poodle_probe(struct platform_device *pdev)
{
+ struct snd_soc_card *card = &poodle;
int ret;
- if (!machine_is_poodle())
- return -ENODEV;
-
locomo_gpio_set_dir(&poodle_locomo_device.dev,
POODLE_LOCOMO_GPIO_AMP_ON, 0);
/* should we mute HP at startup - burning power ?*/
@@ -305,28 +284,36 @@
locomo_gpio_set_dir(&poodle_locomo_device.dev,
POODLE_LOCOMO_GPIO_MUTE_R, 0);
- poodle_snd_device = platform_device_alloc("soc-audio", -1);
- if (!poodle_snd_device)
- return -ENOMEM;
+ card->dev = &pdev->dev;
- platform_set_drvdata(poodle_snd_device, &snd_soc_poodle);
- ret = platform_device_add(poodle_snd_device);
-
+ ret = snd_soc_register_card(card);
if (ret)
- platform_device_put(poodle_snd_device);
-
+ dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
+ ret);
return ret;
}
-static void __exit poodle_exit(void)
+static int __devexit poodle_remove(struct platform_device *pdev)
{
- platform_device_unregister(poodle_snd_device);
+ struct snd_soc_card *card = platform_get_drvdata(pdev);
+
+ snd_soc_unregister_card(card);
+ return 0;
}
-module_init(poodle_init);
-module_exit(poodle_exit);
+static struct platform_driver poodle_driver = {
+ .driver = {
+ .name = "poodle-audio",
+ .owner = THIS_MODULE,
+ },
+ .probe = poodle_probe,
+ .remove = __devexit_p(poodle_remove),
+};
+
+module_platform_driver(poodle_driver);
/* Module information */
MODULE_AUTHOR("Richard Purdie");
MODULE_DESCRIPTION("ALSA SoC Poodle");
MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:poodle-audio");
diff --git a/sound/soc/pxa/pxa-ssp.c b/sound/soc/pxa/pxa-ssp.c
index 8ad93ee..a57cfbc 100644
--- a/sound/soc/pxa/pxa-ssp.c
+++ b/sound/soc/pxa/pxa-ssp.c
@@ -771,7 +771,7 @@
SNDRV_PCM_FMTBIT_S24_LE | \
SNDRV_PCM_FMTBIT_S32_LE)
-static struct snd_soc_dai_ops pxa_ssp_dai_ops = {
+static const struct snd_soc_dai_ops pxa_ssp_dai_ops = {
.startup = pxa_ssp_startup,
.shutdown = pxa_ssp_shutdown,
.trigger = pxa_ssp_trigger,
@@ -825,17 +825,7 @@
.remove = __devexit_p(asoc_ssp_remove),
};
-static int __init pxa_ssp_init(void)
-{
- return platform_driver_register(&asoc_ssp_driver);
-}
-module_init(pxa_ssp_init);
-
-static void __exit pxa_ssp_exit(void)
-{
- platform_driver_unregister(&asoc_ssp_driver);
-}
-module_exit(pxa_ssp_exit);
+module_platform_driver(asoc_ssp_driver);
/* Module information */
MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
diff --git a/sound/soc/pxa/pxa2xx-ac97.c b/sound/soc/pxa/pxa2xx-ac97.c
index ac51c6d..837ff34 100644
--- a/sound/soc/pxa/pxa2xx-ac97.c
+++ b/sound/soc/pxa/pxa2xx-ac97.c
@@ -163,15 +163,15 @@
SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_44100 | \
SNDRV_PCM_RATE_48000)
-static struct snd_soc_dai_ops pxa_ac97_hifi_dai_ops = {
+static const struct snd_soc_dai_ops pxa_ac97_hifi_dai_ops = {
.hw_params = pxa2xx_ac97_hw_params,
};
-static struct snd_soc_dai_ops pxa_ac97_aux_dai_ops = {
+static const struct snd_soc_dai_ops pxa_ac97_aux_dai_ops = {
.hw_params = pxa2xx_ac97_hw_aux_params,
};
-static struct snd_soc_dai_ops pxa_ac97_mic_dai_ops = {
+static const struct snd_soc_dai_ops pxa_ac97_mic_dai_ops = {
.hw_params = pxa2xx_ac97_hw_mic_params,
};
@@ -263,17 +263,7 @@
},
};
-static int __init pxa_ac97_init(void)
-{
- return platform_driver_register(&pxa2xx_ac97_driver);
-}
-module_init(pxa_ac97_init);
-
-static void __exit pxa_ac97_exit(void)
-{
- platform_driver_unregister(&pxa2xx_ac97_driver);
-}
-module_exit(pxa_ac97_exit);
+module_platform_driver(pxa2xx_ac97_driver);
MODULE_AUTHOR("Nicolas Pitre");
MODULE_DESCRIPTION("AC97 driver for the Intel PXA2xx chip");
diff --git a/sound/soc/pxa/pxa2xx-i2s.c b/sound/soc/pxa/pxa2xx-i2s.c
index 11be595..609abd5 100644
--- a/sound/soc/pxa/pxa2xx-i2s.c
+++ b/sound/soc/pxa/pxa2xx-i2s.c
@@ -331,7 +331,7 @@
SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_44100 | \
SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000)
-static struct snd_soc_dai_ops pxa_i2s_dai_ops = {
+static const struct snd_soc_dai_ops pxa_i2s_dai_ops = {
.startup = pxa2xx_i2s_startup,
.shutdown = pxa2xx_i2s_shutdown,
.trigger = pxa2xx_i2s_trigger,
diff --git a/sound/soc/pxa/pxa2xx-pcm.c b/sound/soc/pxa/pxa2xx-pcm.c
index 600676f..fdd6bed 100644
--- a/sound/soc/pxa/pxa2xx-pcm.c
+++ b/sound/soc/pxa/pxa2xx-pcm.c
@@ -141,17 +141,7 @@
.remove = __devexit_p(pxa2xx_soc_platform_remove),
};
-static int __init snd_pxa_pcm_init(void)
-{
- return platform_driver_register(&pxa_pcm_driver);
-}
-module_init(snd_pxa_pcm_init);
-
-static void __exit snd_pxa_pcm_exit(void)
-{
- platform_driver_unregister(&pxa_pcm_driver);
-}
-module_exit(snd_pxa_pcm_exit);
+module_platform_driver(pxa_pcm_driver);
MODULE_AUTHOR("Nicolas Pitre");
MODULE_DESCRIPTION("Intel PXA2xx PCM DMA module");
diff --git a/sound/soc/pxa/raumfeld.c b/sound/soc/pxa/raumfeld.c
index b899a3b..ba15451 100644
--- a/sound/soc/pxa/raumfeld.c
+++ b/sound/soc/pxa/raumfeld.c
@@ -260,6 +260,7 @@
static struct snd_soc_card snd_soc_raumfeld_connector = {
.name = "Raumfeld Connector",
+ .owner = THIS_MODULE,
.dai_link = snd_soc_raumfeld_connector_dai,
.num_links = ARRAY_SIZE(snd_soc_raumfeld_connector_dai),
.suspend_post = raumfeld_analog_suspend,
@@ -268,6 +269,7 @@
static struct snd_soc_card snd_soc_raumfeld_speaker = {
.name = "Raumfeld Speaker",
+ .owner = THIS_MODULE,
.dai_link = snd_soc_raumfeld_speaker_dai,
.num_links = ARRAY_SIZE(snd_soc_raumfeld_speaker_dai),
.suspend_post = raumfeld_analog_suspend,
diff --git a/sound/soc/pxa/saarb.c b/sound/soc/pxa/saarb.c
index d9467a2..c34146b 100644
--- a/sound/soc/pxa/saarb.c
+++ b/sound/soc/pxa/saarb.c
@@ -51,7 +51,7 @@
};
/* saarb machine audio map */
-static const struct snd_soc_dapm_route audio_map[] = {
+static const struct snd_soc_dapm_route saarb_audio_map[] = {
{"Headset Stereophone", NULL, "HS1"},
{"Headset Stereophone", NULL, "HS2"},
@@ -92,15 +92,6 @@
if (ret < 0)
return ret;
- ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
- SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
- if (ret < 0)
- return ret;
- ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
- SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
- if (ret < 0)
- return ret;
-
ret = snd_soc_dai_set_tdm_slot(cpu_dai, 3, 3, 2, width);
return ret;
@@ -119,25 +110,28 @@
.platform_name = "pxa-pcm-audio",
.codec_name = "88pm860x-codec",
.init = saarb_pm860x_init,
+ .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
+ SND_SOC_DAIFMT_CBM_CFM,
.ops = &saarb_i2s_ops,
},
};
static struct snd_soc_card snd_soc_card_saarb = {
.name = "Saarb",
+ .owner = THIS_MODULE,
.dai_link = saarb_dai,
.num_links = ARRAY_SIZE(saarb_dai),
+
+ .dapm_widgets = saarb_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(saarb_dapm_widgets),
+ .dapm_routes = saarb_audio_map,
+ .num_dapm_routes = ARRAY_SIZE(saarb_audio_map),
};
static int saarb_pm860x_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_codec *codec = rtd->codec;
struct snd_soc_dapm_context *dapm = &codec->dapm;
- int ret;
-
- snd_soc_dapm_new_controls(dapm, saarb_dapm_widgets,
- ARRAY_SIZE(saarb_dapm_widgets));
- snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
/* connected pins */
snd_soc_dapm_enable_pin(dapm, "Ext Speaker");
diff --git a/sound/soc/pxa/spitz.c b/sound/soc/pxa/spitz.c
index c2d6ff9..90c5245 100644
--- a/sound/soc/pxa/spitz.c
+++ b/sound/soc/pxa/spitz.c
@@ -143,18 +143,6 @@
break;
}
- /* set codec DAI configuration */
- ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
- SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
- if (ret < 0)
- return ret;
-
- /* set cpu DAI configuration */
- ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
- SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
- if (ret < 0)
- return ret;
-
/* set the codec system clock for DAC and ADC */
ret = snd_soc_dai_set_sysclk(codec_dai, WM8750_SYSCLK, clk,
SND_SOC_CLOCK_IN);
@@ -234,7 +222,7 @@
};
/* Spitz machine audio_map */
-static const struct snd_soc_dapm_route audio_map[] = {
+static const struct snd_soc_dapm_route spitz_audio_map[] = {
/* headphone connected to LOUT1, ROUT1 */
{"Headphone Jack", NULL, "LOUT1"},
@@ -277,7 +265,6 @@
{
struct snd_soc_codec *codec = rtd->codec;
struct snd_soc_dapm_context *dapm = &codec->dapm;
- int err;
/* NC codec pins */
snd_soc_dapm_nc_pin(dapm, "RINPUT1");
@@ -288,19 +275,6 @@
snd_soc_dapm_nc_pin(dapm, "OUT3");
snd_soc_dapm_nc_pin(dapm, "MONO1");
- /* Add spitz specific controls */
- err = snd_soc_add_controls(codec, wm8750_spitz_controls,
- ARRAY_SIZE(wm8750_spitz_controls));
- if (err < 0)
- return err;
-
- /* Add spitz specific widgets */
- snd_soc_dapm_new_controls(dapm, wm8750_dapm_widgets,
- ARRAY_SIZE(wm8750_dapm_widgets));
-
- /* Set up spitz specific audio paths */
- snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
-
return 0;
}
@@ -313,14 +287,24 @@
.platform_name = "pxa-pcm-audio",
.codec_name = "wm8750.0-001b",
.init = spitz_wm8750_init,
+ .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
+ SND_SOC_DAIFMT_CBS_CFS,
.ops = &spitz_ops,
};
/* spitz audio machine driver */
static struct snd_soc_card snd_soc_spitz = {
.name = "Spitz",
+ .owner = THIS_MODULE,
.dai_link = &spitz_dai,
.num_links = 1,
+
+ .controls = wm8750_spitz_controls,
+ .num_controls = ARRAY_SIZE(wm8750_spitz_controls),
+ .dapm_widgets = wm8750_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(wm8750_dapm_widgets),
+ .dapm_routes = spitz_audio_map,
+ .num_dapm_routes = ARRAY_SIZE(spitz_audio_map),
};
static struct platform_device *spitz_snd_device;
diff --git a/sound/soc/pxa/tavorevb3.c b/sound/soc/pxa/tavorevb3.c
index eeec892..8b5ab8f 100644
--- a/sound/soc/pxa/tavorevb3.c
+++ b/sound/soc/pxa/tavorevb3.c
@@ -51,7 +51,7 @@
};
/* tavorevb3 machine audio map */
-static const struct snd_soc_dapm_route audio_map[] = {
+static const struct snd_soc_dapm_route evb3_audio_map[] = {
{"Headset Stereophone", NULL, "HS1"},
{"Headset Stereophone", NULL, "HS2"},
@@ -92,16 +92,6 @@
if (ret < 0)
return ret;
- ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
- SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
- if (ret < 0)
- return ret;
-
- ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
- SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
- if (ret < 0)
- return ret;
-
ret = snd_soc_dai_set_tdm_slot(cpu_dai, 3, 3, 2, width);
return ret;
}
@@ -119,25 +109,28 @@
.platform_name = "pxa-pcm-audio",
.codec_name = "88pm860x-codec",
.init = evb3_pm860x_init,
+ .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
+ SND_SOC_DAIFMT_CBM_CFM,
.ops = &evb3_i2s_ops,
},
};
static struct snd_soc_card snd_soc_card_evb3 = {
.name = "Tavor EVB3",
+ .owner = THIS_MODULE,
.dai_link = evb3_dai,
.num_links = ARRAY_SIZE(evb3_dai),
+
+ .dapm_widgets = evb3_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(evb3_dapm_widgets),
+ .dapm_routes = evb3_audio_map,
+ .num_dapm_routes = ARRAY_SIZE(evb3_audio_map),
};
static int evb3_pm860x_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_codec *codec = rtd->codec;
struct snd_soc_dapm_context *dapm = &codec->dapm;
- int ret;
-
- snd_soc_dapm_new_controls(dapm, evb3_dapm_widgets,
- ARRAY_SIZE(evb3_dapm_widgets));
- snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
/* connected pins */
snd_soc_dapm_enable_pin(dapm, "Ext Speaker");
diff --git a/sound/soc/pxa/tosa.c b/sound/soc/pxa/tosa.c
index 620fc69..564ef08 100644
--- a/sound/soc/pxa/tosa.c
+++ b/sound/soc/pxa/tosa.c
@@ -34,8 +34,6 @@
#include "../codecs/wm9712.h"
#include "pxa2xx-ac97.h"
-static struct snd_soc_card tosa;
-
#define TOSA_HP 0
#define TOSA_MIC_INT 1
#define TOSA_HEADSET 2
@@ -236,70 +234,56 @@
},
};
-static int tosa_probe(struct snd_soc_card *card)
+static struct snd_soc_card tosa = {
+ .name = "Tosa",
+ .owner = THIS_MODULE,
+ .dai_link = tosa_dai,
+ .num_links = ARRAY_SIZE(tosa_dai),
+};
+
+static int __devinit tosa_probe(struct platform_device *pdev)
{
+ struct snd_soc_card *card = ⤩
int ret;
- ret = gpio_request(TOSA_GPIO_L_MUTE, "Headphone Jack");
+ ret = gpio_request_one(TOSA_GPIO_L_MUTE, GPIOF_OUT_INIT_LOW,
+ "Headphone Jack");
if (ret)
return ret;
- ret = gpio_direction_output(TOSA_GPIO_L_MUTE, 0);
- if (ret)
- gpio_free(TOSA_GPIO_L_MUTE);
+ card->dev = &pdev->dev;
+
+ ret = snd_soc_register_card(card);
+ if (ret) {
+ dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
+ ret);
+ gpio_free(TOSA_GPIO_L_MUTE);
+ }
return ret;
}
-static int tosa_remove(struct snd_soc_card *card)
+static int __devexit tosa_remove(struct platform_device *pdev)
{
+ struct snd_soc_card *card = platform_get_drvdata(pdev);
+
gpio_free(TOSA_GPIO_L_MUTE);
+ snd_soc_unregister_card(card);
return 0;
}
-static struct snd_soc_card tosa = {
- .name = "Tosa",
- .dai_link = tosa_dai,
- .num_links = ARRAY_SIZE(tosa_dai),
- .probe = tosa_probe,
- .remove = tosa_remove,
+static struct platform_driver tosa_driver = {
+ .driver = {
+ .name = "tosa-audio",
+ .owner = THIS_MODULE,
+ },
+ .probe = tosa_probe,
+ .remove = __devexit_p(tosa_remove),
};
-static struct platform_device *tosa_snd_device;
-
-static int __init tosa_init(void)
-{
- int ret;
-
- if (!machine_is_tosa())
- return -ENODEV;
-
- tosa_snd_device = platform_device_alloc("soc-audio", -1);
- if (!tosa_snd_device) {
- ret = -ENOMEM;
- goto err_alloc;
- }
-
- platform_set_drvdata(tosa_snd_device, &tosa);
- ret = platform_device_add(tosa_snd_device);
-
- if (!ret)
- return 0;
-
- platform_device_put(tosa_snd_device);
-
-err_alloc:
- return ret;
-}
-
-static void __exit tosa_exit(void)
-{
- platform_device_unregister(tosa_snd_device);
-}
-
-module_init(tosa_init);
-module_exit(tosa_exit);
+module_platform_driver(tosa_driver);
/* Module information */
MODULE_AUTHOR("Richard Purdie");
MODULE_DESCRIPTION("ALSA SoC Tosa");
MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:tosa-audio");
diff --git a/sound/soc/pxa/z2.c b/sound/soc/pxa/z2.c
index b311ffe..76ccb17 100644
--- a/sound/soc/pxa/z2.c
+++ b/sound/soc/pxa/z2.c
@@ -56,18 +56,6 @@
break;
}
- /* set codec DAI configuration */
- ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
- SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
- if (ret < 0)
- return ret;
-
- /* set cpu DAI configuration */
- ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
- SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
- if (ret < 0)
- return ret;
-
/* set the codec system clock for DAC and ADC */
ret = snd_soc_dai_set_sysclk(codec_dai, WM8750_SYSCLK, clk,
SND_SOC_CLOCK_IN);
@@ -124,7 +112,7 @@
};
/* Z2 machine audio_map */
-static const struct snd_soc_dapm_route audio_map[] = {
+static const struct snd_soc_dapm_route z2_audio_map[] = {
/* headphone connected to LOUT1, ROUT1 */
{"Headphone Jack", NULL, "LOUT1"},
@@ -154,13 +142,6 @@
snd_soc_dapm_disable_pin(dapm, "OUT3");
snd_soc_dapm_disable_pin(dapm, "MONO1");
- /* Add z2 specific widgets */
- snd_soc_dapm_new_controls(dapm, wm8750_dapm_widgets,
- ARRAY_SIZE(wm8750_dapm_widgets));
-
- /* Set up z2 specific audio paths */
- snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
-
/* Jack detection API stuff */
ret = snd_soc_jack_new(codec, "Headset Jack", SND_JACK_HEADSET,
&hs_jack);
@@ -196,14 +177,22 @@
.platform_name = "pxa-pcm-audio",
.codec_name = "wm8750.0-001b",
.init = z2_wm8750_init,
+ .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
+ SND_SOC_DAIFMT_CBS_CFS,
.ops = &z2_ops,
};
/* z2 audio machine driver */
static struct snd_soc_card snd_soc_z2 = {
.name = "Z2",
+ .owner = THIS_MODULE,
.dai_link = &z2_dai,
.num_links = 1,
+
+ .dapm_widgets = wm8750_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(wm8750_dapm_widgets),
+ .dapm_routes = z2_audio_map,
+ .num_dapm_routes = ARRAY_SIZE(z2_audio_map),
};
static struct platform_device *z2_snd_device;
diff --git a/sound/soc/pxa/zylonite.c b/sound/soc/pxa/zylonite.c
index 580aae3..ceb6566 100644
--- a/sound/soc/pxa/zylonite.c
+++ b/sound/soc/pxa/zylonite.c
@@ -249,6 +249,7 @@
static struct snd_soc_card zylonite = {
.name = "Zylonite",
+ .owner = THIS_MODULE,
.probe = &zylonite_probe,
.remove = &zylonite_remove,
.suspend_post = &zylonite_suspend_post,
diff --git a/sound/soc/s6000/s6000-i2s.c b/sound/soc/s6000/s6000-i2s.c
index 3052f64..aaabdba 100644
--- a/sound/soc/s6000/s6000-i2s.c
+++ b/sound/soc/s6000/s6000-i2s.c
@@ -409,7 +409,7 @@
SNDRV_PCM_RATE_8000_192000)
#define S6000_I2S_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE)
-static struct snd_soc_dai_ops s6000_i2s_dai_ops = {
+static const struct snd_soc_dai_ops s6000_i2s_dai_ops = {
.set_fmt = s6000_i2s_set_dai_fmt,
.set_clkdiv = s6000_i2s_set_clkdiv,
.hw_params = s6000_i2s_hw_params,
@@ -604,17 +604,7 @@
},
};
-static int __init s6000_i2s_init(void)
-{
- return platform_driver_register(&s6000_i2s_driver);
-}
-module_init(s6000_i2s_init);
-
-static void __exit s6000_i2s_exit(void)
-{
- platform_driver_unregister(&s6000_i2s_driver);
-}
-module_exit(s6000_i2s_exit);
+module_platform_driver(s6000_i2s_driver);
MODULE_AUTHOR("Daniel Gloeckner");
MODULE_DESCRIPTION("Stretch s6000 family I2S SoC Interface");
diff --git a/sound/soc/s6000/s6000-pcm.c b/sound/soc/s6000/s6000-pcm.c
index 55efc2b..43c014f 100644
--- a/sound/soc/s6000/s6000-pcm.c
+++ b/sound/soc/s6000/s6000-pcm.c
@@ -520,17 +520,7 @@
.remove = __devexit_p(s6000_soc_platform_remove),
};
-static int __init snd_s6000_pcm_init(void)
-{
- return platform_driver_register(&s6000_pcm_driver);
-}
-module_init(snd_s6000_pcm_init);
-
-static void __exit snd_s6000_pcm_exit(void)
-{
- platform_driver_unregister(&s6000_pcm_driver);
-}
-module_exit(snd_s6000_pcm_exit);
+module_platform_driver(s6000_pcm_driver);
MODULE_AUTHOR("Daniel Gloeckner");
MODULE_DESCRIPTION("Stretch s6000 family PCM DMA module");
diff --git a/sound/soc/s6000/s6105-ipcam.c b/sound/soc/s6000/s6105-ipcam.c
index 5890e43..58cfb1e 100644
--- a/sound/soc/s6000/s6105-ipcam.c
+++ b/sound/soc/s6000/s6105-ipcam.c
@@ -187,6 +187,7 @@
/* s6105 audio machine driver */
static struct snd_soc_card snd_soc_card_s6105 = {
.name = "Stretch IP Camera",
+ .owner = THIS_MODULE,
.dai_link = &s6105_dai,
.num_links = 1,
};
diff --git a/sound/soc/samsung/Kconfig b/sound/soc/samsung/Kconfig
index 53aaa69..f3417f2 100644
--- a/sound/soc/samsung/Kconfig
+++ b/sound/soc/samsung/Kconfig
@@ -193,8 +193,22 @@
select SND_SOC_WM9081
select SND_SOC_WM1250_EV1
-config SND_SOC_SPEYSIDE_WM8962
- tristate "Audio support for Wolfson Speyside with WM8962"
+config SND_SOC_TOBERMORY
+ tristate "Audio support for Wolfson Tobermory"
depends on SND_SOC_SAMSUNG && MACH_WLF_CRAGG_6410
select SND_SAMSUNG_I2S
select SND_SOC_WM8962
+
+config SND_SOC_LOWLAND
+ tristate "Audio support for Wolfson Lowland"
+ depends on SND_SOC_SAMSUNG && MACH_WLF_CRAGG_6410
+ select SND_SAMSUNG_I2S
+ select SND_SOC_WM5100
+ select SND_SOC_WM9081
+
+config SND_SOC_LITTLEMILL
+ tristate "Audio support for Wolfson Littlemill"
+ depends on SND_SOC_SAMSUNG && MACH_WLF_CRAGG_6410
+ select SND_SAMSUNG_I2S
+ select MFD_WM8994
+ select SND_SOC_WM8994
diff --git a/sound/soc/samsung/Makefile b/sound/soc/samsung/Makefile
index 8509d3c..9d03beb 100644
--- a/sound/soc/samsung/Makefile
+++ b/sound/soc/samsung/Makefile
@@ -39,7 +39,9 @@
snd-soc-smdk-wm8580pcm-objs := smdk_wm8580pcm.o
snd-soc-smdk-wm8994pcm-objs := smdk_wm8994pcm.o
snd-soc-speyside-objs := speyside.o
-snd-soc-speyside-wm8962-objs := speyside_wm8962.o
+snd-soc-tobermory-objs := tobermory.o
+snd-soc-lowland-objs := lowland.o
+snd-soc-littlemill-objs := littlemill.o
obj-$(CONFIG_SND_SOC_SAMSUNG_JIVE_WM8750) += snd-soc-jive-wm8750.o
obj-$(CONFIG_SND_SOC_SAMSUNG_NEO1973_WM8753) += snd-soc-neo1973-wm8753.o
@@ -60,4 +62,6 @@
obj-$(CONFIG_SND_SOC_SMDK_WM8580_PCM) += snd-soc-smdk-wm8580pcm.o
obj-$(CONFIG_SND_SOC_SMDK_WM8994_PCM) += snd-soc-smdk-wm8994pcm.o
obj-$(CONFIG_SND_SOC_SPEYSIDE) += snd-soc-speyside.o
-obj-$(CONFIG_SND_SOC_SPEYSIDE_WM8962) += snd-soc-speyside-wm8962.o
+obj-$(CONFIG_SND_SOC_TOBERMORY) += snd-soc-tobermory.o
+obj-$(CONFIG_SND_SOC_LOWLAND) += snd-soc-lowland.o
+obj-$(CONFIG_SND_SOC_LITTLEMILL) += snd-soc-littlemill.o
diff --git a/sound/soc/samsung/ac97.c b/sound/soc/samsung/ac97.c
index 16521e3..7b9bf93 100644
--- a/sound/soc/samsung/ac97.c
+++ b/sound/soc/samsung/ac97.c
@@ -329,12 +329,12 @@
return 0;
}
-static struct snd_soc_dai_ops s3c_ac97_dai_ops = {
+static const struct snd_soc_dai_ops s3c_ac97_dai_ops = {
.hw_params = s3c_ac97_hw_params,
.trigger = s3c_ac97_trigger,
};
-static struct snd_soc_dai_ops s3c_ac97_mic_dai_ops = {
+static const struct snd_soc_dai_ops s3c_ac97_mic_dai_ops = {
.hw_params = s3c_ac97_hw_mic_params,
.trigger = s3c_ac97_mic_trigger,
};
@@ -509,17 +509,7 @@
},
};
-static int __init s3c_ac97_init(void)
-{
- return platform_driver_register(&s3c_ac97_driver);
-}
-module_init(s3c_ac97_init);
-
-static void __exit s3c_ac97_exit(void)
-{
- platform_driver_unregister(&s3c_ac97_driver);
-}
-module_exit(s3c_ac97_exit);
+module_platform_driver(s3c_ac97_driver);
MODULE_AUTHOR("Jaswinder Singh, <jassi.brar@samsung.com>");
MODULE_DESCRIPTION("AC97 driver for the Samsung SoC");
diff --git a/sound/soc/samsung/dma.c b/sound/soc/samsung/dma.c
index a68b264..427ae0d 100644
--- a/sound/soc/samsung/dma.c
+++ b/sound/soc/samsung/dma.c
@@ -403,7 +403,6 @@
static int dma_new(struct snd_soc_pcm_runtime *rtd)
{
struct snd_card *card = rtd->card->snd_card;
- struct snd_soc_dai *dai = rtd->cpu_dai;
struct snd_pcm *pcm = rtd->pcm;
int ret = 0;
@@ -414,14 +413,14 @@
if (!card->dev->coherent_dma_mask)
card->dev->coherent_dma_mask = 0xffffffff;
- if (dai->driver->playback.channels_min) {
+ if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
ret = preallocate_dma_buffer(pcm,
SNDRV_PCM_STREAM_PLAYBACK);
if (ret)
goto out;
}
- if (dai->driver->capture.channels_min) {
+ if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
ret = preallocate_dma_buffer(pcm,
SNDRV_PCM_STREAM_CAPTURE);
if (ret)
@@ -458,17 +457,7 @@
.remove = __devexit_p(samsung_asoc_platform_remove),
};
-static int __init samsung_asoc_init(void)
-{
- return platform_driver_register(&asoc_dma_driver);
-}
-module_init(samsung_asoc_init);
-
-static void __exit samsung_asoc_exit(void)
-{
- platform_driver_unregister(&asoc_dma_driver);
-}
-module_exit(samsung_asoc_exit);
+module_platform_driver(asoc_dma_driver);
MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>");
MODULE_DESCRIPTION("Samsung ASoC DMA Driver");
diff --git a/sound/soc/samsung/goni_wm8994.c b/sound/soc/samsung/goni_wm8994.c
index 84f9c3c..c23c2ae 100644
--- a/sound/soc/samsung/goni_wm8994.c
+++ b/sound/soc/samsung/goni_wm8994.c
@@ -244,6 +244,7 @@
static struct snd_soc_card goni = {
.name = "goni",
+ .owner = THIS_MODULE,
.dai_link = goni_dai,
.num_links = ARRAY_SIZE(goni_dai),
diff --git a/sound/soc/samsung/h1940_uda1380.c b/sound/soc/samsung/h1940_uda1380.c
index 03cfa5f..6e32577 100644
--- a/sound/soc/samsung/h1940_uda1380.c
+++ b/sound/soc/samsung/h1940_uda1380.c
@@ -215,6 +215,7 @@
static struct snd_soc_card h1940_asoc = {
.name = "h1940",
+ .owner = THIS_MODULE,
.dai_link = h1940_uda1380_dai,
.num_links = ARRAY_SIZE(h1940_uda1380_dai),
diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c
index bff42bf..87a874d 100644
--- a/sound/soc/samsung/i2s.c
+++ b/sound/soc/samsung/i2s.c
@@ -15,6 +15,7 @@
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/module.h>
+#include <linux/pm_runtime.h>
#include <sound/soc.h>
#include <sound/pcm_params.h>
@@ -881,7 +882,7 @@
writel(CON_RSTCLR, i2s->addr + I2SCON);
if (i2s->quirks & QUIRK_SEC_DAI)
- idma_reg_addr_init((void *)i2s->addr,
+ idma_reg_addr_init(i2s->addr,
i2s->sec_dai->idma_playback.dma_addr);
probe_exit:
@@ -923,7 +924,7 @@
return 0;
}
-static struct snd_soc_dai_ops samsung_i2s_dai_ops = {
+static const struct snd_soc_dai_ops samsung_i2s_dai_ops = {
.trigger = i2s_trigger,
.hw_params = i2s_hw_params,
.set_fmt = i2s_set_fmt,
@@ -945,7 +946,7 @@
{
struct i2s_dai *i2s;
- i2s = kzalloc(sizeof(struct i2s_dai), GFP_KERNEL);
+ i2s = devm_kzalloc(&pdev->dev, sizeof(struct i2s_dai), GFP_KERNEL);
if (i2s == NULL)
return NULL;
@@ -972,10 +973,8 @@
i2s->pdev = platform_device_register_resndata(NULL,
pdev->name, pdev->id + SAMSUNG_I2S_SECOFF,
NULL, 0, NULL, 0);
- if (IS_ERR(i2s->pdev)) {
- kfree(i2s);
+ if (IS_ERR(i2s->pdev))
return NULL;
- }
}
/* Pre-assign snd_soc_dai_set_drvdata */
@@ -1048,7 +1047,7 @@
if (!pri_dai) {
dev_err(&pdev->dev, "Unable to alloc I2S_pri\n");
ret = -ENOMEM;
- goto err1;
+ goto err;
}
pri_dai->dma_playback.dma_addr = regs_base + I2STXD;
@@ -1073,7 +1072,7 @@
if (!sec_dai) {
dev_err(&pdev->dev, "Unable to alloc I2S_sec\n");
ret = -ENOMEM;
- goto err2;
+ goto err;
}
sec_dai->dma_playback.dma_addr = regs_base + I2STXDS;
sec_dai->dma_playback.client =
@@ -1092,17 +1091,15 @@
if (i2s_pdata->cfg_gpio && i2s_pdata->cfg_gpio(pdev)) {
dev_err(&pdev->dev, "Unable to configure gpio\n");
ret = -EINVAL;
- goto err3;
+ goto err;
}
snd_soc_register_dai(&pri_dai->pdev->dev, &pri_dai->i2s_dai_drv);
+ pm_runtime_enable(&pdev->dev);
+
return 0;
-err3:
- kfree(sec_dai);
-err2:
- kfree(pri_dai);
-err1:
+err:
release_mem_region(regs_base, resource_size(res));
return ret;
@@ -1111,6 +1108,7 @@
static __devexit int samsung_i2s_remove(struct platform_device *pdev)
{
struct i2s_dai *i2s, *other;
+ struct resource *res;
i2s = dev_get_drvdata(&pdev->dev);
other = i2s->pri_dai ? : i2s->sec_dai;
@@ -1119,7 +1117,7 @@
other->pri_dai = NULL;
other->sec_dai = NULL;
} else {
- struct resource *res;
+ pm_runtime_disable(&pdev->dev);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (res)
release_mem_region(res->start, resource_size(res));
@@ -1128,8 +1126,6 @@
i2s->pri_dai = NULL;
i2s->sec_dai = NULL;
- kfree(i2s);
-
snd_soc_unregister_dai(&pdev->dev);
return 0;
@@ -1144,17 +1140,7 @@
},
};
-static int __init samsung_i2s_init(void)
-{
- return platform_driver_register(&samsung_i2s_driver);
-}
-module_init(samsung_i2s_init);
-
-static void __exit samsung_i2s_exit(void)
-{
- platform_driver_unregister(&samsung_i2s_driver);
-}
-module_exit(samsung_i2s_exit);
+module_platform_driver(samsung_i2s_driver);
/* Module information */
MODULE_AUTHOR("Jaswinder Singh, <jassi.brar@samsung.com>");
diff --git a/sound/soc/samsung/idma.c b/sound/soc/samsung/idma.c
index c41178e..c227c31 100644
--- a/sound/soc/samsung/idma.c
+++ b/sound/soc/samsung/idma.c
@@ -387,7 +387,6 @@
static int idma_new(struct snd_soc_pcm_runtime *rtd)
{
struct snd_card *card = rtd->card->snd_card;
- struct snd_soc_dai *dai = rtd->cpu_dai;
struct snd_pcm *pcm = rtd->pcm;
int ret = 0;
@@ -396,21 +395,22 @@
if (!card->dev->coherent_dma_mask)
card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
- if (dai->driver->playback.channels_min)
+ if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
ret = preallocate_idma_buffer(pcm,
SNDRV_PCM_STREAM_PLAYBACK);
+ }
return ret;
}
-void idma_reg_addr_init(void *regs, dma_addr_t addr)
+void idma_reg_addr_init(void __iomem *regs, dma_addr_t addr)
{
spin_lock_init(&idma.lock);
idma.regs = regs;
idma.lp_tx_addr = addr;
}
-struct snd_soc_platform_driver asoc_idma_platform = {
+static struct snd_soc_platform_driver asoc_idma_platform = {
.ops = &idma_ops,
.pcm_new = idma_new,
.pcm_free = idma_free,
@@ -437,17 +437,7 @@
.remove = __devexit_p(asoc_idma_platform_remove),
};
-static int __init asoc_idma_init(void)
-{
- return platform_driver_register(&asoc_idma_driver);
-}
-module_init(asoc_idma_init);
-
-static void __exit asoc_idma_exit(void)
-{
- platform_driver_unregister(&asoc_idma_driver);
-}
-module_exit(asoc_idma_exit);
+module_platform_driver(asoc_idma_driver);
MODULE_AUTHOR("Jaswinder Singh, <jassisinghbrar@gmail.com>");
MODULE_DESCRIPTION("Samsung ASoC IDMA Driver");
diff --git a/sound/soc/samsung/idma.h b/sound/soc/samsung/idma.h
index 4827321..8644946 100644
--- a/sound/soc/samsung/idma.h
+++ b/sound/soc/samsung/idma.h
@@ -14,7 +14,7 @@
#ifndef __SND_SOC_SAMSUNG_IDMA_H_
#define __SND_SOC_SAMSUNG_IDMA_H_
-extern void idma_reg_addr_init(void *regs, dma_addr_t addr);
+extern void idma_reg_addr_init(void __iomem *regs, dma_addr_t addr);
/* dma_state */
#define LPAM_DMA_STOP 0
diff --git a/sound/soc/samsung/jive_wm8750.c b/sound/soc/samsung/jive_wm8750.c
index 8e523fd..1578663 100644
--- a/sound/soc/samsung/jive_wm8750.c
+++ b/sound/soc/samsung/jive_wm8750.c
@@ -127,6 +127,7 @@
/* jive audio machine driver */
static struct snd_soc_card snd_soc_machine_jive = {
.name = "Jive",
+ .owner = THIS_MODULE,
.dai_link = &jive_dai,
.num_links = 1,
diff --git a/sound/soc/samsung/littlemill.c b/sound/soc/samsung/littlemill.c
new file mode 100644
index 0000000..9dd818b
--- /dev/null
+++ b/sound/soc/samsung/littlemill.c
@@ -0,0 +1,253 @@
+/*
+ * Littlemill audio support
+ *
+ * Copyright 2011 Wolfson Microelectronics
+ *
+ * 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.
+ */
+
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <sound/jack.h>
+#include <linux/gpio.h>
+#include <linux/module.h>
+
+#include "../codecs/wm8994.h"
+
+static int sample_rate = 44100;
+
+static int littlemill_set_bias_level(struct snd_soc_card *card,
+ struct snd_soc_dapm_context *dapm,
+ enum snd_soc_bias_level level)
+{
+ struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai;
+ int ret;
+
+ if (dapm->dev != codec_dai->dev)
+ return 0;
+
+ switch (level) {
+ case SND_SOC_BIAS_PREPARE:
+ /*
+ * If we've not already clocked things via hw_params()
+ * then do so now, otherwise these are noops.
+ */
+ if (dapm->bias_level == SND_SOC_BIAS_STANDBY) {
+ ret = snd_soc_dai_set_pll(codec_dai, WM8994_FLL1,
+ WM8994_FLL_SRC_MCLK2, 32768,
+ sample_rate * 512);
+ if (ret < 0) {
+ pr_err("Failed to start FLL: %d\n", ret);
+ return ret;
+ }
+
+ ret = snd_soc_dai_set_sysclk(codec_dai,
+ WM8994_SYSCLK_FLL1,
+ sample_rate * 512,
+ SND_SOC_CLOCK_IN);
+ if (ret < 0) {
+ pr_err("Failed to set SYSCLK: %d\n", ret);
+ return ret;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+static int littlemill_set_bias_level_post(struct snd_soc_card *card,
+ struct snd_soc_dapm_context *dapm,
+ enum snd_soc_bias_level level)
+{
+ struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai;
+ int ret;
+
+ if (dapm->dev != codec_dai->dev)
+ return 0;
+
+ switch (level) {
+ case SND_SOC_BIAS_STANDBY:
+ ret = snd_soc_dai_set_sysclk(codec_dai, WM8994_SYSCLK_MCLK2,
+ 32768, SND_SOC_CLOCK_IN);
+ if (ret < 0) {
+ pr_err("Failed to switch away from FLL: %d\n", ret);
+ return ret;
+ }
+
+ ret = snd_soc_dai_set_pll(codec_dai, WM8994_FLL1,
+ 0, 0, 0);
+ if (ret < 0) {
+ pr_err("Failed to stop FLL: %d\n", ret);
+ return ret;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ dapm->bias_level = level;
+
+ return 0;
+}
+
+static int littlemill_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *codec_dai = rtd->codec_dai;
+ int ret;
+
+ sample_rate = params_rate(params);
+
+ ret = snd_soc_dai_set_pll(codec_dai, WM8994_FLL1,
+ WM8994_FLL_SRC_MCLK2, 32768,
+ sample_rate * 512);
+ if (ret < 0) {
+ pr_err("Failed to start FLL: %d\n", ret);
+ return ret;
+ }
+
+ ret = snd_soc_dai_set_sysclk(codec_dai,
+ WM8994_SYSCLK_FLL1,
+ sample_rate * 512,
+ SND_SOC_CLOCK_IN);
+ if (ret < 0) {
+ pr_err("Failed to set SYSCLK: %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static struct snd_soc_ops littlemill_ops = {
+ .hw_params = littlemill_hw_params,
+};
+
+static struct snd_soc_dai_link littlemill_dai[] = {
+ {
+ .name = "CPU",
+ .stream_name = "CPU",
+ .cpu_dai_name = "samsung-i2s.0",
+ .codec_dai_name = "wm8994-aif1",
+ .platform_name = "samsung-audio",
+ .codec_name = "wm8994-codec",
+ .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
+ | SND_SOC_DAIFMT_CBM_CFM,
+ .ops = &littlemill_ops,
+ },
+};
+
+static struct snd_soc_dapm_widget widgets[] = {
+ SND_SOC_DAPM_HP("Headphone", NULL),
+
+ SND_SOC_DAPM_MIC("AMIC", NULL),
+ SND_SOC_DAPM_MIC("DMIC", NULL),
+};
+
+static struct snd_soc_dapm_route audio_paths[] = {
+ { "Headphone", NULL, "HPOUT1L" },
+ { "Headphone", NULL, "HPOUT1R" },
+
+ { "AMIC", NULL, "MICBIAS1" }, /* Default for AMICBIAS jumper */
+ { "IN1LN", NULL, "AMIC" },
+
+ { "DMIC", NULL, "MICBIAS2" }, /* Default for DMICBIAS jumper */
+ { "DMIC1DAT", NULL, "DMIC" },
+ { "DMIC2DAT", NULL, "DMIC" },
+};
+
+static struct snd_soc_jack littlemill_headset;
+
+static int littlemill_late_probe(struct snd_soc_card *card)
+{
+ struct snd_soc_codec *codec = card->rtd[0].codec;
+ struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai;
+ int ret;
+
+ ret = snd_soc_dai_set_sysclk(codec_dai, WM8994_SYSCLK_MCLK2,
+ 32768, SND_SOC_CLOCK_IN);
+ if (ret < 0)
+ return ret;
+
+ ret = snd_soc_jack_new(codec, "Headset",
+ SND_JACK_HEADSET | SND_JACK_MECHANICAL |
+ SND_JACK_BTN_0 | SND_JACK_BTN_1 |
+ SND_JACK_BTN_2 | SND_JACK_BTN_3 |
+ SND_JACK_BTN_4 | SND_JACK_BTN_5,
+ &littlemill_headset);
+ if (ret)
+ return ret;
+
+ /* This will check device compatibility itself */
+ wm8958_mic_detect(codec, &littlemill_headset, NULL, NULL);
+
+ return 0;
+}
+
+static struct snd_soc_card littlemill = {
+ .name = "Littlemill",
+ .owner = THIS_MODULE,
+ .dai_link = littlemill_dai,
+ .num_links = ARRAY_SIZE(littlemill_dai),
+
+ .set_bias_level = littlemill_set_bias_level,
+ .set_bias_level_post = littlemill_set_bias_level_post,
+
+ .dapm_widgets = widgets,
+ .num_dapm_widgets = ARRAY_SIZE(widgets),
+ .dapm_routes = audio_paths,
+ .num_dapm_routes = ARRAY_SIZE(audio_paths),
+
+ .late_probe = littlemill_late_probe,
+};
+
+static __devinit int littlemill_probe(struct platform_device *pdev)
+{
+ struct snd_soc_card *card = &littlemill;
+ int ret;
+
+ card->dev = &pdev->dev;
+
+ ret = snd_soc_register_card(card);
+ if (ret) {
+ dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
+ ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int __devexit littlemill_remove(struct platform_device *pdev)
+{
+ struct snd_soc_card *card = platform_get_drvdata(pdev);
+
+ snd_soc_unregister_card(card);
+
+ return 0;
+}
+
+static struct platform_driver littlemill_driver = {
+ .driver = {
+ .name = "littlemill",
+ .owner = THIS_MODULE,
+ .pm = &snd_soc_pm_ops,
+ },
+ .probe = littlemill_probe,
+ .remove = __devexit_p(littlemill_remove),
+};
+
+module_platform_driver(littlemill_driver);
+
+MODULE_DESCRIPTION("Littlemill audio support");
+MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:littlemill");
diff --git a/sound/soc/samsung/ln2440sbc_alc650.c b/sound/soc/samsung/ln2440sbc_alc650.c
index cde38b8..69c4a59 100644
--- a/sound/soc/samsung/ln2440sbc_alc650.c
+++ b/sound/soc/samsung/ln2440sbc_alc650.c
@@ -34,6 +34,7 @@
static struct snd_soc_card ln2440sbc = {
.name = "LN2440SBC",
+ .owner = THIS_MODULE,
.dai_link = ln2440sbc_dai,
.num_links = ARRAY_SIZE(ln2440sbc_dai),
};
diff --git a/sound/soc/samsung/lowland.c b/sound/soc/samsung/lowland.c
new file mode 100644
index 0000000..4adff93
--- /dev/null
+++ b/sound/soc/samsung/lowland.c
@@ -0,0 +1,237 @@
+/*
+ * Lowland audio support
+ *
+ * Copyright 2011 Wolfson Microelectronics
+ *
+ * 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.
+ */
+
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <sound/jack.h>
+#include <linux/gpio.h>
+#include <linux/module.h>
+
+#include "../codecs/wm5100.h"
+#include "../codecs/wm9081.h"
+
+#define MCLK1_RATE (44100 * 512)
+#define CLKOUT_RATE (44100 * 256)
+
+static int lowland_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ struct snd_soc_dai *codec_dai = rtd->codec_dai;
+ int ret;
+
+ ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S
+ | SND_SOC_DAIFMT_NB_NF
+ | SND_SOC_DAIFMT_CBM_CFM);
+ if (ret < 0)
+ return ret;
+
+ ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S
+ | SND_SOC_DAIFMT_NB_NF
+ | SND_SOC_DAIFMT_CBM_CFM);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+static struct snd_soc_ops lowland_ops = {
+ .hw_params = lowland_hw_params,
+};
+
+static struct snd_soc_jack lowland_headset;
+
+/* Headset jack detection DAPM pins */
+static struct snd_soc_jack_pin lowland_headset_pins[] = {
+ {
+ .pin = "Headphone",
+ .mask = SND_JACK_HEADPHONE | SND_JACK_LINEOUT,
+ },
+ {
+ .pin = "Headset Mic",
+ .mask = SND_JACK_MICROPHONE,
+ },
+};
+
+static int lowland_wm5100_init(struct snd_soc_pcm_runtime *rtd)
+{
+ struct snd_soc_codec *codec = rtd->codec;
+ int ret;
+
+ ret = snd_soc_codec_set_sysclk(codec, WM5100_CLK_SYSCLK,
+ WM5100_CLKSRC_MCLK1, MCLK1_RATE,
+ SND_SOC_CLOCK_IN);
+ if (ret < 0) {
+ pr_err("Failed to set SYSCLK clock source: %d\n", ret);
+ return ret;
+ }
+
+ /* Clock OPCLK, used by the other audio components. */
+ ret = snd_soc_codec_set_sysclk(codec, WM5100_CLK_OPCLK, 0,
+ CLKOUT_RATE, 0);
+ if (ret < 0) {
+ pr_err("Failed to set OPCLK rate: %d\n", ret);
+ return ret;
+ }
+
+ ret = snd_soc_jack_new(codec, "Headset",
+ SND_JACK_LINEOUT | SND_JACK_HEADSET |
+ SND_JACK_BTN_0,
+ &lowland_headset);
+ if (ret)
+ return ret;
+
+ ret = snd_soc_jack_add_pins(&lowland_headset,
+ ARRAY_SIZE(lowland_headset_pins),
+ lowland_headset_pins);
+ if (ret)
+ return ret;
+
+ wm5100_detect(codec, &lowland_headset);
+
+ return 0;
+}
+
+static struct snd_soc_dai_link lowland_dai[] = {
+ {
+ .name = "CPU",
+ .stream_name = "CPU",
+ .cpu_dai_name = "samsung-i2s.0",
+ .codec_dai_name = "wm5100-aif1",
+ .platform_name = "samsung-audio",
+ .codec_name = "wm5100.1-001a",
+ .ops = &lowland_ops,
+ .init = lowland_wm5100_init,
+ },
+ {
+ .name = "Baseband",
+ .stream_name = "Baseband",
+ .cpu_dai_name = "wm5100-aif2",
+ .codec_dai_name = "wm1250-ev1",
+ .codec_name = "wm1250-ev1.1-0027",
+ .ops = &lowland_ops,
+ .ignore_suspend = 1,
+ },
+};
+
+static int lowland_wm9081_init(struct snd_soc_dapm_context *dapm)
+{
+ snd_soc_dapm_nc_pin(dapm, "LINEOUT");
+
+ /* At any time the WM9081 is active it will have this clock */
+ return snd_soc_codec_set_sysclk(dapm->codec, WM9081_SYSCLK_MCLK, 0,
+ CLKOUT_RATE, 0);
+}
+
+static struct snd_soc_aux_dev lowland_aux_dev[] = {
+ {
+ .name = "wm9081",
+ .codec_name = "wm9081.1-006c",
+ .init = lowland_wm9081_init,
+ },
+};
+
+static struct snd_soc_codec_conf lowland_codec_conf[] = {
+ {
+ .dev_name = "wm9081.1-006c",
+ .name_prefix = "Sub",
+ },
+};
+
+static const struct snd_kcontrol_new controls[] = {
+ SOC_DAPM_PIN_SWITCH("Main Speaker"),
+ SOC_DAPM_PIN_SWITCH("Main DMIC"),
+ SOC_DAPM_PIN_SWITCH("Main AMIC"),
+ SOC_DAPM_PIN_SWITCH("WM1250 Input"),
+ SOC_DAPM_PIN_SWITCH("WM1250 Output"),
+ SOC_DAPM_PIN_SWITCH("Headphone"),
+};
+
+static struct snd_soc_dapm_widget widgets[] = {
+ SND_SOC_DAPM_HP("Headphone", NULL),
+ SND_SOC_DAPM_MIC("Headset Mic", NULL),
+
+ SND_SOC_DAPM_SPK("Main Speaker", NULL),
+
+ SND_SOC_DAPM_MIC("Main AMIC", NULL),
+ SND_SOC_DAPM_MIC("Main DMIC", NULL),
+};
+
+static struct snd_soc_dapm_route audio_paths[] = {
+ { "Sub IN1", NULL, "HPOUT2L" },
+ { "Sub IN2", NULL, "HPOUT2R" },
+
+ { "Main Speaker", NULL, "Sub SPKN" },
+ { "Main Speaker", NULL, "Sub SPKP" },
+ { "Main Speaker", NULL, "SPKDAT1" },
+};
+
+static struct snd_soc_card lowland = {
+ .name = "Lowland",
+ .owner = THIS_MODULE,
+ .dai_link = lowland_dai,
+ .num_links = ARRAY_SIZE(lowland_dai),
+ .aux_dev = lowland_aux_dev,
+ .num_aux_devs = ARRAY_SIZE(lowland_aux_dev),
+ .codec_conf = lowland_codec_conf,
+ .num_configs = ARRAY_SIZE(lowland_codec_conf),
+
+ .controls = controls,
+ .num_controls = ARRAY_SIZE(controls),
+ .dapm_widgets = widgets,
+ .num_dapm_widgets = ARRAY_SIZE(widgets),
+ .dapm_routes = audio_paths,
+ .num_dapm_routes = ARRAY_SIZE(audio_paths),
+};
+
+static __devinit int lowland_probe(struct platform_device *pdev)
+{
+ struct snd_soc_card *card = &lowland;
+ int ret;
+
+ card->dev = &pdev->dev;
+
+ ret = snd_soc_register_card(card);
+ if (ret) {
+ dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
+ ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int __devexit lowland_remove(struct platform_device *pdev)
+{
+ struct snd_soc_card *card = platform_get_drvdata(pdev);
+
+ snd_soc_unregister_card(card);
+
+ return 0;
+}
+
+static struct platform_driver lowland_driver = {
+ .driver = {
+ .name = "lowland",
+ .owner = THIS_MODULE,
+ .pm = &snd_soc_pm_ops,
+ },
+ .probe = lowland_probe,
+ .remove = __devexit_p(lowland_remove),
+};
+
+module_platform_driver(lowland_driver);
+
+MODULE_DESCRIPTION("Lowland audio support");
+MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:lowland");
diff --git a/sound/soc/samsung/neo1973_wm8753.c b/sound/soc/samsung/neo1973_wm8753.c
index 7207189..7ac0ba2 100644
--- a/sound/soc/samsung/neo1973_wm8753.c
+++ b/sound/soc/samsung/neo1973_wm8753.c
@@ -465,6 +465,7 @@
static struct snd_soc_card neo1973 = {
.name = "neo1973",
+ .owner = THIS_MODULE,
.dai_link = neo1973_dai,
.num_links = ARRAY_SIZE(neo1973_dai),
.aux_dev = neo1973_aux_devs,
diff --git a/sound/soc/samsung/pcm.c b/sound/soc/samsung/pcm.c
index 05a47cf..56780206c 100644
--- a/sound/soc/samsung/pcm.c
+++ b/sound/soc/samsung/pcm.c
@@ -14,6 +14,7 @@
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/module.h>
+#include <linux/pm_runtime.h>
#include <sound/soc.h>
#include <sound/pcm_params.h>
@@ -452,7 +453,7 @@
return 0;
}
-static struct snd_soc_dai_ops s3c_pcm_dai_ops = {
+static const struct snd_soc_dai_ops s3c_pcm_dai_ops = {
.set_sysclk = s3c_pcm_set_sysclk,
.set_clkdiv = s3c_pcm_set_clkdiv,
.trigger = s3c_pcm_trigger,
@@ -478,7 +479,7 @@
.formats = SNDRV_PCM_FMTBIT_S16_LE, \
}
-struct snd_soc_dai_driver s3c_pcm_dai[] = {
+static struct snd_soc_dai_driver s3c_pcm_dai[] = {
[0] = {
.name = "samsung-pcm.0",
S3C_PCM_DAI_DECLARE,
@@ -488,7 +489,6 @@
S3C_PCM_DAI_DECLARE,
},
};
-EXPORT_SYMBOL_GPL(s3c_pcm_dai);
static __devinit int s3c_pcm_dev_probe(struct platform_device *pdev)
{
@@ -570,12 +570,6 @@
}
clk_enable(pcm->pclk);
- ret = snd_soc_register_dai(&pdev->dev, &s3c_pcm_dai[pdev->id]);
- if (ret != 0) {
- dev_err(&pdev->dev, "failed to get pcm_clock\n");
- goto err5;
- }
-
s3c_pcm_stereo_in[pdev->id].dma_addr = mem_res->start
+ S3C_PCM_RXFIFO;
s3c_pcm_stereo_out[pdev->id].dma_addr = mem_res->start
@@ -587,6 +581,14 @@
pcm->dma_capture = &s3c_pcm_stereo_in[pdev->id];
pcm->dma_playback = &s3c_pcm_stereo_out[pdev->id];
+ pm_runtime_enable(&pdev->dev);
+
+ ret = snd_soc_register_dai(&pdev->dev, &s3c_pcm_dai[pdev->id]);
+ if (ret != 0) {
+ dev_err(&pdev->dev, "failed to get register DAI: %d\n", ret);
+ goto err5;
+ }
+
return 0;
err5:
@@ -610,6 +612,8 @@
snd_soc_unregister_dai(&pdev->dev);
+ pm_runtime_disable(&pdev->dev);
+
iounmap(pcm->regs);
mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -632,17 +636,7 @@
},
};
-static int __init s3c_pcm_init(void)
-{
- return platform_driver_register(&s3c_pcm_driver);
-}
-module_init(s3c_pcm_init);
-
-static void __exit s3c_pcm_exit(void)
-{
- platform_driver_unregister(&s3c_pcm_driver);
-}
-module_exit(s3c_pcm_exit);
+module_platform_driver(s3c_pcm_driver);
/* Module information */
MODULE_AUTHOR("Jaswinder Singh, <jassi.brar@samsung.com>");
diff --git a/sound/soc/samsung/rx1950_uda1380.c b/sound/soc/samsung/rx1950_uda1380.c
index 71b4c02..21e1236 100644
--- a/sound/soc/samsung/rx1950_uda1380.c
+++ b/sound/soc/samsung/rx1950_uda1380.c
@@ -114,6 +114,7 @@
static struct snd_soc_card rx1950_asoc = {
.name = "rx1950",
+ .owner = THIS_MODULE,
.dai_link = rx1950_uda1380_dai,
.num_links = ARRAY_SIZE(rx1950_uda1380_dai),
diff --git a/sound/soc/samsung/s3c2412-i2s.c b/sound/soc/samsung/s3c2412-i2s.c
index 7bbec25..7218507 100644
--- a/sound/soc/samsung/s3c2412-i2s.c
+++ b/sound/soc/samsung/s3c2412-i2s.c
@@ -142,7 +142,7 @@
SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \
SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000)
-static struct snd_soc_dai_ops s3c2412_i2s_dai_ops = {
+static const struct snd_soc_dai_ops s3c2412_i2s_dai_ops = {
.hw_params = s3c2412_i2s_hw_params,
};
@@ -184,17 +184,7 @@
},
};
-static int __init s3c2412_i2s_init(void)
-{
- return platform_driver_register(&s3c2412_iis_driver);
-}
-module_init(s3c2412_i2s_init);
-
-static void __exit s3c2412_i2s_exit(void)
-{
- platform_driver_unregister(&s3c2412_iis_driver);
-}
-module_exit(s3c2412_i2s_exit);
+module_platform_driver(s3c2412_iis_driver);
/* Module information */
MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>");
diff --git a/sound/soc/samsung/s3c24xx-i2s.c b/sound/soc/samsung/s3c24xx-i2s.c
index 558c64b..c4aa4d4 100644
--- a/sound/soc/samsung/s3c24xx-i2s.c
+++ b/sound/soc/samsung/s3c24xx-i2s.c
@@ -444,7 +444,7 @@
SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \
SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000)
-static struct snd_soc_dai_ops s3c24xx_i2s_dai_ops = {
+static const struct snd_soc_dai_ops s3c24xx_i2s_dai_ops = {
.trigger = s3c24xx_i2s_trigger,
.hw_params = s3c24xx_i2s_hw_params,
.set_fmt = s3c24xx_i2s_set_fmt,
@@ -489,17 +489,7 @@
},
};
-static int __init s3c24xx_i2s_init(void)
-{
- return platform_driver_register(&s3c24xx_iis_driver);
-}
-module_init(s3c24xx_i2s_init);
-
-static void __exit s3c24xx_i2s_exit(void)
-{
- platform_driver_unregister(&s3c24xx_iis_driver);
-}
-module_exit(s3c24xx_i2s_exit);
+module_platform_driver(s3c24xx_iis_driver);
/* Module information */
MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>");
diff --git a/sound/soc/samsung/s3c24xx_simtec_hermes.c b/sound/soc/samsung/s3c24xx_simtec_hermes.c
index d125e79..7ace6a8 100644
--- a/sound/soc/samsung/s3c24xx_simtec_hermes.c
+++ b/sound/soc/samsung/s3c24xx_simtec_hermes.c
@@ -89,6 +89,7 @@
/* simtec audio machine driver */
static struct snd_soc_card snd_soc_machine_simtec_aic33 = {
.name = "Simtec-Hermes",
+ .owner = THIS_MODULE,
.dai_link = &simtec_dai_aic33,
.num_links = 1,
@@ -114,21 +115,9 @@
.remove = __devexit_p(simtec_audio_remove),
};
+module_platform_driver(simtec_audio_hermes_platdrv);
+
MODULE_ALIAS("platform:s3c24xx-simtec-hermes-snd");
-
-static int __init simtec_hermes_modinit(void)
-{
- return platform_driver_register(&simtec_audio_hermes_platdrv);
-}
-
-static void __exit simtec_hermes_modexit(void)
-{
- platform_driver_unregister(&simtec_audio_hermes_platdrv);
-}
-
-module_init(simtec_hermes_modinit);
-module_exit(simtec_hermes_modexit);
-
MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
MODULE_DESCRIPTION("ALSA SoC Simtec Audio support");
MODULE_LICENSE("GPL");
diff --git a/sound/soc/samsung/s3c24xx_simtec_tlv320aic23.c b/sound/soc/samsung/s3c24xx_simtec_tlv320aic23.c
index 5e4fd46..c42d5f0 100644
--- a/sound/soc/samsung/s3c24xx_simtec_tlv320aic23.c
+++ b/sound/soc/samsung/s3c24xx_simtec_tlv320aic23.c
@@ -78,6 +78,7 @@
/* simtec audio machine driver */
static struct snd_soc_card snd_soc_machine_simtec_aic23 = {
.name = "Simtec",
+ .owner = THIS_MODULE,
.dai_link = &simtec_dai_aic23,
.num_links = 1,
@@ -92,7 +93,7 @@
return simtec_audio_core_probe(pd, &snd_soc_machine_simtec_aic23);
}
-static struct platform_driver simtec_audio_tlv320aic23_platdrv = {
+static struct platform_driver simtec_audio_tlv320aic23_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "s3c24xx-simtec-tlv320aic23",
@@ -102,21 +103,9 @@
.remove = __devexit_p(simtec_audio_remove),
};
+module_platform_driver(simtec_audio_tlv320aic23_driver);
+
MODULE_ALIAS("platform:s3c24xx-simtec-tlv320aic23");
-
-static int __init simtec_tlv320aic23_modinit(void)
-{
- return platform_driver_register(&simtec_audio_tlv320aic23_platdrv);
-}
-
-static void __exit simtec_tlv320aic23_modexit(void)
-{
- platform_driver_unregister(&simtec_audio_tlv320aic23_platdrv);
-}
-
-module_init(simtec_tlv320aic23_modinit);
-module_exit(simtec_tlv320aic23_modexit);
-
MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
MODULE_DESCRIPTION("ALSA SoC Simtec Audio support");
MODULE_LICENSE("GPL");
diff --git a/sound/soc/samsung/s3c24xx_uda134x.c b/sound/soc/samsung/s3c24xx_uda134x.c
index 548c6ac..d731042 100644
--- a/sound/soc/samsung/s3c24xx_uda134x.c
+++ b/sound/soc/samsung/s3c24xx_uda134x.c
@@ -229,6 +229,7 @@
static struct snd_soc_card snd_soc_s3c24xx_uda134x = {
.name = "S3C24XX_UDA134X",
+ .owner = THIS_MODULE,
.dai_link = &s3c24xx_uda134x_dai_link,
.num_links = 1,
};
@@ -343,19 +344,7 @@
},
};
-static int __init s3c24xx_uda134x_init(void)
-{
- return platform_driver_register(&s3c24xx_uda134x_driver);
-}
-
-static void __exit s3c24xx_uda134x_exit(void)
-{
- platform_driver_unregister(&s3c24xx_uda134x_driver);
-}
-
-
-module_init(s3c24xx_uda134x_init);
-module_exit(s3c24xx_uda134x_exit);
+module_platform_driver(s3c24xx_uda134x_driver);
MODULE_AUTHOR("Zoltan Devai, Christian Pellegrin <chripell@evolware.org>");
MODULE_DESCRIPTION("S3C24XX_UDA134X ALSA SoC audio driver");
diff --git a/sound/soc/samsung/smartq_wm8987.c b/sound/soc/samsung/smartq_wm8987.c
index a22fc44..f2dcb42 100644
--- a/sound/soc/samsung/smartq_wm8987.c
+++ b/sound/soc/samsung/smartq_wm8987.c
@@ -198,6 +198,7 @@
static struct snd_soc_card snd_soc_smartq = {
.name = "SmartQ",
+ .owner = THIS_MODULE,
.dai_link = smartq_dai,
.num_links = ARRAY_SIZE(smartq_dai),
diff --git a/sound/soc/samsung/smdk2443_wm9710.c b/sound/soc/samsung/smdk2443_wm9710.c
index 8bd1dc5..720ba29 100644
--- a/sound/soc/samsung/smdk2443_wm9710.c
+++ b/sound/soc/samsung/smdk2443_wm9710.c
@@ -30,6 +30,7 @@
static struct snd_soc_card smdk2443 = {
.name = "SMDK2443",
+ .owner = THIS_MODULE,
.dai_link = smdk2443_dai,
.num_links = ARRAY_SIZE(smdk2443_dai),
};
diff --git a/sound/soc/samsung/smdk_spdif.c b/sound/soc/samsung/smdk_spdif.c
index e0fd8ad..beaa9c1 100644
--- a/sound/soc/samsung/smdk_spdif.c
+++ b/sound/soc/samsung/smdk_spdif.c
@@ -160,6 +160,7 @@
static struct snd_soc_card smdk = {
.name = "SMDK-S/PDIF",
+ .owner = THIS_MODULE,
.dai_link = &smdk_dai,
.num_links = 1,
};
diff --git a/sound/soc/samsung/smdk_wm8580.c b/sound/soc/samsung/smdk_wm8580.c
index 81b4478..bff8758 100644
--- a/sound/soc/samsung/smdk_wm8580.c
+++ b/sound/soc/samsung/smdk_wm8580.c
@@ -203,6 +203,7 @@
static struct snd_soc_card smdk = {
.name = "SMDK-I2S",
+ .owner = THIS_MODULE,
.dai_link = smdk_dai,
.num_links = 2,
diff --git a/sound/soc/samsung/smdk_wm8580pcm.c b/sound/soc/samsung/smdk_wm8580pcm.c
index 0677473..fab5322 100644
--- a/sound/soc/samsung/smdk_wm8580pcm.c
+++ b/sound/soc/samsung/smdk_wm8580pcm.c
@@ -143,6 +143,7 @@
static struct snd_soc_card smdk_pcm = {
.name = "SMDK-PCM",
+ .owner = THIS_MODULE,
.dai_link = smdk_dai,
.num_links = 2,
};
@@ -188,19 +189,7 @@
.remove = __devexit_p(snd_smdk_remove),
};
-static int __init smdk_audio_init(void)
-{
- return platform_driver_register(&snd_smdk_driver);
-}
-
-module_init(smdk_audio_init);
-
-static void __exit smdk_audio_exit(void)
-{
- platform_driver_unregister(&snd_smdk_driver);
-}
-
-module_exit(smdk_audio_exit);
+module_platform_driver(snd_smdk_driver);
MODULE_AUTHOR("Sangbeom Kim, <sbkim73@samsung.com>");
MODULE_DESCRIPTION("ALSA SoC SMDK WM8580 for PCM");
diff --git a/sound/soc/samsung/smdk_wm8994.c b/sound/soc/samsung/smdk_wm8994.c
index ad9ac42..8eb309f 100644
--- a/sound/soc/samsung/smdk_wm8994.c
+++ b/sound/soc/samsung/smdk_wm8994.c
@@ -144,6 +144,7 @@
static struct snd_soc_card smdk = {
.name = "SMDK-I2S",
+ .owner = THIS_MODULE,
.dai_link = smdk_dai,
.num_links = ARRAY_SIZE(smdk_dai),
};
diff --git a/sound/soc/samsung/smdk_wm8994pcm.c b/sound/soc/samsung/smdk_wm8994pcm.c
index da9c2a2..77ecba9 100644
--- a/sound/soc/samsung/smdk_wm8994pcm.c
+++ b/sound/soc/samsung/smdk_wm8994pcm.c
@@ -124,6 +124,7 @@
static struct snd_soc_card smdk_pcm = {
.name = "SMDK-PCM",
+ .owner = THIS_MODULE,
.dai_link = smdk_dai,
.num_links = 1,
};
@@ -158,19 +159,7 @@
.remove = __devexit_p(snd_smdk_remove),
};
-static int __init smdk_audio_init(void)
-{
- return platform_driver_register(&snd_smdk_driver);
-}
-
-module_init(smdk_audio_init);
-
-static void __exit smdk_audio_exit(void)
-{
- platform_driver_unregister(&snd_smdk_driver);
-}
-
-module_exit(smdk_audio_exit);
+module_platform_driver(snd_smdk_driver);
MODULE_AUTHOR("Sangbeom Kim, <sbkim73@samsung.com>");
MODULE_DESCRIPTION("ALSA SoC SMDK WM8994 for PCM");
diff --git a/sound/soc/samsung/smdk_wm9713.c b/sound/soc/samsung/smdk_wm9713.c
index 31c6daf..8e26a73 100644
--- a/sound/soc/samsung/smdk_wm9713.c
+++ b/sound/soc/samsung/smdk_wm9713.c
@@ -50,6 +50,7 @@
static struct snd_soc_card smdk = {
.name = "SMDK WM9713",
+ .owner = THIS_MODULE,
.dai_link = &smdk_dai,
.num_links = 1,
};
diff --git a/sound/soc/samsung/spdif.c b/sound/soc/samsung/spdif.c
index 468cff1..a5a56a1 100644
--- a/sound/soc/samsung/spdif.c
+++ b/sound/soc/samsung/spdif.c
@@ -334,7 +334,7 @@
#define spdif_resume NULL
#endif
-static struct snd_soc_dai_ops spdif_dai_ops = {
+static const struct snd_soc_dai_ops spdif_dai_ops = {
.set_sysclk = spdif_set_sysclk,
.trigger = spdif_trigger,
.hw_params = spdif_hw_params,
@@ -483,17 +483,7 @@
},
};
-static int __init spdif_init(void)
-{
- return platform_driver_register(&samsung_spdif_driver);
-}
-module_init(spdif_init);
-
-static void __exit spdif_exit(void)
-{
- platform_driver_unregister(&samsung_spdif_driver);
-}
-module_exit(spdif_exit);
+module_platform_driver(samsung_spdif_driver);
MODULE_AUTHOR("Seungwhan Youn, <sw.youn@samsung.com>");
MODULE_DESCRIPTION("Samsung S/PDIF Controller Driver");
diff --git a/sound/soc/samsung/speyside.c b/sound/soc/samsung/speyside.c
index 4b8e354..f9ab770 100644
--- a/sound/soc/samsung/speyside.c
+++ b/sound/soc/samsung/speyside.c
@@ -19,6 +19,7 @@
#include "../codecs/wm9081.h"
#define WM8996_HPSEL_GPIO 214
+#define MCLK_AUDIO_RATE (512 * 48000)
static int speyside_set_bias_level(struct snd_soc_card *card,
struct snd_soc_dapm_context *dapm,
@@ -67,7 +68,7 @@
if (card->dapm.bias_level == SND_SOC_BIAS_STANDBY) {
ret = snd_soc_dai_set_pll(codec_dai, 0,
WM8996_FLL_MCLK2,
- 32768, 48000 * 256);
+ 32768, MCLK_AUDIO_RATE);
if (ret < 0) {
pr_err("Failed to start FLL\n");
return ret;
@@ -75,7 +76,7 @@
ret = snd_soc_dai_set_sysclk(codec_dai,
WM8996_SYSCLK_FLL,
- 48000 * 256,
+ MCLK_AUDIO_RATE,
SND_SOC_CLOCK_IN);
if (ret < 0)
return ret;
@@ -222,11 +223,9 @@
static int speyside_wm9081_init(struct snd_soc_dapm_context *dapm)
{
- snd_soc_dapm_nc_pin(dapm, "LINEOUT");
-
/* At any time the WM9081 is active it will have this clock */
return snd_soc_codec_set_sysclk(dapm->codec, WM9081_SYSCLK_MCLK, 0,
- 48000 * 256, 0);
+ MCLK_AUDIO_RATE, 0);
}
static struct snd_soc_aux_dev speyside_aux_dev[] = {
@@ -292,6 +291,7 @@
static struct snd_soc_card speyside = {
.name = "Speyside",
+ .owner = THIS_MODULE,
.dai_link = speyside_dai,
.num_links = ARRAY_SIZE(speyside_dai),
.aux_dev = speyside_aux_dev,
@@ -308,6 +308,7 @@
.num_dapm_widgets = ARRAY_SIZE(widgets),
.dapm_routes = audio_paths,
.num_dapm_routes = ARRAY_SIZE(audio_paths),
+ .fully_routed = true,
.late_probe = speyside_late_probe,
};
@@ -348,17 +349,7 @@
.remove = __devexit_p(speyside_remove),
};
-static int __init speyside_audio_init(void)
-{
- return platform_driver_register(&speyside_driver);
-}
-module_init(speyside_audio_init);
-
-static void __exit speyside_audio_exit(void)
-{
- platform_driver_unregister(&speyside_driver);
-}
-module_exit(speyside_audio_exit);
+module_platform_driver(speyside_driver);
MODULE_DESCRIPTION("Speyside audio support");
MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
diff --git a/sound/soc/samsung/speyside_wm8962.c b/sound/soc/samsung/tobermory.c
similarity index 69%
rename from sound/soc/samsung/speyside_wm8962.c
rename to sound/soc/samsung/tobermory.c
index e3e2716..9199649 100644
--- a/sound/soc/samsung/speyside_wm8962.c
+++ b/sound/soc/samsung/tobermory.c
@@ -1,5 +1,5 @@
/*
- * Speyside with WM8962 audio support
+ * Tobermory audio support
*
* Copyright 2011 Wolfson Microelectronics
*
@@ -19,7 +19,7 @@
static int sample_rate = 44100;
-static int speyside_wm8962_set_bias_level(struct snd_soc_card *card,
+static int tobermory_set_bias_level(struct snd_soc_card *card,
struct snd_soc_dapm_context *dapm,
enum snd_soc_bias_level level)
{
@@ -56,7 +56,7 @@
return 0;
}
-static int speyside_wm8962_set_bias_level_post(struct snd_soc_card *card,
+static int tobermory_set_bias_level_post(struct snd_soc_card *card,
struct snd_soc_dapm_context *dapm,
enum snd_soc_bias_level level)
{
@@ -92,7 +92,7 @@
return 0;
}
-static int speyside_wm8962_hw_params(struct snd_pcm_substream *substream,
+static int tobermory_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
sample_rate = params_rate(params);
@@ -100,11 +100,11 @@
return 0;
}
-static struct snd_soc_ops speyside_wm8962_ops = {
- .hw_params = speyside_wm8962_hw_params,
+static struct snd_soc_ops tobermory_ops = {
+ .hw_params = tobermory_hw_params,
};
-static struct snd_soc_dai_link speyside_wm8962_dai[] = {
+static struct snd_soc_dai_link tobermory_dai[] = {
{
.name = "CPU",
.stream_name = "CPU",
@@ -114,7 +114,7 @@
.codec_name = "wm8962.1-001a",
.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
| SND_SOC_DAIFMT_CBM_CFM,
- .ops = &speyside_wm8962_ops,
+ .ops = &tobermory_ops,
},
};
@@ -152,10 +152,10 @@
{ "DMICDAT", NULL, "DMIC" },
};
-static struct snd_soc_jack speyside_wm8962_headset;
+static struct snd_soc_jack tobermory_headset;
/* Headset jack detection DAPM pins */
-static struct snd_soc_jack_pin speyside_wm8962_headset_pins[] = {
+static struct snd_soc_jack_pin tobermory_headset_pins[] = {
{
.pin = "Headset Mic",
.mask = SND_JACK_MICROPHONE,
@@ -166,7 +166,7 @@
},
};
-static int speyside_wm8962_late_probe(struct snd_soc_card *card)
+static int tobermory_late_probe(struct snd_soc_card *card)
{
struct snd_soc_codec *codec = card->rtd[0].codec;
struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai;
@@ -179,28 +179,29 @@
ret = snd_soc_jack_new(codec, "Headset",
SND_JACK_HEADSET | SND_JACK_BTN_0,
- &speyside_wm8962_headset);
+ &tobermory_headset);
if (ret)
return ret;
- ret = snd_soc_jack_add_pins(&speyside_wm8962_headset,
- ARRAY_SIZE(speyside_wm8962_headset_pins),
- speyside_wm8962_headset_pins);
+ ret = snd_soc_jack_add_pins(&tobermory_headset,
+ ARRAY_SIZE(tobermory_headset_pins),
+ tobermory_headset_pins);
if (ret)
return ret;
- wm8962_mic_detect(codec, &speyside_wm8962_headset);
+ wm8962_mic_detect(codec, &tobermory_headset);
return 0;
}
-static struct snd_soc_card speyside_wm8962 = {
- .name = "Speyside WM8962",
- .dai_link = speyside_wm8962_dai,
- .num_links = ARRAY_SIZE(speyside_wm8962_dai),
+static struct snd_soc_card tobermory = {
+ .name = "Tobermory",
+ .owner = THIS_MODULE,
+ .dai_link = tobermory_dai,
+ .num_links = ARRAY_SIZE(tobermory_dai),
- .set_bias_level = speyside_wm8962_set_bias_level,
- .set_bias_level_post = speyside_wm8962_set_bias_level_post,
+ .set_bias_level = tobermory_set_bias_level,
+ .set_bias_level_post = tobermory_set_bias_level_post,
.controls = controls,
.num_controls = ARRAY_SIZE(controls),
@@ -208,13 +209,14 @@
.num_dapm_widgets = ARRAY_SIZE(widgets),
.dapm_routes = audio_paths,
.num_dapm_routes = ARRAY_SIZE(audio_paths),
+ .fully_routed = true,
- .late_probe = speyside_wm8962_late_probe,
+ .late_probe = tobermory_late_probe,
};
-static __devinit int speyside_wm8962_probe(struct platform_device *pdev)
+static __devinit int tobermory_probe(struct platform_device *pdev)
{
- struct snd_soc_card *card = &speyside_wm8962;
+ struct snd_soc_card *card = &tobermory;
int ret;
card->dev = &pdev->dev;
@@ -229,7 +231,7 @@
return 0;
}
-static int __devexit speyside_wm8962_remove(struct platform_device *pdev)
+static int __devexit tobermory_remove(struct platform_device *pdev)
{
struct snd_soc_card *card = platform_get_drvdata(pdev);
@@ -238,29 +240,19 @@
return 0;
}
-static struct platform_driver speyside_wm8962_driver = {
+static struct platform_driver tobermory_driver = {
.driver = {
- .name = "speyside-wm8962",
+ .name = "tobermory",
.owner = THIS_MODULE,
.pm = &snd_soc_pm_ops,
},
- .probe = speyside_wm8962_probe,
- .remove = __devexit_p(speyside_wm8962_remove),
+ .probe = tobermory_probe,
+ .remove = __devexit_p(tobermory_remove),
};
-static int __init speyside_wm8962_audio_init(void)
-{
- return platform_driver_register(&speyside_wm8962_driver);
-}
-module_init(speyside_wm8962_audio_init);
+module_platform_driver(tobermory_driver);
-static void __exit speyside_wm8962_audio_exit(void)
-{
- platform_driver_unregister(&speyside_wm8962_driver);
-}
-module_exit(speyside_wm8962_audio_exit);
-
-MODULE_DESCRIPTION("Speyside WM8962 audio support");
+MODULE_DESCRIPTION("Tobermory audio support");
MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:speyside-wm8962");
+MODULE_ALIAS("platform:tobermory");
diff --git a/sound/soc/sh/dma-sh7760.c b/sound/soc/sh/dma-sh7760.c
index db74005..7da2018 100644
--- a/sound/soc/sh/dma-sh7760.c
+++ b/sound/soc/sh/dma-sh7760.c
@@ -369,17 +369,7 @@
.remove = __devexit_p(sh7760_soc_platform_remove),
};
-static int __init snd_sh7760_pcm_init(void)
-{
- return platform_driver_register(&sh7760_pcm_driver);
-}
-module_init(snd_sh7760_pcm_init);
-
-static void __exit snd_sh7760_pcm_exit(void)
-{
- platform_driver_unregister(&sh7760_pcm_driver);
-}
-module_exit(snd_sh7760_pcm_exit);
+module_platform_driver(sh7760_pcm_driver);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("SH7760 Audio DMA (DMABRG) driver");
diff --git a/sound/soc/sh/fsi-ak4642.c b/sound/soc/sh/fsi-ak4642.c
index dff64b9..97f540a 100644
--- a/sound/soc/sh/fsi-ak4642.c
+++ b/sound/soc/sh/fsi-ak4642.c
@@ -49,6 +49,7 @@
};
static struct snd_soc_card fsi_soc_card = {
+ .owner = THIS_MODULE,
.dai_link = &fsi_dai_link,
.num_links = 1,
};
@@ -58,27 +59,23 @@
static int fsi_ak4642_probe(struct platform_device *pdev)
{
int ret = -ENOMEM;
- const struct platform_device_id *id_entry;
- struct fsi_ak4642_data *pdata;
+ struct fsi_ak4642_info *pinfo = pdev->dev.platform_data;
- id_entry = pdev->id_entry;
- if (!id_entry) {
- dev_err(&pdev->dev, "unknown fsi ak4642\n");
- return -ENODEV;
+ if (!pinfo) {
+ dev_err(&pdev->dev, "no info for fsi ak4642\n");
+ goto out;
}
- pdata = (struct fsi_ak4642_data *)id_entry->driver_data;
-
- fsi_snd_device = platform_device_alloc("soc-audio", pdata->id);
+ fsi_snd_device = platform_device_alloc("soc-audio", pinfo->id);
if (!fsi_snd_device)
goto out;
- fsi_dai_link.name = pdata->name;
- fsi_dai_link.stream_name = pdata->name;
- fsi_dai_link.cpu_dai_name = pdata->cpu_dai;
- fsi_dai_link.platform_name = pdata->platform;
- fsi_dai_link.codec_name = pdata->codec;
- fsi_soc_card.name = pdata->card;
+ fsi_dai_link.name = pinfo->name;
+ fsi_dai_link.stream_name = pinfo->name;
+ fsi_dai_link.cpu_dai_name = pinfo->cpu_dai;
+ fsi_dai_link.platform_name = pinfo->platform;
+ fsi_dai_link.codec_name = pinfo->codec;
+ fsi_soc_card.name = pinfo->card;
platform_set_drvdata(fsi_snd_device, &fsi_soc_card);
ret = platform_device_add(fsi_snd_device);
@@ -96,114 +93,15 @@
return 0;
}
-static struct fsi_ak4642_data fsi_a_ak4642 = {
- .name = "AK4642",
- .card = "FSIA-AK4642",
- .cpu_dai = "fsia-dai",
- .codec = "ak4642-codec.0-0012",
- .platform = "sh_fsi.0",
- .id = FSI_PORT_A,
-};
-
-static struct fsi_ak4642_data fsi_b_ak4642 = {
- .name = "AK4642",
- .card = "FSIB-AK4642",
- .cpu_dai = "fsib-dai",
- .codec = "ak4642-codec.0-0012",
- .platform = "sh_fsi.0",
- .id = FSI_PORT_B,
-};
-
-static struct fsi_ak4642_data fsi_a_ak4643 = {
- .name = "AK4643",
- .card = "FSIA-AK4643",
- .cpu_dai = "fsia-dai",
- .codec = "ak4642-codec.0-0013",
- .platform = "sh_fsi.0",
- .id = FSI_PORT_A,
-};
-
-static struct fsi_ak4642_data fsi_b_ak4643 = {
- .name = "AK4643",
- .card = "FSIB-AK4643",
- .cpu_dai = "fsib-dai",
- .codec = "ak4642-codec.0-0013",
- .platform = "sh_fsi.0",
- .id = FSI_PORT_B,
-};
-
-static struct fsi_ak4642_data fsi2_a_ak4642 = {
- .name = "AK4642",
- .card = "FSI2A-AK4642",
- .cpu_dai = "fsia-dai",
- .codec = "ak4642-codec.0-0012",
- .platform = "sh_fsi2",
- .id = FSI_PORT_A,
-};
-
-static struct fsi_ak4642_data fsi2_b_ak4642 = {
- .name = "AK4642",
- .card = "FSI2B-AK4642",
- .cpu_dai = "fsib-dai",
- .codec = "ak4642-codec.0-0012",
- .platform = "sh_fsi2",
- .id = FSI_PORT_B,
-};
-
-static struct fsi_ak4642_data fsi2_a_ak4643 = {
- .name = "AK4643",
- .card = "FSI2A-AK4643",
- .cpu_dai = "fsia-dai",
- .codec = "ak4642-codec.0-0013",
- .platform = "sh_fsi2",
- .id = FSI_PORT_A,
-};
-
-static struct fsi_ak4642_data fsi2_b_ak4643 = {
- .name = "AK4643",
- .card = "FSI2B-AK4643",
- .cpu_dai = "fsib-dai",
- .codec = "ak4642-codec.0-0013",
- .platform = "sh_fsi2",
- .id = FSI_PORT_B,
-};
-
-static struct platform_device_id fsi_id_table[] = {
- /* FSI */
- { "sh_fsi_a_ak4642", (kernel_ulong_t)&fsi_a_ak4642 },
- { "sh_fsi_b_ak4642", (kernel_ulong_t)&fsi_b_ak4642 },
- { "sh_fsi_a_ak4643", (kernel_ulong_t)&fsi_a_ak4643 },
- { "sh_fsi_b_ak4643", (kernel_ulong_t)&fsi_b_ak4643 },
-
- /* FSI 2 */
- { "sh_fsi2_a_ak4642", (kernel_ulong_t)&fsi2_a_ak4642 },
- { "sh_fsi2_b_ak4642", (kernel_ulong_t)&fsi2_b_ak4642 },
- { "sh_fsi2_a_ak4643", (kernel_ulong_t)&fsi2_a_ak4643 },
- { "sh_fsi2_b_ak4643", (kernel_ulong_t)&fsi2_b_ak4643 },
- {},
-};
-
static struct platform_driver fsi_ak4642 = {
.driver = {
.name = "fsi-ak4642-audio",
},
.probe = fsi_ak4642_probe,
.remove = fsi_ak4642_remove,
- .id_table = fsi_id_table,
};
-static int __init fsi_ak4642_init(void)
-{
- return platform_driver_register(&fsi_ak4642);
-}
-
-static void __exit fsi_ak4642_exit(void)
-{
- platform_driver_unregister(&fsi_ak4642);
-}
-
-module_init(fsi_ak4642_init);
-module_exit(fsi_ak4642_exit);
+module_platform_driver(fsi_ak4642);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Generic SH4 FSI-AK4642 sound card");
diff --git a/sound/soc/sh/fsi-da7210.c b/sound/soc/sh/fsi-da7210.c
index f5586b5b..1dd3354 100644
--- a/sound/soc/sh/fsi-da7210.c
+++ b/sound/soc/sh/fsi-da7210.c
@@ -44,6 +44,7 @@
static struct snd_soc_card fsi_soc_card = {
.name = "FSI-DA7210",
+ .owner = THIS_MODULE,
.dai_link = &fsi_da7210_dai,
.num_links = 1,
};
diff --git a/sound/soc/sh/fsi-hdmi.c b/sound/soc/sh/fsi-hdmi.c
index 3ebebe7..6e41908 100644
--- a/sound/soc/sh/fsi-hdmi.c
+++ b/sound/soc/sh/fsi-hdmi.c
@@ -39,6 +39,7 @@
};
static struct snd_soc_card fsi_soc_card = {
+ .owner = THIS_MODULE,
.dai_link = &fsi_dai_link,
.num_links = 1,
};
@@ -110,18 +111,7 @@
.id_table = fsi_id_table,
};
-static int __init fsi_hdmi_init(void)
-{
- return platform_driver_register(&fsi_hdmi);
-}
-
-static void __exit fsi_hdmi_exit(void)
-{
- platform_driver_unregister(&fsi_hdmi);
-}
-
-module_init(fsi_hdmi_init);
-module_exit(fsi_hdmi_exit);
+module_platform_driver(fsi_hdmi);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Generic SH4 FSI-HDMI sound card");
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
index 3d7016e..db6c89a 100644
--- a/sound/soc/sh/fsi.c
+++ b/sound/soc/sh/fsi.c
@@ -32,7 +32,9 @@
#define REG_DIDT 0x0020
#define REG_DODT 0x0024
#define REG_MUTE_ST 0x0028
+#define REG_OUT_DMAC 0x002C
#define REG_OUT_SEL 0x0030
+#define REG_IN_DMAC 0x0038
/* master register */
#define MST_CLK_RST 0x0210
@@ -235,13 +237,13 @@
}
#define fsi_reg_write(p, r, d)\
- __fsi_reg_write((u32)(p->base + REG_##r), d)
+ __fsi_reg_write((p->base + REG_##r), d)
#define fsi_reg_read(p, r)\
- __fsi_reg_read((u32)(p->base + REG_##r))
+ __fsi_reg_read((p->base + REG_##r))
#define fsi_reg_mask_set(p, r, m, d)\
- __fsi_reg_mask_set((u32)(p->base + REG_##r), m, d)
+ __fsi_reg_mask_set((p->base + REG_##r), m, d)
#define fsi_master_read(p, r) _fsi_master_read(p, MST_##r)
#define fsi_core_read(p, r) _fsi_master_read(p, p->core->r)
@@ -886,11 +888,11 @@
int is_play,
struct device *dev)
{
+ struct fsi_master *master = fsi_get_master(fsi);
+ int fsi_ver = master->core->ver;
u32 flags = fsi_get_info_flags(fsi);
u32 data = 0;
- pm_runtime_get_sync(dev);
-
/* clock setting */
if (fsi_is_clk_master(fsi))
data = DIMD | DOMD;
@@ -920,6 +922,17 @@
fsi_reg_mask_set(fsi, OUT_SEL, DMMD, DMMD);
}
+ /*
+ * FIXME
+ *
+ * FSI driver assumed that data package is in-back.
+ * FSI2 chip can select it.
+ */
+ if (fsi_ver >= 2) {
+ fsi_reg_write(fsi, OUT_DMAC, (1 << 4));
+ fsi_reg_write(fsi, IN_DMAC, (1 << 4));
+ }
+
/* irq clear */
fsi_irq_disable(fsi, is_play);
fsi_irq_clear_status(fsi);
@@ -936,8 +949,6 @@
{
if (fsi_is_clk_master(fsi))
fsi_set_master_clk(dev, fsi, fsi->rate, 0);
-
- pm_runtime_put_sync(dev);
}
static int fsi_dai_startup(struct snd_pcm_substream *substream,
@@ -1081,7 +1092,7 @@
return ret;
}
-static struct snd_soc_dai_ops fsi_dai_ops = {
+static const struct snd_soc_dai_ops fsi_dai_ops = {
.startup = fsi_dai_startup,
.shutdown = fsi_dai_shutdown,
.trigger = fsi_dai_trigger,
@@ -1453,18 +1464,7 @@
.id_table = fsi_id_table,
};
-static int __init fsi_mobile_init(void)
-{
- return platform_driver_register(&fsi_driver);
-}
-
-static void __exit fsi_mobile_exit(void)
-{
- platform_driver_unregister(&fsi_driver);
-}
-
-module_init(fsi_mobile_init);
-module_exit(fsi_mobile_exit);
+module_platform_driver(fsi_driver);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("SuperH onchip FSI audio driver");
diff --git a/sound/soc/sh/hac.c b/sound/soc/sh/hac.c
index c87e3ff..3474d7b 100644
--- a/sound/soc/sh/hac.c
+++ b/sound/soc/sh/hac.c
@@ -266,7 +266,7 @@
#define AC97_FMTS \
SNDRV_PCM_FMTBIT_S16_LE
-static struct snd_soc_dai_ops hac_dai_ops = {
+static const struct snd_soc_dai_ops hac_dai_ops = {
.hw_params = hac_hw_params,
};
@@ -332,17 +332,7 @@
.remove = __devexit_p(hac_soc_platform_remove),
};
-static int __init sh4_hac_pcm_init(void)
-{
- return platform_driver_register(&hac_pcm_driver);
-}
-module_init(sh4_hac_pcm_init);
-
-static void __exit sh4_hac_pcm_exit(void)
-{
- platform_driver_unregister(&hac_pcm_driver);
-}
-module_exit(sh4_hac_pcm_exit);
+module_platform_driver(hac_pcm_driver);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("SuperH onchip HAC (AC97) audio driver");
diff --git a/sound/soc/sh/migor.c b/sound/soc/sh/migor.c
index 6088a6a..9d9ad8d 100644
--- a/sound/soc/sh/migor.c
+++ b/sound/soc/sh/migor.c
@@ -164,6 +164,7 @@
/* migor audio machine driver */
static struct snd_soc_card snd_soc_migor = {
.name = "Migo-R",
+ .owner = THIS_MODULE,
.dai_link = &migor_dai,
.num_links = 1,
};
diff --git a/sound/soc/sh/sh7760-ac97.c b/sound/soc/sh/sh7760-ac97.c
index c62ae68..4a3568a 100644
--- a/sound/soc/sh/sh7760-ac97.c
+++ b/sound/soc/sh/sh7760-ac97.c
@@ -16,10 +16,6 @@
#define IPSEL 0xFE400034
-/* platform specific structs can be declared here */
-extern struct snd_soc_dai_driver sh4_hac_dai[2];
-extern struct snd_soc_platform_driver sh7760_soc_platform;
-
static struct snd_soc_dai_link sh7760_ac97_dai = {
.name = "AC97",
.stream_name = "AC97 HiFi",
@@ -32,6 +28,7 @@
static struct snd_soc_card sh7760_ac97_soc_machine = {
.name = "SH7760 AC97",
+ .owner = THIS_MODULE,
.dai_link = &sh7760_ac97_dai,
.num_links = 1,
};
diff --git a/sound/soc/sh/siu_dai.c b/sound/soc/sh/siu_dai.c
index edacfeb..52d4c17 100644
--- a/sound/soc/sh/siu_dai.c
+++ b/sound/soc/sh/siu_dai.c
@@ -112,9 +112,6 @@
dev_dbg(port_info->pcm->card->dev, "%s\n", __func__);
- /* Turn on SIU clock */
- pm_runtime_get_sync(info->dev);
-
/* Issue software reset to siu */
siu_write32(base + SIU_SRCTL, 0);
@@ -158,9 +155,6 @@
/* SIU software reset */
siu_write32(base + SIU_SRCTL, 0);
-
- /* Turn off SIU clock */
- pm_runtime_put_sync(info->dev);
}
static void siu_dai_spbAselect(struct siu_port *port_info)
@@ -707,7 +701,7 @@
return ret;
}
-static struct snd_soc_dai_ops siu_dai_ops = {
+static const struct snd_soc_dai_ops siu_dai_ops = {
.startup = siu_dai_startup,
.shutdown = siu_dai_shutdown,
.prepare = siu_dai_prepare,
@@ -852,18 +846,7 @@
.remove = __devexit_p(siu_remove),
};
-static int __init siu_init(void)
-{
- return platform_driver_register(&siu_driver);
-}
-
-static void __exit siu_exit(void)
-{
- platform_driver_unregister(&siu_driver);
-}
-
-module_init(siu_init)
-module_exit(siu_exit)
+module_platform_driver(siu_driver);
MODULE_AUTHOR("Carlos Munoz <carlos@kenati.com>");
MODULE_DESCRIPTION("ALSA SoC SH7722 SIU driver");
diff --git a/sound/soc/sh/ssi.c b/sound/soc/sh/ssi.c
index e0c621c..ff82b56 100644
--- a/sound/soc/sh/ssi.c
+++ b/sound/soc/sh/ssi.c
@@ -332,7 +332,7 @@
SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_U24_3LE | \
SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_U32_LE)
-static struct snd_soc_dai_ops ssi_dai_ops = {
+static const struct snd_soc_dai_ops ssi_dai_ops = {
.startup = ssi_startup,
.shutdown = ssi_shutdown,
.trigger = ssi_trigger,
@@ -401,17 +401,7 @@
.remove = __devexit_p(sh4_soc_dai_remove),
};
-static int __init snd_sh4_ssi_init(void)
-{
- return platform_driver_register(&sh4_ssi_driver);
-}
-module_init(snd_sh4_ssi_init);
-
-static void __exit snd_sh4_ssi_exit(void)
-{
- platform_driver_unregister(&sh4_ssi_driver);
-}
-module_exit(snd_sh4_ssi_exit);
+module_platform_driver(sh4_ssi_driver);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("SuperH onchip SSI (I2S) audio driver");
diff --git a/sound/soc/soc-cache.c b/sound/soc/soc-cache.c
index 9077aa4..9d56f02 100644
--- a/sound/soc/soc-cache.c
+++ b/sound/soc/soc-cache.c
@@ -14,7 +14,6 @@
#include <linux/i2c.h>
#include <linux/spi/spi.h>
#include <sound/soc.h>
-#include <linux/lzo.h>
#include <linux/bitmap.h>
#include <linux/rbtree.h>
#include <linux/export.h>
@@ -67,750 +66,6 @@
return -1;
}
-struct snd_soc_rbtree_node {
- struct rb_node node; /* the actual rbtree node holding this block */
- unsigned int base_reg; /* base register handled by this block */
- unsigned int word_size; /* number of bytes needed to represent the register index */
- void *block; /* block of adjacent registers */
- unsigned int blklen; /* number of registers available in the block */
-} __attribute__ ((packed));
-
-struct snd_soc_rbtree_ctx {
- struct rb_root root;
- struct snd_soc_rbtree_node *cached_rbnode;
-};
-
-static inline void snd_soc_rbtree_get_base_top_reg(
- struct snd_soc_rbtree_node *rbnode,
- unsigned int *base, unsigned int *top)
-{
- *base = rbnode->base_reg;
- *top = rbnode->base_reg + rbnode->blklen - 1;
-}
-
-static unsigned int snd_soc_rbtree_get_register(
- struct snd_soc_rbtree_node *rbnode, unsigned int idx)
-{
- unsigned int val;
-
- switch (rbnode->word_size) {
- case 1: {
- u8 *p = rbnode->block;
- val = p[idx];
- return val;
- }
- case 2: {
- u16 *p = rbnode->block;
- val = p[idx];
- return val;
- }
- default:
- BUG();
- break;
- }
- return -1;
-}
-
-static void snd_soc_rbtree_set_register(struct snd_soc_rbtree_node *rbnode,
- unsigned int idx, unsigned int val)
-{
- switch (rbnode->word_size) {
- case 1: {
- u8 *p = rbnode->block;
- p[idx] = val;
- break;
- }
- case 2: {
- u16 *p = rbnode->block;
- p[idx] = val;
- break;
- }
- default:
- BUG();
- break;
- }
-}
-
-static struct snd_soc_rbtree_node *snd_soc_rbtree_lookup(
- struct rb_root *root, unsigned int reg)
-{
- struct rb_node *node;
- struct snd_soc_rbtree_node *rbnode;
- unsigned int base_reg, top_reg;
-
- node = root->rb_node;
- while (node) {
- rbnode = container_of(node, struct snd_soc_rbtree_node, node);
- snd_soc_rbtree_get_base_top_reg(rbnode, &base_reg, &top_reg);
- if (reg >= base_reg && reg <= top_reg)
- return rbnode;
- else if (reg > top_reg)
- node = node->rb_right;
- else if (reg < base_reg)
- node = node->rb_left;
- }
-
- return NULL;
-}
-
-static int snd_soc_rbtree_insert(struct rb_root *root,
- struct snd_soc_rbtree_node *rbnode)
-{
- struct rb_node **new, *parent;
- struct snd_soc_rbtree_node *rbnode_tmp;
- unsigned int base_reg_tmp, top_reg_tmp;
- unsigned int base_reg;
-
- parent = NULL;
- new = &root->rb_node;
- while (*new) {
- rbnode_tmp = container_of(*new, struct snd_soc_rbtree_node,
- node);
- /* base and top registers of the current rbnode */
- snd_soc_rbtree_get_base_top_reg(rbnode_tmp, &base_reg_tmp,
- &top_reg_tmp);
- /* base register of the rbnode to be added */
- base_reg = rbnode->base_reg;
- parent = *new;
- /* if this register has already been inserted, just return */
- if (base_reg >= base_reg_tmp &&
- base_reg <= top_reg_tmp)
- return 0;
- else if (base_reg > top_reg_tmp)
- new = &((*new)->rb_right);
- else if (base_reg < base_reg_tmp)
- new = &((*new)->rb_left);
- }
-
- /* insert the node into the rbtree */
- rb_link_node(&rbnode->node, parent, new);
- rb_insert_color(&rbnode->node, root);
-
- return 1;
-}
-
-static int snd_soc_rbtree_cache_sync(struct snd_soc_codec *codec)
-{
- struct snd_soc_rbtree_ctx *rbtree_ctx;
- struct rb_node *node;
- struct snd_soc_rbtree_node *rbnode;
- unsigned int regtmp;
- unsigned int val, def;
- int ret;
- int i;
-
- rbtree_ctx = codec->reg_cache;
- for (node = rb_first(&rbtree_ctx->root); node; node = rb_next(node)) {
- rbnode = rb_entry(node, struct snd_soc_rbtree_node, node);
- for (i = 0; i < rbnode->blklen; ++i) {
- regtmp = rbnode->base_reg + i;
- val = snd_soc_rbtree_get_register(rbnode, i);
- def = snd_soc_get_cache_val(codec->reg_def_copy, i,
- rbnode->word_size);
- if (val == def)
- continue;
-
- WARN_ON(!snd_soc_codec_writable_register(codec, regtmp));
-
- codec->cache_bypass = 1;
- ret = snd_soc_write(codec, regtmp, val);
- codec->cache_bypass = 0;
- if (ret)
- return ret;
- dev_dbg(codec->dev, "Synced register %#x, value = %#x\n",
- regtmp, val);
- }
- }
-
- return 0;
-}
-
-static int snd_soc_rbtree_insert_to_block(struct snd_soc_rbtree_node *rbnode,
- unsigned int pos, unsigned int reg,
- unsigned int value)
-{
- u8 *blk;
-
- blk = krealloc(rbnode->block,
- (rbnode->blklen + 1) * rbnode->word_size, GFP_KERNEL);
- if (!blk)
- return -ENOMEM;
-
- /* insert the register value in the correct place in the rbnode block */
- memmove(blk + (pos + 1) * rbnode->word_size,
- blk + pos * rbnode->word_size,
- (rbnode->blklen - pos) * rbnode->word_size);
-
- /* update the rbnode block, its size and the base register */
- rbnode->block = blk;
- rbnode->blklen++;
- if (!pos)
- rbnode->base_reg = reg;
-
- snd_soc_rbtree_set_register(rbnode, pos, value);
- return 0;
-}
-
-static int snd_soc_rbtree_cache_write(struct snd_soc_codec *codec,
- unsigned int reg, unsigned int value)
-{
- struct snd_soc_rbtree_ctx *rbtree_ctx;
- struct snd_soc_rbtree_node *rbnode, *rbnode_tmp;
- struct rb_node *node;
- unsigned int val;
- unsigned int reg_tmp;
- unsigned int base_reg, top_reg;
- unsigned int pos;
- int i;
- int ret;
-
- rbtree_ctx = codec->reg_cache;
- /* look up the required register in the cached rbnode */
- rbnode = rbtree_ctx->cached_rbnode;
- if (rbnode) {
- snd_soc_rbtree_get_base_top_reg(rbnode, &base_reg, &top_reg);
- if (reg >= base_reg && reg <= top_reg) {
- reg_tmp = reg - base_reg;
- val = snd_soc_rbtree_get_register(rbnode, reg_tmp);
- if (val == value)
- return 0;
- snd_soc_rbtree_set_register(rbnode, reg_tmp, value);
- return 0;
- }
- }
- /* if we can't locate it in the cached rbnode we'll have
- * to traverse the rbtree looking for it.
- */
- rbnode = snd_soc_rbtree_lookup(&rbtree_ctx->root, reg);
- if (rbnode) {
- reg_tmp = reg - rbnode->base_reg;
- val = snd_soc_rbtree_get_register(rbnode, reg_tmp);
- if (val == value)
- return 0;
- snd_soc_rbtree_set_register(rbnode, reg_tmp, value);
- rbtree_ctx->cached_rbnode = rbnode;
- } else {
- /* bail out early, no need to create the rbnode yet */
- if (!value)
- return 0;
- /* look for an adjacent register to the one we are about to add */
- for (node = rb_first(&rbtree_ctx->root); node;
- node = rb_next(node)) {
- rbnode_tmp = rb_entry(node, struct snd_soc_rbtree_node, node);
- for (i = 0; i < rbnode_tmp->blklen; ++i) {
- reg_tmp = rbnode_tmp->base_reg + i;
- if (abs(reg_tmp - reg) != 1)
- continue;
- /* decide where in the block to place our register */
- if (reg_tmp + 1 == reg)
- pos = i + 1;
- else
- pos = i;
- ret = snd_soc_rbtree_insert_to_block(rbnode_tmp, pos,
- reg, value);
- if (ret)
- return ret;
- rbtree_ctx->cached_rbnode = rbnode_tmp;
- return 0;
- }
- }
- /* we did not manage to find a place to insert it in an existing
- * block so create a new rbnode with a single register in its block.
- * This block will get populated further if any other adjacent
- * registers get modified in the future.
- */
- rbnode = kzalloc(sizeof *rbnode, GFP_KERNEL);
- if (!rbnode)
- return -ENOMEM;
- rbnode->blklen = 1;
- rbnode->base_reg = reg;
- rbnode->word_size = codec->driver->reg_word_size;
- rbnode->block = kmalloc(rbnode->blklen * rbnode->word_size,
- GFP_KERNEL);
- if (!rbnode->block) {
- kfree(rbnode);
- return -ENOMEM;
- }
- snd_soc_rbtree_set_register(rbnode, 0, value);
- snd_soc_rbtree_insert(&rbtree_ctx->root, rbnode);
- rbtree_ctx->cached_rbnode = rbnode;
- }
-
- return 0;
-}
-
-static int snd_soc_rbtree_cache_read(struct snd_soc_codec *codec,
- unsigned int reg, unsigned int *value)
-{
- struct snd_soc_rbtree_ctx *rbtree_ctx;
- struct snd_soc_rbtree_node *rbnode;
- unsigned int base_reg, top_reg;
- unsigned int reg_tmp;
-
- rbtree_ctx = codec->reg_cache;
- /* look up the required register in the cached rbnode */
- rbnode = rbtree_ctx->cached_rbnode;
- if (rbnode) {
- snd_soc_rbtree_get_base_top_reg(rbnode, &base_reg, &top_reg);
- if (reg >= base_reg && reg <= top_reg) {
- reg_tmp = reg - base_reg;
- *value = snd_soc_rbtree_get_register(rbnode, reg_tmp);
- return 0;
- }
- }
- /* if we can't locate it in the cached rbnode we'll have
- * to traverse the rbtree looking for it.
- */
- rbnode = snd_soc_rbtree_lookup(&rbtree_ctx->root, reg);
- if (rbnode) {
- reg_tmp = reg - rbnode->base_reg;
- *value = snd_soc_rbtree_get_register(rbnode, reg_tmp);
- rbtree_ctx->cached_rbnode = rbnode;
- } else {
- /* uninitialized registers default to 0 */
- *value = 0;
- }
-
- return 0;
-}
-
-static int snd_soc_rbtree_cache_exit(struct snd_soc_codec *codec)
-{
- struct rb_node *next;
- struct snd_soc_rbtree_ctx *rbtree_ctx;
- struct snd_soc_rbtree_node *rbtree_node;
-
- /* if we've already been called then just return */
- rbtree_ctx = codec->reg_cache;
- if (!rbtree_ctx)
- return 0;
-
- /* free up the rbtree */
- next = rb_first(&rbtree_ctx->root);
- while (next) {
- rbtree_node = rb_entry(next, struct snd_soc_rbtree_node, node);
- next = rb_next(&rbtree_node->node);
- rb_erase(&rbtree_node->node, &rbtree_ctx->root);
- kfree(rbtree_node->block);
- kfree(rbtree_node);
- }
-
- /* release the resources */
- kfree(codec->reg_cache);
- codec->reg_cache = NULL;
-
- return 0;
-}
-
-static int snd_soc_rbtree_cache_init(struct snd_soc_codec *codec)
-{
- struct snd_soc_rbtree_ctx *rbtree_ctx;
- unsigned int word_size;
- unsigned int val;
- int i;
- int ret;
-
- codec->reg_cache = kmalloc(sizeof *rbtree_ctx, GFP_KERNEL);
- if (!codec->reg_cache)
- return -ENOMEM;
-
- rbtree_ctx = codec->reg_cache;
- rbtree_ctx->root = RB_ROOT;
- rbtree_ctx->cached_rbnode = NULL;
-
- if (!codec->reg_def_copy)
- return 0;
-
- word_size = codec->driver->reg_word_size;
- for (i = 0; i < codec->driver->reg_cache_size; ++i) {
- val = snd_soc_get_cache_val(codec->reg_def_copy, i,
- word_size);
- if (!val)
- continue;
- ret = snd_soc_rbtree_cache_write(codec, i, val);
- if (ret)
- goto err;
- }
-
- return 0;
-
-err:
- snd_soc_cache_exit(codec);
- return ret;
-}
-
-#ifdef CONFIG_SND_SOC_CACHE_LZO
-struct snd_soc_lzo_ctx {
- void *wmem;
- void *dst;
- const void *src;
- size_t src_len;
- size_t dst_len;
- size_t decompressed_size;
- unsigned long *sync_bmp;
- int sync_bmp_nbits;
-};
-
-#define LZO_BLOCK_NUM 8
-static int snd_soc_lzo_block_count(void)
-{
- return LZO_BLOCK_NUM;
-}
-
-static int snd_soc_lzo_prepare(struct snd_soc_lzo_ctx *lzo_ctx)
-{
- lzo_ctx->wmem = kmalloc(LZO1X_MEM_COMPRESS, GFP_KERNEL);
- if (!lzo_ctx->wmem)
- return -ENOMEM;
- return 0;
-}
-
-static int snd_soc_lzo_compress(struct snd_soc_lzo_ctx *lzo_ctx)
-{
- size_t compress_size;
- int ret;
-
- ret = lzo1x_1_compress(lzo_ctx->src, lzo_ctx->src_len,
- lzo_ctx->dst, &compress_size, lzo_ctx->wmem);
- if (ret != LZO_E_OK || compress_size > lzo_ctx->dst_len)
- return -EINVAL;
- lzo_ctx->dst_len = compress_size;
- return 0;
-}
-
-static int snd_soc_lzo_decompress(struct snd_soc_lzo_ctx *lzo_ctx)
-{
- size_t dst_len;
- int ret;
-
- dst_len = lzo_ctx->dst_len;
- ret = lzo1x_decompress_safe(lzo_ctx->src, lzo_ctx->src_len,
- lzo_ctx->dst, &dst_len);
- if (ret != LZO_E_OK || dst_len != lzo_ctx->dst_len)
- return -EINVAL;
- return 0;
-}
-
-static int snd_soc_lzo_compress_cache_block(struct snd_soc_codec *codec,
- struct snd_soc_lzo_ctx *lzo_ctx)
-{
- int ret;
-
- lzo_ctx->dst_len = lzo1x_worst_compress(PAGE_SIZE);
- lzo_ctx->dst = kmalloc(lzo_ctx->dst_len, GFP_KERNEL);
- if (!lzo_ctx->dst) {
- lzo_ctx->dst_len = 0;
- return -ENOMEM;
- }
-
- ret = snd_soc_lzo_compress(lzo_ctx);
- if (ret < 0)
- return ret;
- return 0;
-}
-
-static int snd_soc_lzo_decompress_cache_block(struct snd_soc_codec *codec,
- struct snd_soc_lzo_ctx *lzo_ctx)
-{
- int ret;
-
- lzo_ctx->dst_len = lzo_ctx->decompressed_size;
- lzo_ctx->dst = kmalloc(lzo_ctx->dst_len, GFP_KERNEL);
- if (!lzo_ctx->dst) {
- lzo_ctx->dst_len = 0;
- return -ENOMEM;
- }
-
- ret = snd_soc_lzo_decompress(lzo_ctx);
- if (ret < 0)
- return ret;
- return 0;
-}
-
-static inline int snd_soc_lzo_get_blkindex(struct snd_soc_codec *codec,
- unsigned int reg)
-{
- const struct snd_soc_codec_driver *codec_drv;
-
- codec_drv = codec->driver;
- return (reg * codec_drv->reg_word_size) /
- DIV_ROUND_UP(codec->reg_size, snd_soc_lzo_block_count());
-}
-
-static inline int snd_soc_lzo_get_blkpos(struct snd_soc_codec *codec,
- unsigned int reg)
-{
- const struct snd_soc_codec_driver *codec_drv;
-
- codec_drv = codec->driver;
- return reg % (DIV_ROUND_UP(codec->reg_size, snd_soc_lzo_block_count()) /
- codec_drv->reg_word_size);
-}
-
-static inline int snd_soc_lzo_get_blksize(struct snd_soc_codec *codec)
-{
- return DIV_ROUND_UP(codec->reg_size, snd_soc_lzo_block_count());
-}
-
-static int snd_soc_lzo_cache_sync(struct snd_soc_codec *codec)
-{
- struct snd_soc_lzo_ctx **lzo_blocks;
- unsigned int val;
- int i;
- int ret;
-
- lzo_blocks = codec->reg_cache;
- for_each_set_bit(i, lzo_blocks[0]->sync_bmp, lzo_blocks[0]->sync_bmp_nbits) {
- WARN_ON(!snd_soc_codec_writable_register(codec, i));
- ret = snd_soc_cache_read(codec, i, &val);
- if (ret)
- return ret;
- codec->cache_bypass = 1;
- ret = snd_soc_write(codec, i, val);
- codec->cache_bypass = 0;
- if (ret)
- return ret;
- dev_dbg(codec->dev, "Synced register %#x, value = %#x\n",
- i, val);
- }
-
- return 0;
-}
-
-static int snd_soc_lzo_cache_write(struct snd_soc_codec *codec,
- unsigned int reg, unsigned int value)
-{
- struct snd_soc_lzo_ctx *lzo_block, **lzo_blocks;
- int ret, blkindex, blkpos;
- size_t blksize, tmp_dst_len;
- void *tmp_dst;
-
- /* index of the compressed lzo block */
- blkindex = snd_soc_lzo_get_blkindex(codec, reg);
- /* register index within the decompressed block */
- blkpos = snd_soc_lzo_get_blkpos(codec, reg);
- /* size of the compressed block */
- blksize = snd_soc_lzo_get_blksize(codec);
- lzo_blocks = codec->reg_cache;
- lzo_block = lzo_blocks[blkindex];
-
- /* save the pointer and length of the compressed block */
- tmp_dst = lzo_block->dst;
- tmp_dst_len = lzo_block->dst_len;
-
- /* prepare the source to be the compressed block */
- lzo_block->src = lzo_block->dst;
- lzo_block->src_len = lzo_block->dst_len;
-
- /* decompress the block */
- ret = snd_soc_lzo_decompress_cache_block(codec, lzo_block);
- if (ret < 0) {
- kfree(lzo_block->dst);
- goto out;
- }
-
- /* write the new value to the cache */
- if (snd_soc_set_cache_val(lzo_block->dst, blkpos, value,
- codec->driver->reg_word_size)) {
- kfree(lzo_block->dst);
- goto out;
- }
-
- /* prepare the source to be the decompressed block */
- lzo_block->src = lzo_block->dst;
- lzo_block->src_len = lzo_block->dst_len;
-
- /* compress the block */
- ret = snd_soc_lzo_compress_cache_block(codec, lzo_block);
- if (ret < 0) {
- kfree(lzo_block->dst);
- kfree(lzo_block->src);
- goto out;
- }
-
- /* set the bit so we know we have to sync this register */
- set_bit(reg, lzo_block->sync_bmp);
- kfree(tmp_dst);
- kfree(lzo_block->src);
- return 0;
-out:
- lzo_block->dst = tmp_dst;
- lzo_block->dst_len = tmp_dst_len;
- return ret;
-}
-
-static int snd_soc_lzo_cache_read(struct snd_soc_codec *codec,
- unsigned int reg, unsigned int *value)
-{
- struct snd_soc_lzo_ctx *lzo_block, **lzo_blocks;
- int ret, blkindex, blkpos;
- size_t blksize, tmp_dst_len;
- void *tmp_dst;
-
- *value = 0;
- /* index of the compressed lzo block */
- blkindex = snd_soc_lzo_get_blkindex(codec, reg);
- /* register index within the decompressed block */
- blkpos = snd_soc_lzo_get_blkpos(codec, reg);
- /* size of the compressed block */
- blksize = snd_soc_lzo_get_blksize(codec);
- lzo_blocks = codec->reg_cache;
- lzo_block = lzo_blocks[blkindex];
-
- /* save the pointer and length of the compressed block */
- tmp_dst = lzo_block->dst;
- tmp_dst_len = lzo_block->dst_len;
-
- /* prepare the source to be the compressed block */
- lzo_block->src = lzo_block->dst;
- lzo_block->src_len = lzo_block->dst_len;
-
- /* decompress the block */
- ret = snd_soc_lzo_decompress_cache_block(codec, lzo_block);
- if (ret >= 0)
- /* fetch the value from the cache */
- *value = snd_soc_get_cache_val(lzo_block->dst, blkpos,
- codec->driver->reg_word_size);
-
- kfree(lzo_block->dst);
- /* restore the pointer and length of the compressed block */
- lzo_block->dst = tmp_dst;
- lzo_block->dst_len = tmp_dst_len;
- return 0;
-}
-
-static int snd_soc_lzo_cache_exit(struct snd_soc_codec *codec)
-{
- struct snd_soc_lzo_ctx **lzo_blocks;
- int i, blkcount;
-
- lzo_blocks = codec->reg_cache;
- if (!lzo_blocks)
- return 0;
-
- blkcount = snd_soc_lzo_block_count();
- /*
- * the pointer to the bitmap used for syncing the cache
- * is shared amongst all lzo_blocks. Ensure it is freed
- * only once.
- */
- if (lzo_blocks[0])
- kfree(lzo_blocks[0]->sync_bmp);
- for (i = 0; i < blkcount; ++i) {
- if (lzo_blocks[i]) {
- kfree(lzo_blocks[i]->wmem);
- kfree(lzo_blocks[i]->dst);
- }
- /* each lzo_block is a pointer returned by kmalloc or NULL */
- kfree(lzo_blocks[i]);
- }
- kfree(lzo_blocks);
- codec->reg_cache = NULL;
- return 0;
-}
-
-static int snd_soc_lzo_cache_init(struct snd_soc_codec *codec)
-{
- struct snd_soc_lzo_ctx **lzo_blocks;
- size_t bmp_size;
- const struct snd_soc_codec_driver *codec_drv;
- int ret, tofree, i, blksize, blkcount;
- const char *p, *end;
- unsigned long *sync_bmp;
-
- ret = 0;
- codec_drv = codec->driver;
-
- /*
- * If we have not been given a default register cache
- * then allocate a dummy zero-ed out region, compress it
- * and remember to free it afterwards.
- */
- tofree = 0;
- if (!codec->reg_def_copy)
- tofree = 1;
-
- if (!codec->reg_def_copy) {
- codec->reg_def_copy = kzalloc(codec->reg_size, GFP_KERNEL);
- if (!codec->reg_def_copy)
- return -ENOMEM;
- }
-
- blkcount = snd_soc_lzo_block_count();
- codec->reg_cache = kzalloc(blkcount * sizeof *lzo_blocks,
- GFP_KERNEL);
- if (!codec->reg_cache) {
- ret = -ENOMEM;
- goto err_tofree;
- }
- lzo_blocks = codec->reg_cache;
-
- /*
- * allocate a bitmap to be used when syncing the cache with
- * the hardware. Each time a register is modified, the corresponding
- * bit is set in the bitmap, so we know that we have to sync
- * that register.
- */
- bmp_size = codec_drv->reg_cache_size;
- sync_bmp = kmalloc(BITS_TO_LONGS(bmp_size) * sizeof(long),
- GFP_KERNEL);
- if (!sync_bmp) {
- ret = -ENOMEM;
- goto err;
- }
- bitmap_zero(sync_bmp, bmp_size);
-
- /* allocate the lzo blocks and initialize them */
- for (i = 0; i < blkcount; ++i) {
- lzo_blocks[i] = kzalloc(sizeof **lzo_blocks,
- GFP_KERNEL);
- if (!lzo_blocks[i]) {
- kfree(sync_bmp);
- ret = -ENOMEM;
- goto err;
- }
- lzo_blocks[i]->sync_bmp = sync_bmp;
- lzo_blocks[i]->sync_bmp_nbits = bmp_size;
- /* alloc the working space for the compressed block */
- ret = snd_soc_lzo_prepare(lzo_blocks[i]);
- if (ret < 0)
- goto err;
- }
-
- blksize = snd_soc_lzo_get_blksize(codec);
- p = codec->reg_def_copy;
- end = codec->reg_def_copy + codec->reg_size;
- /* compress the register map and fill the lzo blocks */
- for (i = 0; i < blkcount; ++i, p += blksize) {
- lzo_blocks[i]->src = p;
- if (p + blksize > end)
- lzo_blocks[i]->src_len = end - p;
- else
- lzo_blocks[i]->src_len = blksize;
- ret = snd_soc_lzo_compress_cache_block(codec,
- lzo_blocks[i]);
- if (ret < 0)
- goto err;
- lzo_blocks[i]->decompressed_size =
- lzo_blocks[i]->src_len;
- }
-
- if (tofree) {
- kfree(codec->reg_def_copy);
- codec->reg_def_copy = NULL;
- }
- return 0;
-err:
- snd_soc_cache_exit(codec);
-err_tofree:
- if (tofree) {
- kfree(codec->reg_def_copy);
- codec->reg_def_copy = NULL;
- }
- return ret;
-}
-#endif
-
static int snd_soc_flat_cache_sync(struct snd_soc_codec *codec)
{
int i;
@@ -889,26 +144,6 @@
.write = snd_soc_flat_cache_write,
.sync = snd_soc_flat_cache_sync
},
-#ifdef CONFIG_SND_SOC_CACHE_LZO
- {
- .id = SND_SOC_LZO_COMPRESSION,
- .name = "LZO",
- .init = snd_soc_lzo_cache_init,
- .exit = snd_soc_lzo_cache_exit,
- .read = snd_soc_lzo_cache_read,
- .write = snd_soc_lzo_cache_write,
- .sync = snd_soc_lzo_cache_sync
- },
-#endif
- {
- .id = SND_SOC_RBTREE_COMPRESSION,
- .name = "rbtree",
- .init = snd_soc_rbtree_cache_init,
- .exit = snd_soc_rbtree_cache_exit,
- .read = snd_soc_rbtree_cache_read,
- .write = snd_soc_rbtree_cache_write,
- .sync = snd_soc_rbtree_cache_sync
- }
};
int snd_soc_cache_init(struct snd_soc_codec *codec)
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index a25fa63..3986520 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -32,6 +32,7 @@
#include <linux/platform_device.h>
#include <linux/ctype.h>
#include <linux/slab.h>
+#include <linux/of.h>
#include <sound/ac97_codec.h>
#include <sound/core.h>
#include <sound/jack.h>
@@ -58,8 +59,6 @@
static LIST_HEAD(platform_list);
static LIST_HEAD(codec_list);
-int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num);
-
/*
* This is a timeout to do a DAPM powerdown after a stream is closed().
* It can be used to eliminate pops between different playback streams, e.g.
@@ -170,8 +169,7 @@
static ssize_t codec_reg_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
- struct snd_soc_pcm_runtime *rtd =
- container_of(dev, struct snd_soc_pcm_runtime, dev);
+ struct snd_soc_pcm_runtime *rtd = dev_get_drvdata(dev);
return soc_codec_reg_show(rtd->codec, buf, PAGE_SIZE, 0);
}
@@ -181,8 +179,7 @@
static ssize_t pmdown_time_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
- struct snd_soc_pcm_runtime *rtd =
- container_of(dev, struct snd_soc_pcm_runtime, dev);
+ struct snd_soc_pcm_runtime *rtd = dev_get_drvdata(dev);
return sprintf(buf, "%ld\n", rtd->pmdown_time);
}
@@ -191,8 +188,7 @@
struct device_attribute *attr,
const char *buf, size_t count)
{
- struct snd_soc_pcm_runtime *rtd =
- container_of(dev, struct snd_soc_pcm_runtime, dev);
+ struct snd_soc_pcm_runtime *rtd = dev_get_drvdata(dev);
int ret;
ret = strict_strtol(buf, 10, &rtd->pmdown_time);
@@ -412,7 +408,7 @@
snd_soc_debugfs_root);
if (!card->debugfs_card_root) {
dev_warn(card->dev,
- "ASoC: Failed to create codec debugfs directory\n");
+ "ASoC: Failed to create card debugfs directory\n");
return;
}
@@ -572,7 +568,7 @@
switch (codec->dapm.bias_level) {
case SND_SOC_BIAS_STANDBY:
case SND_SOC_BIAS_OFF:
- codec->driver->suspend(codec, PMSG_SUSPEND);
+ codec->driver->suspend(codec);
codec->suspended = 1;
codec->cache_sync = 1;
break;
@@ -741,7 +737,7 @@
#define snd_soc_resume NULL
#endif
-static struct snd_soc_dai_ops null_dai_ops = {
+static const struct snd_soc_dai_ops null_dai_ops = {
};
static int soc_bind_dai_link(struct snd_soc_card *card, int num)
@@ -763,10 +759,16 @@
}
/* no, then find CPU DAI from registered DAIs*/
list_for_each_entry(cpu_dai, &dai_list, list) {
- if (!strcmp(cpu_dai->name, dai_link->cpu_dai_name)) {
- rtd->cpu_dai = cpu_dai;
- goto find_codec;
+ if (dai_link->cpu_dai_of_node) {
+ if (cpu_dai->dev->of_node != dai_link->cpu_dai_of_node)
+ continue;
+ } else {
+ if (strcmp(cpu_dai->name, dai_link->cpu_dai_name))
+ continue;
}
+
+ rtd->cpu_dai = cpu_dai;
+ goto find_codec;
}
dev_dbg(card->dev, "CPU DAI %s not registered\n",
dai_link->cpu_dai_name);
@@ -779,22 +781,33 @@
/* no, then find CODEC from registered CODECs*/
list_for_each_entry(codec, &codec_list, list) {
- if (!strcmp(codec->name, dai_link->codec_name)) {
- rtd->codec = codec;
-
- /* CODEC found, so find CODEC DAI from registered DAIs from this CODEC*/
- list_for_each_entry(codec_dai, &dai_list, list) {
- if (codec->dev == codec_dai->dev &&
- !strcmp(codec_dai->name, dai_link->codec_dai_name)) {
- rtd->codec_dai = codec_dai;
- goto find_platform;
- }
- }
- dev_dbg(card->dev, "CODEC DAI %s not registered\n",
- dai_link->codec_dai_name);
-
- goto find_platform;
+ if (dai_link->codec_of_node) {
+ if (codec->dev->of_node != dai_link->codec_of_node)
+ continue;
+ } else {
+ if (strcmp(codec->name, dai_link->codec_name))
+ continue;
}
+
+ rtd->codec = codec;
+
+ /*
+ * CODEC found, so find CODEC DAI from registered DAIs from
+ * this CODEC
+ */
+ list_for_each_entry(codec_dai, &dai_list, list) {
+ if (codec->dev == codec_dai->dev &&
+ !strcmp(codec_dai->name,
+ dai_link->codec_dai_name)) {
+
+ rtd->codec_dai = codec_dai;
+ goto find_platform;
+ }
+ }
+ dev_dbg(card->dev, "CODEC DAI %s not registered\n",
+ dai_link->codec_dai_name);
+
+ goto find_platform;
}
dev_dbg(card->dev, "CODEC %s not registered\n",
dai_link->codec_name);
@@ -806,15 +819,22 @@
/* if there's no platform we match on the empty platform */
platform_name = dai_link->platform_name;
- if (!platform_name)
+ if (!platform_name && !dai_link->platform_of_node)
platform_name = "snd-soc-dummy";
/* no, then find one from the set of registered platforms */
list_for_each_entry(platform, &platform_list, list) {
- if (!strcmp(platform->name, platform_name)) {
- rtd->platform = platform;
- goto out;
+ if (dai_link->platform_of_node) {
+ if (platform->dev->of_node !=
+ dai_link->platform_of_node)
+ continue;
+ } else {
+ if (strcmp(platform->name, platform_name))
+ continue;
}
+
+ rtd->platform = platform;
+ goto out;
}
dev_dbg(card->dev, "platform %s not registered\n",
@@ -861,9 +881,9 @@
/* unregister the rtd device */
if (rtd->dev_registered) {
- device_remove_file(&rtd->dev, &dev_attr_pmdown_time);
- device_remove_file(&rtd->dev, &dev_attr_codec_reg);
- device_unregister(&rtd->dev);
+ device_remove_file(rtd->dev, &dev_attr_pmdown_time);
+ device_remove_file(rtd->dev, &dev_attr_codec_reg);
+ device_unregister(rtd->dev);
rtd->dev_registered = 0;
}
@@ -1038,7 +1058,10 @@
return ret;
}
-static void rtd_release(struct device *dev) {}
+static void rtd_release(struct device *dev)
+{
+ kfree(dev);
+}
static int soc_post_component_init(struct snd_soc_card *card,
struct snd_soc_codec *codec,
@@ -1081,11 +1104,17 @@
/* register the rtd device */
rtd->codec = codec;
- rtd->dev.parent = card->dev;
- rtd->dev.release = rtd_release;
- rtd->dev.init_name = name;
+
+ rtd->dev = kzalloc(sizeof(struct device), GFP_KERNEL);
+ if (!rtd->dev)
+ return -ENOMEM;
+ device_initialize(rtd->dev);
+ rtd->dev->parent = card->dev;
+ rtd->dev->release = rtd_release;
+ rtd->dev->init_name = name;
+ dev_set_drvdata(rtd->dev, rtd);
mutex_init(&rtd->pcm_mutex);
- ret = device_register(&rtd->dev);
+ ret = device_add(rtd->dev);
if (ret < 0) {
dev_err(card->dev,
"asoc: failed to register runtime device: %d\n", ret);
@@ -1094,14 +1123,14 @@
rtd->dev_registered = 1;
/* add DAPM sysfs entries for this codec */
- ret = snd_soc_dapm_sys_add(&rtd->dev);
+ ret = snd_soc_dapm_sys_add(rtd->dev);
if (ret < 0)
dev_err(codec->dev,
"asoc: failed to add codec dapm sysfs entries: %d\n",
ret);
/* add codec sysfs entries */
- ret = device_create_file(&rtd->dev, &dev_attr_codec_reg);
+ ret = device_create_file(rtd->dev, &dev_attr_codec_reg);
if (ret < 0)
dev_err(codec->dev,
"asoc: failed to add codec sysfs files: %d\n", ret);
@@ -1190,7 +1219,7 @@
if (ret)
return ret;
- ret = device_create_file(&rtd->dev, &dev_attr_pmdown_time);
+ ret = device_create_file(rtd->dev, &dev_attr_pmdown_time);
if (ret < 0)
printk(KERN_WARNING "asoc: failed to add pmdown_time sysfs\n");
@@ -1288,8 +1317,8 @@
/* unregister the rtd device */
if (rtd->dev_registered) {
- device_remove_file(&rtd->dev, &dev_attr_codec_reg);
- device_unregister(&rtd->dev);
+ device_remove_file(rtd->dev, &dev_attr_codec_reg);
+ device_del(rtd->dev);
rtd->dev_registered = 0;
}
@@ -1488,6 +1517,10 @@
snd_soc_dapm_new_widgets(&card->dapm);
+ if (card->fully_routed)
+ list_for_each_entry(codec, &card->codec_dev_list, card_list)
+ snd_soc_dapm_auto_nc_codec_pins(codec);
+
ret = snd_card_register(card->snd_card);
if (ret < 0) {
printk(KERN_ERR "asoc: failed to register soundcard for %s\n", card->name);
@@ -2818,6 +2851,40 @@
if (!card->name || !card->dev)
return -EINVAL;
+ for (i = 0; i < card->num_links; i++) {
+ struct snd_soc_dai_link *link = &card->dai_link[i];
+
+ /*
+ * Codec must be specified by 1 of name or OF node,
+ * not both or neither.
+ */
+ if (!!link->codec_name == !!link->codec_of_node) {
+ dev_err(card->dev,
+ "Neither/both codec name/of_node are set\n");
+ return -EINVAL;
+ }
+
+ /*
+ * Platform may be specified by either name or OF node, but
+ * can be left unspecified, and a dummy platform will be used.
+ */
+ if (link->platform_name && link->platform_of_node) {
+ dev_err(card->dev,
+ "Both platform name/of_node are set\n");
+ return -EINVAL;
+ }
+
+ /*
+ * CPU DAI must be specified by 1 of name or OF node,
+ * not both or neither.
+ */
+ if (!!link->cpu_dai_name == !!link->cpu_dai_of_node) {
+ dev_err(card->dev,
+ "Neither/both cpu_dai name/of_node are set\n");
+ return -EINVAL;
+ }
+ }
+
dev_set_drvdata(card->dev, card);
snd_soc_initialize_card_lists(card);
@@ -3305,6 +3372,87 @@
}
EXPORT_SYMBOL_GPL(snd_soc_unregister_codec);
+/* Retrieve a card's name from device tree */
+int snd_soc_of_parse_card_name(struct snd_soc_card *card,
+ const char *propname)
+{
+ struct device_node *np = card->dev->of_node;
+ int ret;
+
+ ret = of_property_read_string_index(np, propname, 0, &card->name);
+ /*
+ * EINVAL means the property does not exist. This is fine providing
+ * card->name was previously set, which is checked later in
+ * snd_soc_register_card.
+ */
+ if (ret < 0 && ret != -EINVAL) {
+ dev_err(card->dev,
+ "Property '%s' could not be read: %d\n",
+ propname, ret);
+ return ret;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(snd_soc_of_parse_card_name);
+
+int snd_soc_of_parse_audio_routing(struct snd_soc_card *card,
+ const char *propname)
+{
+ struct device_node *np = card->dev->of_node;
+ int num_routes;
+ struct snd_soc_dapm_route *routes;
+ int i, ret;
+
+ num_routes = of_property_count_strings(np, propname);
+ if (num_routes & 1) {
+ dev_err(card->dev,
+ "Property '%s's length is not even\n",
+ propname);
+ return -EINVAL;
+ }
+ num_routes /= 2;
+ if (!num_routes) {
+ dev_err(card->dev,
+ "Property '%s's length is zero\n",
+ propname);
+ return -EINVAL;
+ }
+
+ routes = devm_kzalloc(card->dev, num_routes * sizeof(*routes),
+ GFP_KERNEL);
+ if (!routes) {
+ dev_err(card->dev,
+ "Could not allocate DAPM route table\n");
+ return -EINVAL;
+ }
+
+ for (i = 0; i < num_routes; i++) {
+ ret = of_property_read_string_index(np, propname,
+ 2 * i, &routes[i].sink);
+ if (ret) {
+ dev_err(card->dev,
+ "Property '%s' index %d could not be read: %d\n",
+ propname, 2 * i, ret);
+ return -EINVAL;
+ }
+ ret = of_property_read_string_index(np, propname,
+ (2 * i) + 1, &routes[i].source);
+ if (ret) {
+ dev_err(card->dev,
+ "Property '%s' index %d could not be read: %d\n",
+ propname, (2 * i) + 1, ret);
+ return -EINVAL;
+ }
+ }
+
+ card->num_dapm_routes = num_routes;
+ card->dapm_routes = routes;
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(snd_soc_of_parse_audio_routing);
+
static int __init snd_soc_init(void)
{
#ifdef CONFIG_DEBUG_FS
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index f42e8b9..3ad1f59 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -39,6 +39,7 @@
#include <linux/platform_device.h>
#include <linux/jiffies.h>
#include <linux/debugfs.h>
+#include <linux/pm_runtime.h>
#include <linux/slab.h>
#include <sound/core.h>
#include <sound/pcm.h>
@@ -339,6 +340,7 @@
case snd_soc_dapm_output:
case snd_soc_dapm_adc:
case snd_soc_dapm_input:
+ case snd_soc_dapm_siggen:
case snd_soc_dapm_dac:
case snd_soc_dapm_micbias:
case snd_soc_dapm_vmid:
@@ -772,6 +774,11 @@
return widget->inputs;
}
+ /* signal generator */
+ if (widget->id == snd_soc_dapm_siggen) {
+ widget->inputs = snd_soc_dapm_suspend_check(widget);
+ return widget->inputs;
+ }
}
list_for_each_entry(path, &widget->sources, list_sink) {
@@ -1200,6 +1207,9 @@
/* If we're off and we're not supposed to be go into STANDBY */
if (d->bias_level == SND_SOC_BIAS_OFF &&
d->target_bias_level != SND_SOC_BIAS_OFF) {
+ if (d->dev)
+ pm_runtime_get_sync(d->dev);
+
ret = snd_soc_dapm_set_bias_level(d, SND_SOC_BIAS_STANDBY);
if (ret != 0)
dev_err(d->dev,
@@ -1239,6 +1249,9 @@
ret = snd_soc_dapm_set_bias_level(d, SND_SOC_BIAS_OFF);
if (ret != 0)
dev_err(d->dev, "Failed to turn off bias: %d\n", ret);
+
+ if (d->dev)
+ pm_runtime_put_sync(d->dev);
}
/* If we just powered up then move to active bias */
@@ -1725,8 +1738,7 @@
static ssize_t dapm_widget_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
- struct snd_soc_pcm_runtime *rtd =
- container_of(dev, struct snd_soc_pcm_runtime, dev);
+ struct snd_soc_pcm_runtime *rtd = dev_get_drvdata(dev);
struct snd_soc_codec *codec =rtd->codec;
struct snd_soc_dapm_widget *w;
int count = 0;
@@ -1982,6 +1994,7 @@
case snd_soc_dapm_out_drv:
case snd_soc_dapm_input:
case snd_soc_dapm_output:
+ case snd_soc_dapm_siggen:
case snd_soc_dapm_micbias:
case snd_soc_dapm_vmid:
case snd_soc_dapm_pre:
@@ -2947,6 +2960,79 @@
}
EXPORT_SYMBOL_GPL(snd_soc_dapm_ignore_suspend);
+static bool snd_soc_dapm_widget_in_card_paths(struct snd_soc_card *card,
+ struct snd_soc_dapm_widget *w)
+{
+ struct snd_soc_dapm_path *p;
+
+ list_for_each_entry(p, &card->paths, list) {
+ if ((p->source == w) || (p->sink == w)) {
+ dev_dbg(card->dev,
+ "... Path %s(id:%d dapm:%p) - %s(id:%d dapm:%p)\n",
+ p->source->name, p->source->id, p->source->dapm,
+ p->sink->name, p->sink->id, p->sink->dapm);
+
+ /* Connected to something other than the codec */
+ if (p->source->dapm != p->sink->dapm)
+ return true;
+ /*
+ * Loopback connection from codec external pin to
+ * codec external pin
+ */
+ if (p->sink->id == snd_soc_dapm_input) {
+ switch (p->source->id) {
+ case snd_soc_dapm_output:
+ case snd_soc_dapm_micbias:
+ return true;
+ default:
+ break;
+ }
+ }
+ }
+ }
+
+ return false;
+}
+
+/**
+ * snd_soc_dapm_auto_nc_codec_pins - call snd_soc_dapm_nc_pin for unused pins
+ * @codec: The codec whose pins should be processed
+ *
+ * Automatically call snd_soc_dapm_nc_pin() for any external pins in the codec
+ * which are unused. Pins are used if they are connected externally to the
+ * codec, whether that be to some other device, or a loop-back connection to
+ * the codec itself.
+ */
+void snd_soc_dapm_auto_nc_codec_pins(struct snd_soc_codec *codec)
+{
+ struct snd_soc_card *card = codec->card;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
+ struct snd_soc_dapm_widget *w;
+
+ dev_dbg(codec->dev, "Auto NC: DAPMs: card:%p codec:%p\n",
+ &card->dapm, &codec->dapm);
+
+ list_for_each_entry(w, &card->widgets, list) {
+ if (w->dapm != dapm)
+ continue;
+ switch (w->id) {
+ case snd_soc_dapm_input:
+ case snd_soc_dapm_output:
+ case snd_soc_dapm_micbias:
+ dev_dbg(codec->dev, "Auto NC: Checking widget %s\n",
+ w->name);
+ if (!snd_soc_dapm_widget_in_card_paths(card, w)) {
+ dev_dbg(codec->dev,
+ "... Not in map; disabling\n");
+ snd_soc_dapm_nc_pin(dapm, w->name);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+}
+
/**
* snd_soc_dapm_free - free dapm resources
* @dapm: DAPM context
diff --git a/sound/soc/soc-jack.c b/sound/soc/soc-jack.c
index 6c5ebd3..ee4353f 100644
--- a/sound/soc/soc-jack.c
+++ b/sound/soc/soc-jack.c
@@ -341,10 +341,8 @@
gpios[i].gpio, ret);
}
-#ifdef CONFIG_GPIO_SYSFS
/* Expose GPIO value over sysfs for diagnostic purposes */
gpio_export(gpios[i].gpio, false);
-#endif
/* Update initial jack status */
snd_soc_jack_gpio_detect(&gpios[i]);
@@ -376,9 +374,7 @@
int i;
for (i = 0; i < count; i++) {
-#ifdef CONFIG_GPIO_SYSFS
gpio_unexport(gpios[i].gpio);
-#endif
free_irq(gpio_to_irq(gpios[i].gpio), &gpios[i]);
cancel_delayed_work_sync(&gpios[i].work);
gpio_free(gpios[i].gpio);
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
index ee15337..cdc860a 100644
--- a/sound/soc/soc-pcm.c
+++ b/sound/soc/soc-pcm.c
@@ -19,6 +19,7 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/delay.h>
+#include <linux/pm_runtime.h>
#include <linux/slab.h>
#include <linux/workqueue.h>
#include <sound/core.h>
@@ -77,6 +78,10 @@
struct snd_soc_dai_driver *codec_dai_drv = codec_dai->driver;
int ret = 0;
+ pm_runtime_get_sync(cpu_dai->dev);
+ pm_runtime_get_sync(codec_dai->dev);
+ pm_runtime_get_sync(platform->dev);
+
mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
/* startup the audio subsystem */
@@ -233,6 +238,11 @@
cpu_dai->driver->ops->shutdown(substream, cpu_dai);
out:
mutex_unlock(&rtd->pcm_mutex);
+
+ pm_runtime_put(platform->dev);
+ pm_runtime_put(codec_dai->dev);
+ pm_runtime_put(cpu_dai->dev);
+
return ret;
}
@@ -319,7 +329,8 @@
cpu_dai->runtime = NULL;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- if (unlikely(codec->ignore_pmdown_time)) {
+ if (codec->ignore_pmdown_time ||
+ rtd->dai_link->ignore_pmdown_time) {
/* powered down playback stream now */
snd_soc_dapm_stream_event(rtd,
codec_dai->driver->playback.stream_name,
@@ -338,6 +349,11 @@
}
mutex_unlock(&rtd->pcm_mutex);
+
+ pm_runtime_put(platform->dev);
+ pm_runtime_put(codec_dai->dev);
+ pm_runtime_put(cpu_dai->dev);
+
return 0;
}
@@ -582,17 +598,6 @@
return offset;
}
-/* ASoC PCM operations */
-static struct snd_pcm_ops soc_pcm_ops = {
- .open = soc_pcm_open,
- .close = soc_pcm_close,
- .hw_params = soc_pcm_hw_params,
- .hw_free = soc_pcm_hw_free,
- .prepare = soc_pcm_prepare,
- .trigger = soc_pcm_trigger,
- .pointer = soc_pcm_pointer,
-};
-
/* create a new pcm */
int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num)
{
@@ -600,10 +605,19 @@
struct snd_soc_platform *platform = rtd->platform;
struct snd_soc_dai *codec_dai = rtd->codec_dai;
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ struct snd_pcm_ops *soc_pcm_ops = &rtd->ops;
struct snd_pcm *pcm;
char new_name[64];
int ret = 0, playback = 0, capture = 0;
+ soc_pcm_ops->open = soc_pcm_open;
+ soc_pcm_ops->close = soc_pcm_close;
+ soc_pcm_ops->hw_params = soc_pcm_hw_params;
+ soc_pcm_ops->hw_free = soc_pcm_hw_free;
+ soc_pcm_ops->prepare = soc_pcm_prepare;
+ soc_pcm_ops->trigger = soc_pcm_trigger;
+ soc_pcm_ops->pointer = soc_pcm_pointer;
+
/* check client and interface hw capabilities */
snprintf(new_name, sizeof(new_name), "%s %s-%d",
rtd->dai_link->stream_name, codec_dai->name, num);
@@ -627,20 +641,20 @@
rtd->pcm = pcm;
pcm->private_data = rtd;
if (platform->driver->ops) {
- soc_pcm_ops.mmap = platform->driver->ops->mmap;
- soc_pcm_ops.pointer = platform->driver->ops->pointer;
- soc_pcm_ops.ioctl = platform->driver->ops->ioctl;
- soc_pcm_ops.copy = platform->driver->ops->copy;
- soc_pcm_ops.silence = platform->driver->ops->silence;
- soc_pcm_ops.ack = platform->driver->ops->ack;
- soc_pcm_ops.page = platform->driver->ops->page;
+ soc_pcm_ops->mmap = platform->driver->ops->mmap;
+ soc_pcm_ops->pointer = platform->driver->ops->pointer;
+ soc_pcm_ops->ioctl = platform->driver->ops->ioctl;
+ soc_pcm_ops->copy = platform->driver->ops->copy;
+ soc_pcm_ops->silence = platform->driver->ops->silence;
+ soc_pcm_ops->ack = platform->driver->ops->ack;
+ soc_pcm_ops->page = platform->driver->ops->page;
}
if (playback)
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &soc_pcm_ops);
+ snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, soc_pcm_ops);
if (capture)
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &soc_pcm_ops);
+ snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, soc_pcm_ops);
if (platform->driver->pcm_new) {
ret = platform->driver->pcm_new(rtd);
diff --git a/sound/soc/tegra/Kconfig b/sound/soc/tegra/Kconfig
index c6af1fd..ce1b773 100644
--- a/sound/soc/tegra/Kconfig
+++ b/sound/soc/tegra/Kconfig
@@ -47,3 +47,12 @@
help
Say Y or M here if you want to add support for SoC audio on the
TrimSlice platform.
+
+config SND_SOC_TEGRA_ALC5632
+ tristate "SoC Audio support for Tegra boards using an ALC5632 codec"
+ depends on SND_SOC_TEGRA && I2C
+ select SND_SOC_TEGRA_I2S
+ select SND_SOC_ALC5632
+ help
+ Say Y or M here if you want to add support for SoC audio on the
+ Toshiba AC100 netbook.
diff --git a/sound/soc/tegra/Makefile b/sound/soc/tegra/Makefile
index 4d943b3..8e584b8 100644
--- a/sound/soc/tegra/Makefile
+++ b/sound/soc/tegra/Makefile
@@ -14,6 +14,8 @@
# Tegra machine Support
snd-soc-tegra-wm8903-objs := tegra_wm8903.o
snd-soc-tegra-trimslice-objs := trimslice.o
+snd-soc-tegra-alc5632-objs := tegra_alc5632.o
obj-$(CONFIG_SND_SOC_TEGRA_WM8903) += snd-soc-tegra-wm8903.o
obj-$(CONFIG_SND_SOC_TEGRA_TRIMSLICE) += snd-soc-tegra-trimslice.o
+obj-$(CONFIG_SND_SOC_TEGRA_ALC5632) += snd-soc-tegra-alc5632.o
diff --git a/sound/soc/tegra/tegra_alc5632.c b/sound/soc/tegra/tegra_alc5632.c
new file mode 100644
index 0000000..4a0e805
--- /dev/null
+++ b/sound/soc/tegra/tegra_alc5632.c
@@ -0,0 +1,214 @@
+/*
+* tegra_alc5632.c -- Toshiba AC100(PAZ00) machine ASoC driver
+*
+* Copyright (C) 2011 The AC100 Kernel Team <ac100@lists.lauchpad.net>
+*
+* Authors: Leon Romanovsky <leon@leon.nu>
+* Andrey Danin <danindrey@mail.ru>
+* Marc Dietrich <marvin24@gmx.de>
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License version 2 as
+* published by the Free Software Foundation.
+*/
+
+#include <asm/mach-types.h>
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/gpio.h>
+
+#include <sound/core.h>
+#include <sound/jack.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+
+#include "../codecs/alc5632.h"
+
+#include "tegra_das.h"
+#include "tegra_i2s.h"
+#include "tegra_pcm.h"
+#include "tegra_asoc_utils.h"
+
+#define DRV_NAME "tegra-alc5632"
+
+struct tegra_alc5632 {
+ struct tegra_asoc_utils_data util_data;
+};
+
+static int tegra_alc5632_asoc_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *codec_dai = rtd->codec_dai;
+ struct snd_soc_codec *codec = rtd->codec;
+ struct snd_soc_card *card = codec->card;
+ struct tegra_alc5632 *alc5632 = snd_soc_card_get_drvdata(card);
+ int srate, mclk;
+ int err;
+
+ srate = params_rate(params);
+ mclk = 512 * srate;
+
+ err = tegra_asoc_utils_set_rate(&alc5632->util_data, srate, mclk);
+ if (err < 0) {
+ dev_err(card->dev, "Can't configure clocks\n");
+ return err;
+ }
+
+ err = snd_soc_dai_set_sysclk(codec_dai, 0, mclk,
+ SND_SOC_CLOCK_IN);
+ if (err < 0) {
+ dev_err(card->dev, "codec_dai clock not set\n");
+ return err;
+ }
+
+ return 0;
+}
+
+static struct snd_soc_ops tegra_alc5632_asoc_ops = {
+ .hw_params = tegra_alc5632_asoc_hw_params,
+};
+
+static struct snd_soc_jack tegra_alc5632_hs_jack;
+
+static struct snd_soc_jack_pin tegra_alc5632_hs_jack_pins[] = {
+ {
+ .pin = "Headset Mic",
+ .mask = SND_JACK_MICROPHONE,
+ },
+ {
+ .pin = "Headset Stereophone",
+ .mask = SND_JACK_HEADPHONE,
+ },
+};
+
+static const struct snd_soc_dapm_widget tegra_alc5632_dapm_widgets[] = {
+ SND_SOC_DAPM_SPK("Int Spk", NULL),
+ SND_SOC_DAPM_HP("Headset Stereophone", NULL),
+ SND_SOC_DAPM_MIC("Headset Mic", NULL),
+};
+
+static const struct snd_soc_dapm_route tegra_alc5632_audio_map[] = {
+ /* Internal Speaker */
+ {"Int Spk", NULL, "SPKOUT"},
+ {"Int Spk", NULL, "SPKOUTN"},
+
+ /* Headset Mic */
+ {"MIC1", NULL, "MICBIAS1"},
+ {"MICBIAS1", NULL, "Headset Mic"},
+
+ /* Headset Stereophone */
+ {"Headset Stereophone", NULL, "HPR"},
+ {"Headset Stereophone", NULL, "HPL"},
+};
+
+static const struct snd_kcontrol_new tegra_alc5632_controls[] = {
+ SOC_DAPM_PIN_SWITCH("Int Spk"),
+};
+
+static int tegra_alc5632_asoc_init(struct snd_soc_pcm_runtime *rtd)
+{
+ struct snd_soc_codec *codec = rtd->codec;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
+
+ snd_soc_jack_new(codec, "Headset Jack", SND_JACK_HEADSET,
+ &tegra_alc5632_hs_jack);
+ snd_soc_jack_add_pins(&tegra_alc5632_hs_jack,
+ ARRAY_SIZE(tegra_alc5632_hs_jack_pins),
+ tegra_alc5632_hs_jack_pins);
+
+ snd_soc_dapm_force_enable_pin(dapm, "MICBIAS1");
+
+ return 0;
+}
+
+static struct snd_soc_dai_link tegra_alc5632_dai = {
+ .name = "ALC5632",
+ .stream_name = "ALC5632 PCM",
+ .codec_name = "alc5632.0-001e",
+ .platform_name = "tegra-pcm-audio",
+ .cpu_dai_name = "tegra-i2s.0",
+ .codec_dai_name = "alc5632-hifi",
+ .init = tegra_alc5632_asoc_init,
+ .ops = &tegra_alc5632_asoc_ops,
+ .dai_fmt = SND_SOC_DAIFMT_I2S
+ | SND_SOC_DAIFMT_NB_NF
+ | SND_SOC_DAIFMT_CBS_CFS,
+};
+
+static struct snd_soc_card snd_soc_tegra_alc5632 = {
+ .name = "tegra-alc5632",
+ .owner = THIS_MODULE,
+ .dai_link = &tegra_alc5632_dai,
+ .num_links = 1,
+ .controls = tegra_alc5632_controls,
+ .num_controls = ARRAY_SIZE(tegra_alc5632_controls),
+ .dapm_widgets = tegra_alc5632_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(tegra_alc5632_dapm_widgets),
+ .dapm_routes = tegra_alc5632_audio_map,
+ .num_dapm_routes = ARRAY_SIZE(tegra_alc5632_audio_map),
+ .fully_routed = true,
+};
+
+static __devinit int tegra_alc5632_probe(struct platform_device *pdev)
+{
+ struct snd_soc_card *card = &snd_soc_tegra_alc5632;
+ struct tegra_alc5632 *alc5632;
+ int ret;
+
+ alc5632 = devm_kzalloc(&pdev->dev,
+ sizeof(struct tegra_alc5632), GFP_KERNEL);
+ if (!alc5632) {
+ dev_err(&pdev->dev, "Can't allocate tegra_alc5632\n");
+ return -ENOMEM;
+ }
+
+ ret = tegra_asoc_utils_init(&alc5632->util_data, &pdev->dev);
+ if (ret)
+ return ret;
+
+ card->dev = &pdev->dev;
+ platform_set_drvdata(pdev, card);
+ snd_soc_card_set_drvdata(card, alc5632);
+
+ ret = snd_soc_register_card(card);
+ if (ret) {
+ dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n",
+ ret);
+ tegra_asoc_utils_fini(&alc5632->util_data);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int __devexit tegra_alc5632_remove(struct platform_device *pdev)
+{
+ struct snd_soc_card *card = platform_get_drvdata(pdev);
+ struct tegra_alc5632 *alc5632 = snd_soc_card_get_drvdata(card);
+
+ snd_soc_unregister_card(card);
+
+ tegra_asoc_utils_fini(&alc5632->util_data);
+
+ return 0;
+}
+
+static struct platform_driver tegra_alc5632_driver = {
+ .driver = {
+ .name = DRV_NAME,
+ .owner = THIS_MODULE,
+ .pm = &snd_soc_pm_ops,
+ },
+ .probe = tegra_alc5632_probe,
+ .remove = __devexit_p(tegra_alc5632_remove),
+};
+module_platform_driver(tegra_alc5632_driver);
+
+MODULE_AUTHOR("Leon Romanovsky <leon@leon.nu>");
+MODULE_DESCRIPTION("Tegra+ALC5632 machine ASoC driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:" DRV_NAME);
diff --git a/sound/soc/tegra/tegra_das.c b/sound/soc/tegra/tegra_das.c
index 3b55a44..3b3c1ba 100644
--- a/sound/soc/tegra/tegra_das.c
+++ b/sound/soc/tegra/tegra_das.c
@@ -172,11 +172,11 @@
if (das)
return -ENODEV;
- das = kzalloc(sizeof(struct tegra_das), GFP_KERNEL);
+ das = devm_kzalloc(&pdev->dev, sizeof(struct tegra_das), GFP_KERNEL);
if (!das) {
dev_err(&pdev->dev, "Can't allocate tegra_das\n");
ret = -ENOMEM;
- goto exit;
+ goto err;
}
das->dev = &pdev->dev;
@@ -184,22 +184,35 @@
if (!res) {
dev_err(&pdev->dev, "No memory resource\n");
ret = -ENODEV;
- goto err_free;
+ goto err;
}
- region = request_mem_region(res->start, resource_size(res),
- pdev->name);
+ region = devm_request_mem_region(&pdev->dev, res->start,
+ resource_size(res), pdev->name);
if (!region) {
dev_err(&pdev->dev, "Memory region already claimed\n");
ret = -EBUSY;
- goto err_free;
+ goto err;
}
- das->regs = ioremap(res->start, resource_size(res));
+ das->regs = devm_ioremap(&pdev->dev, res->start, resource_size(res));
if (!das->regs) {
dev_err(&pdev->dev, "ioremap failed\n");
ret = -ENOMEM;
- goto err_release;
+ goto err;
+ }
+
+ ret = tegra_das_connect_dap_to_dac(TEGRA_DAS_DAP_ID_1,
+ TEGRA_DAS_DAP_SEL_DAC1);
+ if (ret) {
+ dev_err(&pdev->dev, "Can't set up DAS DAP connection\n");
+ goto err;
+ }
+ ret = tegra_das_connect_dac_to_dap(TEGRA_DAS_DAC_ID_1,
+ TEGRA_DAS_DAC_SEL_DAP1);
+ if (ret) {
+ dev_err(&pdev->dev, "Can't set up DAS DAC connection\n");
+ goto err;
}
tegra_das_debug_add(das);
@@ -208,58 +221,41 @@
return 0;
-err_release:
- release_mem_region(res->start, resource_size(res));
-err_free:
- kfree(das);
+err:
das = NULL;
-exit:
return ret;
}
static int __devexit tegra_das_remove(struct platform_device *pdev)
{
- struct resource *res;
-
if (!das)
return -ENODEV;
- platform_set_drvdata(pdev, NULL);
-
tegra_das_debug_remove(das);
- iounmap(das->regs);
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- release_mem_region(res->start, resource_size(res));
-
- kfree(das);
das = NULL;
return 0;
}
+static const struct of_device_id tegra_das_of_match[] __devinitconst = {
+ { .compatible = "nvidia,tegra20-das", },
+ {},
+};
+
static struct platform_driver tegra_das_driver = {
.probe = tegra_das_probe,
.remove = __devexit_p(tegra_das_remove),
.driver = {
.name = DRV_NAME,
+ .owner = THIS_MODULE,
+ .of_match_table = tegra_das_of_match,
},
};
-
-static int __init tegra_das_modinit(void)
-{
- return platform_driver_register(&tegra_das_driver);
-}
-module_init(tegra_das_modinit);
-
-static void __exit tegra_das_modexit(void)
-{
- platform_driver_unregister(&tegra_das_driver);
-}
-module_exit(tegra_das_modexit);
+module_platform_driver(tegra_das_driver);
MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>");
MODULE_DESCRIPTION("Tegra DAS driver");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:" DRV_NAME);
+MODULE_DEVICE_TABLE(of, tegra_das_of_match);
diff --git a/sound/soc/tegra/tegra_i2s.c b/sound/soc/tegra/tegra_i2s.c
index 6728fab..33509de 100644
--- a/sound/soc/tegra/tegra_i2s.c
+++ b/sound/soc/tegra/tegra_i2s.c
@@ -36,13 +36,13 @@
#include <linux/seq_file.h>
#include <linux/slab.h>
#include <linux/io.h>
+#include <linux/of.h>
#include <mach/iomap.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include "tegra_das.h"
#include "tegra_i2s.h"
#define DRV_NAME "tegra-i2s"
@@ -99,13 +99,11 @@
.release = single_release,
};
-static void tegra_i2s_debug_add(struct tegra_i2s *i2s, int id)
+static void tegra_i2s_debug_add(struct tegra_i2s *i2s)
{
- char name[] = DRV_NAME ".0";
-
- snprintf(name, sizeof(name), DRV_NAME".%1d", id);
- i2s->debug = debugfs_create_file(name, S_IRUGO, snd_soc_debugfs_root,
- i2s, &tegra_i2s_debug_fops);
+ i2s->debug = debugfs_create_file(i2s->dai.name, S_IRUGO,
+ snd_soc_debugfs_root, i2s,
+ &tegra_i2s_debug_fops);
}
static void tegra_i2s_debug_remove(struct tegra_i2s *i2s)
@@ -306,93 +304,54 @@
return 0;
}
-static struct snd_soc_dai_ops tegra_i2s_dai_ops = {
+static const struct snd_soc_dai_ops tegra_i2s_dai_ops = {
.set_fmt = tegra_i2s_set_fmt,
.hw_params = tegra_i2s_hw_params,
.trigger = tegra_i2s_trigger,
};
-static struct snd_soc_dai_driver tegra_i2s_dai[] = {
- {
- .name = DRV_NAME ".0",
- .probe = tegra_i2s_probe,
- .playback = {
- .channels_min = 2,
- .channels_max = 2,
- .rates = SNDRV_PCM_RATE_8000_96000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- },
- .capture = {
- .channels_min = 2,
- .channels_max = 2,
- .rates = SNDRV_PCM_RATE_8000_96000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- },
- .ops = &tegra_i2s_dai_ops,
- .symmetric_rates = 1,
+static const struct snd_soc_dai_driver tegra_i2s_dai_template = {
+ .probe = tegra_i2s_probe,
+ .playback = {
+ .channels_min = 2,
+ .channels_max = 2,
+ .rates = SNDRV_PCM_RATE_8000_96000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE,
},
- {
- .name = DRV_NAME ".1",
- .probe = tegra_i2s_probe,
- .playback = {
- .channels_min = 2,
- .channels_max = 2,
- .rates = SNDRV_PCM_RATE_8000_96000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- },
- .capture = {
- .channels_min = 2,
- .channels_max = 2,
- .rates = SNDRV_PCM_RATE_8000_96000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- },
- .ops = &tegra_i2s_dai_ops,
- .symmetric_rates = 1,
+ .capture = {
+ .channels_min = 2,
+ .channels_max = 2,
+ .rates = SNDRV_PCM_RATE_8000_96000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE,
},
+ .ops = &tegra_i2s_dai_ops,
+ .symmetric_rates = 1,
};
static __devinit int tegra_i2s_platform_probe(struct platform_device *pdev)
{
struct tegra_i2s * i2s;
struct resource *mem, *memregion, *dmareq;
+ u32 of_dma[2];
+ u32 dma_ch;
int ret;
- if ((pdev->id < 0) ||
- (pdev->id >= ARRAY_SIZE(tegra_i2s_dai))) {
- dev_err(&pdev->dev, "ID %d out of range\n", pdev->id);
- return -EINVAL;
- }
-
- /*
- * FIXME: Until a codec driver exists for the tegra DAS, hard-code a
- * 1:1 mapping between audio controllers and audio ports.
- */
- ret = tegra_das_connect_dap_to_dac(TEGRA_DAS_DAP_ID_1 + pdev->id,
- TEGRA_DAS_DAP_SEL_DAC1 + pdev->id);
- if (ret) {
- dev_err(&pdev->dev, "Can't set up DAP connection\n");
- return ret;
- }
- ret = tegra_das_connect_dac_to_dap(TEGRA_DAS_DAC_ID_1 + pdev->id,
- TEGRA_DAS_DAC_SEL_DAP1 + pdev->id);
- if (ret) {
- dev_err(&pdev->dev, "Can't set up DAC connection\n");
- return ret;
- }
-
- i2s = kzalloc(sizeof(struct tegra_i2s), GFP_KERNEL);
+ i2s = devm_kzalloc(&pdev->dev, sizeof(struct tegra_i2s), GFP_KERNEL);
if (!i2s) {
dev_err(&pdev->dev, "Can't allocate tegra_i2s\n");
ret = -ENOMEM;
- goto exit;
+ goto err;
}
dev_set_drvdata(&pdev->dev, i2s);
+ i2s->dai = tegra_i2s_dai_template;
+ i2s->dai.name = dev_name(&pdev->dev);
+
i2s->clk_i2s = clk_get(&pdev->dev, NULL);
if (IS_ERR(i2s->clk_i2s)) {
dev_err(&pdev->dev, "Can't retrieve i2s clock\n");
ret = PTR_ERR(i2s->clk_i2s);
- goto err_free;
+ goto err;
}
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -404,104 +363,93 @@
dmareq = platform_get_resource(pdev, IORESOURCE_DMA, 0);
if (!dmareq) {
- dev_err(&pdev->dev, "No DMA resource\n");
- ret = -ENODEV;
- goto err_clk_put;
+ if (of_property_read_u32_array(pdev->dev.of_node,
+ "nvidia,dma-request-selector",
+ of_dma, 2) < 0) {
+ dev_err(&pdev->dev, "No DMA resource\n");
+ ret = -ENODEV;
+ goto err_clk_put;
+ }
+ dma_ch = of_dma[1];
+ } else {
+ dma_ch = dmareq->start;
}
- memregion = request_mem_region(mem->start, resource_size(mem),
- DRV_NAME);
+ memregion = devm_request_mem_region(&pdev->dev, mem->start,
+ resource_size(mem), DRV_NAME);
if (!memregion) {
dev_err(&pdev->dev, "Memory region already claimed\n");
ret = -EBUSY;
goto err_clk_put;
}
- i2s->regs = ioremap(mem->start, resource_size(mem));
+ i2s->regs = devm_ioremap(&pdev->dev, mem->start, resource_size(mem));
if (!i2s->regs) {
dev_err(&pdev->dev, "ioremap failed\n");
ret = -ENOMEM;
- goto err_release;
+ goto err_clk_put;
}
i2s->capture_dma_data.addr = mem->start + TEGRA_I2S_FIFO2;
i2s->capture_dma_data.wrap = 4;
i2s->capture_dma_data.width = 32;
- i2s->capture_dma_data.req_sel = dmareq->start;
+ i2s->capture_dma_data.req_sel = dma_ch;
i2s->playback_dma_data.addr = mem->start + TEGRA_I2S_FIFO1;
i2s->playback_dma_data.wrap = 4;
i2s->playback_dma_data.width = 32;
- i2s->playback_dma_data.req_sel = dmareq->start;
+ i2s->playback_dma_data.req_sel = dma_ch;
i2s->reg_ctrl = TEGRA_I2S_CTRL_FIFO_FORMAT_PACKED;
- ret = snd_soc_register_dai(&pdev->dev, &tegra_i2s_dai[pdev->id]);
+ ret = snd_soc_register_dai(&pdev->dev, &i2s->dai);
if (ret) {
dev_err(&pdev->dev, "Could not register DAI: %d\n", ret);
ret = -ENOMEM;
- goto err_unmap;
+ goto err_clk_put;
}
- tegra_i2s_debug_add(i2s, pdev->id);
+ tegra_i2s_debug_add(i2s);
return 0;
-err_unmap:
- iounmap(i2s->regs);
-err_release:
- release_mem_region(mem->start, resource_size(mem));
err_clk_put:
clk_put(i2s->clk_i2s);
-err_free:
- kfree(i2s);
-exit:
+err:
return ret;
}
static int __devexit tegra_i2s_platform_remove(struct platform_device *pdev)
{
struct tegra_i2s *i2s = dev_get_drvdata(&pdev->dev);
- struct resource *res;
snd_soc_unregister_dai(&pdev->dev);
tegra_i2s_debug_remove(i2s);
- iounmap(i2s->regs);
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- release_mem_region(res->start, resource_size(res));
-
clk_put(i2s->clk_i2s);
- kfree(i2s);
-
return 0;
}
+static const struct of_device_id tegra_i2s_of_match[] __devinitconst = {
+ { .compatible = "nvidia,tegra20-i2s", },
+ {},
+};
+
static struct platform_driver tegra_i2s_driver = {
.driver = {
.name = DRV_NAME,
.owner = THIS_MODULE,
+ .of_match_table = tegra_i2s_of_match,
},
.probe = tegra_i2s_platform_probe,
.remove = __devexit_p(tegra_i2s_platform_remove),
};
-
-static int __init snd_tegra_i2s_init(void)
-{
- return platform_driver_register(&tegra_i2s_driver);
-}
-module_init(snd_tegra_i2s_init);
-
-static void __exit snd_tegra_i2s_exit(void)
-{
- platform_driver_unregister(&tegra_i2s_driver);
-}
-module_exit(snd_tegra_i2s_exit);
+module_platform_driver(tegra_i2s_driver);
MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>");
MODULE_DESCRIPTION("Tegra I2S ASoC driver");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:" DRV_NAME);
+MODULE_DEVICE_TABLE(of, tegra_i2s_of_match);
diff --git a/sound/soc/tegra/tegra_i2s.h b/sound/soc/tegra/tegra_i2s.h
index 2b38a09..15ce1e2 100644
--- a/sound/soc/tegra/tegra_i2s.h
+++ b/sound/soc/tegra/tegra_i2s.h
@@ -153,6 +153,7 @@
#define TEGRA_I2S_FIFO_SCR_FIFO1_ATN_LVL_TWELVE_SLOTS (TEGRA_I2S_FIFO_ATN_LVL_TWELVE_SLOTS << TEGRA_I2S_FIFO_SCR_FIFO1_ATN_LVL_SHIFT)
struct tegra_i2s {
+ struct snd_soc_dai_driver dai;
struct clk *clk_i2s;
int clk_refs;
struct tegra_pcm_dma_params capture_dma_data;
diff --git a/sound/soc/tegra/tegra_pcm.c b/sound/soc/tegra/tegra_pcm.c
index 436def1..c224315 100644
--- a/sound/soc/tegra/tegra_pcm.c
+++ b/sound/soc/tegra/tegra_pcm.c
@@ -330,7 +330,6 @@
static int tegra_pcm_new(struct snd_soc_pcm_runtime *rtd)
{
struct snd_card *card = rtd->card->snd_card;
- struct snd_soc_dai *dai = rtd->cpu_dai;
struct snd_pcm *pcm = rtd->pcm;
int ret = 0;
@@ -339,14 +338,14 @@
if (!card->dev->coherent_dma_mask)
card->dev->coherent_dma_mask = 0xffffffff;
- if (dai->driver->playback.channels_min) {
+ if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
ret = tegra_pcm_preallocate_dma_buffer(pcm,
SNDRV_PCM_STREAM_PLAYBACK);
if (ret)
goto err;
}
- if (dai->driver->capture.channels_min) {
+ if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
ret = tegra_pcm_preallocate_dma_buffer(pcm,
SNDRV_PCM_STREAM_CAPTURE);
if (ret)
@@ -392,18 +391,7 @@
.probe = tegra_pcm_platform_probe,
.remove = __devexit_p(tegra_pcm_platform_remove),
};
-
-static int __init snd_tegra_pcm_init(void)
-{
- return platform_driver_register(&tegra_pcm_driver);
-}
-module_init(snd_tegra_pcm_init);
-
-static void __exit snd_tegra_pcm_exit(void)
-{
- platform_driver_unregister(&tegra_pcm_driver);
-}
-module_exit(snd_tegra_pcm_exit);
+module_platform_driver(tegra_pcm_driver);
MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>");
MODULE_DESCRIPTION("Tegra PCM ASoC driver");
diff --git a/sound/soc/tegra/tegra_spdif.c b/sound/soc/tegra/tegra_spdif.c
index dd11d0c..475428c 100644
--- a/sound/soc/tegra/tegra_spdif.c
+++ b/sound/soc/tegra/tegra_spdif.c
@@ -226,7 +226,7 @@
return 0;
}
-static struct snd_soc_dai_ops tegra_spdif_dai_ops = {
+static const struct snd_soc_dai_ops tegra_spdif_dai_ops = {
.hw_params = tegra_spdif_hw_params,
.trigger = tegra_spdif_trigger,
};
@@ -352,17 +352,7 @@
.remove = __devexit_p(tegra_spdif_platform_remove),
};
-static int __init snd_tegra_spdif_init(void)
-{
- return platform_driver_register(&tegra_spdif_driver);
-}
-module_init(snd_tegra_spdif_init);
-
-static void __exit snd_tegra_spdif_exit(void)
-{
- platform_driver_unregister(&tegra_spdif_driver);
-}
-module_exit(snd_tegra_spdif_exit);
+module_platform_driver(tegra_spdif_driver);
MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>");
MODULE_DESCRIPTION("Tegra SPDIF ASoC driver");
diff --git a/sound/soc/tegra/tegra_wm8903.c b/sound/soc/tegra/tegra_wm8903.c
index a81cf39..566655e 100644
--- a/sound/soc/tegra/tegra_wm8903.c
+++ b/sound/soc/tegra/tegra_wm8903.c
@@ -34,6 +34,7 @@
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/gpio.h>
+#include <linux/of_gpio.h>
#include <mach/tegra_wm8903_pdata.h>
@@ -59,8 +60,9 @@
#define GPIO_HP_DET BIT(4)
struct tegra_wm8903 {
+ struct tegra_wm8903_platform_data pdata;
+ struct platform_device *pcm_dev;
struct tegra_asoc_utils_data util_data;
- struct tegra_wm8903_platform_data *pdata;
int gpio_requested;
};
@@ -160,7 +162,7 @@
struct snd_soc_dapm_context *dapm = w->dapm;
struct snd_soc_card *card = dapm->card;
struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card);
- struct tegra_wm8903_platform_data *pdata = machine->pdata;
+ struct tegra_wm8903_platform_data *pdata = &machine->pdata;
if (!(machine->gpio_requested & GPIO_SPKR_EN))
return 0;
@@ -177,7 +179,7 @@
struct snd_soc_dapm_context *dapm = w->dapm;
struct snd_soc_card *card = dapm->card;
struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card);
- struct tegra_wm8903_platform_data *pdata = machine->pdata;
+ struct tegra_wm8903_platform_data *pdata = &machine->pdata;
if (!(machine->gpio_requested & GPIO_HP_MUTE))
return 0;
@@ -201,8 +203,8 @@
{"Int Spk", NULL, "RON"},
{"Int Spk", NULL, "LOP"},
{"Int Spk", NULL, "LON"},
- {"Mic Bias", NULL, "Mic Jack"},
- {"IN1L", NULL, "Mic Bias"},
+ {"Mic Jack", NULL, "MICBIAS"},
+ {"IN1L", NULL, "Mic Jack"},
};
static const struct snd_soc_dapm_route seaboard_audio_map[] = {
@@ -212,8 +214,8 @@
{"Int Spk", NULL, "RON"},
{"Int Spk", NULL, "LOP"},
{"Int Spk", NULL, "LON"},
- {"Mic Bias", NULL, "Mic Jack"},
- {"IN1R", NULL, "Mic Bias"},
+ {"Mic Jack", NULL, "MICBIAS"},
+ {"IN1R", NULL, "Mic Jack"},
};
static const struct snd_soc_dapm_route kaen_audio_map[] = {
@@ -223,8 +225,8 @@
{"Int Spk", NULL, "RON"},
{"Int Spk", NULL, "LOP"},
{"Int Spk", NULL, "LON"},
- {"Mic Bias", NULL, "Mic Jack"},
- {"IN2R", NULL, "Mic Bias"},
+ {"Mic Jack", NULL, "MICBIAS"},
+ {"IN2R", NULL, "Mic Jack"},
};
static const struct snd_soc_dapm_route aebl_audio_map[] = {
@@ -232,8 +234,8 @@
{"Headphone Jack", NULL, "HPOUTL"},
{"Int Spk", NULL, "LINEOUTR"},
{"Int Spk", NULL, "LINEOUTL"},
- {"Mic Bias", NULL, "Mic Jack"},
- {"IN1R", NULL, "Mic Bias"},
+ {"Mic Jack", NULL, "MICBIAS"},
+ {"IN1R", NULL, "Mic Jack"},
};
static const struct snd_kcontrol_new tegra_wm8903_controls[] = {
@@ -246,9 +248,36 @@
struct snd_soc_dapm_context *dapm = &codec->dapm;
struct snd_soc_card *card = codec->card;
struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card);
- struct tegra_wm8903_platform_data *pdata = machine->pdata;
+ struct tegra_wm8903_platform_data *pdata = &machine->pdata;
+ struct device_node *np = card->dev->of_node;
int ret;
+ if (card->dev->platform_data) {
+ memcpy(pdata, card->dev->platform_data, sizeof(*pdata));
+ } else if (np) {
+ /*
+ * This part must be in init() rather than probe() in order to
+ * guarantee that the WM8903 has been probed, and hence its
+ * GPIO controller registered, which is a pre-condition for
+ * of_get_named_gpio() to be able to map the phandles in the
+ * properties to the controller node. Given this, all
+ * pdata handling is in init() for consistency.
+ */
+ pdata->gpio_spkr_en = of_get_named_gpio(np,
+ "nvidia,spkr-en-gpios", 0);
+ pdata->gpio_hp_mute = of_get_named_gpio(np,
+ "nvidia,hp-mute-gpios", 0);
+ pdata->gpio_hp_det = of_get_named_gpio(np,
+ "nvidia,hp-det-gpios", 0);
+ pdata->gpio_int_mic_en = of_get_named_gpio(np,
+ "nvidia,int-mic-en-gpios", 0);
+ pdata->gpio_ext_mic_en = of_get_named_gpio(np,
+ "nvidia,ext-mic-en-gpios", 0);
+ } else {
+ dev_err(card->dev, "No platform data supplied\n");
+ return -EINVAL;
+ }
+
if (gpio_is_valid(pdata->gpio_spkr_en)) {
ret = gpio_request(pdata->gpio_spkr_en, "spkr_en");
if (ret) {
@@ -316,28 +345,7 @@
wm8903_mic_detect(codec, &tegra_wm8903_mic_jack, SND_JACK_MICROPHONE,
0);
- snd_soc_dapm_force_enable_pin(dapm, "Mic Bias");
-
- /* FIXME: Calculate automatically based on DAPM routes? */
- if (!machine_is_harmony())
- snd_soc_dapm_nc_pin(dapm, "IN1L");
- if (!machine_is_seaboard() && !machine_is_aebl())
- snd_soc_dapm_nc_pin(dapm, "IN1R");
- snd_soc_dapm_nc_pin(dapm, "IN2L");
- if (!machine_is_kaen())
- snd_soc_dapm_nc_pin(dapm, "IN2R");
- snd_soc_dapm_nc_pin(dapm, "IN3L");
- snd_soc_dapm_nc_pin(dapm, "IN3R");
-
- if (machine_is_aebl()) {
- snd_soc_dapm_nc_pin(dapm, "LON");
- snd_soc_dapm_nc_pin(dapm, "RON");
- snd_soc_dapm_nc_pin(dapm, "ROP");
- snd_soc_dapm_nc_pin(dapm, "LOP");
- } else {
- snd_soc_dapm_nc_pin(dapm, "LINEOUTR");
- snd_soc_dapm_nc_pin(dapm, "LINEOUTL");
- }
+ snd_soc_dapm_force_enable_pin(dapm, "MICBIAS");
return 0;
}
@@ -355,6 +363,7 @@
static struct snd_soc_card snd_soc_tegra_wm8903 = {
.name = "tegra-wm8903",
+ .owner = THIS_MODULE,
.dai_link = &tegra_wm8903_dai,
.num_links = 1,
@@ -362,51 +371,91 @@
.num_controls = ARRAY_SIZE(tegra_wm8903_controls),
.dapm_widgets = tegra_wm8903_dapm_widgets,
.num_dapm_widgets = ARRAY_SIZE(tegra_wm8903_dapm_widgets),
+ .fully_routed = true,
};
static __devinit int tegra_wm8903_driver_probe(struct platform_device *pdev)
{
struct snd_soc_card *card = &snd_soc_tegra_wm8903;
struct tegra_wm8903 *machine;
- struct tegra_wm8903_platform_data *pdata;
int ret;
- pdata = pdev->dev.platform_data;
- if (!pdata) {
+ if (!pdev->dev.platform_data && !pdev->dev.of_node) {
dev_err(&pdev->dev, "No platform data supplied\n");
return -EINVAL;
}
- machine = kzalloc(sizeof(struct tegra_wm8903), GFP_KERNEL);
+ machine = devm_kzalloc(&pdev->dev, sizeof(struct tegra_wm8903),
+ GFP_KERNEL);
if (!machine) {
dev_err(&pdev->dev, "Can't allocate tegra_wm8903 struct\n");
- return -ENOMEM;
+ ret = -ENOMEM;
+ goto err;
}
-
- machine->pdata = pdata;
-
- ret = tegra_asoc_utils_init(&machine->util_data, &pdev->dev);
- if (ret)
- goto err_free_machine;
+ machine->pcm_dev = ERR_PTR(-EINVAL);
card->dev = &pdev->dev;
platform_set_drvdata(pdev, card);
snd_soc_card_set_drvdata(card, machine);
- if (machine_is_harmony()) {
- card->dapm_routes = harmony_audio_map;
- card->num_dapm_routes = ARRAY_SIZE(harmony_audio_map);
- } else if (machine_is_seaboard()) {
- card->dapm_routes = seaboard_audio_map;
- card->num_dapm_routes = ARRAY_SIZE(seaboard_audio_map);
- } else if (machine_is_kaen()) {
- card->dapm_routes = kaen_audio_map;
- card->num_dapm_routes = ARRAY_SIZE(kaen_audio_map);
+ if (pdev->dev.of_node) {
+ ret = snd_soc_of_parse_card_name(card, "nvidia,model");
+ if (ret)
+ goto err;
+
+ ret = snd_soc_of_parse_audio_routing(card,
+ "nvidia,audio-routing");
+ if (ret)
+ goto err;
+
+ tegra_wm8903_dai.codec_name = NULL;
+ tegra_wm8903_dai.codec_of_node = of_parse_phandle(
+ pdev->dev.of_node, "nvidia,audio-codec", 0);
+ if (!tegra_wm8903_dai.codec_of_node) {
+ dev_err(&pdev->dev,
+ "Property 'nvidia,audio-codec' missing or invalid\n");
+ ret = -EINVAL;
+ goto err;
+ }
+
+ tegra_wm8903_dai.cpu_dai_name = NULL;
+ tegra_wm8903_dai.cpu_dai_of_node = of_parse_phandle(
+ pdev->dev.of_node, "nvidia,i2s-controller", 0);
+ if (!tegra_wm8903_dai.cpu_dai_of_node) {
+ dev_err(&pdev->dev,
+ "Property 'nvidia,i2s-controller' missing or invalid\n");
+ ret = -EINVAL;
+ goto err;
+ }
+
+ machine->pcm_dev = platform_device_register_simple(
+ "tegra-pcm-audio", -1, NULL, 0);
+ if (IS_ERR(machine->pcm_dev)) {
+ dev_err(&pdev->dev,
+ "Can't instantiate tegra-pcm-audio\n");
+ ret = PTR_ERR(machine->pcm_dev);
+ goto err;
+ }
} else {
- card->dapm_routes = aebl_audio_map;
- card->num_dapm_routes = ARRAY_SIZE(aebl_audio_map);
+ if (machine_is_harmony()) {
+ card->dapm_routes = harmony_audio_map;
+ card->num_dapm_routes = ARRAY_SIZE(harmony_audio_map);
+ } else if (machine_is_seaboard()) {
+ card->dapm_routes = seaboard_audio_map;
+ card->num_dapm_routes = ARRAY_SIZE(seaboard_audio_map);
+ } else if (machine_is_kaen()) {
+ card->dapm_routes = kaen_audio_map;
+ card->num_dapm_routes = ARRAY_SIZE(kaen_audio_map);
+ } else {
+ card->dapm_routes = aebl_audio_map;
+ card->num_dapm_routes = ARRAY_SIZE(aebl_audio_map);
+ }
}
+ ret = tegra_asoc_utils_init(&machine->util_data, &pdev->dev);
+ if (ret)
+ goto err_unregister;
+
ret = snd_soc_register_card(card);
if (ret) {
dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n",
@@ -418,8 +467,10 @@
err_fini_utils:
tegra_asoc_utils_fini(&machine->util_data);
-err_free_machine:
- kfree(machine);
+err_unregister:
+ if (!IS_ERR(machine->pcm_dev))
+ platform_device_unregister(machine->pcm_dev);
+err:
return ret;
}
@@ -427,7 +478,7 @@
{
struct snd_soc_card *card = platform_get_drvdata(pdev);
struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card);
- struct tegra_wm8903_platform_data *pdata = machine->pdata;
+ struct tegra_wm8903_platform_data *pdata = &machine->pdata;
if (machine->gpio_requested & GPIO_HP_DET)
snd_soc_jack_free_gpios(&tegra_wm8903_hp_jack,
@@ -446,35 +497,31 @@
snd_soc_unregister_card(card);
tegra_asoc_utils_fini(&machine->util_data);
-
- kfree(machine);
+ if (!IS_ERR(machine->pcm_dev))
+ platform_device_unregister(machine->pcm_dev);
return 0;
}
+static const struct of_device_id tegra_wm8903_of_match[] __devinitconst = {
+ { .compatible = "nvidia,tegra-audio-wm8903", },
+ {},
+};
+
static struct platform_driver tegra_wm8903_driver = {
.driver = {
.name = DRV_NAME,
.owner = THIS_MODULE,
.pm = &snd_soc_pm_ops,
+ .of_match_table = tegra_wm8903_of_match,
},
.probe = tegra_wm8903_driver_probe,
.remove = __devexit_p(tegra_wm8903_driver_remove),
};
-
-static int __init tegra_wm8903_modinit(void)
-{
- return platform_driver_register(&tegra_wm8903_driver);
-}
-module_init(tegra_wm8903_modinit);
-
-static void __exit tegra_wm8903_modexit(void)
-{
- platform_driver_unregister(&tegra_wm8903_driver);
-}
-module_exit(tegra_wm8903_modexit);
+module_platform_driver(tegra_wm8903_driver);
MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>");
MODULE_DESCRIPTION("Tegra+WM8903 machine ASoC driver");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:" DRV_NAME);
+MODULE_DEVICE_TABLE(of, tegra_wm8903_of_match);
diff --git a/sound/soc/tegra/trimslice.c b/sound/soc/tegra/trimslice.c
index b3a7efa..2bdfc550 100644
--- a/sound/soc/tegra/trimslice.c
+++ b/sound/soc/tegra/trimslice.c
@@ -115,18 +115,6 @@
{"RLINEIN", NULL, "Line In"},
};
-static int trimslice_asoc_init(struct snd_soc_pcm_runtime *rtd)
-{
- struct snd_soc_codec *codec = rtd->codec;
- struct snd_soc_dapm_context *dapm = &codec->dapm;
-
- snd_soc_dapm_nc_pin(dapm, "LHPOUT");
- snd_soc_dapm_nc_pin(dapm, "RHPOUT");
- snd_soc_dapm_nc_pin(dapm, "MICIN");
-
- return 0;
-}
-
static struct snd_soc_dai_link trimslice_tlv320aic23_dai = {
.name = "TLV320AIC23",
.stream_name = "AIC23",
@@ -134,12 +122,12 @@
.platform_name = "tegra-pcm-audio",
.cpu_dai_name = "tegra-i2s.0",
.codec_dai_name = "tlv320aic23-hifi",
- .init = trimslice_asoc_init,
.ops = &trimslice_asoc_ops,
};
static struct snd_soc_card snd_soc_trimslice = {
.name = "tegra-trimslice",
+ .owner = THIS_MODULE,
.dai_link = &trimslice_tlv320aic23_dai,
.num_links = 1,
@@ -147,6 +135,7 @@
.num_dapm_widgets = ARRAY_SIZE(trimslice_dapm_widgets),
.dapm_routes = trimslice_audio_map,
.num_dapm_routes = ARRAY_SIZE(trimslice_audio_map),
+ .fully_routed = true,
};
static __devinit int tegra_snd_trimslice_probe(struct platform_device *pdev)
@@ -155,15 +144,17 @@
struct tegra_trimslice *trimslice;
int ret;
- trimslice = kzalloc(sizeof(struct tegra_trimslice), GFP_KERNEL);
+ trimslice = devm_kzalloc(&pdev->dev, sizeof(struct tegra_trimslice),
+ GFP_KERNEL);
if (!trimslice) {
dev_err(&pdev->dev, "Can't allocate tegra_trimslice\n");
- return -ENOMEM;
+ ret = -ENOMEM;
+ goto err;
}
ret = tegra_asoc_utils_init(&trimslice->util_data, &pdev->dev);
if (ret)
- goto err_free_trimslice;
+ goto err;
card->dev = &pdev->dev;
platform_set_drvdata(pdev, card);
@@ -180,8 +171,7 @@
err_fini_utils:
tegra_asoc_utils_fini(&trimslice->util_data);
-err_free_trimslice:
- kfree(trimslice);
+err:
return ret;
}
@@ -194,8 +184,6 @@
tegra_asoc_utils_fini(&trimslice->util_data);
- kfree(trimslice);
-
return 0;
}
@@ -207,18 +195,7 @@
.probe = tegra_snd_trimslice_probe,
.remove = __devexit_p(tegra_snd_trimslice_remove),
};
-
-static int __init snd_tegra_trimslice_init(void)
-{
- return platform_driver_register(&tegra_snd_trimslice_driver);
-}
-module_init(snd_tegra_trimslice_init);
-
-static void __exit snd_tegra_trimslice_exit(void)
-{
- platform_driver_unregister(&tegra_snd_trimslice_driver);
-}
-module_exit(snd_tegra_trimslice_exit);
+module_platform_driver(tegra_snd_trimslice_driver);
MODULE_AUTHOR("Mike Rapoport <mike@compulab.co.il>");
MODULE_DESCRIPTION("Trimslice machine ASoC driver");
diff --git a/sound/soc/txx9/txx9aclc-ac97.c b/sound/soc/txx9/txx9aclc-ac97.c
index a4e3f55..28db4ca 100644
--- a/sound/soc/txx9/txx9aclc-ac97.c
+++ b/sound/soc/txx9/txx9aclc-ac97.c
@@ -223,18 +223,7 @@
},
};
-static int __init txx9aclc_ac97_init(void)
-{
- return platform_driver_register(&txx9aclc_ac97_driver);
-}
-
-static void __exit txx9aclc_ac97_exit(void)
-{
- platform_driver_unregister(&txx9aclc_ac97_driver);
-}
-
-module_init(txx9aclc_ac97_init);
-module_exit(txx9aclc_ac97_exit);
+module_platform_driver(txx9aclc_ac97_driver);
MODULE_AUTHOR("Atsushi Nemoto <anemo@mba.ocn.ne.jp>");
MODULE_DESCRIPTION("TXx9 ACLC AC97 driver");
diff --git a/sound/soc/txx9/txx9aclc-generic.c b/sound/soc/txx9/txx9aclc-generic.c
index 9b5e283..b056a14 100644
--- a/sound/soc/txx9/txx9aclc-generic.c
+++ b/sound/soc/txx9/txx9aclc-generic.c
@@ -32,6 +32,7 @@
static struct snd_soc_card txx9aclc_generic_card = {
.name = "Generic TXx9 ACLC Audio",
+ .owner = THIS_MODULE,
.dai_link = &txx9aclc_generic_dai,
.num_links = 1,
};
diff --git a/sound/soc/txx9/txx9aclc.c b/sound/soc/txx9/txx9aclc.c
index 3de99af..93931de 100644
--- a/sound/soc/txx9/txx9aclc.c
+++ b/sound/soc/txx9/txx9aclc.c
@@ -438,17 +438,7 @@
.remove = __devexit_p(txx9aclc_soc_platform_remove),
};
-static int __init snd_txx9aclc_pcm_init(void)
-{
- return platform_driver_register(&txx9aclc_pcm_driver);
-}
-module_init(snd_txx9aclc_pcm_init);
-
-static void __exit snd_txx9aclc_pcm_exit(void)
-{
- platform_driver_unregister(&txx9aclc_pcm_driver);
-}
-module_exit(snd_txx9aclc_pcm_exit);
+module_platform_driver(txx9aclc_pcm_driver);
MODULE_AUTHOR("Atsushi Nemoto <anemo@mba.ocn.ne.jp>");
MODULE_DESCRIPTION("TXx9 ACLC Audio DMA driver");
diff --git a/sound/sparc/amd7930.c b/sound/sparc/amd7930.c
index f036776..b63b3a8 100644
--- a/sound/sparc/amd7930.c
+++ b/sound/sparc/amd7930.c
@@ -50,7 +50,7 @@
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
+static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
module_param_array(index, int, NULL, 0444);
MODULE_PARM_DESC(index, "Index value for Sun AMD7930 soundcard.");
diff --git a/sound/sparc/cs4231.c b/sound/sparc/cs4231.c
index 0e618f8..f2eabd3 100644
--- a/sound/sparc/cs4231.c
+++ b/sound/sparc/cs4231.c
@@ -40,7 +40,7 @@
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
/* Enable this card */
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
+static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
module_param_array(index, int, NULL, 0444);
MODULE_PARM_DESC(index, "Index value for Sun CS4231 soundcard.");
@@ -2118,15 +2118,4 @@
.remove = __devexit_p(cs4231_remove),
};
-static int __init cs4231_init(void)
-{
- return platform_driver_register(&cs4231_driver);
-}
-
-static void __exit cs4231_exit(void)
-{
- platform_driver_unregister(&cs4231_driver);
-}
-
-module_init(cs4231_init);
-module_exit(cs4231_exit);
+module_platform_driver(cs4231_driver);
diff --git a/sound/sparc/dbri.c b/sound/sparc/dbri.c
index 4a4f1d7..a6b0deb 100644
--- a/sound/sparc/dbri.c
+++ b/sound/sparc/dbri.c
@@ -80,7 +80,7 @@
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
/* Enable this card */
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
+static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
module_param_array(index, int, NULL, 0444);
MODULE_PARM_DESC(index, "Index value for Sun DBRI soundcard.");
@@ -2697,16 +2697,4 @@
.remove = __devexit_p(dbri_remove),
};
-/* Probe for the dbri chip and then attach the driver. */
-static int __init dbri_init(void)
-{
- return platform_driver_register(&dbri_sbus_driver);
-}
-
-static void __exit dbri_exit(void)
-{
- platform_driver_unregister(&dbri_sbus_driver);
-}
-
-module_init(dbri_init);
-module_exit(dbri_exit);
+module_platform_driver(dbri_sbus_driver);
diff --git a/sound/usb/6fire/chip.c b/sound/usb/6fire/chip.c
index ac2d5e1..8af92e3 100644
--- a/sound/usb/6fire/chip.c
+++ b/sound/usb/6fire/chip.c
@@ -35,7 +35,7 @@
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-max */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* Id for card */
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable card */
+static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable card */
static struct sfire_chip *chips[SNDRV_CARDS] = SNDRV_DEFAULT_PTR;
static struct usb_device *devices[SNDRV_CARDS] = SNDRV_DEFAULT_PTR;
diff --git a/sound/usb/caiaq/device.c b/sound/usb/caiaq/device.c
index 457fb27..64aed43 100644
--- a/sound/usb/caiaq/device.c
+++ b/sound/usb/caiaq/device.c
@@ -55,7 +55,7 @@
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-max */
static char* id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* Id for this card */
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
+static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
static int snd_card_used[SNDRV_CARDS];
module_param_array(index, int, NULL, 0444);
diff --git a/sound/usb/card.c b/sound/usb/card.c
index 0f6dc0d..4a7be7b 100644
--- a/sound/usb/card.c
+++ b/sound/usb/card.c
@@ -78,14 +78,14 @@
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;/* Enable this card */
+static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;/* Enable this card */
/* Vendor/product IDs for this card */
static int vid[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = -1 };
static int pid[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = -1 };
static int nrpacks = 8; /* max. number of packets per urb */
-static int async_unlink = 1;
+static bool async_unlink = 1;
static int device_setup[SNDRV_CARDS]; /* device parameter for this card */
-static int ignore_ctl_error;
+static bool ignore_ctl_error;
module_param_array(index, int, NULL, 0444);
MODULE_PARM_DESC(index, "Index value for the USB audio adapter.");
diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c
index 81c6ede..08dcce5 100644
--- a/sound/usb/endpoint.c
+++ b/sound/usb/endpoint.c
@@ -17,6 +17,7 @@
#include <linux/gfp.h>
#include <linux/init.h>
+#include <linux/ratelimit.h>
#include <linux/usb.h>
#include <linux/usb/audio.h>
@@ -458,8 +459,8 @@
for (i = 0; i < urb->number_of_packets; i++) {
cp = (unsigned char *)urb->transfer_buffer + urb->iso_frame_desc[i].offset;
- if (urb->iso_frame_desc[i].status) {
- snd_printd(KERN_ERR "frame %d active: %d\n", i, urb->iso_frame_desc[i].status);
+ if (urb->iso_frame_desc[i].status && printk_ratelimit()) {
+ snd_printdd("frame %d active: %d\n", i, urb->iso_frame_desc[i].status);
// continue;
}
bytes = urb->iso_frame_desc[i].actual_length;
diff --git a/sound/usb/format.c b/sound/usb/format.c
index 89421d1..e09aba1 100644
--- a/sound/usb/format.c
+++ b/sound/usb/format.c
@@ -209,6 +209,8 @@
return 0;
}
+#define MAX_UAC2_NR_RATES 1024
+
/*
* Helper function to walk the array of sample rate triplets reported by
* the device. The problem is that we need to parse whole array first to
@@ -226,7 +228,7 @@
int min = combine_quad(&data[2 + 12 * i]);
int max = combine_quad(&data[6 + 12 * i]);
int res = combine_quad(&data[10 + 12 * i]);
- int rate;
+ unsigned int rate;
if ((max < 0) || (min < 0) || (res < 0) || (max < min))
continue;
@@ -253,6 +255,10 @@
fp->rates |= snd_pcm_rate_to_rate_bit(rate);
nr_rates++;
+ if (nr_rates >= MAX_UAC2_NR_RATES) {
+ snd_printk(KERN_ERR "invalid uac2 rates\n");
+ break;
+ }
/* avoid endless loop */
if (res == 0)
diff --git a/sound/usb/misc/ua101.c b/sound/usb/misc/ua101.c
index 4c11da9..8b81cb5 100644
--- a/sound/usb/misc/ua101.c
+++ b/sound/usb/misc/ua101.c
@@ -52,7 +52,7 @@
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 bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
static unsigned int queue_length = 21;
module_param_array(index, int, NULL, 0444);
diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h
index 32d2a21..8edc503 100644
--- a/sound/usb/quirks-table.h
+++ b/sound/usb/quirks-table.h
@@ -269,6 +269,32 @@
YAMAHA_DEVICE(0x105b, NULL),
YAMAHA_DEVICE(0x105c, NULL),
YAMAHA_DEVICE(0x105d, NULL),
+{
+ USB_DEVICE(0x0499, 0x1503),
+ .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
+ /* .vendor_name = "Yamaha", */
+ /* .product_name = "MOX6/MOX8", */
+ .ifnum = QUIRK_ANY_INTERFACE,
+ .type = QUIRK_COMPOSITE,
+ .data = (const struct snd_usb_audio_quirk[]) {
+ {
+ .ifnum = 1,
+ .type = QUIRK_AUDIO_STANDARD_INTERFACE
+ },
+ {
+ .ifnum = 2,
+ .type = QUIRK_AUDIO_STANDARD_INTERFACE
+ },
+ {
+ .ifnum = 3,
+ .type = QUIRK_MIDI_YAMAHA
+ },
+ {
+ .ifnum = -1
+ }
+ }
+ }
+},
YAMAHA_DEVICE(0x2000, "DGP-7"),
YAMAHA_DEVICE(0x2001, "DGP-5"),
YAMAHA_DEVICE(0x2002, NULL),
@@ -2336,6 +2362,16 @@
}
},
+{
+ USB_DEVICE_VENDOR_SPEC(0x0944, 0x0201),
+ .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
+ .vendor_name = "KORG, Inc.",
+ /* .product_name = "ToneLab ST", */
+ .ifnum = 3,
+ .type = QUIRK_MIDI_STANDARD_INTERFACE,
+ }
+},
+
/* AKAI devices */
{
USB_DEVICE(0x09e8, 0x0062),
diff --git a/sound/usb/usx2y/us122l.c b/sound/usb/usx2y/us122l.c
index 625f7ca..c4fd3b1 100644
--- a/sound/usb/usx2y/us122l.c
+++ b/sound/usb/usx2y/us122l.c
@@ -37,7 +37,7 @@
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-max */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* Id for this card */
/* Enable this card */
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
+static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
module_param_array(index, int, NULL, 0444);
MODULE_PARM_DESC(index, "Index value for "NAME_ALLCAPS".");
diff --git a/sound/usb/usx2y/usb_stream.c b/sound/usb/usx2y/usb_stream.c
index c400ade..1e7a47a 100644
--- a/sound/usb/usx2y/usb_stream.c
+++ b/sound/usb/usx2y/usb_stream.c
@@ -674,7 +674,7 @@
inurb->transfer_buffer_length =
inurb->number_of_packets *
inurb->iso_frame_desc[0].length;
- preempt_disable();
+
if (u == 0) {
int now;
struct usb_device *dev = inurb->dev;
@@ -686,19 +686,17 @@
}
err = usb_submit_urb(inurb, GFP_ATOMIC);
if (err < 0) {
- preempt_enable();
snd_printk(KERN_ERR"usb_submit_urb(sk->inurb[%i])"
" returned %i\n", u, err);
return err;
}
err = usb_submit_urb(outurb, GFP_ATOMIC);
if (err < 0) {
- preempt_enable();
snd_printk(KERN_ERR"usb_submit_urb(sk->outurb[%i])"
" returned %i\n", u, err);
return err;
}
- preempt_enable();
+
if (inurb->start_frame != outurb->start_frame) {
snd_printd(KERN_DEBUG
"u[%i] start_frames differ in:%u out:%u\n",
diff --git a/sound/usb/usx2y/usbusx2y.c b/sound/usb/usx2y/usbusx2y.c
index 0c738ed..9af7c1f 100644
--- a/sound/usb/usx2y/usbusx2y.c
+++ b/sound/usb/usx2y/usbusx2y.c
@@ -154,7 +154,7 @@
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-max */
static char* id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* Id for this card */
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
+static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
module_param_array(index, int, NULL, 0444);
MODULE_PARM_DESC(index, "Index value for "NAME_ALLCAPS".");